From 5b181d33d49cde3cb128a6582501b50e22bdee10 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:09:28 +0200 Subject: [PATCH 001/353] Initial removal of unneeded progression types --- .../CSharpProgressionLanguageService.cs | 256 +-- .../Core/Def/Progression/GraphBuilder.cs | 430 ++--- .../Core/Def/Progression/GraphNodeCreation.cs | 32 +- .../Core/Def/Progression/GraphProvider.cs | 126 +- .../GraphQueries/CallsGraphQuery.cs | 110 +- .../ContainsChildrenGraphQuery.cs | 150 +- .../GraphQueries/ContainsGraphQuery.cs | 112 +- .../GraphQueries/ImplementedByGraphQuery.cs | 80 +- .../GraphQueries/ImplementsGraphQuery.cs | 98 +- .../GraphQueries/InheritedByGraphQuery.cs | 102 +- .../GraphQueries/InheritsGraphQuery.cs | 120 +- .../GraphQueries/IsCalledByGraphQuery.cs | 74 +- .../GraphQueries/IsUsedByGraphQuery.cs | 124 +- .../GraphQueries/OverriddenByGraphQuery.cs | 66 +- .../GraphQueries/OverridesGraphQuery.cs | 72 +- .../IProgressionLanguageService.cs | 28 +- .../Core/Def/Progression/SymbolContainment.cs | 154 +- .../Progression/CSharpSymbolLabelTests.vb | 390 ++-- .../Test/Progression/CallsGraphQueryTests.vb | 470 ++--- .../ContainsChildrenGraphQueryTests.vb | 324 ++-- .../Progression/ContainsGraphQueryTests.vb | 784 ++++---- .../Progression/GraphNodeCreationTests.vb | 1622 ++++++++--------- .../Core/Test/Progression/GraphNodeIdTests.vb | 266 +-- .../Test/Progression/GraphProviderTests.vb | 24 +- .../ImplementedByGraphQueryTests.vb | 126 +- .../Progression/ImplementsGraphQueryTests.vb | 156 +- .../Progression/InheritedByGraphQueryTests.vb | 476 ++--- .../InheritsFromGraphQueryTests.vb | 216 +-- .../Progression/IsCalledByGraphQueryTests.vb | 118 +- .../Progression/IsUsedByGraphQueryTests.vb | 110 +- .../OverriddenByGraphQueryTests.vb | 180 +- .../Progression/OverridesGraphQueryTests.vb | 180 +- .../Test/Progression/ProgressionTestState.vb | 34 +- .../VisualBasicSymbolLabelTests.vb | 146 +- .../VisualBasicProgressionLanguageService.vb | 190 +- 35 files changed, 3973 insertions(+), 3973 deletions(-) diff --git a/src/VisualStudio/CSharp/Impl/Progression/CSharpProgressionLanguageService.cs b/src/VisualStudio/CSharp/Impl/Progression/CSharpProgressionLanguageService.cs index 2a538e5454a8c..156fd89c0919e 100644 --- a/src/VisualStudio/CSharp/Impl/Progression/CSharpProgressionLanguageService.cs +++ b/src/VisualStudio/CSharp/Impl/Progression/CSharpProgressionLanguageService.cs @@ -1,128 +1,128 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#nullable disable - -using System; -using System.Collections.Generic; -using System.Composition; -using System.Threading; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Symbols; -using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.PooledObjects; -using Microsoft.CodeAnalysis.Shared.Extensions; -using Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -namespace Microsoft.VisualStudio.LanguageServices.CSharp.Progression; - -[ExportLanguageService(typeof(IProgressionLanguageService), LanguageNames.CSharp), Shared] -internal sealed partial class CSharpProgressionLanguageService : IProgressionLanguageService -{ - private static readonly SymbolDisplayFormat s_descriptionFormat = new( - globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.OmittedAsContaining, - typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces, - genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters, - memberOptions: SymbolDisplayMemberOptions.IncludeParameters | - SymbolDisplayMemberOptions.IncludeContainingType, - parameterOptions: SymbolDisplayParameterOptions.IncludeType | - SymbolDisplayParameterOptions.IncludeParamsRefOut | - SymbolDisplayParameterOptions.IncludeOptionalBrackets, - miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes); - - private static readonly SymbolDisplayFormat s_labelFormat = new( - genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters, - memberOptions: SymbolDisplayMemberOptions.IncludeParameters | - SymbolDisplayMemberOptions.IncludeExplicitInterface, - parameterOptions: SymbolDisplayParameterOptions.IncludeType | - SymbolDisplayParameterOptions.IncludeParamsRefOut | - SymbolDisplayParameterOptions.IncludeOptionalBrackets, - delegateStyle: SymbolDisplayDelegateStyle.NameAndParameters, - miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes); - - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public CSharpProgressionLanguageService() - { - } - - public IEnumerable GetTopLevelNodesFromDocument(SyntaxNode root, CancellationToken cancellationToken) - { - // We implement this method lazily so we are able to abort as soon as we need to. - if (!cancellationToken.IsCancellationRequested) - { - using var _ = ArrayBuilder.GetInstance(out var nodes); - nodes.Push(root); - - while (nodes.TryPop(out var node)) - { - if (!cancellationToken.IsCancellationRequested) - { - if (node.Kind() is SyntaxKind.ClassDeclaration or - SyntaxKind.RecordDeclaration or - SyntaxKind.RecordStructDeclaration or - SyntaxKind.DelegateDeclaration or - SyntaxKind.EnumDeclaration or - SyntaxKind.InterfaceDeclaration or - SyntaxKind.StructDeclaration or - SyntaxKind.VariableDeclarator or - SyntaxKind.MethodDeclaration or - SyntaxKind.PropertyDeclaration) - { - yield return node; - } - else - { - foreach (var child in node.ChildNodes()) - { - nodes.Push(child); - } - } - } - } - } - } - - public string GetDescriptionForSymbol(ISymbol symbol, bool includeContainingSymbol) - => GetSymbolText(symbol, includeContainingSymbol, s_descriptionFormat); - - public string GetLabelForSymbol(ISymbol symbol, bool includeContainingSymbol) - => GetSymbolText(symbol, includeContainingSymbol, s_labelFormat); - - private static string GetSymbolText(ISymbol symbol, bool includeContainingSymbol, SymbolDisplayFormat displayFormat) - { - var label = symbol.ToDisplayString(displayFormat); - - var typeToShow = GetType(symbol); - - if (typeToShow != null) - { - label += " : " + typeToShow.ToDisplayString(s_labelFormat); - } - - if (includeContainingSymbol && symbol.ContainingSymbol != null) - { - label += " (" + symbol.ContainingSymbol.ToDisplayString(s_labelFormat) + ")"; - } - - return label; - } - - private static ITypeSymbol GetType(ISymbol symbol) - { - switch (symbol) - { - case IEventSymbol f: return f.Type; - case IFieldSymbol f: return f.ContainingType.TypeKind == TypeKind.Enum ? null : f.Type; - case IMethodSymbol m: return IncludeReturnType(m) ? m.ReturnType : null; - case IPropertySymbol p: return p.Type; - case INamedTypeSymbol n: return n.IsDelegateType() ? n.DelegateInvokeMethod.ReturnType : null; - default: return null; - } - } - - private static bool IncludeReturnType(IMethodSymbol f) - => f.MethodKind is MethodKind.Ordinary or MethodKind.ExplicitInterfaceImplementation; -} +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. + +//#nullable disable + +//using System; +//using System.Collections.Generic; +//using System.Composition; +//using System.Threading; +//using Microsoft.CodeAnalysis; +//using Microsoft.CodeAnalysis.CSharp; +//using Microsoft.CodeAnalysis.CSharp.Symbols; +//using Microsoft.CodeAnalysis.Host.Mef; +//using Microsoft.CodeAnalysis.PooledObjects; +//using Microsoft.CodeAnalysis.Shared.Extensions; +//using Microsoft.VisualStudio.LanguageServices.Implementation.Progression; + +//namespace Microsoft.VisualStudio.LanguageServices.CSharp.Progression; + +//[ExportLanguageService(typeof(IProgressionLanguageService), LanguageNames.CSharp), Shared] +//internal sealed partial class CSharpProgressionLanguageService : IProgressionLanguageService +//{ +// private static readonly SymbolDisplayFormat s_descriptionFormat = new( +// globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.OmittedAsContaining, +// typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces, +// genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters, +// memberOptions: SymbolDisplayMemberOptions.IncludeParameters | +// SymbolDisplayMemberOptions.IncludeContainingType, +// parameterOptions: SymbolDisplayParameterOptions.IncludeType | +// SymbolDisplayParameterOptions.IncludeParamsRefOut | +// SymbolDisplayParameterOptions.IncludeOptionalBrackets, +// miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes); + +// private static readonly SymbolDisplayFormat s_labelFormat = new( +// genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters, +// memberOptions: SymbolDisplayMemberOptions.IncludeParameters | +// SymbolDisplayMemberOptions.IncludeExplicitInterface, +// parameterOptions: SymbolDisplayParameterOptions.IncludeType | +// SymbolDisplayParameterOptions.IncludeParamsRefOut | +// SymbolDisplayParameterOptions.IncludeOptionalBrackets, +// delegateStyle: SymbolDisplayDelegateStyle.NameAndParameters, +// miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes); + +// [ImportingConstructor] +// [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] +// public CSharpProgressionLanguageService() +// { +// } + +// public IEnumerable GetTopLevelNodesFromDocument(SyntaxNode root, CancellationToken cancellationToken) +// { +// // We implement this method lazily so we are able to abort as soon as we need to. +// if (!cancellationToken.IsCancellationRequested) +// { +// using var _ = ArrayBuilder.GetInstance(out var nodes); +// nodes.Push(root); + +// while (nodes.TryPop(out var node)) +// { +// if (!cancellationToken.IsCancellationRequested) +// { +// if (node.Kind() is SyntaxKind.ClassDeclaration or +// SyntaxKind.RecordDeclaration or +// SyntaxKind.RecordStructDeclaration or +// SyntaxKind.DelegateDeclaration or +// SyntaxKind.EnumDeclaration or +// SyntaxKind.InterfaceDeclaration or +// SyntaxKind.StructDeclaration or +// SyntaxKind.VariableDeclarator or +// SyntaxKind.MethodDeclaration or +// SyntaxKind.PropertyDeclaration) +// { +// yield return node; +// } +// else +// { +// foreach (var child in node.ChildNodes()) +// { +// nodes.Push(child); +// } +// } +// } +// } +// } +// } + +// public string GetDescriptionForSymbol(ISymbol symbol, bool includeContainingSymbol) +// => GetSymbolText(symbol, includeContainingSymbol, s_descriptionFormat); + +// public string GetLabelForSymbol(ISymbol symbol, bool includeContainingSymbol) +// => GetSymbolText(symbol, includeContainingSymbol, s_labelFormat); + +// private static string GetSymbolText(ISymbol symbol, bool includeContainingSymbol, SymbolDisplayFormat displayFormat) +// { +// var label = symbol.ToDisplayString(displayFormat); + +// var typeToShow = GetType(symbol); + +// if (typeToShow != null) +// { +// label += " : " + typeToShow.ToDisplayString(s_labelFormat); +// } + +// if (includeContainingSymbol && symbol.ContainingSymbol != null) +// { +// label += " (" + symbol.ContainingSymbol.ToDisplayString(s_labelFormat) + ")"; +// } + +// return label; +// } + +// private static ITypeSymbol GetType(ISymbol symbol) +// { +// switch (symbol) +// { +// case IEventSymbol f: return f.Type; +// case IFieldSymbol f: return f.ContainingType.TypeKind == TypeKind.Enum ? null : f.Type; +// case IMethodSymbol m: return IncludeReturnType(m) ? m.ReturnType : null; +// case IPropertySymbol p: return p.Type; +// case INamedTypeSymbol n: return n.IsDelegateType() ? n.DelegateInvokeMethod.ReturnType : null; +// default: return null; +// } +// } + +// private static bool IncludeReturnType(IMethodSymbol f) +// => f.MethodKind is MethodKind.Ordinary or MethodKind.ExplicitInterfaceImplementation; +//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs b/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs index 76abcdc6c535e..0ada9e186601e 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs @@ -181,131 +181,131 @@ public ISymbol GetSymbol(GraphNode node, CancellationToken cancellationToken) } } - public Task AddNodeAsync(ISymbol symbol, GraphNode relatedNode, CancellationToken cancellationToken) - { - // The lack of a lock here is acceptable, since each of the functions lock, and GetContextProject/GetContextDocument - // never change for the same input. - return AddNodeAsync( - symbol, - GetContextProject(relatedNode, cancellationToken), - GetContextDocument(relatedNode, cancellationToken), - cancellationToken); - } - - public async Task AddNodeAsync( - ISymbol symbol, Project contextProject, Document contextDocument, CancellationToken cancellationToken) - { - // Figure out what the location for this node should be. We'll arbitrarily pick the - // first one, unless we have a contextDocument to restrict it - var preferredLocation = symbol.Locations.FirstOrDefault(l => l.SourceTree != null); - - if (contextDocument != null) - { - var syntaxTree = await contextDocument.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); - - // If we have one in that tree, use it - preferredLocation = symbol.Locations.FirstOrDefault(l => l.SourceTree == syntaxTree) ?? preferredLocation; - } - - // We may need to look up source code within this solution - if (preferredLocation == null && symbol.Locations.Any(static loc => loc.IsInMetadata)) - { - var newSymbol = await SymbolFinder.FindSourceDefinitionAsync(symbol, contextProject.Solution, cancellationToken).ConfigureAwait(false); - if (newSymbol != null) - preferredLocation = newSymbol.Locations.Where(loc => loc.IsInSource).FirstOrDefault(); - } - - using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) - { - var node = await GetOrCreateNodeAsync(Graph, symbol, _solution, cancellationToken).ConfigureAwait(false); - - node[RoslynGraphProperties.SymbolId] = (SymbolKey?)symbol.GetSymbolKey(cancellationToken); - node[RoslynGraphProperties.ContextProjectId] = GetContextProjectId(contextProject, symbol); - node[RoslynGraphProperties.ExplicitInterfaceImplementations] = symbol.ExplicitInterfaceImplementations().Select(s => s.GetSymbolKey()).ToList(); - node[RoslynGraphProperties.DeclaredAccessibility] = symbol.DeclaredAccessibility; - node[RoslynGraphProperties.SymbolModifiers] = symbol.GetSymbolModifiers(); - node[RoslynGraphProperties.SymbolKind] = symbol.Kind; - - if (contextDocument != null) - node[RoslynGraphProperties.ContextDocumentId] = contextDocument.Id; - - if (preferredLocation?.SourceTree != null) - { - var lineSpan = preferredLocation.GetLineSpan(); - var sourceLocation = TryCreateSourceLocation( - preferredLocation.SourceTree.FilePath, - lineSpan.Span); - if (sourceLocation != null) - node[CodeNodeProperties.SourceLocation] = sourceLocation.Value; - } - - // Keep track of this as a node we have added. Note this is a HashSet, so if the node was already added - // we won't double-count. - _createdNodes.Add(node); - - _nodeToSymbolMap[node] = symbol; - _nodeToContextProjectMap[node] = contextProject; - - if (contextDocument != null) - _nodeToContextDocumentMap[node] = contextDocument; - - return node; - } - } - - internal static async Task GetOrCreateNodeAsync(Graph graph, ISymbol symbol, Solution solution, CancellationToken cancellationToken) - { - GraphNode node; - - switch (symbol.Kind) - { - case SymbolKind.Assembly: - node = await GetOrCreateNodeAssemblyAsync(graph, (IAssemblySymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - break; - - case SymbolKind.Namespace: - node = await GetOrCreateNodeForNamespaceAsync(graph, (INamespaceSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - break; - - case SymbolKind.NamedType: - case SymbolKind.ErrorType: - node = await GetOrCreateNodeForNamedTypeAsync(graph, (INamedTypeSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - break; - - case SymbolKind.Method: - node = await GetOrCreateNodeForMethodAsync(graph, (IMethodSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - break; - - case SymbolKind.Field: - node = await GetOrCreateNodeForFieldAsync(graph, (IFieldSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - break; - - case SymbolKind.Property: - node = await GetOrCreateNodeForPropertyAsync(graph, (IPropertySymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - break; - - case SymbolKind.Event: - node = await GetOrCreateNodeForEventAsync(graph, (IEventSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - break; - - case SymbolKind.Parameter: - node = await GetOrCreateNodeForParameterAsync(graph, (IParameterSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - break; - - case SymbolKind.Local: - case SymbolKind.RangeVariable: - node = await GetOrCreateNodeForLocalVariableAsync(graph, symbol, solution, cancellationToken).ConfigureAwait(false); - break; - - default: - throw new ArgumentException("symbol"); - } - - UpdatePropertiesForNode(symbol, node); - UpdateLabelsForNode(symbol, solution, node); - - return node; - } + //public Task AddNodeAsync(ISymbol symbol, GraphNode relatedNode, CancellationToken cancellationToken) + //{ + // // The lack of a lock here is acceptable, since each of the functions lock, and GetContextProject/GetContextDocument + // // never change for the same input. + // return AddNodeAsync( + // symbol, + // GetContextProject(relatedNode, cancellationToken), + // GetContextDocument(relatedNode, cancellationToken), + // cancellationToken); + //} + + //public async Task AddNodeAsync( + // ISymbol symbol, Project contextProject, Document contextDocument, CancellationToken cancellationToken) + //{ + // // Figure out what the location for this node should be. We'll arbitrarily pick the + // // first one, unless we have a contextDocument to restrict it + // var preferredLocation = symbol.Locations.FirstOrDefault(l => l.SourceTree != null); + + // if (contextDocument != null) + // { + // var syntaxTree = await contextDocument.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); + + // // If we have one in that tree, use it + // preferredLocation = symbol.Locations.FirstOrDefault(l => l.SourceTree == syntaxTree) ?? preferredLocation; + // } + + // // We may need to look up source code within this solution + // if (preferredLocation == null && symbol.Locations.Any(static loc => loc.IsInMetadata)) + // { + // var newSymbol = await SymbolFinder.FindSourceDefinitionAsync(symbol, contextProject.Solution, cancellationToken).ConfigureAwait(false); + // if (newSymbol != null) + // preferredLocation = newSymbol.Locations.Where(loc => loc.IsInSource).FirstOrDefault(); + // } + + // using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) + // { + // var node = await GetOrCreateNodeAsync(Graph, symbol, _solution, cancellationToken).ConfigureAwait(false); + + // node[RoslynGraphProperties.SymbolId] = (SymbolKey?)symbol.GetSymbolKey(cancellationToken); + // node[RoslynGraphProperties.ContextProjectId] = GetContextProjectId(contextProject, symbol); + // node[RoslynGraphProperties.ExplicitInterfaceImplementations] = symbol.ExplicitInterfaceImplementations().Select(s => s.GetSymbolKey()).ToList(); + // node[RoslynGraphProperties.DeclaredAccessibility] = symbol.DeclaredAccessibility; + // node[RoslynGraphProperties.SymbolModifiers] = symbol.GetSymbolModifiers(); + // node[RoslynGraphProperties.SymbolKind] = symbol.Kind; + + // if (contextDocument != null) + // node[RoslynGraphProperties.ContextDocumentId] = contextDocument.Id; + + // if (preferredLocation?.SourceTree != null) + // { + // var lineSpan = preferredLocation.GetLineSpan(); + // var sourceLocation = TryCreateSourceLocation( + // preferredLocation.SourceTree.FilePath, + // lineSpan.Span); + // if (sourceLocation != null) + // node[CodeNodeProperties.SourceLocation] = sourceLocation.Value; + // } + + // // Keep track of this as a node we have added. Note this is a HashSet, so if the node was already added + // // we won't double-count. + // _createdNodes.Add(node); + + // _nodeToSymbolMap[node] = symbol; + // _nodeToContextProjectMap[node] = contextProject; + + // if (contextDocument != null) + // _nodeToContextDocumentMap[node] = contextDocument; + + // return node; + // } + //} + + //internal static async Task GetOrCreateNodeAsync(Graph graph, ISymbol symbol, Solution solution, CancellationToken cancellationToken) + //{ + // GraphNode node; + + // switch (symbol.Kind) + // { + // case SymbolKind.Assembly: + // node = await GetOrCreateNodeAssemblyAsync(graph, (IAssemblySymbol)symbol, solution, cancellationToken).ConfigureAwait(false); + // break; + + // case SymbolKind.Namespace: + // node = await GetOrCreateNodeForNamespaceAsync(graph, (INamespaceSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); + // break; + + // case SymbolKind.NamedType: + // case SymbolKind.ErrorType: + // node = await GetOrCreateNodeForNamedTypeAsync(graph, (INamedTypeSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); + // break; + + // case SymbolKind.Method: + // node = await GetOrCreateNodeForMethodAsync(graph, (IMethodSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); + // break; + + // case SymbolKind.Field: + // node = await GetOrCreateNodeForFieldAsync(graph, (IFieldSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); + // break; + + // case SymbolKind.Property: + // node = await GetOrCreateNodeForPropertyAsync(graph, (IPropertySymbol)symbol, solution, cancellationToken).ConfigureAwait(false); + // break; + + // case SymbolKind.Event: + // node = await GetOrCreateNodeForEventAsync(graph, (IEventSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); + // break; + + // case SymbolKind.Parameter: + // node = await GetOrCreateNodeForParameterAsync(graph, (IParameterSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); + // break; + + // case SymbolKind.Local: + // case SymbolKind.RangeVariable: + // node = await GetOrCreateNodeForLocalVariableAsync(graph, symbol, solution, cancellationToken).ConfigureAwait(false); + // break; + + // default: + // throw new ArgumentException("symbol"); + // } + + // UpdatePropertiesForNode(symbol, node); + // UpdateLabelsForNode(symbol, solution, node); + + // return node; + //} private static async Task GetOrCreateNodeForParameterAsync(Graph graph, IParameterSymbol parameterSymbol, Solution solution, CancellationToken cancellationToken) { @@ -338,96 +338,96 @@ private static async Task GetOrCreateNodeAssemblyAsync(Graph graph, I return node; } - private static void UpdateLabelsForNode(ISymbol symbol, Solution solution, GraphNode node) - { - var progressionLanguageService = solution.Services.GetLanguageServices(symbol.Language).GetService(); - - // A call from unittest may not have a proper language service. - if (progressionLanguageService != null) - { - node[RoslynGraphProperties.Description] = progressionLanguageService.GetDescriptionForSymbol(symbol, includeContainingSymbol: false); - node[RoslynGraphProperties.DescriptionWithContainingSymbol] = progressionLanguageService.GetDescriptionForSymbol(symbol, includeContainingSymbol: true); - - node[RoslynGraphProperties.FormattedLabelWithoutContainingSymbol] = progressionLanguageService.GetLabelForSymbol(symbol, includeContainingSymbol: false); - node[RoslynGraphProperties.FormattedLabelWithContainingSymbol] = progressionLanguageService.GetLabelForSymbol(symbol, includeContainingSymbol: true); - } - - switch (symbol.Kind) - { - case SymbolKind.NamedType: - var typeSymbol = (INamedTypeSymbol)symbol; - if (typeSymbol.IsGenericType) - { - // Symbol.name does not contain type params for generic types, so we populate them here for some requiring cases like VS properties panel. - node.Label = (string)node[RoslynGraphProperties.FormattedLabelWithoutContainingSymbol]; - - // Some consumers like CodeMap want to show types in an unified way for both C# and VB. - // Therefore, populate a common label property using only name and its type parameters. - // For example, VB's "Goo(Of T)" or C#'s "Goo(): T" will be shown as "Goo". - // This property will be used for drag-and-drop case. - var commonLabel = new System.Text.StringBuilder(); - commonLabel.Append(typeSymbol.Name); - commonLabel.Append('<'); - commonLabel.Append(string.Join(", ", typeSymbol.TypeParameters.Select(t => t.Name))); - commonLabel.Append('>'); - node[Microsoft.VisualStudio.ArchitectureTools.ProgressiveReveal.ProgressiveRevealSchema.CommonLabel] = commonLabel.ToString(); - - return; - } - else - { - node.Label = symbol.Name; - } - - break; - - case SymbolKind.Method: - var methodSymbol = (IMethodSymbol)symbol; - if (methodSymbol.MethodKind == MethodKind.Constructor) - { - node.Label = CodeQualifiedIdentifierBuilder.SpecialNames.GetConstructorLabel(methodSymbol.ContainingSymbol.Name); - } - else if (methodSymbol.MethodKind == MethodKind.StaticConstructor) - { - node.Label = CodeQualifiedIdentifierBuilder.SpecialNames.GetStaticConstructorLabel(methodSymbol.ContainingSymbol.Name); - } - else if (methodSymbol.MethodKind == MethodKind.Destructor) - { - node.Label = CodeQualifiedIdentifierBuilder.SpecialNames.GetFinalizerLabel(methodSymbol.ContainingSymbol.Name); - } - else - { - node.Label = methodSymbol.Name; - } - - break; - - case SymbolKind.Property: - node.Label = symbol.MetadataName; - - var propertySymbol = (IPropertySymbol)symbol; - if (propertySymbol.IsIndexer && LanguageNames.CSharp == propertySymbol.Language) - { - // For C# indexer, we will strip off the "[]" - node.Label = symbol.Name.Replace("[]", string.Empty); - } - - break; - - case SymbolKind.Namespace: - // Use a name with its parents (e.g., A.B.C) - node.Label = symbol.ToDisplayString(); - break; - - default: - node.Label = symbol.Name; - break; - } - - // When a node is dragged and dropped from SE to CodeMap, its label could be reset during copying to clipboard. - // So, we try to keep its label that we computed above in a common label property, which CodeMap can access later. - node[Microsoft.VisualStudio.ArchitectureTools.ProgressiveReveal.ProgressiveRevealSchema.CommonLabel] = node.Label; - } + //private static void UpdateLabelsForNode(ISymbol symbol, Solution solution, GraphNode node) + //{ + // var progressionLanguageService = solution.Services.GetLanguageServices(symbol.Language).GetService(); + + // // A call from unittest may not have a proper language service. + // if (progressionLanguageService != null) + // { + // node[RoslynGraphProperties.Description] = progressionLanguageService.GetDescriptionForSymbol(symbol, includeContainingSymbol: false); + // node[RoslynGraphProperties.DescriptionWithContainingSymbol] = progressionLanguageService.GetDescriptionForSymbol(symbol, includeContainingSymbol: true); + + // node[RoslynGraphProperties.FormattedLabelWithoutContainingSymbol] = progressionLanguageService.GetLabelForSymbol(symbol, includeContainingSymbol: false); + // node[RoslynGraphProperties.FormattedLabelWithContainingSymbol] = progressionLanguageService.GetLabelForSymbol(symbol, includeContainingSymbol: true); + // } + + // switch (symbol.Kind) + // { + // case SymbolKind.NamedType: + // var typeSymbol = (INamedTypeSymbol)symbol; + // if (typeSymbol.IsGenericType) + // { + // // Symbol.name does not contain type params for generic types, so we populate them here for some requiring cases like VS properties panel. + // node.Label = (string)node[RoslynGraphProperties.FormattedLabelWithoutContainingSymbol]; + + // // Some consumers like CodeMap want to show types in an unified way for both C# and VB. + // // Therefore, populate a common label property using only name and its type parameters. + // // For example, VB's "Goo(Of T)" or C#'s "Goo(): T" will be shown as "Goo". + // // This property will be used for drag-and-drop case. + // var commonLabel = new System.Text.StringBuilder(); + // commonLabel.Append(typeSymbol.Name); + // commonLabel.Append('<'); + // commonLabel.Append(string.Join(", ", typeSymbol.TypeParameters.Select(t => t.Name))); + // commonLabel.Append('>'); + // node[Microsoft.VisualStudio.ArchitectureTools.ProgressiveReveal.ProgressiveRevealSchema.CommonLabel] = commonLabel.ToString(); + + // return; + // } + // else + // { + // node.Label = symbol.Name; + // } + + // break; + + // case SymbolKind.Method: + // var methodSymbol = (IMethodSymbol)symbol; + // if (methodSymbol.MethodKind == MethodKind.Constructor) + // { + // node.Label = CodeQualifiedIdentifierBuilder.SpecialNames.GetConstructorLabel(methodSymbol.ContainingSymbol.Name); + // } + // else if (methodSymbol.MethodKind == MethodKind.StaticConstructor) + // { + // node.Label = CodeQualifiedIdentifierBuilder.SpecialNames.GetStaticConstructorLabel(methodSymbol.ContainingSymbol.Name); + // } + // else if (methodSymbol.MethodKind == MethodKind.Destructor) + // { + // node.Label = CodeQualifiedIdentifierBuilder.SpecialNames.GetFinalizerLabel(methodSymbol.ContainingSymbol.Name); + // } + // else + // { + // node.Label = methodSymbol.Name; + // } + + // break; + + // case SymbolKind.Property: + // node.Label = symbol.MetadataName; + + // var propertySymbol = (IPropertySymbol)symbol; + // if (propertySymbol.IsIndexer && LanguageNames.CSharp == propertySymbol.Language) + // { + // // For C# indexer, we will strip off the "[]" + // node.Label = symbol.Name.Replace("[]", string.Empty); + // } + + // break; + + // case SymbolKind.Namespace: + // // Use a name with its parents (e.g., A.B.C) + // node.Label = symbol.ToDisplayString(); + // break; + + // default: + // node.Label = symbol.Name; + // break; + // } + + // // When a node is dragged and dropped from SE to CodeMap, its label could be reset during copying to clipboard. + // // So, we try to keep its label that we computed above in a common label property, which CodeMap can access later. + // node[Microsoft.VisualStudio.ArchitectureTools.ProgressiveReveal.ProgressiveRevealSchema.CommonLabel] = node.Label; + //} private static void UpdatePropertiesForNode(ISymbol symbol, GraphNode node) { diff --git a/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs b/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs index 7cbae5050f676..fef47a425b614 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs @@ -57,23 +57,23 @@ public static async Task CreateNodeIdAsync(ISymbol symbol, Solution } } - public static async Task CreateNodeAsync(this Graph graph, ISymbol symbol, Solution solution, CancellationToken cancellationToken) - { - if (graph == null) - { - throw new ArgumentNullException(nameof(graph)); - } + //public static async Task CreateNodeAsync(this Graph graph, ISymbol symbol, Solution solution, CancellationToken cancellationToken) + //{ + // if (graph == null) + // { + // throw new ArgumentNullException(nameof(graph)); + // } - if (symbol == null) - { - throw new ArgumentNullException(nameof(symbol)); - } + // if (symbol == null) + // { + // throw new ArgumentNullException(nameof(symbol)); + // } - if (solution == null) - { - throw new ArgumentNullException(nameof(solution)); - } + // if (solution == null) + // { + // throw new ArgumentNullException(nameof(solution)); + // } - return await GraphBuilder.GetOrCreateNodeAsync(graph, symbol, solution, cancellationToken).ConfigureAwait(false); - } + // return await GraphBuilder.GetOrCreateNodeAsync(graph, symbol, solution, cancellationToken).ConfigureAwait(false); + //} } diff --git a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs index 1ab0c1d885dd7..484eb0ea3a098 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs @@ -73,69 +73,69 @@ public static ImmutableArray GetGraphQueries(IGraphContext context) { using var _ = ArrayBuilder.GetInstance(out var graphQueries); - if (context.Direction == GraphContextDirection.Self && context.RequestedProperties.Contains(DgmlNodeProperties.ContainsChildren)) - { - graphQueries.Add(new ContainsChildrenGraphQuery()); - } - - if (context.Direction == GraphContextDirection.Contains || - (context.Direction == GraphContextDirection.Target && context.LinkCategories.Contains(CodeLinkCategories.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.Self && context.RequestedProperties.Contains(DgmlNodeProperties.ContainsChildren)) + //{ + // graphQueries.Add(new ContainsChildrenGraphQuery()); + //} + + //if (context.Direction == GraphContextDirection.Contains || + // (context.Direction == GraphContextDirection.Target && context.LinkCategories.Contains(CodeLinkCategories.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) { diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/CallsGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/CallsGraphQuery.cs index b8c4e03ae4373..b9c71823f476b 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/CallsGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphQueries/CallsGraphQuery.cs @@ -1,67 +1,67 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. -#nullable disable +//#nullable disable -using System.Collections.Immutable; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Internal.Log; -using Microsoft.CodeAnalysis.PooledObjects; -using Microsoft.VisualStudio.GraphModel; -using Microsoft.VisualStudio.GraphModel.Schemas; +//using System.Collections.Immutable; +//using System.Threading; +//using System.Threading.Tasks; +//using Microsoft.CodeAnalysis; +//using Microsoft.CodeAnalysis.Internal.Log; +//using Microsoft.CodeAnalysis.PooledObjects; +//using Microsoft.VisualStudio.GraphModel; +//using Microsoft.VisualStudio.GraphModel.Schemas; -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; -internal sealed class CallsGraphQuery : IGraphQuery -{ - public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) - { - using var _ = Logger.LogBlock(FunctionId.GraphQuery_Calls, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); +//internal sealed class CallsGraphQuery : IGraphQuery +//{ +// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) +// { +// using var _ = Logger.LogBlock(FunctionId.GraphQuery_Calls, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); - var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); +// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - foreach (var node in context.InputNodes) - { - var symbol = graphBuilder.GetSymbol(node, cancellationToken); - if (symbol != null) - { - foreach (var newSymbol in await GetCalledMethodSymbolsAsync(symbol, solution, cancellationToken).ConfigureAwait(false)) - { - cancellationToken.ThrowIfCancellationRequested(); +// foreach (var node in context.InputNodes) +// { +// var symbol = graphBuilder.GetSymbol(node, cancellationToken); +// if (symbol != null) +// { +// foreach (var newSymbol in await GetCalledMethodSymbolsAsync(symbol, solution, cancellationToken).ConfigureAwait(false)) +// { +// cancellationToken.ThrowIfCancellationRequested(); - var newNode = await graphBuilder.AddNodeAsync(newSymbol, relatedNode: node, cancellationToken).ConfigureAwait(false); - graphBuilder.AddLink(node, CodeLinkCategories.Calls, newNode, cancellationToken); - } - } - } +// var newNode = await graphBuilder.AddNodeAsync(newSymbol, relatedNode: node, cancellationToken).ConfigureAwait(false); +// graphBuilder.AddLink(node, CodeLinkCategories.Calls, newNode, cancellationToken); +// } +// } +// } - return graphBuilder; - } +// return graphBuilder; +// } - private static async Task> GetCalledMethodSymbolsAsync( - ISymbol symbol, Solution solution, CancellationToken cancellationToken) - { - using var _ = ArrayBuilder.GetInstance(out var symbols); +// private static async Task> GetCalledMethodSymbolsAsync( +// ISymbol symbol, Solution solution, CancellationToken cancellationToken) +// { +// using var _ = ArrayBuilder.GetInstance(out var symbols); - foreach (var reference in symbol.DeclaringSyntaxReferences) - { - var semanticModel = await solution.GetDocument(reference.SyntaxTree).GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); - foreach (var syntaxNode in (await reference.GetSyntaxAsync(cancellationToken).ConfigureAwait(false)).DescendantNodes()) - { - cancellationToken.ThrowIfCancellationRequested(); +// foreach (var reference in symbol.DeclaringSyntaxReferences) +// { +// var semanticModel = await solution.GetDocument(reference.SyntaxTree).GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); +// foreach (var syntaxNode in (await reference.GetSyntaxAsync(cancellationToken).ConfigureAwait(false)).DescendantNodes()) +// { +// cancellationToken.ThrowIfCancellationRequested(); - var newSymbol = semanticModel.GetSymbolInfo(syntaxNode, cancellationToken).Symbol; - if (newSymbol != null && newSymbol is IMethodSymbol && - (newSymbol.CanBeReferencedByName || ((IMethodSymbol)newSymbol).MethodKind == MethodKind.Constructor)) - { - symbols.Add(newSymbol); - } - } - } +// var newSymbol = semanticModel.GetSymbolInfo(syntaxNode, cancellationToken).Symbol; +// if (newSymbol != null && newSymbol is IMethodSymbol && +// (newSymbol.CanBeReferencedByName || ((IMethodSymbol)newSymbol).MethodKind == MethodKind.Constructor)) +// { +// symbols.Add(newSymbol); +// } +// } +// } - return symbols.ToImmutableAndClear(); - } -} +// return symbols.ToImmutableAndClear(); +// } +//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/ContainsChildrenGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/ContainsChildrenGraphQuery.cs index c116f6dcab525..939a786978edc 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/ContainsChildrenGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphQueries/ContainsChildrenGraphQuery.cs @@ -1,83 +1,83 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. -using System; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.VisualStudio.GraphModel; -using Microsoft.VisualStudio.GraphModel.Schemas; +//using System; +//using System.Linq; +//using System.Threading; +//using System.Threading.Tasks; +//using Microsoft.CodeAnalysis; +//using Microsoft.VisualStudio.GraphModel; +//using Microsoft.VisualStudio.GraphModel.Schemas; -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; -internal sealed class ContainsChildrenGraphQuery : IGraphQuery -{ - public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) - { - var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); +//internal sealed class ContainsChildrenGraphQuery : IGraphQuery +//{ +// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) +// { +// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - foreach (var node in context.InputNodes) - { - if (!cancellationToken.IsCancellationRequested) - { - var symbol = graphBuilder.GetSymbol(node, cancellationToken); - if (symbol != null) - { - var containsChildren = SymbolContainment.GetContainedSymbols(symbol).Any(); - graphBuilder.AddDeferredPropertySet( - node, DgmlNodeProperties.ContainsChildren, containsChildren, cancellationToken); - } - else if (node.HasCategory(CodeNodeCategories.File)) - { - var document = graphBuilder.GetContextDocument(node, cancellationToken); - if (document != null) - { - var childNodes = await SymbolContainment.GetContainedSyntaxNodesAsync(document, cancellationToken).ConfigureAwait(false); - graphBuilder.AddDeferredPropertySet( - node, DgmlNodeProperties.ContainsChildren, childNodes.Any(), cancellationToken); - } - else - { - var uri = node.Id.GetNestedValueByName(CodeGraphNodeIdName.File); - if (uri != null) - { - // Since a solution load is not yet completed, there is no document available to answer this query. - // The solution explorer presumes that if somebody doesn't answer for a file, they never will. - // See Providers\GraphContextAttachedCollectionSource.cs for more. Therefore we should answer by setting - // ContainsChildren property to either true or false, so any following updates will be tractable. - // We will set it to false since the solution explorer assumes the default for this query response is 'false'. +// foreach (var node in context.InputNodes) +// { +// if (!cancellationToken.IsCancellationRequested) +// { +// var symbol = graphBuilder.GetSymbol(node, cancellationToken); +// if (symbol != null) +// { +// var containsChildren = SymbolContainment.GetContainedSymbols(symbol).Any(); +// graphBuilder.AddDeferredPropertySet( +// node, DgmlNodeProperties.ContainsChildren, containsChildren, cancellationToken); +// } +// else if (node.HasCategory(CodeNodeCategories.File)) +// { +// var document = graphBuilder.GetContextDocument(node, cancellationToken); +// if (document != null) +// { +// var childNodes = await SymbolContainment.GetContainedSyntaxNodesAsync(document, cancellationToken).ConfigureAwait(false); +// graphBuilder.AddDeferredPropertySet( +// node, DgmlNodeProperties.ContainsChildren, childNodes.Any(), cancellationToken); +// } +// else +// { +// var uri = node.Id.GetNestedValueByName(CodeGraphNodeIdName.File); +// if (uri != null) +// { +// // Since a solution load is not yet completed, there is no document available to answer this query. +// // The solution explorer presumes that if somebody doesn't answer for a file, they never will. +// // See Providers\GraphContextAttachedCollectionSource.cs for more. Therefore we should answer by setting +// // ContainsChildren property to either true or false, so any following updates will be tractable. +// // We will set it to false since the solution explorer assumes the default for this query response is 'false'. - // Todo: we may need fallback to check if this node actually represents a C# or VB language - // even when its extension fails to say so. One option would be to call DTEWrapper.IsRegisteredForLangService, - // which may not be called here however since deadlock could happen. +// // Todo: we may need fallback to check if this node actually represents a C# or VB language +// // even when its extension fails to say so. One option would be to call DTEWrapper.IsRegisteredForLangService, +// // which may not be called here however since deadlock could happen. - // The Uri returned by `GetNestedValueByName()` above isn't necessarily absolute and the `OriginalString` is - // the only property that doesn't throw if the UriKind is relative, so `OriginalString` must be used instead - // of `AbsolutePath`. - var path = uri.OriginalString; +// // The Uri returned by `GetNestedValueByName()` above isn't necessarily absolute and the `OriginalString` is +// // the only property that doesn't throw if the UriKind is relative, so `OriginalString` must be used instead +// // of `AbsolutePath`. +// var path = uri.OriginalString; - // Recorded in https://github.com/dotnet/roslyn/issues/27805, we - // have seen crashes because the URI in the graph node has the - // following form, including the quotes (which are invalid path - // characters): - // C:\path\to\"some path\App.config" - // So we avoid calling Path.GetExtension here. Alternatively, we - // could check for illegal path characters directly first, but then - // that check would actually happen twice because GetExtension will - // also perform the check. - if (path.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) || path.EndsWith(".vb", StringComparison.OrdinalIgnoreCase)) - { - graphBuilder.AddDeferredPropertySet( - node, DgmlNodeProperties.ContainsChildren, value: false, cancellationToken); - } - } - } - } - } - } +// // Recorded in https://github.com/dotnet/roslyn/issues/27805, we +// // have seen crashes because the URI in the graph node has the +// // following form, including the quotes (which are invalid path +// // characters): +// // C:\path\to\"some path\App.config" +// // So we avoid calling Path.GetExtension here. Alternatively, we +// // could check for illegal path characters directly first, but then +// // that check would actually happen twice because GetExtension will +// // also perform the check. +// if (path.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) || path.EndsWith(".vb", StringComparison.OrdinalIgnoreCase)) +// { +// graphBuilder.AddDeferredPropertySet( +// node, DgmlNodeProperties.ContainsChildren, value: false, cancellationToken); +// } +// } +// } +// } +// } +// } - return graphBuilder; - } -} +// return graphBuilder; +// } +//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/ContainsGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/ContainsGraphQuery.cs index f8fa2b2f5dbb6..b0aaaba954729 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/ContainsGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphQueries/ContainsGraphQuery.cs @@ -1,67 +1,67 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Internal.Log; -using Microsoft.VisualStudio.GraphModel; -using Microsoft.VisualStudio.GraphModel.Schemas; +//using System.Collections.Generic; +//using System.Threading; +//using System.Threading.Tasks; +//using Microsoft.CodeAnalysis; +//using Microsoft.CodeAnalysis.Internal.Log; +//using Microsoft.VisualStudio.GraphModel; +//using Microsoft.VisualStudio.GraphModel.Schemas; -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; -internal sealed class ContainsGraphQuery : IGraphQuery -{ - public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) - { - using var _ = Logger.LogBlock(FunctionId.GraphQuery_Contains, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); +//internal sealed class ContainsGraphQuery : IGraphQuery +//{ +// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) +// { +// using var _ = Logger.LogBlock(FunctionId.GraphQuery_Contains, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); - var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - var nodesToProcess = context.InputNodes; +// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); +// var nodesToProcess = context.InputNodes; - for (var depth = 0; depth < context.LinkDepth; depth++) - { - // This is the list of nodes we created and will process - var newNodes = new HashSet(); +// for (var depth = 0; depth < context.LinkDepth; depth++) +// { +// // This is the list of nodes we created and will process +// var newNodes = new HashSet(); - foreach (var node in nodesToProcess) - { - cancellationToken.ThrowIfCancellationRequested(); +// foreach (var node in nodesToProcess) +// { +// cancellationToken.ThrowIfCancellationRequested(); - var symbol = graphBuilder.GetSymbol(node, cancellationToken); - if (symbol != null) - { - foreach (var newSymbol in SymbolContainment.GetContainedSymbols(symbol)) - { - cancellationToken.ThrowIfCancellationRequested(); +// var symbol = graphBuilder.GetSymbol(node, cancellationToken); +// if (symbol != null) +// { +// foreach (var newSymbol in SymbolContainment.GetContainedSymbols(symbol)) +// { +// cancellationToken.ThrowIfCancellationRequested(); - var newNode = await graphBuilder.AddNodeAsync( - newSymbol, relatedNode: node, cancellationToken).ConfigureAwait(false); - graphBuilder.AddLink(node, GraphCommonSchema.Contains, newNode, cancellationToken); - } - } - else if (node.HasCategory(CodeNodeCategories.File)) - { - var document = graphBuilder.GetContextDocument(node, cancellationToken); - if (document != null) - { - foreach (var newSymbol in await SymbolContainment.GetContainedSymbolsAsync(document, cancellationToken).ConfigureAwait(false)) - { - cancellationToken.ThrowIfCancellationRequested(); +// var newNode = await graphBuilder.AddNodeAsync( +// newSymbol, relatedNode: node, cancellationToken).ConfigureAwait(false); +// graphBuilder.AddLink(node, GraphCommonSchema.Contains, newNode, cancellationToken); +// } +// } +// else if (node.HasCategory(CodeNodeCategories.File)) +// { +// var document = graphBuilder.GetContextDocument(node, cancellationToken); +// if (document != null) +// { +// foreach (var newSymbol in await SymbolContainment.GetContainedSymbolsAsync(document, cancellationToken).ConfigureAwait(false)) +// { +// cancellationToken.ThrowIfCancellationRequested(); - var newNode = await graphBuilder.AddNodeAsync( - newSymbol, relatedNode: node, cancellationToken).ConfigureAwait(false); - graphBuilder.AddLink(node, GraphCommonSchema.Contains, newNode, cancellationToken); - } - } - } - } +// var newNode = await graphBuilder.AddNodeAsync( +// newSymbol, relatedNode: node, cancellationToken).ConfigureAwait(false); +// graphBuilder.AddLink(node, GraphCommonSchema.Contains, newNode, cancellationToken); +// } +// } +// } +// } - nodesToProcess = newNodes; - } +// nodesToProcess = newNodes; +// } - return graphBuilder; - } -} +// return graphBuilder; +// } +//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/ImplementedByGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/ImplementedByGraphQuery.cs index d6b6967233b7b..1d09043ea411f 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/ImplementedByGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphQueries/ImplementedByGraphQuery.cs @@ -1,46 +1,46 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.FindSymbols; -using Microsoft.CodeAnalysis.Internal.Log; -using Microsoft.VisualStudio.GraphModel; -using Microsoft.VisualStudio.GraphModel.Schemas; +//using System.Threading; +//using System.Threading.Tasks; +//using Microsoft.CodeAnalysis; +//using Microsoft.CodeAnalysis.FindSymbols; +//using Microsoft.CodeAnalysis.Internal.Log; +//using Microsoft.VisualStudio.GraphModel; +//using Microsoft.VisualStudio.GraphModel.Schemas; -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; -internal sealed class ImplementedByGraphQuery : IGraphQuery -{ - public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) - { - using (Logger.LogBlock(FunctionId.GraphQuery_ImplementedBy, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken)) - { - var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); +//internal sealed class ImplementedByGraphQuery : IGraphQuery +//{ +// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) +// { +// using (Logger.LogBlock(FunctionId.GraphQuery_ImplementedBy, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken)) +// { +// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - foreach (var node in context.InputNodes) - { - var symbol = graphBuilder.GetSymbol(node, cancellationToken); - if (symbol is INamedTypeSymbol or - IMethodSymbol or - IPropertySymbol or - IEventSymbol) - { - var implementations = await SymbolFinder.FindImplementationsAsync(symbol, solution, cancellationToken: cancellationToken).ConfigureAwait(false); +// foreach (var node in context.InputNodes) +// { +// var symbol = graphBuilder.GetSymbol(node, cancellationToken); +// if (symbol is INamedTypeSymbol or +// IMethodSymbol or +// IPropertySymbol or +// IEventSymbol) +// { +// var implementations = await SymbolFinder.FindImplementationsAsync(symbol, solution, cancellationToken: cancellationToken).ConfigureAwait(false); - foreach (var implementation in implementations) - { - var symbolNode = await graphBuilder.AddNodeAsync( - implementation, relatedNode: node, cancellationToken).ConfigureAwait(false); - graphBuilder.AddLink( - symbolNode, CodeLinkCategories.Implements, node, cancellationToken); - } - } - } +// foreach (var implementation in implementations) +// { +// var symbolNode = await graphBuilder.AddNodeAsync( +// implementation, relatedNode: node, cancellationToken).ConfigureAwait(false); +// graphBuilder.AddLink( +// symbolNode, CodeLinkCategories.Implements, node, cancellationToken); +// } +// } +// } - return graphBuilder; - } - } -} +// return graphBuilder; +// } +// } +//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/ImplementsGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/ImplementsGraphQuery.cs index d165a54688759..9c356f8dc5d2a 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/ImplementsGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphQueries/ImplementsGraphQuery.cs @@ -1,56 +1,56 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. -using System.Collections.Immutable; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.FindSymbols; -using Microsoft.CodeAnalysis.Internal.Log; -using Microsoft.VisualStudio.GraphModel; -using Microsoft.VisualStudio.GraphModel.Schemas; +//using System.Collections.Immutable; +//using System.Threading; +//using System.Threading.Tasks; +//using Microsoft.CodeAnalysis; +//using Microsoft.CodeAnalysis.FindSymbols; +//using Microsoft.CodeAnalysis.Internal.Log; +//using Microsoft.VisualStudio.GraphModel; +//using Microsoft.VisualStudio.GraphModel.Schemas; -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; -internal sealed class ImplementsGraphQuery : IGraphQuery -{ - public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) - { - using (Logger.LogBlock(FunctionId.GraphQuery_Implements, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken)) - { - var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); +//internal sealed class ImplementsGraphQuery : IGraphQuery +//{ +// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) +// { +// using (Logger.LogBlock(FunctionId.GraphQuery_Implements, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken)) +// { +// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - foreach (var node in context.InputNodes) - { - var symbol = graphBuilder.GetSymbol(node, cancellationToken); - if (symbol is INamedTypeSymbol namedType) - { - var implementedSymbols = ImmutableArray.CastUp(namedType.AllInterfaces); +// foreach (var node in context.InputNodes) +// { +// var symbol = graphBuilder.GetSymbol(node, cancellationToken); +// if (symbol is INamedTypeSymbol namedType) +// { +// var implementedSymbols = ImmutableArray.CastUp(namedType.AllInterfaces); - await AddImplementedSymbolsAsync(graphBuilder, node, implementedSymbols, cancellationToken).ConfigureAwait(false); - } - else if (symbol is IMethodSymbol or - IPropertySymbol or - IEventSymbol) - { - var implements = await SymbolFinder.FindImplementedInterfaceMembersArrayAsync(symbol, solution, cancellationToken: cancellationToken).ConfigureAwait(false); - await AddImplementedSymbolsAsync(graphBuilder, node, implements, cancellationToken).ConfigureAwait(false); - } - } +// await AddImplementedSymbolsAsync(graphBuilder, node, implementedSymbols, cancellationToken).ConfigureAwait(false); +// } +// else if (symbol is IMethodSymbol or +// IPropertySymbol or +// IEventSymbol) +// { +// var implements = await SymbolFinder.FindImplementedInterfaceMembersArrayAsync(symbol, solution, cancellationToken: cancellationToken).ConfigureAwait(false); +// await AddImplementedSymbolsAsync(graphBuilder, node, implements, cancellationToken).ConfigureAwait(false); +// } +// } - return graphBuilder; - } - } +// return graphBuilder; +// } +// } - private static async Task AddImplementedSymbolsAsync( - GraphBuilder graphBuilder, GraphNode node, ImmutableArray implementedSymbols, CancellationToken cancellationToken) - { - foreach (var interfaceType in implementedSymbols) - { - var interfaceTypeNode = await graphBuilder.AddNodeAsync( - interfaceType, relatedNode: node, cancellationToken).ConfigureAwait(false); - graphBuilder.AddLink(node, CodeLinkCategories.Implements, interfaceTypeNode, cancellationToken); - } - } -} +// private static async Task AddImplementedSymbolsAsync( +// GraphBuilder graphBuilder, GraphNode node, ImmutableArray implementedSymbols, CancellationToken cancellationToken) +// { +// foreach (var interfaceType in implementedSymbols) +// { +// var interfaceTypeNode = await graphBuilder.AddNodeAsync( +// interfaceType, relatedNode: node, cancellationToken).ConfigureAwait(false); +// graphBuilder.AddLink(node, CodeLinkCategories.Implements, interfaceTypeNode, cancellationToken); +// } +// } +//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/InheritedByGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/InheritedByGraphQuery.cs index 3652bb8972666..fc247d9dbb3db 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/InheritedByGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphQueries/InheritedByGraphQuery.cs @@ -1,58 +1,58 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.FindSymbols; -using Microsoft.CodeAnalysis.Internal.Log; -using Microsoft.VisualStudio.GraphModel; -using Microsoft.VisualStudio.GraphModel.Schemas; -using Roslyn.Utilities; +//using System.Threading; +//using System.Threading.Tasks; +//using Microsoft.CodeAnalysis; +//using Microsoft.CodeAnalysis.FindSymbols; +//using Microsoft.CodeAnalysis.Internal.Log; +//using Microsoft.VisualStudio.GraphModel; +//using Microsoft.VisualStudio.GraphModel.Schemas; +//using Roslyn.Utilities; -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; -internal sealed class InheritedByGraphQuery : IGraphQuery -{ - public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) - { - using var _ = Logger.LogBlock(FunctionId.GraphQuery_InheritedBy, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); +//internal sealed class InheritedByGraphQuery : IGraphQuery +//{ +// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) +// { +// using var _ = Logger.LogBlock(FunctionId.GraphQuery_InheritedBy, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); - var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); +// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - foreach (var node in context.InputNodes) - { - var symbol = graphBuilder.GetSymbol(node, cancellationToken); - if (symbol is not INamedTypeSymbol namedType) - continue; +// foreach (var node in context.InputNodes) +// { +// var symbol = graphBuilder.GetSymbol(node, cancellationToken); +// if (symbol is not INamedTypeSymbol namedType) +// continue; - if (namedType.TypeKind == TypeKind.Class) - { - var derivedTypes = await SymbolFinder.FindDerivedClassesArrayAsync( - namedType, solution, transitive: false, cancellationToken: cancellationToken).ConfigureAwait(false); - foreach (var derivedType in derivedTypes) - { - var symbolNode = await graphBuilder.AddNodeAsync( - derivedType, relatedNode: node, cancellationToken).ConfigureAwait(false); - graphBuilder.AddLink(symbolNode, CodeLinkCategories.InheritsFrom, node, cancellationToken); - } - } - else if (namedType.TypeKind == TypeKind.Interface) - { - var implementingClassesAndStructs = await SymbolFinder.FindImplementationsArrayAsync( - namedType, solution, transitive: false, cancellationToken: cancellationToken).ConfigureAwait(false); - var derivedInterfaces = await SymbolFinder.FindDerivedInterfacesArrayAsync( - namedType, solution, transitive: false, cancellationToken: cancellationToken).ConfigureAwait(false); - foreach (var derivedType in implementingClassesAndStructs.ConcatFast(derivedInterfaces)) - { - var symbolNode = await graphBuilder.AddNodeAsync( - derivedType, relatedNode: node, cancellationToken).ConfigureAwait(false); - graphBuilder.AddLink(symbolNode, CodeLinkCategories.InheritsFrom, node, cancellationToken); - } - } - } +// if (namedType.TypeKind == TypeKind.Class) +// { +// var derivedTypes = await SymbolFinder.FindDerivedClassesArrayAsync( +// namedType, solution, transitive: false, cancellationToken: cancellationToken).ConfigureAwait(false); +// foreach (var derivedType in derivedTypes) +// { +// var symbolNode = await graphBuilder.AddNodeAsync( +// derivedType, relatedNode: node, cancellationToken).ConfigureAwait(false); +// graphBuilder.AddLink(symbolNode, CodeLinkCategories.InheritsFrom, node, cancellationToken); +// } +// } +// else if (namedType.TypeKind == TypeKind.Interface) +// { +// var implementingClassesAndStructs = await SymbolFinder.FindImplementationsArrayAsync( +// namedType, solution, transitive: false, cancellationToken: cancellationToken).ConfigureAwait(false); +// var derivedInterfaces = await SymbolFinder.FindDerivedInterfacesArrayAsync( +// namedType, solution, transitive: false, cancellationToken: cancellationToken).ConfigureAwait(false); +// foreach (var derivedType in implementingClassesAndStructs.ConcatFast(derivedInterfaces)) +// { +// var symbolNode = await graphBuilder.AddNodeAsync( +// derivedType, relatedNode: node, cancellationToken).ConfigureAwait(false); +// graphBuilder.AddLink(symbolNode, CodeLinkCategories.InheritsFrom, node, cancellationToken); +// } +// } +// } - return graphBuilder; - } -} +// return graphBuilder; +// } +//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/InheritsGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/InheritsGraphQuery.cs index 3bd99611b9691..803449edba356 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/InheritsGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphQueries/InheritsGraphQuery.cs @@ -1,60 +1,60 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Internal.Log; -using Microsoft.VisualStudio.GraphModel; -using Microsoft.VisualStudio.GraphModel.Schemas; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -internal sealed class InheritsGraphQuery : IGraphQuery -{ - public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) - { - using var _ = Logger.LogBlock(FunctionId.GraphQuery_Inherits, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); - - var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - var nodesToProcess = context.InputNodes; - - for (var depth = 0; depth < context.LinkDepth; depth++) - { - // This is the list of nodes we created and will process - var newNodes = new HashSet(); - - foreach (var node in nodesToProcess) - { - var symbol = graphBuilder.GetSymbol(node, cancellationToken); - if (symbol is INamedTypeSymbol namedType) - { - if (namedType.BaseType != null) - { - var baseTypeNode = await graphBuilder.AddNodeAsync( - namedType.BaseType, relatedNode: node, cancellationToken).ConfigureAwait(false); - newNodes.Add(baseTypeNode); - graphBuilder.AddLink(node, CodeLinkCategories.InheritsFrom, baseTypeNode, cancellationToken); - } - else if (namedType.TypeKind == TypeKind.Interface && !namedType.OriginalDefinition.AllInterfaces.IsEmpty) - { - foreach (var baseNode in namedType.OriginalDefinition.AllInterfaces.Distinct()) - { - var baseTypeNode = await graphBuilder.AddNodeAsync( - baseNode, relatedNode: node, cancellationToken).ConfigureAwait(false); - newNodes.Add(baseTypeNode); - graphBuilder.AddLink(node, CodeLinkCategories.InheritsFrom, baseTypeNode, cancellationToken); - } - } - } - } - - nodesToProcess = newNodes; - } - - return graphBuilder; - } -} +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. + +//using System.Collections.Generic; +//using System.Linq; +//using System.Threading; +//using System.Threading.Tasks; +//using Microsoft.CodeAnalysis; +//using Microsoft.CodeAnalysis.Internal.Log; +//using Microsoft.VisualStudio.GraphModel; +//using Microsoft.VisualStudio.GraphModel.Schemas; + +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; + +//internal sealed class InheritsGraphQuery : IGraphQuery +//{ +// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) +// { +// using var _ = Logger.LogBlock(FunctionId.GraphQuery_Inherits, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); + +// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); +// var nodesToProcess = context.InputNodes; + +// for (var depth = 0; depth < context.LinkDepth; depth++) +// { +// // This is the list of nodes we created and will process +// var newNodes = new HashSet(); + +// foreach (var node in nodesToProcess) +// { +// var symbol = graphBuilder.GetSymbol(node, cancellationToken); +// if (symbol is INamedTypeSymbol namedType) +// { +// if (namedType.BaseType != null) +// { +// var baseTypeNode = await graphBuilder.AddNodeAsync( +// namedType.BaseType, relatedNode: node, cancellationToken).ConfigureAwait(false); +// newNodes.Add(baseTypeNode); +// graphBuilder.AddLink(node, CodeLinkCategories.InheritsFrom, baseTypeNode, cancellationToken); +// } +// else if (namedType.TypeKind == TypeKind.Interface && !namedType.OriginalDefinition.AllInterfaces.IsEmpty) +// { +// foreach (var baseNode in namedType.OriginalDefinition.AllInterfaces.Distinct()) +// { +// var baseTypeNode = await graphBuilder.AddNodeAsync( +// baseNode, relatedNode: node, cancellationToken).ConfigureAwait(false); +// newNodes.Add(baseTypeNode); +// graphBuilder.AddLink(node, CodeLinkCategories.InheritsFrom, baseTypeNode, cancellationToken); +// } +// } +// } +// } + +// nodesToProcess = newNodes; +// } + +// return graphBuilder; +// } +//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/IsCalledByGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/IsCalledByGraphQuery.cs index 837cc7c5a6e24..80c5d75597617 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/IsCalledByGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphQueries/IsCalledByGraphQuery.cs @@ -1,43 +1,43 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.FindSymbols; -using Microsoft.CodeAnalysis.Internal.Log; -using Microsoft.VisualStudio.GraphModel; -using Microsoft.VisualStudio.GraphModel.Schemas; +//using System.Linq; +//using System.Threading; +//using System.Threading.Tasks; +//using Microsoft.CodeAnalysis; +//using Microsoft.CodeAnalysis.FindSymbols; +//using Microsoft.CodeAnalysis.Internal.Log; +//using Microsoft.VisualStudio.GraphModel; +//using Microsoft.VisualStudio.GraphModel.Schemas; -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; -internal sealed class IsCalledByGraphQuery : IGraphQuery -{ - public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) - { - using (Logger.LogBlock(FunctionId.GraphQuery_IsCalledBy, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken)) - { - var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); +//internal sealed class IsCalledByGraphQuery : IGraphQuery +//{ +// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) +// { +// using (Logger.LogBlock(FunctionId.GraphQuery_IsCalledBy, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken)) +// { +// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - foreach (var node in context.InputNodes) - { - var symbol = graphBuilder.GetSymbol(node, cancellationToken); - if (symbol != null) - { - var callers = await SymbolFinder.FindCallersAsync(symbol, solution, cancellationToken).ConfigureAwait(false); +// foreach (var node in context.InputNodes) +// { +// var symbol = graphBuilder.GetSymbol(node, cancellationToken); +// if (symbol != null) +// { +// var callers = await SymbolFinder.FindCallersAsync(symbol, solution, cancellationToken).ConfigureAwait(false); - foreach (var caller in callers.Where(c => c.IsDirect)) - { - var callerNode = await graphBuilder.AddNodeAsync( - caller.CallingSymbol, relatedNode: node, cancellationToken).ConfigureAwait(false); - graphBuilder.AddLink(callerNode, CodeLinkCategories.Calls, node, cancellationToken); - } - } - } +// foreach (var caller in callers.Where(c => c.IsDirect)) +// { +// var callerNode = await graphBuilder.AddNodeAsync( +// caller.CallingSymbol, relatedNode: node, cancellationToken).ConfigureAwait(false); +// graphBuilder.AddLink(callerNode, CodeLinkCategories.Calls, node, cancellationToken); +// } +// } +// } - return graphBuilder; - } - } -} +// return graphBuilder; +// } +// } +//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/IsUsedByGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/IsUsedByGraphQuery.cs index 5709c6d9c0818..3fb51862de848 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/IsUsedByGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphQueries/IsUsedByGraphQuery.cs @@ -1,74 +1,74 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.FindSymbols; -using Microsoft.CodeAnalysis.Internal.Log; -using Microsoft.VisualStudio.GraphModel; -using Microsoft.VisualStudio.GraphModel.Schemas; +//using System.Linq; +//using System.Threading; +//using System.Threading.Tasks; +//using Microsoft.CodeAnalysis; +//using Microsoft.CodeAnalysis.FindSymbols; +//using Microsoft.CodeAnalysis.Internal.Log; +//using Microsoft.VisualStudio.GraphModel; +//using Microsoft.VisualStudio.GraphModel.Schemas; -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; -internal sealed class IsUsedByGraphQuery : IGraphQuery -{ - public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) - { - using (Logger.LogBlock(FunctionId.GraphQuery_IsUsedBy, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken)) - { - var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); +//internal sealed class IsUsedByGraphQuery : IGraphQuery +//{ +// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) +// { +// using (Logger.LogBlock(FunctionId.GraphQuery_IsUsedBy, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken)) +// { +// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - foreach (var node in context.InputNodes) - { - var symbol = graphBuilder.GetSymbol(node, cancellationToken); - var references = await SymbolFinder.FindReferencesAsync(symbol, solution, cancellationToken).ConfigureAwait(false); +// foreach (var node in context.InputNodes) +// { +// var symbol = graphBuilder.GetSymbol(node, cancellationToken); +// var references = await SymbolFinder.FindReferencesAsync(symbol, solution, cancellationToken).ConfigureAwait(false); - foreach (var reference in references) - { - var referencedSymbol = reference.Definition; - var projectId = graphBuilder.GetContextProject(node, cancellationToken).Id; +// foreach (var reference in references) +// { +// var referencedSymbol = reference.Definition; +// var projectId = graphBuilder.GetContextProject(node, cancellationToken).Id; - var allLocations = referencedSymbol.Locations.Concat(reference.Locations.Select(r => r.Location)) - .Where(l => l != null && l.IsInSource); +// var allLocations = referencedSymbol.Locations.Concat(reference.Locations.Select(r => r.Location)) +// .Where(l => l != null && l.IsInSource); - foreach (var location in allLocations) - { - var locationNode = GetLocationNode(location, context, projectId, cancellationToken); - if (locationNode != null) - graphBuilder.AddLink(node, CodeLinkCategories.SourceReferences, locationNode, cancellationToken); - } - } - } +// foreach (var location in allLocations) +// { +// var locationNode = GetLocationNode(location, context, projectId, cancellationToken); +// if (locationNode != null) +// graphBuilder.AddLink(node, CodeLinkCategories.SourceReferences, locationNode, cancellationToken); +// } +// } +// } - return graphBuilder; - } - } +// return graphBuilder; +// } +// } - private static GraphNode? GetLocationNode(Location location, IGraphContext context, ProjectId projectId, CancellationToken cancellationToken) - { - var span = location.GetLineSpan(); - if (location.SourceTree == null) - return null; +// private static GraphNode? GetLocationNode(Location location, IGraphContext context, ProjectId projectId, CancellationToken cancellationToken) +// { +// var span = location.GetLineSpan(); +// if (location.SourceTree == null) +// return null; - var lineText = location.SourceTree.GetText(cancellationToken).Lines[span.StartLinePosition.Line].ToString(); - var filePath = location.SourceTree.FilePath; - var sourceLocation = GraphBuilder.TryCreateSourceLocation(filePath, span.Span); - if (sourceLocation == null) - return null; +// var lineText = location.SourceTree.GetText(cancellationToken).Lines[span.StartLinePosition.Line].ToString(); +// var filePath = location.SourceTree.FilePath; +// var sourceLocation = GraphBuilder.TryCreateSourceLocation(filePath, span.Span); +// if (sourceLocation == null) +// return null; - var label = string.Format("{0} ({1}, {2}): {3}", - System.IO.Path.GetFileName(filePath), - span.StartLinePosition.Line + 1, - span.StartLinePosition.Character + 1, - lineText.TrimStart()); - var locationNode = context.Graph.Nodes.GetOrCreate(sourceLocation.Value.CreateGraphNodeId(), label, CodeNodeCategories.SourceLocation); - locationNode[CodeNodeProperties.SourceLocation] = sourceLocation.Value; - locationNode[RoslynGraphProperties.ContextProjectId] = projectId; - locationNode[DgmlNodeProperties.Icon] = IconHelper.GetIconName("Reference", Accessibility.NotApplicable); +// var label = string.Format("{0} ({1}, {2}): {3}", +// System.IO.Path.GetFileName(filePath), +// span.StartLinePosition.Line + 1, +// span.StartLinePosition.Character + 1, +// lineText.TrimStart()); +// var locationNode = context.Graph.Nodes.GetOrCreate(sourceLocation.Value.CreateGraphNodeId(), label, CodeNodeCategories.SourceLocation); +// locationNode[CodeNodeProperties.SourceLocation] = sourceLocation.Value; +// locationNode[RoslynGraphProperties.ContextProjectId] = projectId; +// locationNode[DgmlNodeProperties.Icon] = IconHelper.GetIconName("Reference", Accessibility.NotApplicable); - return locationNode; - } -} +// return locationNode; +// } +//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/OverriddenByGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/OverriddenByGraphQuery.cs index ade96133d757e..af6f8006fb179 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/OverriddenByGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphQueries/OverriddenByGraphQuery.cs @@ -1,39 +1,39 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Internal.Log; -using Microsoft.CodeAnalysis.Shared.Extensions; -using Microsoft.VisualStudio.GraphModel; +//using System.Threading; +//using System.Threading.Tasks; +//using Microsoft.CodeAnalysis; +//using Microsoft.CodeAnalysis.Internal.Log; +//using Microsoft.CodeAnalysis.Shared.Extensions; +//using Microsoft.VisualStudio.GraphModel; -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; -internal sealed class OverriddenByGraphQuery : IGraphQuery -{ - public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) - { - using var _ = Logger.LogBlock(FunctionId.GraphQuery_OverriddenBy, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); +//internal sealed class OverriddenByGraphQuery : IGraphQuery +//{ +// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) +// { +// using var _ = Logger.LogBlock(FunctionId.GraphQuery_OverriddenBy, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); - var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); +// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - foreach (var node in context.InputNodes) - { - var symbol = graphBuilder.GetSymbol(node, cancellationToken); - if (symbol != null) - { - var overriddenMember = symbol.GetOverriddenMember(); - if (overriddenMember != null) - { - var symbolNode = await graphBuilder.AddNodeAsync( - overriddenMember, relatedNode: node, cancellationToken).ConfigureAwait(false); - graphBuilder.AddLink(node, RoslynGraphCategories.Overrides, symbolNode, cancellationToken); - } - } - } +// foreach (var node in context.InputNodes) +// { +// var symbol = graphBuilder.GetSymbol(node, cancellationToken); +// if (symbol != null) +// { +// var overriddenMember = symbol.GetOverriddenMember(); +// if (overriddenMember != null) +// { +// var symbolNode = await graphBuilder.AddNodeAsync( +// overriddenMember, relatedNode: node, cancellationToken).ConfigureAwait(false); +// graphBuilder.AddLink(node, RoslynGraphCategories.Overrides, symbolNode, cancellationToken); +// } +// } +// } - return graphBuilder; - } -} +// return graphBuilder; +// } +//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/OverridesGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/OverridesGraphQuery.cs index 668e8915ba742..053be8c47e3a8 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/OverridesGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphQueries/OverridesGraphQuery.cs @@ -1,41 +1,41 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.FindSymbols; -using Microsoft.CodeAnalysis.Internal.Log; -using Microsoft.VisualStudio.GraphModel; +//using System.Threading; +//using System.Threading.Tasks; +//using Microsoft.CodeAnalysis; +//using Microsoft.CodeAnalysis.FindSymbols; +//using Microsoft.CodeAnalysis.Internal.Log; +//using Microsoft.VisualStudio.GraphModel; -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; -internal sealed class OverridesGraphQuery : IGraphQuery -{ - public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) - { - using (Logger.LogBlock(FunctionId.GraphQuery_Overrides, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken)) - { - var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); +//internal sealed class OverridesGraphQuery : IGraphQuery +//{ +// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) +// { +// using (Logger.LogBlock(FunctionId.GraphQuery_Overrides, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken)) +// { +// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - foreach (var node in context.InputNodes) - { - var symbol = graphBuilder.GetSymbol(node, cancellationToken); - if (symbol is IMethodSymbol or - IPropertySymbol or - IEventSymbol) - { - var overrides = await SymbolFinder.FindOverridesAsync(symbol, solution, cancellationToken: cancellationToken).ConfigureAwait(false); - foreach (var o in overrides) - { - var symbolNode = await graphBuilder.AddNodeAsync(o, relatedNode: node, cancellationToken).ConfigureAwait(false); - graphBuilder.AddLink(symbolNode, RoslynGraphCategories.Overrides, node, cancellationToken); - } - } - } +// foreach (var node in context.InputNodes) +// { +// var symbol = graphBuilder.GetSymbol(node, cancellationToken); +// if (symbol is IMethodSymbol or +// IPropertySymbol or +// IEventSymbol) +// { +// var overrides = await SymbolFinder.FindOverridesAsync(symbol, solution, cancellationToken: cancellationToken).ConfigureAwait(false); +// foreach (var o in overrides) +// { +// var symbolNode = await graphBuilder.AddNodeAsync(o, relatedNode: node, cancellationToken).ConfigureAwait(false); +// graphBuilder.AddLink(symbolNode, RoslynGraphCategories.Overrides, node, cancellationToken); +// } +// } +// } - return graphBuilder; - } - } -} +// return graphBuilder; +// } +// } +//} diff --git a/src/VisualStudio/Core/Def/Progression/IProgressionLanguageService.cs b/src/VisualStudio/Core/Def/Progression/IProgressionLanguageService.cs index 1b548f7e86877..f00bc3076a077 100644 --- a/src/VisualStudio/Core/Def/Progression/IProgressionLanguageService.cs +++ b/src/VisualStudio/Core/Def/Progression/IProgressionLanguageService.cs @@ -1,17 +1,17 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. -using System.Collections.Generic; -using System.Threading; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Host; +//using System.Collections.Generic; +//using System.Threading; +//using Microsoft.CodeAnalysis; +//using Microsoft.CodeAnalysis.Host; -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; -internal interface IProgressionLanguageService : ILanguageService -{ - IEnumerable GetTopLevelNodesFromDocument(SyntaxNode root, CancellationToken cancellationToken); - string GetDescriptionForSymbol(ISymbol symbol, bool includeContainingSymbol); - string GetLabelForSymbol(ISymbol symbol, bool includeContainingSymbol); -} +//internal interface IProgressionLanguageService : ILanguageService +//{ +// IEnumerable GetTopLevelNodesFromDocument(SyntaxNode root, CancellationToken cancellationToken); +// string GetDescriptionForSymbol(ISymbol symbol, bool includeContainingSymbol); +// string GetLabelForSymbol(ISymbol symbol, bool includeContainingSymbol); +//} diff --git a/src/VisualStudio/Core/Def/Progression/SymbolContainment.cs b/src/VisualStudio/Core/Def/Progression/SymbolContainment.cs index fb56cc3f795b9..6b8be85ffff74 100644 --- a/src/VisualStudio/Core/Def/Progression/SymbolContainment.cs +++ b/src/VisualStudio/Core/Def/Progression/SymbolContainment.cs @@ -1,91 +1,91 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. -#nullable disable +//#nullable disable -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.PooledObjects; -using Microsoft.CodeAnalysis.Shared.Extensions; +//using System.Collections.Generic; +//using System.Collections.Immutable; +//using System.Threading; +//using System.Threading.Tasks; +//using Microsoft.CodeAnalysis; +//using Microsoft.CodeAnalysis.PooledObjects; +//using Microsoft.CodeAnalysis.Shared.Extensions; -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; -internal static class SymbolContainment -{ - public static async Task> GetContainedSyntaxNodesAsync(Document document, CancellationToken cancellationToken) - { - var progressionLanguageService = document.GetLanguageService(); - if (progressionLanguageService == null) - return []; +//internal static class SymbolContainment +//{ +// public static async Task> GetContainedSyntaxNodesAsync(Document document, CancellationToken cancellationToken) +// { +// var progressionLanguageService = document.GetLanguageService(); +// if (progressionLanguageService == null) +// return []; - var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); - var root = await syntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); - return progressionLanguageService.GetTopLevelNodesFromDocument(root, cancellationToken); - } +// var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); +// var root = await syntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); +// return progressionLanguageService.GetTopLevelNodesFromDocument(root, cancellationToken); +// } - public static async Task> GetContainedSymbolsAsync(Document document, CancellationToken cancellationToken) - { - var syntaxNodes = await GetContainedSyntaxNodesAsync(document, cancellationToken).ConfigureAwait(false); - var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); - using var _ = ArrayBuilder.GetInstance(out var symbols); +// public static async Task> GetContainedSymbolsAsync(Document document, CancellationToken cancellationToken) +// { +// var syntaxNodes = await GetContainedSyntaxNodesAsync(document, cancellationToken).ConfigureAwait(false); +// var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); +// using var _ = ArrayBuilder.GetInstance(out var symbols); - foreach (var syntaxNode in syntaxNodes) - { - cancellationToken.ThrowIfCancellationRequested(); +// foreach (var syntaxNode in syntaxNodes) +// { +// cancellationToken.ThrowIfCancellationRequested(); - var symbol = semanticModel.GetDeclaredSymbol(syntaxNode, cancellationToken); - if (symbol != null && - !string.IsNullOrEmpty(symbol.Name) && - IsTopLevelSymbol(symbol)) - { - symbols.Add(symbol); - } - } +// var symbol = semanticModel.GetDeclaredSymbol(syntaxNode, cancellationToken); +// if (symbol != null && +// !string.IsNullOrEmpty(symbol.Name) && +// IsTopLevelSymbol(symbol)) +// { +// symbols.Add(symbol); +// } +// } - return symbols.ToImmutableAndClear(); - } +// return symbols.ToImmutableAndClear(); +// } - private static bool IsTopLevelSymbol(ISymbol symbol) - { - switch (symbol.Kind) - { - case SymbolKind.NamedType: - case SymbolKind.Method: - case SymbolKind.Field: - case SymbolKind.Property: - case SymbolKind.Event: - return true; +// private static bool IsTopLevelSymbol(ISymbol symbol) +// { +// switch (symbol.Kind) +// { +// case SymbolKind.NamedType: +// case SymbolKind.Method: +// case SymbolKind.Field: +// case SymbolKind.Property: +// case SymbolKind.Event: +// return true; - default: - return false; - } - } +// default: +// return false; +// } +// } - public static IEnumerable GetContainedSymbols(ISymbol symbol) - { - if (symbol is INamedTypeSymbol namedType) - { - foreach (var member in namedType.GetMembers()) - { - if (member.IsImplicitlyDeclared) - { - continue; - } +// public static IEnumerable GetContainedSymbols(ISymbol symbol) +// { +// if (symbol is INamedTypeSymbol namedType) +// { +// foreach (var member in namedType.GetMembers()) +// { +// if (member.IsImplicitlyDeclared) +// { +// continue; +// } - if (member is IMethodSymbol method && method.AssociatedSymbol != null) - { - continue; - } +// if (member is IMethodSymbol method && method.AssociatedSymbol != null) +// { +// continue; +// } - if (!string.IsNullOrEmpty(member.Name)) - { - yield return member; - } - } - } - } -} +// if (!string.IsNullOrEmpty(member.Name)) +// { +// yield return member; +// } +// } +// } +// } +//} diff --git a/src/VisualStudio/Core/Test/Progression/CSharpSymbolLabelTests.vb b/src/VisualStudio/Core/Test/Progression/CSharpSymbolLabelTests.vb index cd58e8270ce4d..d21f121fda6b0 100644 --- a/src/VisualStudio/Core/Test/Progression/CSharpSymbolLabelTests.vb +++ b/src/VisualStudio/Core/Test/Progression/CSharpSymbolLabelTests.vb @@ -1,195 +1,195 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. - -Imports System.Threading.Tasks -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Roslyn.Test.Utilities - -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - - Public Class CSharpSymbolLabelTests - - Public Async Function TestNamedType() As Task - Using testState = ProgressionTestState.Create( - - - - class $$C { } - - - ) - - Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "C", "C") - End Using - End Function - - - Public Async Function TestGenericNamedType() As Task - Using testState = ProgressionTestState.Create( - - - { } - ]]> - - ) - - Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "C", "C") - End Using - End Function - - - Public Async Function TestGenericMethod() As Task - Using testState = ProgressionTestState.Create( - - - () { } } - ]]> - - ) - - Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M() : void", "C.M() : void") - End Using - End Function - - - Public Async Function TestMethodWithParamsParameter() As Task - Using testState = ProgressionTestState.Create( - - - - class C { void $$M(params string[] goo) { } } - - - ) - - Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M(params string[]) : void", "C.M(params string[]) : void") - End Using - End Function - - - Public Async Function TestMethodWithOptionalParameter() As Task - Using testState = ProgressionTestState.Create( - - - - class C { void $$M(int i = 0) { } } - - - ) - - Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M([int]) : void", "C.M([int]) : void") - End Using - End Function - - - Public Async Function TestMethodWithRefAndOutParameters() As Task - Using testState = ProgressionTestState.Create( - - - - class C { void $$M(out string goo, ref string bar) { } } - - - ) - - Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M(out string, ref string) : void", "C.M(out string, ref string) : void") - End Using - End Function - - - Public Async Function TestEnumMember() As Task - Using testState = ProgressionTestState.Create( - - - - enum E { $$M } - - - ) - - Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M", "E.M") - End Using - End Function - - - Public Async Function TestConstructor() As Task - Using testState = ProgressionTestState.Create( - - - - class C { $$C() { } } - - - ) - - Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "C()", "C.C()") - End Using - End Function - - - Public Async Function TestDestructor() As Task - Using testState = ProgressionTestState.Create( - - - - class C { ~$$C() { } } - - - ) - - Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "~C()", "C.~C()") - End Using - End Function - - - Public Async Function TestExplicitlyImplementedInterface() As Task - Using testState = ProgressionTestState.Create( - - - - using System; - class C : IDisposable { void IDisposable.$$Dispose() { } } - - - ) - - Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "IDisposable.Dispose() : void", "C.Dispose() : void") - End Using - End Function - - - Public Async Function TestFixedFieldInStruct() As Task - Using testState = ProgressionTestState.Create( - - - - struct C { fixed int $$f[42]; } - - - ) - - Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "f : int*", "C.f : int*") - End Using - End Function - - - - Public Async Function TestDelegateStyle() As Task - Using testState = ProgressionTestState.Create( - - - - delegate void $$Goo(); - - - ) - - Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "Goo() : void", "Goo : void") - End Using - End Function - End Class -End Namespace +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. + +'Imports System.Threading.Tasks +'Imports Microsoft.CodeAnalysis.Test.Utilities +'Imports Microsoft.VisualStudio.GraphModel +'Imports Roslyn.Test.Utilities + +'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression +' +' Public Class CSharpSymbolLabelTests +' +' Public Async Function TestNamedType() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class $$C { } +' +' +' ) + +' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "C", "C") +' End Using +' End Function + +' +' Public Async Function TestGenericNamedType() As Task +' Using testState = ProgressionTestState.Create( +' +' +' { } +' ]]> +' +' ) + +' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "C", "C") +' End Using +' End Function + +' +' Public Async Function TestGenericMethod() As Task +' Using testState = ProgressionTestState.Create( +' +' +' () { } } +' ]]> +' +' ) + +' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M() : void", "C.M() : void") +' End Using +' End Function + +' +' Public Async Function TestMethodWithParamsParameter() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class C { void $$M(params string[] goo) { } } +' +' +' ) + +' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M(params string[]) : void", "C.M(params string[]) : void") +' End Using +' End Function + +' +' Public Async Function TestMethodWithOptionalParameter() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class C { void $$M(int i = 0) { } } +' +' +' ) + +' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M([int]) : void", "C.M([int]) : void") +' End Using +' End Function + +' +' Public Async Function TestMethodWithRefAndOutParameters() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class C { void $$M(out string goo, ref string bar) { } } +' +' +' ) + +' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M(out string, ref string) : void", "C.M(out string, ref string) : void") +' End Using +' End Function + +' +' Public Async Function TestEnumMember() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' enum E { $$M } +' +' +' ) + +' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M", "E.M") +' End Using +' End Function + +' +' Public Async Function TestConstructor() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class C { $$C() { } } +' +' +' ) + +' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "C()", "C.C()") +' End Using +' End Function + +' +' Public Async Function TestDestructor() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class C { ~$$C() { } } +' +' +' ) + +' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "~C()", "C.~C()") +' End Using +' End Function + +' +' Public Async Function TestExplicitlyImplementedInterface() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' using System; +' class C : IDisposable { void IDisposable.$$Dispose() { } } +' +' +' ) + +' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "IDisposable.Dispose() : void", "C.Dispose() : void") +' End Using +' End Function + +' +' Public Async Function TestFixedFieldInStruct() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' struct C { fixed int $$f[42]; } +' +' +' ) + +' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "f : int*", "C.f : int*") +' End Using +' End Function + +' +' +' Public Async Function TestDelegateStyle() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' delegate void $$Goo(); +' +' +' ) + +' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "Goo() : void", "Goo : void") +' End Using +' End Function +' End Class +'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/CallsGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/CallsGraphQueryTests.vb index 7ae2fc97e7581..05e4fc4e026d9 100644 --- a/src/VisualStudio/Core/Test/Progression/CallsGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/CallsGraphQueryTests.vb @@ -1,235 +1,235 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. - -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -Imports Roslyn.Test.Utilities - -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - - Public Class CallsGraphQueryTests - - Public Async Function CallsSimpleTests() As Task - Using testState = ProgressionTestState.Create( - - - - class A - { - public A() { } - public void Run() { } - static void $$Main(string[] args) { new A().Run(); } - } - - - ) - - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New CallsGraphQuery(), GraphContextDirection.Source) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function CallsLambdaTests() As Task - Using testState = ProgressionTestState.Create( - - - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -class A - { - static void $$Goo(String[] args) - { - int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; - int oddNumbers = numbers.Count(n => n % 2 == 1); - } - } - - - ) - - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New CallsGraphQuery(), GraphContextDirection.Source) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function CallsPropertiesTests() As Task - Using testState = ProgressionTestState.Create( - - - - class A - { - static public int Get() { return 1; } - public int $$PropertyA = A.Get(); - } - - - ) - - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New CallsGraphQuery(), GraphContextDirection.Source) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function CallsDelegatesTests() As Task - Using testState = ProgressionTestState.Create( - - - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -delegate void MyDelegate1(int x, float y); - -class C -{ - public void DelegatedMethod(int x, float y = 3.0f) { System.Console.WriteLine(y); } - static void $$Main(string[] args) - { - C mc = new C(); - MyDelegate1 md1 = null; - md1 += mc.DelegatedMethod; - md1(1, 5); - md1 -= mc.DelegatedMethod; - } -} - - - ) - - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New CallsGraphQuery(), GraphContextDirection.Source) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function CallsDelegateCreationExpressionTests() As Task - Using testState = ProgressionTestState.Create( - - - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -delegate void MyEvent(); - -class Test -{ - event MyEvent Clicked; - void Handler() { } - - public void $$Run() - { - Test t = new Test(); - t.Clicked += new MyEvent(Handler); - } -} - - - ) - - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New CallsGraphQuery(), GraphContextDirection.Source) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - - ) - End Using - End Function - End Class -End Namespace +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. + +'Imports Microsoft.CodeAnalysis.Test.Utilities +'Imports Microsoft.VisualStudio.GraphModel +'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression +'Imports Roslyn.Test.Utilities + +'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression +' +' Public Class CallsGraphQueryTests +' +' Public Async Function CallsSimpleTests() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class A +' { +' public A() { } +' public void Run() { } +' static void $$Main(string[] args) { new A().Run(); } +' } +' +' +' ) + +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New CallsGraphQuery(), GraphContextDirection.Source) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function CallsLambdaTests() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +'using System; +'using System.Collections.Generic; +'using System.Linq; +'using System.Threading.Tasks; + +'class A +' { +' static void $$Goo(String[] args) +' { +' int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; +' int oddNumbers = numbers.Count(n => n % 2 == 1); +' } +' } +' +' +' ) + +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New CallsGraphQuery(), GraphContextDirection.Source) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function CallsPropertiesTests() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class A +' { +' static public int Get() { return 1; } +' public int $$PropertyA = A.Get(); +' } +' +' +' ) + +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New CallsGraphQuery(), GraphContextDirection.Source) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function CallsDelegatesTests() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +'using System; +'using System.Collections.Generic; +'using System.Linq; +'using System.Threading.Tasks; + +'delegate void MyDelegate1(int x, float y); + +'class C +'{ +' public void DelegatedMethod(int x, float y = 3.0f) { System.Console.WriteLine(y); } +' static void $$Main(string[] args) +' { +' C mc = new C(); +' MyDelegate1 md1 = null; +' md1 += mc.DelegatedMethod; +' md1(1, 5); +' md1 -= mc.DelegatedMethod; +' } +'} +' +' +' ) + +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New CallsGraphQuery(), GraphContextDirection.Source) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function CallsDelegateCreationExpressionTests() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +'using System; +'using System.Collections.Generic; +'using System.Linq; +'using System.Threading.Tasks; + +'delegate void MyEvent(); + +'class Test +'{ +' event MyEvent Clicked; +' void Handler() { } + +' public void $$Run() +' { +' Test t = new Test(); +' t.Clicked += new MyEvent(Handler); +' } +'} +' +' +' ) + +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New CallsGraphQuery(), GraphContextDirection.Source) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function +' End Class +'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/ContainsChildrenGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/ContainsChildrenGraphQueryTests.vb index bc9061ce5293d..a1ec582316309 100644 --- a/src/VisualStudio/Core/Test/Progression/ContainsChildrenGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/ContainsChildrenGraphQueryTests.vb @@ -1,162 +1,162 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. - -Imports System.Threading.Tasks -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Microsoft.VisualStudio.GraphModel.Schemas -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -Imports Roslyn.Test.Utilities - -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - - Public Class ContainsChildrenGraphQueryTests - - Public Async Function ContainsChildrenForDocument() As Task - Using testState = ProgressionTestState.Create( - - - - class C { } - - - ) - - Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsChildrenGraphQuery(), GraphContextDirection.Self) - - Dim node = outputContext.Graph.Nodes.Single() - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - ) - End Using - End Function - - - Public Async Function ContainsChildrenForEmptyDocument() As Task - Using testState = ProgressionTestState.Create( - - - - - - ) - - Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsChildrenGraphQuery(), GraphContextDirection.Self) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - ) - End Using - End Function - - - - Public Async Function ContainsChildrenForFileWithIllegalPath() As Task - Using testState = ProgressionTestState.Create() - Dim graph = New Graph - graph.Nodes.GetOrCreate( - GraphNodeId.GetNested(GraphNodeId.GetPartial(CodeGraphNodeIdName.File, New Uri("C:\path\to\""some folder\App.config""", UriKind.RelativeOrAbsolute))), - label:=String.Empty, - CodeNodeCategories.File) - - ' Just making sure it doesn't throw. - Dim outputContext = Await testState.GetGraphContextAfterQuery(graph, New ContainsChildrenGraphQuery(), GraphContextDirection.Self) - End Using - End Function - - - - Public Async Function ContainsChildrenForNotYetLoadedSolution() As Task - Using testState = ProgressionTestState.Create( - - - - class C { } - - - ) - - Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") - - ' To simulate the situation where a solution is not yet loaded and project info is not available, - ' remove a project from the solution. - - Dim oldSolution = testState.GetSolution() - Dim newSolution = oldSolution.RemoveProject(oldSolution.ProjectIds.FirstOrDefault()) - Dim outputContext = Await testState.GetGraphContextAfterQueryWithSolution(inputGraph, newSolution, New ContainsChildrenGraphQuery(), GraphContextDirection.Self) - - ' ContainsChildren should be set to false, so following updates will be tractable. - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - ) - - End Using - End Function - - - Public Async Function ContainsChildrenForNodeWithRelativeUriPath() As Task - Using testState = ProgressionTestState.Create( - - - - Class C - End Class - - - ) - - ' Force creation of a graph node that has a nested relative URI file path. This simulates nodes that - ' other project types can give us for non-code files. E.g., `favicon.ico` for web projects. - Dim nodeId = GraphNodeId.GetNested(GraphNodeId.GetPartial(CodeGraphNodeIdName.File, New Uri("/Z:/Project.vb", UriKind.Relative))) - Dim inputGraph = New Graph() - Dim node = inputGraph.Nodes.GetOrCreate(nodeId) - node.AddCategory(CodeNodeCategories.File) - - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsChildrenGraphQuery(), GraphContextDirection.Any) - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - ) - End Using - End Function - End Class -End Namespace +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. + +'Imports System.Threading.Tasks +'Imports Microsoft.CodeAnalysis.Test.Utilities +'Imports Microsoft.VisualStudio.GraphModel +'Imports Microsoft.VisualStudio.GraphModel.Schemas +'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression +'Imports Roslyn.Test.Utilities + +'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression +' +' Public Class ContainsChildrenGraphQueryTests +' +' Public Async Function ContainsChildrenForDocument() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class C { } +' +' +' ) + +' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsChildrenGraphQuery(), GraphContextDirection.Self) + +' Dim node = outputContext.Graph.Nodes.Single() + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function ContainsChildrenForEmptyDocument() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' +' +' ) + +' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsChildrenGraphQuery(), GraphContextDirection.Self) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' +' Public Async Function ContainsChildrenForFileWithIllegalPath() As Task +' Using testState = ProgressionTestState.Create() +' Dim graph = New Graph +' graph.Nodes.GetOrCreate( +' GraphNodeId.GetNested(GraphNodeId.GetPartial(CodeGraphNodeIdName.File, New Uri("C:\path\to\""some folder\App.config""", UriKind.RelativeOrAbsolute))), +' label:=String.Empty, +' CodeNodeCategories.File) + +' ' Just making sure it doesn't throw. +' Dim outputContext = Await testState.GetGraphContextAfterQuery(graph, New ContainsChildrenGraphQuery(), GraphContextDirection.Self) +' End Using +' End Function + +' +' +' Public Async Function ContainsChildrenForNotYetLoadedSolution() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class C { } +' +' +' ) + +' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") + +' ' To simulate the situation where a solution is not yet loaded and project info is not available, +' ' remove a project from the solution. + +' Dim oldSolution = testState.GetSolution() +' Dim newSolution = oldSolution.RemoveProject(oldSolution.ProjectIds.FirstOrDefault()) +' Dim outputContext = Await testState.GetGraphContextAfterQueryWithSolution(inputGraph, newSolution, New ContainsChildrenGraphQuery(), GraphContextDirection.Self) + +' ' ContainsChildren should be set to false, so following updates will be tractable. + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' ) + +' End Using +' End Function + +' +' Public Async Function ContainsChildrenForNodeWithRelativeUriPath() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' Class C +' End Class +' +' +' ) + +' ' Force creation of a graph node that has a nested relative URI file path. This simulates nodes that +' ' other project types can give us for non-code files. E.g., `favicon.ico` for web projects. +' Dim nodeId = GraphNodeId.GetNested(GraphNodeId.GetPartial(CodeGraphNodeIdName.File, New Uri("/Z:/Project.vb", UriKind.Relative))) +' Dim inputGraph = New Graph() +' Dim node = inputGraph.Nodes.GetOrCreate(nodeId) +' node.AddCategory(CodeNodeCategories.File) + +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsChildrenGraphQuery(), GraphContextDirection.Any) +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function +' End Class +'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/ContainsGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/ContainsGraphQueryTests.vb index eaf1373204612..13d5f9cc96cc3 100644 --- a/src/VisualStudio/Core/Test/Progression/ContainsGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/ContainsGraphQueryTests.vb @@ -1,392 +1,392 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. - -Imports System.Threading.Tasks -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -Imports Roslyn.Test.Utilities - -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - - Public Class ContainsGraphQueryTests - - Public Async Function TypesContainedInCSharpDocument() As Task - Using testState = ProgressionTestState.Create( - - - - class C { } - enum E { } - interface I { } - struct S { } - record R1 { } - record R2; - record class R3; - record struct R4 { } - - - ) - - Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - - - - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function TypesContainedInCSharpDocumentInsideNamespace() As Task - Using testState = ProgressionTestState.Create( - - - - namespace N.M - { - class C { } - enum E { } - interface I { } - struct S { } - } - - - ) - - Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function TypesContainedInVisualBasicDocument() As Task - Using testState = ProgressionTestState.Create( - - - - Class C - End Class - - Enum E - End Enum - - Interface I - End Interface - - Module M - End Module - - Structure S - End Structure - - - ) - - Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.vb") - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function MembersContainedInCSharpScriptDocument() As Task - Using testState = ProgressionTestState.Create( - - - - - int F; - int P { get; set; } - void M() - { - } - - - ) - - Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.csx") - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains).ConfigureAwait(False) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function MembersContainedInClass() As Task - Using testState = ProgressionTestState.Create( - - - - class $$C { void M(); event System.EventHandler E; } - - - ) - - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function NestedTypesContainedInClass() As Task - Using testState = ProgressionTestState.Create( - - - - class C { class $$D { class E { } } } - - - ) - - Dim inputGraph = await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function EnumMembersInEnum() As Task - Using testState = ProgressionTestState.Create( - - - - enum $$E { M } - - - ) - - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function NothingInBrokenCode() As Task - Using testState = ProgressionTestState.Create( - - - - [(delegate static - - - ) - - Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - ) - End Using - End Function - - - Public Async Function NothingInBrokenCode2() As Task - Using testState = ProgressionTestState.Create( - - - - int this[] { get { int x; } } - - - ) - - Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - ) - End Using - End Function - - - Public Async Function NothingInBrokenCode3() As Task - Using testState = ProgressionTestState.Create( - - - - Module $$Module1 - Public Class - End Module - - - ) - - Dim inputGraph = await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - ) - End Using - End Function - End Class -End Namespace +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. + +'Imports System.Threading.Tasks +'Imports Microsoft.CodeAnalysis.Test.Utilities +'Imports Microsoft.VisualStudio.GraphModel +'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression +'Imports Roslyn.Test.Utilities + +'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression +' +' Public Class ContainsGraphQueryTests +' +' Public Async Function TypesContainedInCSharpDocument() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class C { } +' enum E { } +' interface I { } +' struct S { } +' record R1 { } +' record R2; +' record class R3; +' record struct R4 { } +' +' +' ) + +' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TypesContainedInCSharpDocumentInsideNamespace() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' namespace N.M +' { +' class C { } +' enum E { } +' interface I { } +' struct S { } +' } +' +' +' ) + +' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TypesContainedInVisualBasicDocument() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' Class C +' End Class + +' Enum E +' End Enum + +' Interface I +' End Interface + +' Module M +' End Module + +' Structure S +' End Structure +' +' +' ) + +' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.vb") +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function MembersContainedInCSharpScriptDocument() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' +' int F; +' int P { get; set; } +' void M() +' { +' } +' +' +' ) + +' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.csx") +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains).ConfigureAwait(False) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function MembersContainedInClass() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class $$C { void M(); event System.EventHandler E; } +' +' +' ) + +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function NestedTypesContainedInClass() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class C { class $$D { class E { } } } +' +' +' ) + +' Dim inputGraph = await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function EnumMembersInEnum() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' enum $$E { M } +' +' +' ) + +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function NothingInBrokenCode() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' [(delegate static +' +' +' ) + +' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function NothingInBrokenCode2() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' int this[] { get { int x; } } +' +' +' ) + +' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function NothingInBrokenCode3() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' Module $$Module1 +' Public Class +' End Module +' +' +' ) + +' Dim inputGraph = await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function +' End Class +'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/GraphNodeCreationTests.vb b/src/VisualStudio/Core/Test/Progression/GraphNodeCreationTests.vb index b2854f9dd0195..c990ed0d20858 100644 --- a/src/VisualStudio/Core/Test/Progression/GraphNodeCreationTests.vb +++ b/src/VisualStudio/Core/Test/Progression/GraphNodeCreationTests.vb @@ -1,811 +1,811 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. - -Imports System.Threading -Imports System.Threading.Tasks -Imports Microsoft.CodeAnalysis -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -Imports Microsoft.VisualStudio.LanguageServices.Progression -Imports Roslyn.Test.Utilities - -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - - Public Class GraphNodeCreationTests - Private Shared Async Function AssertCreatedNodeIsAsync(code As String, expectedId As String, xml As XElement, Optional language As String = "C#") As Task - Using testState = ProgressionTestState.Create( - - CommonReferences="true" FilePath="Z:\Project.csproj"> - - <%= code %> - - - ) - Dim symbol = Await testState.GetMarkedSymbolAsync() - Dim node = GraphNodeCreation.CreateNodeIdAsync(symbol, testState.GetSolution(), CancellationToken.None).Result - Assert.Equal(expectedId, node.ToString()) - - Dim graph = New Graph() - Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) - AssertSimplifiedGraphIs(graph, xml) - End Using - End Function - - - Public Async Function TestSimpleType() As Task - Await AssertCreatedNodeIsAsync("namespace N { class $$C { } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C)", - - - - - - - - - ) - End Function - - - Public Async Function TestNamespaceType() As Task - Await AssertCreatedNodeIsAsync("namespace $$N { class C { } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N)", - - - - - - - - - ) - End Function - - - Public Async Function TestLongNamespaceType() As Task - Await AssertCreatedNodeIsAsync("namespace N.$$N1.N11 { class C { } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N.N1)", - - - - - - - - - ) - End Function - - - Public Async Function TestSimpleParameterType() As Task - Await AssertCreatedNodeIsAsync("namespace N { class C { void M(int $$x) { } } }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32)]) ParameterIdentifier=x)", - - - - - - - - - - ) - End Function - - - Public Async Function TestDelegateType() As Task - Await AssertCreatedNodeIsAsync("namespace N { delegate void D(string $$m); }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=D Member=(Name=Invoke OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=String)]) ParameterIdentifier=m)", - - - - - - - - - - ) - End Function - - - Public Async Function TestLambdaParameterType() As Task - Await AssertCreatedNodeIsAsync("namespace N { class C { void M(Func $$x) { } } }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/bin/CSharpAssembly1.dll Type=(Name=Func GenericParameterCount=2 GenericArguments=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32),(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32)]))]) ParameterIdentifier=x)", - - - - - - - - - - ) - End Function - - - Public Async Function TestLocalType() As Task - Await AssertCreatedNodeIsAsync("namespace N { class C { int M() { int $$y = 0; return y; } } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=M LocalVariable=y)", - - - - - - - - - ) - End Function - - - Public Async Function TestFirstLocalWithSameNameType() As Task - Await AssertCreatedNodeIsAsync("namespace N { class C { int M() { { int $$y = 0; } { int y = 1;} } } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=M LocalVariable=y)", - - - - - - - - - ) - End Function - - - Public Async Function TestSecondLocalWithSameNameType() As Task - Await AssertCreatedNodeIsAsync("namespace N { class C { int M() { { int y = 0; } { int $$y = 1;} } } }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=M LocalVariable=y LocalVariableIndex=1)", - - - - - - - - - ) - End Function - - - Public Async Function TestErrorType() As Task - Await AssertCreatedNodeIsAsync( - "Class $$C : Inherits D : End Class", - "(Assembly=file:///Z:/bin/VisualBasicAssembly1.dll Type=C)", - - - - - - - - - , - LanguageNames.VisualBasic) - End Function - - - Public Async Function TestSimpleMethodSymbolTest() As Task - Using testState = ProgressionTestState.Create( - - - - - ) - - Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() - Dim formattedLabelExtension As New GraphFormattedLabelExtension() - Assert.Equal("Goo(string[]) : void", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) - Assert.Equal("Goo", graphNode.Label) - End Using - End Function - - - Public Async Function TestReferenceParameterSymbolTest() As Task - Await AssertCreatedNodeIsAsync("namespace N { class C { void $$Goo(ref int i) { i = i + 1; } } }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=Goo OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32 ParamKind=Ref)]))", - - - - - - - - - - ) - End Function - - - Public Async Function TestReferenceOutParameterSymbolTest() As Task - Await AssertCreatedNodeIsAsync("namespace N { class C { void $$Goo(out int i) { i = 1; } } }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=Goo OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32 ParamKind=Ref)]))", - - - - - - - - - - ) - End Function - - - Public Async Function TestSimpleIndexerTest() As Task - Using testState = ProgressionTestState.Create( - - - - - ) - - Dim symbol = Await testState.GetMarkedSymbolAsync() - Dim graph = New Graph() - Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) - AssertSimplifiedGraphIs(graph, - - - - - - - - - - ) - End Using - End Function - - - Public Async Function TestAttributedIndexerTest() As Task - Using testState = ProgressionTestState.Create( - - - - - ) - - Dim symbol = Await testState.GetMarkedSymbolAsync() - Dim graph = New Graph() - Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) - AssertSimplifiedGraphIs(graph, - - - - - - - - - - ) - End Using - End Function - - - Public Async Function TestParameterWithConversionOperatorTest() As Task - Using testState = ProgressionTestState.Create( - - - - - ) - - Dim symbol = Await testState.GetMarkedSymbolAsync() - Dim graph = New Graph() - Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) - AssertSimplifiedGraphIs(graph, - - - - - - - - - - ) - End Using - End Function - - - Public Async Function TestLocalVBVariableType() As Task - Using testState = ProgressionTestState.Create( - - - - - ) - - Dim symbol = Await testState.GetMarkedSymbolAsync() - Dim graph = New Graph() - Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) - AssertSimplifiedGraphIs(graph, - - - - - - - - - ) - End Using - End Function - - - Public Async Function TestLocalVBRangeTypeVariable() As Task - Using testState = ProgressionTestState.Create( - - - - - ) - - Dim symbol = Await testState.GetMarkedSymbolAsync() - Dim graph = New Graph() - Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) - AssertSimplifiedGraphIs(graph, - - - - - - - - - ) - End Using - End Function - - - Public Async Function TestLocalVBVariableWithinBlockType() As Task - Using testState = ProgressionTestState.Create( - - - - - ) - - Dim symbol = Await testState.GetMarkedSymbolAsync() - Dim graph = New Graph() - Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) - AssertSimplifiedGraphIs(graph, - - - - - - - - - ) - End Using - End Function - - - Public Async Function TestLocalVariableIndexTest() As Task - Using testState = ProgressionTestState.Create( - - - - - ) - - Dim symbol = Await testState.GetMarkedSymbolAsync() - Dim graph = New Graph() - Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) - AssertSimplifiedGraphIs(graph, - - - - - - - - - ) - End Using - End Function - - - Public Async Function TestGenericArgumentsTest() As Task - Using testState = ProgressionTestState.Create( - - - - { - public class MgtpTestInnerClass - { - public void MgtpTestMethod( - T1 p1, - T2[][,] p2, - T3 p3, - T4[][,] p4, - T5 p5, - MgtpTestOuterClass> p6) - { - } - - public void MgtpTestMethod2( - T1 p1, - T2[][,] p2, - T3 p3, - T4[][,] p4, - T5 p5, - MgtpTestOuterClass> p6) - { - } - } - } - } - ]]> - - ) - - Dim symbol = Await testState.GetMarkedSymbolAsync() - Dim graph = New Graph() - Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) - AssertSimplifiedGraphIs(graph, - - - - - - - - - ) - End Using - End Function - - - Public Async Function TestGenericArgumentsTest2() As Task - Using testState = ProgressionTestState.Create( - - - - { - public class MgtpTestInnerClass - { - public void MgtpTestMethod( - T1 p1, - T2[][,] p2, - T3 p3, - T4[][,] p4, - T5 p5, - MgtpTestOuterClass> p6) - { - } - - public void MgtpTestMethod2( - T1 p1, - T2[][,] p2, - T3 p3, - T4[][,] p4, - T5 p5, - MgtpTestOuterClass> p6) - { - } - } - } - } - ]]> - - ) - - Dim symbol = Await testState.GetMarkedSymbolAsync() - Dim graph = New Graph() - Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) - AssertSimplifiedGraphIs(graph, - - - - - - - - - ) - End Using - End Function - - - Public Async Function TestGenericCSharpMethodSymbolTest() As Task - Using testState = ProgressionTestState.Create( - - - { - void $$Goo() {} - } - ]]> - - ) - - Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() - Dim formattedLabelExtension As New GraphFormattedLabelExtension() - Assert.Equal("Goo() : void", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) - Assert.Equal("Goo", graphNode.Label) - End Using - End Function - - - Public Async Function TestGenericCSharpTypeSymbolTest() As Task - Using testState = ProgressionTestState.Create( - - - { - } - ]]> - - ) - - Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() - Dim formattedLabelExtension As New GraphFormattedLabelExtension() - Assert.Equal("C", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) - Assert.Equal("C", graphNode.Label) - - Dim symbol = Await testState.GetMarkedSymbolAsync() - Dim graph = New Graph() - Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) - AssertSimplifiedGraphIs(graph, - - - - - - - - - ) - End Using - End Function - - - Public Async Function TestGenericCSharpMethodTypeSymbolTest() As Task - Using testState = ProgressionTestState.Create( - - - (T param); - } - ]]> - - ) - - Dim symbol = Await testState.GetMarkedSymbolAsync() - Dim graph = New Graph() - Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) - AssertSimplifiedGraphIs(graph, - - - - - - - - - ) - End Using - End Function - - - Public Async Function TestGenericVBMethodSymbolTest() As Task - Using testState = ProgressionTestState.Create( - - - - Module Module1 - Public Class Goo(Of T) - Public Sub $$Goo(ByVal x As T) - End Sub - End Class - End Module - - - ) - - Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() - Dim formattedLabelExtension As New GraphFormattedLabelExtension() - Assert.Equal("Goo(T)", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) - Assert.Equal("Goo", graphNode.Label) - End Using - End Function - - - Public Async Function TestGenericVBTypeSymbolTest() As Task - Using testState = ProgressionTestState.Create( - - - - Module Module1 - Public Class $$Goo(Of T) - End Class - End Module - - - ) - - Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() - Dim formattedLabelExtension As New GraphFormattedLabelExtension() - Assert.Equal("Goo(Of T)", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) - Assert.Equal("Goo(Of T)", graphNode.Label) - - Dim symbol = Await testState.GetMarkedSymbolAsync() - Dim graph = New Graph() - Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) - AssertSimplifiedGraphIs(graph, - - - - - - - - - ) - End Using - End Function - - - Public Async Function TestMultiGenericVBTypeSymbolTest() As Task - Using testState = ProgressionTestState.Create( - - - - Module Module1 - Public Class $$Goo(Of T, X) - End Class - End Module - - - ) - - Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() - Dim formattedLabelExtension As New GraphFormattedLabelExtension() - Assert.Equal("Goo(Of T, X)", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) - Assert.Equal("Goo(Of T, X)", graphNode.Label) - - Dim symbol = Await testState.GetMarkedSymbolAsync() - Dim graph = New Graph() - Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) - AssertSimplifiedGraphIs(graph, - - - - - - - - - ) - End Using - End Function - - - Public Async Function TestFilteringPropertiesTest() As Task - Using testState = ProgressionTestState.Create( - - - -Public Class TestEvents - Public Custom Event CustomEvent As EventHandler(Of Object) - AddHandler($$value As EventHandler(Of Object)) - - End AddHandler - - RemoveHandler(value As EventHandler(Of Object)) - - End RemoveHandler - - RaiseEvent(sender As Object, e As Object) - - End RaiseEvent - End Event -End Class - - - ) - - Dim symbol = Await testState.GetMarkedSymbolAsync() - Dim graph = New Graph() - Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) - AssertSimplifiedGraphIs(graph, - - - - - - - - - - ) - End Using - End Function - End Class -End Namespace +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. + +'Imports System.Threading +'Imports System.Threading.Tasks +'Imports Microsoft.CodeAnalysis +'Imports Microsoft.CodeAnalysis.Test.Utilities +'Imports Microsoft.VisualStudio.GraphModel +'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression +'Imports Microsoft.VisualStudio.LanguageServices.Progression +'Imports Roslyn.Test.Utilities + +'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression +' +' Public Class GraphNodeCreationTests +' Private Shared Async Function AssertCreatedNodeIsAsync(code As String, expectedId As String, xml As XElement, Optional language As String = "C#") As Task +' Using testState = ProgressionTestState.Create( +' +' CommonReferences="true" FilePath="Z:\Project.csproj"> +' +' <%= code %> +' +' +' ) +' Dim symbol = Await testState.GetMarkedSymbolAsync() +' Dim node = GraphNodeCreation.CreateNodeIdAsync(symbol, testState.GetSolution(), CancellationToken.None).Result +' Assert.Equal(expectedId, node.ToString()) + +' Dim graph = New Graph() +' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) +' AssertSimplifiedGraphIs(graph, xml) +' End Using +' End Function + +' +' Public Async Function TestSimpleType() As Task +' Await AssertCreatedNodeIsAsync("namespace N { class $$C { } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C)", +' +' +' +' +' +' +' +' +' ) +' End Function + +' +' Public Async Function TestNamespaceType() As Task +' Await AssertCreatedNodeIsAsync("namespace $$N { class C { } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N)", +' +' +' +' +' +' +' +' +' ) +' End Function + +' +' Public Async Function TestLongNamespaceType() As Task +' Await AssertCreatedNodeIsAsync("namespace N.$$N1.N11 { class C { } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N.N1)", +' +' +' +' +' +' +' +' +' ) +' End Function + +' +' Public Async Function TestSimpleParameterType() As Task +' Await AssertCreatedNodeIsAsync("namespace N { class C { void M(int $$x) { } } }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32)]) ParameterIdentifier=x)", +' +' +' +' +' +' +' +' +' +' ) +' End Function + +' +' Public Async Function TestDelegateType() As Task +' Await AssertCreatedNodeIsAsync("namespace N { delegate void D(string $$m); }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=D Member=(Name=Invoke OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=String)]) ParameterIdentifier=m)", +' +' +' +' +' +' +' +' +' +' ) +' End Function + +' +' Public Async Function TestLambdaParameterType() As Task +' Await AssertCreatedNodeIsAsync("namespace N { class C { void M(Func $$x) { } } }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/bin/CSharpAssembly1.dll Type=(Name=Func GenericParameterCount=2 GenericArguments=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32),(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32)]))]) ParameterIdentifier=x)", +' +' +' +' +' +' +' +' +' +' ) +' End Function + +' +' Public Async Function TestLocalType() As Task +' Await AssertCreatedNodeIsAsync("namespace N { class C { int M() { int $$y = 0; return y; } } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=M LocalVariable=y)", +' +' +' +' +' +' +' +' +' ) +' End Function + +' +' Public Async Function TestFirstLocalWithSameNameType() As Task +' Await AssertCreatedNodeIsAsync("namespace N { class C { int M() { { int $$y = 0; } { int y = 1;} } } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=M LocalVariable=y)", +' +' +' +' +' +' +' +' +' ) +' End Function + +' +' Public Async Function TestSecondLocalWithSameNameType() As Task +' Await AssertCreatedNodeIsAsync("namespace N { class C { int M() { { int y = 0; } { int $$y = 1;} } } }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=M LocalVariable=y LocalVariableIndex=1)", +' +' +' +' +' +' +' +' +' ) +' End Function + +' +' Public Async Function TestErrorType() As Task +' Await AssertCreatedNodeIsAsync( +' "Class $$C : Inherits D : End Class", +' "(Assembly=file:///Z:/bin/VisualBasicAssembly1.dll Type=C)", +' +' +' +' +' +' +' +' +' , +' LanguageNames.VisualBasic) +' End Function + +' +' Public Async Function TestSimpleMethodSymbolTest() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' +' ) + +' Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() +' Dim formattedLabelExtension As New GraphFormattedLabelExtension() +' Assert.Equal("Goo(string[]) : void", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) +' Assert.Equal("Goo", graphNode.Label) +' End Using +' End Function + +' +' Public Async Function TestReferenceParameterSymbolTest() As Task +' Await AssertCreatedNodeIsAsync("namespace N { class C { void $$Goo(ref int i) { i = i + 1; } } }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=Goo OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32 ParamKind=Ref)]))", +' +' +' +' +' +' +' +' +' +' ) +' End Function + +' +' Public Async Function TestReferenceOutParameterSymbolTest() As Task +' Await AssertCreatedNodeIsAsync("namespace N { class C { void $$Goo(out int i) { i = 1; } } }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=Goo OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32 ParamKind=Ref)]))", +' +' +' +' +' +' +' +' +' +' ) +' End Function + +' +' Public Async Function TestSimpleIndexerTest() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' +' ) + +' Dim symbol = Await testState.GetMarkedSymbolAsync() +' Dim graph = New Graph() +' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) +' AssertSimplifiedGraphIs(graph, +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TestAttributedIndexerTest() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' +' ) + +' Dim symbol = Await testState.GetMarkedSymbolAsync() +' Dim graph = New Graph() +' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) +' AssertSimplifiedGraphIs(graph, +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TestParameterWithConversionOperatorTest() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' +' ) + +' Dim symbol = Await testState.GetMarkedSymbolAsync() +' Dim graph = New Graph() +' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) +' AssertSimplifiedGraphIs(graph, +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TestLocalVBVariableType() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' +' ) + +' Dim symbol = Await testState.GetMarkedSymbolAsync() +' Dim graph = New Graph() +' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) +' AssertSimplifiedGraphIs(graph, +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TestLocalVBRangeTypeVariable() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' +' ) + +' Dim symbol = Await testState.GetMarkedSymbolAsync() +' Dim graph = New Graph() +' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) +' AssertSimplifiedGraphIs(graph, +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TestLocalVBVariableWithinBlockType() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' +' ) + +' Dim symbol = Await testState.GetMarkedSymbolAsync() +' Dim graph = New Graph() +' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) +' AssertSimplifiedGraphIs(graph, +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TestLocalVariableIndexTest() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' +' ) + +' Dim symbol = Await testState.GetMarkedSymbolAsync() +' Dim graph = New Graph() +' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) +' AssertSimplifiedGraphIs(graph, +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TestGenericArgumentsTest() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' { +' public class MgtpTestInnerClass +' { +' public void MgtpTestMethod( +' T1 p1, +' T2[][,] p2, +' T3 p3, +' T4[][,] p4, +' T5 p5, +' MgtpTestOuterClass> p6) +' { +' } + +' public void MgtpTestMethod2( +' T1 p1, +' T2[][,] p2, +' T3 p3, +' T4[][,] p4, +' T5 p5, +' MgtpTestOuterClass> p6) +' { +' } +' } +' } +' } +' ]]> +' +' ) + +' Dim symbol = Await testState.GetMarkedSymbolAsync() +' Dim graph = New Graph() +' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) +' AssertSimplifiedGraphIs(graph, +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TestGenericArgumentsTest2() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' { +' public class MgtpTestInnerClass +' { +' public void MgtpTestMethod( +' T1 p1, +' T2[][,] p2, +' T3 p3, +' T4[][,] p4, +' T5 p5, +' MgtpTestOuterClass> p6) +' { +' } + +' public void MgtpTestMethod2( +' T1 p1, +' T2[][,] p2, +' T3 p3, +' T4[][,] p4, +' T5 p5, +' MgtpTestOuterClass> p6) +' { +' } +' } +' } +' } +' ]]> +' +' ) + +' Dim symbol = Await testState.GetMarkedSymbolAsync() +' Dim graph = New Graph() +' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) +' AssertSimplifiedGraphIs(graph, +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TestGenericCSharpMethodSymbolTest() As Task +' Using testState = ProgressionTestState.Create( +' +' +' { +' void $$Goo() {} +' } +' ]]> +' +' ) + +' Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() +' Dim formattedLabelExtension As New GraphFormattedLabelExtension() +' Assert.Equal("Goo() : void", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) +' Assert.Equal("Goo", graphNode.Label) +' End Using +' End Function + +' +' Public Async Function TestGenericCSharpTypeSymbolTest() As Task +' Using testState = ProgressionTestState.Create( +' +' +' { +' } +' ]]> +' +' ) + +' Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() +' Dim formattedLabelExtension As New GraphFormattedLabelExtension() +' Assert.Equal("C", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) +' Assert.Equal("C", graphNode.Label) + +' Dim symbol = Await testState.GetMarkedSymbolAsync() +' Dim graph = New Graph() +' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) +' AssertSimplifiedGraphIs(graph, +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TestGenericCSharpMethodTypeSymbolTest() As Task +' Using testState = ProgressionTestState.Create( +' +' +' (T param); +' } +' ]]> +' +' ) + +' Dim symbol = Await testState.GetMarkedSymbolAsync() +' Dim graph = New Graph() +' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) +' AssertSimplifiedGraphIs(graph, +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TestGenericVBMethodSymbolTest() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' Module Module1 +' Public Class Goo(Of T) +' Public Sub $$Goo(ByVal x As T) +' End Sub +' End Class +' End Module +' +' +' ) + +' Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() +' Dim formattedLabelExtension As New GraphFormattedLabelExtension() +' Assert.Equal("Goo(T)", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) +' Assert.Equal("Goo", graphNode.Label) +' End Using +' End Function + +' +' Public Async Function TestGenericVBTypeSymbolTest() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' Module Module1 +' Public Class $$Goo(Of T) +' End Class +' End Module +' +' +' ) + +' Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() +' Dim formattedLabelExtension As New GraphFormattedLabelExtension() +' Assert.Equal("Goo(Of T)", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) +' Assert.Equal("Goo(Of T)", graphNode.Label) + +' Dim symbol = Await testState.GetMarkedSymbolAsync() +' Dim graph = New Graph() +' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) +' AssertSimplifiedGraphIs(graph, +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TestMultiGenericVBTypeSymbolTest() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' Module Module1 +' Public Class $$Goo(Of T, X) +' End Class +' End Module +' +' +' ) + +' Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() +' Dim formattedLabelExtension As New GraphFormattedLabelExtension() +' Assert.Equal("Goo(Of T, X)", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) +' Assert.Equal("Goo(Of T, X)", graphNode.Label) + +' Dim symbol = Await testState.GetMarkedSymbolAsync() +' Dim graph = New Graph() +' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) +' AssertSimplifiedGraphIs(graph, +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TestFilteringPropertiesTest() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +'Public Class TestEvents +' Public Custom Event CustomEvent As EventHandler(Of Object) +' AddHandler($$value As EventHandler(Of Object)) + +' End AddHandler + +' RemoveHandler(value As EventHandler(Of Object)) + +' End RemoveHandler + +' RaiseEvent(sender As Object, e As Object) + +' End RaiseEvent +' End Event +'End Class +' +' +' ) + +' Dim symbol = Await testState.GetMarkedSymbolAsync() +' Dim graph = New Graph() +' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) +' AssertSimplifiedGraphIs(graph, +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function +' End Class +'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/GraphNodeIdTests.vb b/src/VisualStudio/Core/Test/Progression/GraphNodeIdTests.vb index 79e1b53c52cbf..0712a8f2c4747 100644 --- a/src/VisualStudio/Core/Test/Progression/GraphNodeIdTests.vb +++ b/src/VisualStudio/Core/Test/Progression/GraphNodeIdTests.vb @@ -1,133 +1,133 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. - -Imports System.Threading.Tasks -Imports Microsoft.CodeAnalysis -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Roslyn.Test.Utilities - -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - - Public Class GraphNodeIdTests - Private Shared Async Function AssertMarkedNodeIdIsAsync(code As String, expectedId As String, Optional language As String = "C#", Optional symbolTransform As Func(Of ISymbol, ISymbol) = Nothing) As Task - Using testState = ProgressionTestState.Create( - - CommonReferences="true" FilePath="Z:\Project.csproj"> - - <%= code %> - - - ) - - Dim graph = await testState.GetGraphWithMarkedSymbolNodeAsync(symbolTransform) - Dim node = graph.Nodes.Single() - Assert.Equal(expectedId, node.Id.ToString()) - End Using - End Function - - - Public Async Function TestSimpleType() As Task - Await AssertMarkedNodeIdIsAsync("namespace N { class $$C { } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C)") - End Function - - - Public Async Function TestNestedType() As Task - Await AssertMarkedNodeIdIsAsync("namespace N { class C { class $$E { } } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=E ParentType=C))") - End Function - - - Public Async Function TestMemberWithSimpleArrayType() As Task - Await AssertMarkedNodeIdIsAsync( - "namespace N { class C { void $$M(int[] p) { } } }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=(Name=Int32 ArrayRank=1 ParentType=Int32))]))") - End Function - - - Public Async Function TestMemberWithNestedArrayType() As Task - Await AssertMarkedNodeIdIsAsync( - "namespace N { class C { void $$M(int[][,] p) { } } }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=(Name=Int32 ArrayRank=1 ParentType=(Name=Int32 ArrayRank=2 ParentType=Int32)))]))") - End Function - - - Public Async Function TestMemberWithPointerType() As Task - Await AssertMarkedNodeIdIsAsync( - "namespace N { class C { struct S { } unsafe void $$M(S** p) { } } }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=S Indirection=2 ParentType=C))]))") - End Function - - - Public Async Function TestMemberWithVoidPointerType() As Task - Await AssertMarkedNodeIdIsAsync( - "namespace N { class C { unsafe void $$M(void* p) { } } }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=(Name=Void Indirection=1))]))") - End Function - - - Public Async Function TestMemberWithGenericTypeParameters() As Task - Await AssertMarkedNodeIdIsAsync( - "namespace N { class C { void $$M(T t, U u) { } } }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=C GenericParameterCount=1) Member=(Name=M GenericParameterCount=1 OverloadingParameters=[(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=C GenericParameterCount=1) ParameterIdentifier=0),(ParameterIdentifier=0)]))") - End Function - - - Public Async Function TestMemberWithParameterTypeConstructedWithMemberTypeParameter() As Task - Await AssertMarkedNodeIdIsAsync( - "namespace N { class C { void $$M(T t, System.Func u) { } } }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M GenericParameterCount=1 OverloadingParameters=[(ParameterIdentifier=0),(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=(Name=Func GenericParameterCount=2 GenericArguments=[(ParameterIdentifier=0),(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32)]))]))") - End Function - - - Public Async Function TestMemberWithArraysOfGenericTypeParameters() As Task - Await AssertMarkedNodeIdIsAsync( - "namespace N { class C { void $$M(T[] t, U[] u) { } } }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=C GenericParameterCount=1) Member=(Name=M GenericParameterCount=1 OverloadingParameters=[(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(ArrayRank=1 ParentType=(Type=(Name=C GenericParameterCount=1) ParameterIdentifier=0))),(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(ArrayRank=1 ParentType=(ParameterIdentifier=0)))]))") - End Function - - - Public Async Function TestMemberWithArraysOfGenericTypeParameters2() As Task - Await AssertMarkedNodeIdIsAsync( - "namespace N { class C { void $$M(T[][,] t, U[][,] u) { } } }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=C GenericParameterCount=1) Member=(Name=M GenericParameterCount=1 OverloadingParameters=[(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(ArrayRank=1 ParentType=(ArrayRank=2 ParentType=(Type=(Name=C GenericParameterCount=1) ParameterIdentifier=0)))),(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(ArrayRank=1 ParentType=(ArrayRank=2 ParentType=(ParameterIdentifier=0))))]))") - End Function - - - Public Async Function TestMemberWithGenericType() As Task - Await AssertMarkedNodeIdIsAsync( - "namespace N { class C { void $$M(System.Collections.Generic.List p) { } } }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System.Collections.Generic Type=(Name=List GenericParameterCount=1 GenericArguments=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32)]))]))") - End Function - - - Public Async Function TestMemberWithDynamicType() As Task - Await AssertMarkedNodeIdIsAsync( - "namespace N { class C { void $$M(dynamic d) { } } }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Namespace=System Type=Object)]))") - End Function - - - Public Async Function TestMemberWithGenericTypeOfDynamicType() As Task - Await AssertMarkedNodeIdIsAsync( - "namespace N { class C { void $$M(System.Collections.Generic.List p) { } } }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System.Collections.Generic Type=(Name=List GenericParameterCount=1 GenericArguments=[(Namespace=System Type=Object)]))]))") - End Function - - - Public Async Function TestMemberWithArrayOfDynamicType() As Task - Await AssertMarkedNodeIdIsAsync( - "namespace N { class C { void $$M(dynamic[] d) { } } }", - "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Namespace=System Type=(Name=Object ArrayRank=1 ParentType=Object))]))") - End Function - - - Public Async Function TestErrorType() As Task - Await AssertMarkedNodeIdIsAsync( - "Class $$C : Inherits D : End Class", - "Type=D", - LanguageNames.VisualBasic, - Function(s) DirectCast(s, INamedTypeSymbol).BaseType) - End Function - End Class -End Namespace +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. + +'Imports System.Threading.Tasks +'Imports Microsoft.CodeAnalysis +'Imports Microsoft.CodeAnalysis.Test.Utilities +'Imports Microsoft.VisualStudio.GraphModel +'Imports Roslyn.Test.Utilities + +'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression +' +' Public Class GraphNodeIdTests +' Private Shared Async Function AssertMarkedNodeIdIsAsync(code As String, expectedId As String, Optional language As String = "C#", Optional symbolTransform As Func(Of ISymbol, ISymbol) = Nothing) As Task +' Using testState = ProgressionTestState.Create( +' +' CommonReferences="true" FilePath="Z:\Project.csproj"> +' +' <%= code %> +' +' +' ) + +' Dim graph = await testState.GetGraphWithMarkedSymbolNodeAsync(symbolTransform) +' Dim node = graph.Nodes.Single() +' Assert.Equal(expectedId, node.Id.ToString()) +' End Using +' End Function + +' +' Public Async Function TestSimpleType() As Task +' Await AssertMarkedNodeIdIsAsync("namespace N { class $$C { } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C)") +' End Function + +' +' Public Async Function TestNestedType() As Task +' Await AssertMarkedNodeIdIsAsync("namespace N { class C { class $$E { } } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=E ParentType=C))") +' End Function + +' +' Public Async Function TestMemberWithSimpleArrayType() As Task +' Await AssertMarkedNodeIdIsAsync( +' "namespace N { class C { void $$M(int[] p) { } } }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=(Name=Int32 ArrayRank=1 ParentType=Int32))]))") +' End Function + +' +' Public Async Function TestMemberWithNestedArrayType() As Task +' Await AssertMarkedNodeIdIsAsync( +' "namespace N { class C { void $$M(int[][,] p) { } } }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=(Name=Int32 ArrayRank=1 ParentType=(Name=Int32 ArrayRank=2 ParentType=Int32)))]))") +' End Function + +' +' Public Async Function TestMemberWithPointerType() As Task +' Await AssertMarkedNodeIdIsAsync( +' "namespace N { class C { struct S { } unsafe void $$M(S** p) { } } }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=S Indirection=2 ParentType=C))]))") +' End Function + +' +' Public Async Function TestMemberWithVoidPointerType() As Task +' Await AssertMarkedNodeIdIsAsync( +' "namespace N { class C { unsafe void $$M(void* p) { } } }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=(Name=Void Indirection=1))]))") +' End Function + +' +' Public Async Function TestMemberWithGenericTypeParameters() As Task +' Await AssertMarkedNodeIdIsAsync( +' "namespace N { class C { void $$M(T t, U u) { } } }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=C GenericParameterCount=1) Member=(Name=M GenericParameterCount=1 OverloadingParameters=[(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=C GenericParameterCount=1) ParameterIdentifier=0),(ParameterIdentifier=0)]))") +' End Function + +' +' Public Async Function TestMemberWithParameterTypeConstructedWithMemberTypeParameter() As Task +' Await AssertMarkedNodeIdIsAsync( +' "namespace N { class C { void $$M(T t, System.Func u) { } } }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M GenericParameterCount=1 OverloadingParameters=[(ParameterIdentifier=0),(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=(Name=Func GenericParameterCount=2 GenericArguments=[(ParameterIdentifier=0),(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32)]))]))") +' End Function + +' +' Public Async Function TestMemberWithArraysOfGenericTypeParameters() As Task +' Await AssertMarkedNodeIdIsAsync( +' "namespace N { class C { void $$M(T[] t, U[] u) { } } }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=C GenericParameterCount=1) Member=(Name=M GenericParameterCount=1 OverloadingParameters=[(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(ArrayRank=1 ParentType=(Type=(Name=C GenericParameterCount=1) ParameterIdentifier=0))),(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(ArrayRank=1 ParentType=(ParameterIdentifier=0)))]))") +' End Function + +' +' Public Async Function TestMemberWithArraysOfGenericTypeParameters2() As Task +' Await AssertMarkedNodeIdIsAsync( +' "namespace N { class C { void $$M(T[][,] t, U[][,] u) { } } }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=C GenericParameterCount=1) Member=(Name=M GenericParameterCount=1 OverloadingParameters=[(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(ArrayRank=1 ParentType=(ArrayRank=2 ParentType=(Type=(Name=C GenericParameterCount=1) ParameterIdentifier=0)))),(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(ArrayRank=1 ParentType=(ArrayRank=2 ParentType=(ParameterIdentifier=0))))]))") +' End Function + +' +' Public Async Function TestMemberWithGenericType() As Task +' Await AssertMarkedNodeIdIsAsync( +' "namespace N { class C { void $$M(System.Collections.Generic.List p) { } } }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System.Collections.Generic Type=(Name=List GenericParameterCount=1 GenericArguments=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32)]))]))") +' End Function + +' +' Public Async Function TestMemberWithDynamicType() As Task +' Await AssertMarkedNodeIdIsAsync( +' "namespace N { class C { void $$M(dynamic d) { } } }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Namespace=System Type=Object)]))") +' End Function + +' +' Public Async Function TestMemberWithGenericTypeOfDynamicType() As Task +' Await AssertMarkedNodeIdIsAsync( +' "namespace N { class C { void $$M(System.Collections.Generic.List p) { } } }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System.Collections.Generic Type=(Name=List GenericParameterCount=1 GenericArguments=[(Namespace=System Type=Object)]))]))") +' End Function + +' +' Public Async Function TestMemberWithArrayOfDynamicType() As Task +' Await AssertMarkedNodeIdIsAsync( +' "namespace N { class C { void $$M(dynamic[] d) { } } }", +' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Namespace=System Type=(Name=Object ArrayRank=1 ParentType=Object))]))") +' End Function + +' +' Public Async Function TestErrorType() As Task +' Await AssertMarkedNodeIdIsAsync( +' "Class $$C : Inherits D : End Class", +' "Type=D", +' LanguageNames.VisualBasic, +' Function(s) DirectCast(s, INamedTypeSymbol).BaseType) +' End Function +' End Class +'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/GraphProviderTests.vb b/src/VisualStudio/Core/Test/Progression/GraphProviderTests.vb index 98c8bcef7d1f1..5808a9a42f02a 100644 --- a/src/VisualStudio/Core/Test/Progression/GraphProviderTests.vb +++ b/src/VisualStudio/Core/Test/Progression/GraphProviderTests.vb @@ -12,19 +12,19 @@ Imports Roslyn.Test.Utilities Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression Public Class GraphProviderTests - - Public Sub TestGetContainsGraphQueries() - Dim context = CreateGraphContext(GraphContextDirection.Contains, Array.Empty(Of GraphCategory)()) - Dim queries = RoslynGraphProvider.GetGraphQueries(context) - Assert.Equal(queries.Single().GetType(), GetType(ContainsGraphQuery)) - End Sub + ' + 'Public Sub TestGetContainsGraphQueries() + ' Dim context = CreateGraphContext(GraphContextDirection.Contains, Array.Empty(Of GraphCategory)()) + ' Dim queries = RoslynGraphProvider.GetGraphQueries(context) + ' Assert.Equal(queries.Single().GetType(), GetType(ContainsGraphQuery)) + 'End Sub - - Public Sub TestGetContainsGraphQueriesWithTarget() - Dim context = CreateGraphContext(GraphContextDirection.Target, {CodeLinkCategories.Contains}) - Dim queries = RoslynGraphProvider.GetGraphQueries(context) - Assert.Equal(queries.Single().GetType(), GetType(ContainsGraphQuery)) - End Sub + ' + 'Public Sub TestGetContainsGraphQueriesWithTarget() + ' Dim context = CreateGraphContext(GraphContextDirection.Target, {CodeLinkCategories.Contains}) + ' Dim queries = RoslynGraphProvider.GetGraphQueries(context) + ' Assert.Equal(queries.Single().GetType(), GetType(ContainsGraphQuery)) + 'End Sub Private Shared Function CreateGraphContext(direction As GraphContextDirection, linkCategories As IEnumerable(Of GraphCategory)) As IGraphContext Dim context = New Mock(Of IGraphContext)(MockBehavior.Strict) diff --git a/src/VisualStudio/Core/Test/Progression/ImplementedByGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/ImplementedByGraphQueryTests.vb index fa776780712f6..fed26fa953de4 100644 --- a/src/VisualStudio/Core/Test/Progression/ImplementedByGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/ImplementedByGraphQueryTests.vb @@ -1,73 +1,73 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. -Imports System.Threading.Tasks -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -Imports Roslyn.Test.Utilities +'Imports System.Threading.Tasks +'Imports Microsoft.CodeAnalysis.Test.Utilities +'Imports Microsoft.VisualStudio.GraphModel +'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression +'Imports Roslyn.Test.Utilities -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression +'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - - Public Class ImplementedByGraphQueryTests - - Public Async Function TestImplementedBy1() As Task - Using testState = ProgressionTestState.Create( - - - -using System; +' +' Public Class ImplementedByGraphQueryTests +' +' Public Async Function TestImplementedBy1() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +'using System; -interface $$IBlah { -} +'interface $$IBlah { +'} -abstract class Base -{ - public abstract int CompareTo(object obj); -} +'abstract class Base +'{ +' public abstract int CompareTo(object obj); +'} -class Goo : Base, IComparable, IBlah -{ - public override int CompareTo(object obj) - { - throw new NotImplementedException(); - } -} +'class Goo : Base, IComparable, IBlah +'{ +' public override int CompareTo(object obj) +' { +' throw new NotImplementedException(); +' } +'} -class Goo2 : Base, IBlah -{ - public override int CompareTo(object obj) - { - throw new NotImplementedException(); - } -} - - - ) +'class Goo2 : Base, IBlah +'{ +' public override int CompareTo(object obj) +' { +' throw new NotImplementedException(); +' } +'} +' +' +' ) - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ImplementedByGraphQuery(), GraphContextDirection.Target) +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ImplementedByGraphQuery(), GraphContextDirection.Target) - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - - ) - End Using - End Function - End Class +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function +' End Class -End Namespace +'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/ImplementsGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/ImplementsGraphQueryTests.vb index 1cce66f485dc7..4aa284d5cd6e6 100644 --- a/src/VisualStudio/Core/Test/Progression/ImplementsGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/ImplementsGraphQueryTests.vb @@ -1,87 +1,87 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. -Imports System.Threading.Tasks -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -Imports Roslyn.Test.Utilities +'Imports System.Threading.Tasks +'Imports Microsoft.CodeAnalysis.Test.Utilities +'Imports Microsoft.VisualStudio.GraphModel +'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression +'Imports Roslyn.Test.Utilities -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression +'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - - Public Class ImplementsGraphQueryTests - - Public Async Function TestClassImplementsInterface1() As Task - Using testState = ProgressionTestState.Create( - - - - class $$C : System.IDisposable { } - - - ) +' +' Public Class ImplementsGraphQueryTests +' +' Public Async Function TestClassImplementsInterface1() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class $$C : System.IDisposable { } +' +' +' ) - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ImplementsGraphQuery(), GraphContextDirection.Target) +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ImplementsGraphQuery(), GraphContextDirection.Target) - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - ) - End Using - End Function +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function - - Public Async Function TestMethodImplementsInterfaceMethod1() As Task - Using testState = ProgressionTestState.Create( - - - -using System; +' +' Public Async Function TestMethodImplementsInterfaceMethod1() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +'using System; -class Goo : IComparable -{ - public int $$CompareTo(object obj) - { - throw new NotImplementedException(); - } -} - - - ) +'class Goo : IComparable +'{ +' public int $$CompareTo(object obj) +' { +' throw new NotImplementedException(); +' } +'} +' +' +' ) - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ImplementsGraphQuery(), GraphContextDirection.Target) +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ImplementsGraphQuery(), GraphContextDirection.Target) - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - ) - End Using - End Function - End Class -End Namespace +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function +' End Class +'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/InheritedByGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/InheritedByGraphQueryTests.vb index 333c3bbf6ef51..8556a02a0d1e4 100644 --- a/src/VisualStudio/Core/Test/Progression/InheritedByGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/InheritedByGraphQueryTests.vb @@ -1,238 +1,238 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. - -Imports System.Threading.Tasks -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -Imports Roslyn.Test.Utilities - -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - - - Public Class InheritedByGraphQueryTests - - Public Async Function TestInheritedByClassesCSharp() As Task - Using testState = ProgressionTestState.Create( - - - -using System; - -interface IBlah { -} - -abstract class $$Base -{ - public abstract int CompareTo(object obj); -} - -class Goo : Base, IComparable, IBlah -{ - public override int CompareTo(object obj) - { - throw new NotImplementedException(); - } -} - -class Goo2 : Base, IBlah -{ - public override int CompareTo(object obj) - { - throw new NotImplementedException(); - } -} - -class ReallyDerived : Goo // should not be shown as inherited by Base -{ -} - - - ) - - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritedByGraphQuery(), GraphContextDirection.Target) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function TestInheritedByInterfacesCSharp() As Task - Using testState = ProgressionTestState.Create( - - - -using System; - -public interface $$I { } - -public class C : I { } // should appear as being derived from (implementing) I - -public class C2 : C { } // should not appear as being derived from (implementing) I - -interface I2 : I, IComparable -{ - void M(); -} - -interface I3 : I2 // should not be shown as inherited by I -{ -} - - - ) - - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritedByGraphQuery(), GraphContextDirection.Target) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function TestInheritedByClassesVisualBasic() As Task - Using testState = ProgressionTestState.Create( - - - -Imports System - -Interface IBlah -End Interface - -MustInherit Class $$Base - Public MustOverride Function CompareTo(obj As Object) As Integer -End Class - -Class Goo - Inherits Base - Implements IComparable, IBlah - Public Overrides Function CompareTo(obj As Object) As Integer Implements IComparable.CompareTo - Throw New NotImplementedException() - End Function -End Class - -Class Goo2 - Inherits Base - Implements IBlah - Public Overrides Function CompareTo(obj As Object) As Integer - Throw New NotImplementedException() - End Function -End Class - -Class ReallyDerived ' should not be shown as inherited by Base - Inherits Goo -End Class - - - ) - - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritedByGraphQuery(), GraphContextDirection.Target) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function TestInheritedByInterfacesVisualBasic() As Task - Using testState = ProgressionTestState.Create( - - - -Imports System - -Public Interface $$I -End Interface - -Public Class C ' should appear as being derived from (implementing) I - Implements I -End Class - -Public Class C2 ' should not appear as being derived from (implementing) I - Inherits C -End Class - -Interface I2 - Inherits I, IComparable - Sub M() -End Interface - -Interface I3 ' should not be shown as inherited by I - Inherits I2 -End Interface - - - ) - - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritedByGraphQuery(), GraphContextDirection.Target) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - - ) - End Using - End Function - End Class - -End Namespace +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. + +'Imports System.Threading.Tasks +'Imports Microsoft.CodeAnalysis.Test.Utilities +'Imports Microsoft.VisualStudio.GraphModel +'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression +'Imports Roslyn.Test.Utilities + +'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression + +' +' Public Class InheritedByGraphQueryTests +' +' Public Async Function TestInheritedByClassesCSharp() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +'using System; + +'interface IBlah { +'} + +'abstract class $$Base +'{ +' public abstract int CompareTo(object obj); +'} + +'class Goo : Base, IComparable, IBlah +'{ +' public override int CompareTo(object obj) +' { +' throw new NotImplementedException(); +' } +'} + +'class Goo2 : Base, IBlah +'{ +' public override int CompareTo(object obj) +' { +' throw new NotImplementedException(); +' } +'} + +'class ReallyDerived : Goo // should not be shown as inherited by Base +'{ +'} +' +' +' ) + +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritedByGraphQuery(), GraphContextDirection.Target) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TestInheritedByInterfacesCSharp() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +'using System; + +'public interface $$I { } + +'public class C : I { } // should appear as being derived from (implementing) I + +'public class C2 : C { } // should not appear as being derived from (implementing) I + +'interface I2 : I, IComparable +'{ +' void M(); +'} + +'interface I3 : I2 // should not be shown as inherited by I +'{ +'} +' +' +' ) + +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritedByGraphQuery(), GraphContextDirection.Target) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TestInheritedByClassesVisualBasic() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +'Imports System + +'Interface IBlah +'End Interface + +'MustInherit Class $$Base +' Public MustOverride Function CompareTo(obj As Object) As Integer +'End Class + +'Class Goo +' Inherits Base +' Implements IComparable, IBlah +' Public Overrides Function CompareTo(obj As Object) As Integer Implements IComparable.CompareTo +' Throw New NotImplementedException() +' End Function +'End Class + +'Class Goo2 +' Inherits Base +' Implements IBlah +' Public Overrides Function CompareTo(obj As Object) As Integer +' Throw New NotImplementedException() +' End Function +'End Class + +'Class ReallyDerived ' should not be shown as inherited by Base +' Inherits Goo +'End Class +' +' +' ) + +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritedByGraphQuery(), GraphContextDirection.Target) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function TestInheritedByInterfacesVisualBasic() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +'Imports System + +'Public Interface $$I +'End Interface + +'Public Class C ' should appear as being derived from (implementing) I +' Implements I +'End Class + +'Public Class C2 ' should not appear as being derived from (implementing) I +' Inherits C +'End Class + +'Interface I2 +' Inherits I, IComparable +' Sub M() +'End Interface + +'Interface I3 ' should not be shown as inherited by I +' Inherits I2 +'End Interface +' +' +' ) + +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritedByGraphQuery(), GraphContextDirection.Target) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function +' End Class + +'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/InheritsFromGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/InheritsFromGraphQueryTests.vb index 1faa562860c9e..23b1a60e10826 100644 --- a/src/VisualStudio/Core/Test/Progression/InheritsFromGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/InheritsFromGraphQueryTests.vb @@ -1,119 +1,119 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. -Imports System.IO -Imports System.Threading.Tasks -Imports Microsoft.CodeAnalysis.LanguageServer -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -Imports Roslyn.Test.Utilities +'Imports System.IO +'Imports System.Threading.Tasks +'Imports Microsoft.CodeAnalysis.LanguageServer +'Imports Microsoft.CodeAnalysis.Test.Utilities +'Imports Microsoft.VisualStudio.GraphModel +'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression +'Imports Roslyn.Test.Utilities -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - - Public Class InheritsGraphQueryTests - - Public Async Function BaseTypesOfSimpleType() As Task - Using testState = ProgressionTestState.Create( - - - - class $$C : System.IDisposable { } - - - ) +'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression +' +' Public Class InheritsGraphQueryTests +' +' Public Async Function BaseTypesOfSimpleType() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class $$C : System.IDisposable { } +' +' +' ) - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritsGraphQuery(), GraphContextDirection.Target) +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritsGraphQuery(), GraphContextDirection.Target) - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - ) - End Using - End Function +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function - - Public Async Function TestErrorBaseType() As Task - Using testState = ProgressionTestState.Create( - - - - class $$C : A { } - - - ) +' +' Public Async Function TestErrorBaseType() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class $$C : A { } +' +' +' ) - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritsGraphQuery(), GraphContextDirection.Target) +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritsGraphQuery(), GraphContextDirection.Target) - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - ) - End Using - End Function +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function - - Public Async Function TestSolutionWithMultipleProjects() As Task - Using testState = ProgressionTestState.Create( - - - public class A { } - - - ProjectA - public class B : A { } - - - ProjectB - public class C : B$$ { } - - ) +' +' Public Async Function TestSolutionWithMultipleProjects() As Task +' Using testState = ProgressionTestState.Create( +' +' +' public class A { } +' +' +' ProjectA +' public class B : A { } +' +' +' ProjectB +' public class C : B$$ { } +' +' ) - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritsGraphQuery(), GraphContextDirection.Target) +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritsGraphQuery(), GraphContextDirection.Target) - Dim dirUri = ProtocolConversions.GetAbsoluteUriString(Path.Combine(TestWorkspace.RootDirectory, "bin")) & "/" +' Dim dirUri = ProtocolConversions.GetAbsoluteUriString(Path.Combine(TestWorkspace.RootDirectory, "bin")) & "/" - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - /> - /> - - ) - End Using - End Function - End Class -End Namespace +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' /> +' /> +' +' ) +' End Using +' End Function +' End Class +'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/IsCalledByGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/IsCalledByGraphQueryTests.vb index e25024ffc3003..5eeaf4ac6e5f2 100644 --- a/src/VisualStudio/Core/Test/Progression/IsCalledByGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/IsCalledByGraphQueryTests.vb @@ -1,65 +1,65 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. -Imports System.Threading.Tasks -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -Imports Roslyn.Test.Utilities +'Imports System.Threading.Tasks +'Imports Microsoft.CodeAnalysis.Test.Utilities +'Imports Microsoft.VisualStudio.GraphModel +'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression +'Imports Roslyn.Test.Utilities -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - - Public Class IsCalledByGraphQueryTests - - Public Async Function IsCalledBySimpleTests() As Task - Using testState = ProgressionTestState.Create( - - - - class A - { - public $$A() { } - public virtual void Run() { } - } +'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression +' +' Public Class IsCalledByGraphQueryTests +' +' Public Async Function IsCalledBySimpleTests() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class A +' { +' public $$A() { } +' public virtual void Run() { } +' } - class B : A - { - public B() { } - override public void Run() { var x = new A(); x.Run(); } - } +' class B : A +' { +' public B() { } +' override public void Run() { var x = new A(); x.Run(); } +' } - class C - { - public C() { } - public void Goo() - { - var x = new B(); - x.Run(); - } - } - - - ) +' class C +' { +' public C() { } +' public void Goo() +' { +' var x = new B(); +' x.Run(); +' } +' } +' +' +' ) - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New IsCalledByGraphQuery(), GraphContextDirection.Target) +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New IsCalledByGraphQuery(), GraphContextDirection.Target) - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - ) - End Using - End Function - End Class -End Namespace +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function +' End Class +'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/IsUsedByGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/IsUsedByGraphQueryTests.vb index 7c1914ffe879c..4c5905393ade4 100644 --- a/src/VisualStudio/Core/Test/Progression/IsUsedByGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/IsUsedByGraphQueryTests.vb @@ -1,59 +1,59 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. -Imports System.Threading.Tasks -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -Imports Roslyn.Test.Utilities +'Imports System.Threading.Tasks +'Imports Microsoft.CodeAnalysis.Test.Utilities +'Imports Microsoft.VisualStudio.GraphModel +'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression +'Imports Roslyn.Test.Utilities -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - - Public Class IsUsedByGraphQueryTests - - Public Async Function IsUsedByTests() As Task - Using testState = ProgressionTestState.Create( - - - - public class C { - public int $$X; - public int Y = X * X; - public void M() { - int x = 10; - int y = x + X; - } - } - - - ) +'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression +' +' Public Class IsUsedByGraphQueryTests +' +' Public Async Function IsUsedByTests() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' public class C { +' public int $$X; +' public int Y = X * X; +' public void M() { +' int x = 10; +' int y = x + X; +' } +' } +' +' +' ) - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New IsUsedByGraphQuery(), GraphContextDirection.Target) +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New IsUsedByGraphQuery(), GraphContextDirection.Target) - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - - - - - - - ) - End Using - End Function - End Class -End Namespace +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function +' End Class +'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/OverriddenByGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/OverriddenByGraphQueryTests.vb index 2dc28dc9c5bb0..5ea5259793f30 100644 --- a/src/VisualStudio/Core/Test/Progression/OverriddenByGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/OverriddenByGraphQueryTests.vb @@ -1,102 +1,102 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. -Imports System.Threading.Tasks -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -Imports Roslyn.Test.Utilities +'Imports System.Threading.Tasks +'Imports Microsoft.CodeAnalysis.Test.Utilities +'Imports Microsoft.VisualStudio.GraphModel +'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression +'Imports Roslyn.Test.Utilities -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression +'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - - Public Class OverriddenByGraphQueryTests - - Public Async Function TestOverriddenByMethod1() As Task - Using testState = ProgressionTestState.Create( - - - -using System; +' +' Public Class OverriddenByGraphQueryTests +' +' Public Async Function TestOverriddenByMethod1() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +'using System; -abstract class Base -{ - public abstract int $$CompareTo(object obj); -} +'abstract class Base +'{ +' public abstract int $$CompareTo(object obj); +'} -class Goo : Base, IComparable -{ - public override int CompareTo(object obj) - { - throw new NotImplementedException(); - } -} - - - ) +'class Goo : Base, IComparable +'{ +' public override int CompareTo(object obj) +' { +' throw new NotImplementedException(); +' } +'} +' +' +' ) - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New OverriddenByGraphQuery(), GraphContextDirection.Target) +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New OverriddenByGraphQuery(), GraphContextDirection.Target) - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - ) - End Using - End Function +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function - - Public Async Function TestOverriddenByMethod2() As Task - Using testState = ProgressionTestState.Create( - - - -using System; +' +' Public Async Function TestOverriddenByMethod2() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +'using System; -abstract class Base -{ - public abstract int CompareTo(object obj); -} +'abstract class Base +'{ +' public abstract int CompareTo(object obj); +'} -class Goo : Base, IComparable -{ - public override int $$CompareTo(object obj) - { - throw new NotImplementedException(); - } -} - - - ) +'class Goo : Base, IComparable +'{ +' public override int $$CompareTo(object obj) +' { +' throw new NotImplementedException(); +' } +'} +' +' +' ) - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New OverriddenByGraphQuery(), GraphContextDirection.Target) +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New OverriddenByGraphQuery(), GraphContextDirection.Target) - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - ) - End Using - End Function - End Class -End Namespace +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function +' End Class +'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/OverridesGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/OverridesGraphQueryTests.vb index ef9f77e03ca9d..2cde2c772d54c 100644 --- a/src/VisualStudio/Core/Test/Progression/OverridesGraphQueryTests.vb +++ b/src/VisualStudio/Core/Test/Progression/OverridesGraphQueryTests.vb @@ -1,102 +1,102 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. -Imports System.Threading.Tasks -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -Imports Roslyn.Test.Utilities +'Imports System.Threading.Tasks +'Imports Microsoft.CodeAnalysis.Test.Utilities +'Imports Microsoft.VisualStudio.GraphModel +'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression +'Imports Roslyn.Test.Utilities -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression +'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - - Public Class OverridesGraphQueryTests - - Public Async Function TestOverridesMethod1() As Task - Using testState = ProgressionTestState.Create( - - - -using System; +' +' Public Class OverridesGraphQueryTests +' +' Public Async Function TestOverridesMethod1() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +'using System; -abstract class Base -{ - public abstract int $$CompareTo(object obj); -} +'abstract class Base +'{ +' public abstract int $$CompareTo(object obj); +'} -class Goo : Base, IComparable -{ - public override int CompareTo(object obj) - { - throw new NotImplementedException(); - } -} - - - ) +'class Goo : Base, IComparable +'{ +' public override int CompareTo(object obj) +' { +' throw new NotImplementedException(); +' } +'} +' +' +' ) - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New OverridesGraphQuery(), GraphContextDirection.Target) +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New OverridesGraphQuery(), GraphContextDirection.Target) - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - ) - End Using - End Function +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function - - Public Async Function TestOverridesMethod2() As Task - Using testState = ProgressionTestState.Create( - - - -using System; +' +' Public Async Function TestOverridesMethod2() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +'using System; -abstract class Base -{ - public abstract int CompareTo(object obj); -} +'abstract class Base +'{ +' public abstract int CompareTo(object obj); +'} -class Goo : Base, IComparable -{ - public override int $$CompareTo(object obj) - { - throw new NotImplementedException(); - } -} - - - ) +'class Goo : Base, IComparable +'{ +' public override int $$CompareTo(object obj) +' { +' throw new NotImplementedException(); +' } +'} +' +' +' ) - Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() - Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New OverridesGraphQuery(), GraphContextDirection.Target) +' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() +' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New OverridesGraphQuery(), GraphContextDirection.Target) - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - ) - End Using - End Function - End Class -End Namespace +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function +' End Class +'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb b/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb index 636f822ce01a5..3c0f2280eede6 100644 --- a/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb +++ b/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb @@ -32,19 +32,19 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression Return graphBuilder.Graph End Function - Public Async Function GetGraphWithMarkedSymbolNodeAsync(Optional symbolTransform As Func(Of ISymbol, ISymbol) = Nothing) As Task(Of Graph) - Dim hostDocument As TestHostDocument = Workspace.Documents.Single(Function(d) d.CursorPosition.HasValue) - Dim document = Workspace.CurrentSolution.GetDocument(hostDocument.Id) - Dim symbol = Await GetMarkedSymbolAsync() + 'Public Async Function GetGraphWithMarkedSymbolNodeAsync(Optional symbolTransform As Func(Of ISymbol, ISymbol) = Nothing) As Task(Of Graph) + ' Dim hostDocument As TestHostDocument = Workspace.Documents.Single(Function(d) d.CursorPosition.HasValue) + ' Dim document = Workspace.CurrentSolution.GetDocument(hostDocument.Id) + ' Dim symbol = Await GetMarkedSymbolAsync() - If symbolTransform IsNot Nothing Then - symbol = symbolTransform(symbol) - End If + ' If symbolTransform IsNot Nothing Then + ' symbol = symbolTransform(symbol) + ' End If - Dim graphBuilder As New GraphBuilder(Workspace.CurrentSolution) - Await graphBuilder.AddNodeAsync(symbol, document.Project, document, CancellationToken.None) - Return graphBuilder.Graph - End Function + ' Dim graphBuilder As New GraphBuilder(Workspace.CurrentSolution) + ' Await graphBuilder.AddNodeAsync(symbol, document.Project, document, CancellationToken.None) + ' Return graphBuilder.Graph + 'End Function Public Async Function GetGraphContextAfterQuery(graph As Graph, graphQuery As IGraphQuery, direction As GraphContextDirection) As Task(Of IGraphContext) Dim graphContext As New MockGraphContext(direction, graph.Copy(), graph.Nodes) @@ -66,13 +66,13 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression Workspace.Dispose() End Sub - Public Async Function AssertMarkedSymbolLabelIsAsync(graphCommandId As String, label As String, description As String) As Task - Dim graphNode = (Await GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() - Dim formattedLabelExtension As New GraphFormattedLabelExtension() + 'Public Async Function AssertMarkedSymbolLabelIsAsync(graphCommandId As String, label As String, description As String) As Task + ' Dim graphNode = (Await GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() + ' Dim formattedLabelExtension As New GraphFormattedLabelExtension() - Assert.Equal(label, formattedLabelExtension.Label(graphNode, graphCommandId)) - Assert.Equal(description, formattedLabelExtension.Description(graphNode, graphCommandId)) - End Function + ' Assert.Equal(label, formattedLabelExtension.Label(graphNode, graphCommandId)) + ' Assert.Equal(description, formattedLabelExtension.Description(graphNode, graphCommandId)) + 'End Function Public Function GetMarkedSymbolAsync() As Task(Of ISymbol) Dim hostDocument As TestHostDocument = Workspace.Documents.Single(Function(d) d.CursorPosition.HasValue) diff --git a/src/VisualStudio/Core/Test/Progression/VisualBasicSymbolLabelTests.vb b/src/VisualStudio/Core/Test/Progression/VisualBasicSymbolLabelTests.vb index e12ac6dacd82a..cbf5a8af16882 100644 --- a/src/VisualStudio/Core/Test/Progression/VisualBasicSymbolLabelTests.vb +++ b/src/VisualStudio/Core/Test/Progression/VisualBasicSymbolLabelTests.vb @@ -1,82 +1,82 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. -Imports System.Threading.Tasks -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Roslyn.Test.Utilities +'Imports System.Threading.Tasks +'Imports Microsoft.CodeAnalysis.Test.Utilities +'Imports Microsoft.VisualStudio.GraphModel +'Imports Roslyn.Test.Utilities -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - - Public Class VisualBasicSymbolLabelTests - - Public Async Function TestMethodWithOptionalParameter() As Task - Using testState = ProgressionTestState.Create( - - - - Class C - Sub $$S(Optional i As Integer = 42) - End Sub - End Class - - - ) +'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression +' +' Public Class VisualBasicSymbolLabelTests +' +' Public Async Function TestMethodWithOptionalParameter() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' Class C +' Sub $$S(Optional i As Integer = 42) +' End Sub +' End Class +' +' +' ) - Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "S([Integer])", "C.S([Integer])") - End Using - End Function +' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "S([Integer])", "C.S([Integer])") +' End Using +' End Function - - Public Async Function TestMethodWithByRefParameter() As Task - Using testState = ProgressionTestState.Create( - - - - Class C - Sub $$S(ByRef i As Integer) - End Sub - End Class - - - ) +' +' Public Async Function TestMethodWithByRefParameter() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' Class C +' Sub $$S(ByRef i As Integer) +' End Sub +' End Class +' +' +' ) - Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "S(ByRef Integer)", "C.S(ByRef Integer)") - End Using - End Function +' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "S(ByRef Integer)", "C.S(ByRef Integer)") +' End Using +' End Function - - Public Async Function TestEnumMember() As Task - Using testState = ProgressionTestState.Create( - - - - Enum E - $$M - End Enum - - - ) +' +' Public Async Function TestEnumMember() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' Enum E +' $$M +' End Enum +' +' +' ) - Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M", "E.M") - End Using - End Function +' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M", "E.M") +' End Using +' End Function - - Public Async Function TestGenericType() As Task - Using testState = ProgressionTestState.Create( - - - - Class $$C(Of T) - End Class - - - ) +' +' Public Async Function TestGenericType() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' Class $$C(Of T) +' End Class +' +' +' ) - Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "C(Of T)", "C(Of T)") - End Using - End Function - End Class -End Namespace +' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "C(Of T)", "C(Of T)") +' End Using +' End Function +' End Class +'End Namespace diff --git a/src/VisualStudio/VisualBasic/Impl/Progression/VisualBasicProgressionLanguageService.vb b/src/VisualStudio/VisualBasic/Impl/Progression/VisualBasicProgressionLanguageService.vb index 992dfd14e75fe..0b4391863868f 100644 --- a/src/VisualStudio/VisualBasic/Impl/Progression/VisualBasicProgressionLanguageService.vb +++ b/src/VisualStudio/VisualBasic/Impl/Progression/VisualBasicProgressionLanguageService.vb @@ -1,95 +1,95 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. - -Imports System.Composition -Imports System.Threading -Imports Microsoft.CodeAnalysis -Imports Microsoft.CodeAnalysis.Host -Imports Microsoft.CodeAnalysis.Host.Mef -Imports Microsoft.CodeAnalysis.Shared.Extensions -Imports Microsoft.CodeAnalysis.VisualBasic -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression - -Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Progression - - Partial Friend Class VisualBasicProgressionLanguageService - Implements IProgressionLanguageService - - - - Public Sub New() - End Sub - - Public Function GetTopLevelNodesFromDocument(root As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of SyntaxNode) Implements IProgressionLanguageService.GetTopLevelNodesFromDocument - ' TODO: Implement this lazily like in C#? - Dim nodes = New Stack(Of SyntaxNode)() - - Dim result = New List(Of SyntaxNode) - - nodes.Push(root) - - While nodes.Count > 0 - cancellationToken.ThrowIfCancellationRequested() - - Dim node = nodes.Pop() - - If node.Kind = SyntaxKind.ClassBlock OrElse - node.Kind = SyntaxKind.DelegateFunctionStatement OrElse - node.Kind = SyntaxKind.DelegateSubStatement OrElse - node.Kind = SyntaxKind.EnumBlock OrElse - node.Kind = SyntaxKind.ModuleBlock OrElse - node.Kind = SyntaxKind.InterfaceBlock OrElse - node.Kind = SyntaxKind.StructureBlock OrElse - node.Kind = SyntaxKind.FieldDeclaration OrElse - node.Kind = SyntaxKind.SubBlock OrElse - node.Kind = SyntaxKind.FunctionBlock OrElse - node.Kind = SyntaxKind.PropertyBlock Then - result.Add(node) - Else - For Each child In node.ChildNodes() - nodes.Push(child) - Next - End If - End While - - Return result - End Function - - Private Shared ReadOnly s_descriptionFormat As SymbolDisplayFormat = New SymbolDisplayFormat( - globalNamespaceStyle:=SymbolDisplayGlobalNamespaceStyle.OmittedAsContaining, - typeQualificationStyle:=SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces, - genericsOptions:=SymbolDisplayGenericsOptions.IncludeTypeParameters, - memberOptions:=SymbolDisplayMemberOptions.IncludeParameters Or SymbolDisplayMemberOptions.IncludeContainingType, - parameterOptions:=SymbolDisplayParameterOptions.IncludeType Or SymbolDisplayParameterOptions.IncludeParamsRefOut Or SymbolDisplayParameterOptions.IncludeOptionalBrackets, - miscellaneousOptions:=SymbolDisplayMiscellaneousOptions.UseSpecialTypes) - - Public Function GetDescriptionForSymbol(symbol As ISymbol, includeContainingSymbol As Boolean) As String Implements IProgressionLanguageService.GetDescriptionForSymbol - Return GetSymbolText(symbol, False, s_descriptionFormat) - End Function - - Private Shared ReadOnly s_labelFormat As SymbolDisplayFormat = New SymbolDisplayFormat( - genericsOptions:=SymbolDisplayGenericsOptions.IncludeTypeParameters, - memberOptions:=SymbolDisplayMemberOptions.IncludeParameters Or SymbolDisplayMemberOptions.IncludeType, - parameterOptions:=SymbolDisplayParameterOptions.IncludeType Or SymbolDisplayParameterOptions.IncludeParamsRefOut Or SymbolDisplayParameterOptions.IncludeOptionalBrackets, - miscellaneousOptions:=SymbolDisplayMiscellaneousOptions.UseSpecialTypes) - - Public Function GetLabelForSymbol(symbol As ISymbol, includeContainingSymbol As Boolean) As String Implements IProgressionLanguageService.GetLabelForSymbol - Return GetSymbolText(symbol, includeContainingSymbol, s_labelFormat) - End Function - - Private Shared Function GetSymbolText(symbol As ISymbol, includeContainingSymbol As Boolean, displayFormat As SymbolDisplayFormat) As String - If symbol.Kind = SymbolKind.Field AndAlso symbol.ContainingType.TypeKind = TypeKind.Enum Then - displayFormat = displayFormat.RemoveMemberOptions(SymbolDisplayMemberOptions.IncludeType) - End If - - Dim label As String = symbol.ToDisplayString(displayFormat) - - If includeContainingSymbol AndAlso symbol.ContainingSymbol IsNot Nothing Then - label += " (" + symbol.ContainingSymbol.ToDisplayString(displayFormat) + ")" - End If - - Return label - End Function - End Class -End Namespace +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. + +'Imports System.Composition +'Imports System.Threading +'Imports Microsoft.CodeAnalysis +'Imports Microsoft.CodeAnalysis.Host +'Imports Microsoft.CodeAnalysis.Host.Mef +'Imports Microsoft.CodeAnalysis.Shared.Extensions +'Imports Microsoft.CodeAnalysis.VisualBasic +'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression + +'Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Progression +' +' Partial Friend Class VisualBasicProgressionLanguageService +' Implements IProgressionLanguageService + +' +' +' Public Sub New() +' End Sub + +' Public Function GetTopLevelNodesFromDocument(root As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of SyntaxNode) Implements IProgressionLanguageService.GetTopLevelNodesFromDocument +' ' TODO: Implement this lazily like in C#? +' Dim nodes = New Stack(Of SyntaxNode)() + +' Dim result = New List(Of SyntaxNode) + +' nodes.Push(root) + +' While nodes.Count > 0 +' cancellationToken.ThrowIfCancellationRequested() + +' Dim node = nodes.Pop() + +' If node.Kind = SyntaxKind.ClassBlock OrElse +' node.Kind = SyntaxKind.DelegateFunctionStatement OrElse +' node.Kind = SyntaxKind.DelegateSubStatement OrElse +' node.Kind = SyntaxKind.EnumBlock OrElse +' node.Kind = SyntaxKind.ModuleBlock OrElse +' node.Kind = SyntaxKind.InterfaceBlock OrElse +' node.Kind = SyntaxKind.StructureBlock OrElse +' node.Kind = SyntaxKind.FieldDeclaration OrElse +' node.Kind = SyntaxKind.SubBlock OrElse +' node.Kind = SyntaxKind.FunctionBlock OrElse +' node.Kind = SyntaxKind.PropertyBlock Then +' result.Add(node) +' Else +' For Each child In node.ChildNodes() +' nodes.Push(child) +' Next +' End If +' End While + +' Return result +' End Function + +' Private Shared ReadOnly s_descriptionFormat As SymbolDisplayFormat = New SymbolDisplayFormat( +' globalNamespaceStyle:=SymbolDisplayGlobalNamespaceStyle.OmittedAsContaining, +' typeQualificationStyle:=SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces, +' genericsOptions:=SymbolDisplayGenericsOptions.IncludeTypeParameters, +' memberOptions:=SymbolDisplayMemberOptions.IncludeParameters Or SymbolDisplayMemberOptions.IncludeContainingType, +' parameterOptions:=SymbolDisplayParameterOptions.IncludeType Or SymbolDisplayParameterOptions.IncludeParamsRefOut Or SymbolDisplayParameterOptions.IncludeOptionalBrackets, +' miscellaneousOptions:=SymbolDisplayMiscellaneousOptions.UseSpecialTypes) + +' Public Function GetDescriptionForSymbol(symbol As ISymbol, includeContainingSymbol As Boolean) As String Implements IProgressionLanguageService.GetDescriptionForSymbol +' Return GetSymbolText(symbol, False, s_descriptionFormat) +' End Function + +' Private Shared ReadOnly s_labelFormat As SymbolDisplayFormat = New SymbolDisplayFormat( +' genericsOptions:=SymbolDisplayGenericsOptions.IncludeTypeParameters, +' memberOptions:=SymbolDisplayMemberOptions.IncludeParameters Or SymbolDisplayMemberOptions.IncludeType, +' parameterOptions:=SymbolDisplayParameterOptions.IncludeType Or SymbolDisplayParameterOptions.IncludeParamsRefOut Or SymbolDisplayParameterOptions.IncludeOptionalBrackets, +' miscellaneousOptions:=SymbolDisplayMiscellaneousOptions.UseSpecialTypes) + +' Public Function GetLabelForSymbol(symbol As ISymbol, includeContainingSymbol As Boolean) As String Implements IProgressionLanguageService.GetLabelForSymbol +' Return GetSymbolText(symbol, includeContainingSymbol, s_labelFormat) +' End Function + +' Private Shared Function GetSymbolText(symbol As ISymbol, includeContainingSymbol As Boolean, displayFormat As SymbolDisplayFormat) As String +' If symbol.Kind = SymbolKind.Field AndAlso symbol.ContainingType.TypeKind = TypeKind.Enum Then +' displayFormat = displayFormat.RemoveMemberOptions(SymbolDisplayMemberOptions.IncludeType) +' End If + +' Dim label As String = symbol.ToDisplayString(displayFormat) + +' If includeContainingSymbol AndAlso symbol.ContainingSymbol IsNot Nothing Then +' label += " (" + symbol.ContainingSymbol.ToDisplayString(displayFormat) + ")" +' End If + +' Return label +' End Function +' End Class +'End Namespace From 15f847182d40dcfb9b9d7dda2ae5d6f96adabd1a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:10:51 +0200 Subject: [PATCH 002/353] Remove more unused code --- .../Core/Def/Progression/GraphBuilder.cs | 466 +++++++++--------- 1 file changed, 233 insertions(+), 233 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs b/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs index 0ada9e186601e..04ec44d639718 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs @@ -307,36 +307,36 @@ public ISymbol GetSymbol(GraphNode node, CancellationToken cancellationToken) // return node; //} - private static async Task GetOrCreateNodeForParameterAsync(Graph graph, IParameterSymbol parameterSymbol, Solution solution, CancellationToken cancellationToken) - { - var id = await GraphNodeIdCreation.GetIdForParameterAsync(parameterSymbol, solution, cancellationToken).ConfigureAwait(false); - var node = graph.Nodes.GetOrCreate(id); - node.AddCategory(CodeNodeCategories.Parameter); + //private static async Task GetOrCreateNodeForParameterAsync(Graph graph, IParameterSymbol parameterSymbol, Solution solution, CancellationToken cancellationToken) + //{ + // var id = await GraphNodeIdCreation.GetIdForParameterAsync(parameterSymbol, solution, cancellationToken).ConfigureAwait(false); + // var node = graph.Nodes.GetOrCreate(id); + // node.AddCategory(CodeNodeCategories.Parameter); - node.SetValue(Properties.IsByReference, parameterSymbol.RefKind == RefKind.Ref); - node.SetValue(Properties.IsOut, parameterSymbol.RefKind == RefKind.Out); - node.SetValue(Properties.IsParameterArray, parameterSymbol.IsParams); + // node.SetValue(Properties.IsByReference, parameterSymbol.RefKind == RefKind.Ref); + // node.SetValue(Properties.IsOut, parameterSymbol.RefKind == RefKind.Out); + // node.SetValue(Properties.IsParameterArray, parameterSymbol.IsParams); - return node; - } + // return node; + //} - private static async Task GetOrCreateNodeForLocalVariableAsync(Graph graph, ISymbol localSymbol, Solution solution, CancellationToken cancellationToken) - { - var id = await GraphNodeIdCreation.GetIdForLocalVariableAsync(localSymbol, solution, cancellationToken).ConfigureAwait(false); - var node = graph.Nodes.GetOrCreate(id); - node.AddCategory(NodeCategories.LocalExpression); + //private static async Task GetOrCreateNodeForLocalVariableAsync(Graph graph, ISymbol localSymbol, Solution solution, CancellationToken cancellationToken) + //{ + // var id = await GraphNodeIdCreation.GetIdForLocalVariableAsync(localSymbol, solution, cancellationToken).ConfigureAwait(false); + // var node = graph.Nodes.GetOrCreate(id); + // node.AddCategory(NodeCategories.LocalExpression); - return node; - } + // return node; + //} - private static async Task GetOrCreateNodeAssemblyAsync(Graph graph, IAssemblySymbol assemblySymbol, Solution solution, CancellationToken cancellationToken) - { - var id = await GraphNodeIdCreation.GetIdForAssemblyAsync(assemblySymbol, solution, cancellationToken).ConfigureAwait(false); - var node = graph.Nodes.GetOrCreate(id); - node.AddCategory(CodeNodeCategories.Assembly); + //private static async Task GetOrCreateNodeAssemblyAsync(Graph graph, IAssemblySymbol assemblySymbol, Solution solution, CancellationToken cancellationToken) + //{ + // var id = await GraphNodeIdCreation.GetIdForAssemblyAsync(assemblySymbol, solution, cancellationToken).ConfigureAwait(false); + // var node = graph.Nodes.GetOrCreate(id); + // node.AddCategory(CodeNodeCategories.Assembly); - return node; - } + // return node; + //} //private static void UpdateLabelsForNode(ISymbol symbol, Solution solution, GraphNode node) //{ @@ -429,253 +429,253 @@ private static async Task GetOrCreateNodeAssemblyAsync(Graph graph, I // node[Microsoft.VisualStudio.ArchitectureTools.ProgressiveReveal.ProgressiveRevealSchema.CommonLabel] = node.Label; //} - private static void UpdatePropertiesForNode(ISymbol symbol, GraphNode node) - { - // Set accessibility properties - switch (symbol.DeclaredAccessibility) - { - case Accessibility.Public: - node[Properties.IsPublic] = true; - break; + //private static void UpdatePropertiesForNode(ISymbol symbol, GraphNode node) + //{ + // // Set accessibility properties + // switch (symbol.DeclaredAccessibility) + // { + // case Accessibility.Public: + // node[Properties.IsPublic] = true; + // break; - case Accessibility.Internal: - node[Properties.IsInternal] = true; - break; + // case Accessibility.Internal: + // node[Properties.IsInternal] = true; + // break; - case Accessibility.Protected: - node[Properties.IsProtected] = true; - break; + // case Accessibility.Protected: + // node[Properties.IsProtected] = true; + // break; - case Accessibility.Private: - node[Properties.IsPrivate] = true; - break; + // case Accessibility.Private: + // node[Properties.IsPrivate] = true; + // break; - case Accessibility.ProtectedOrInternal: - node[Properties.IsProtectedOrInternal] = true; - break; + // case Accessibility.ProtectedOrInternal: + // node[Properties.IsProtectedOrInternal] = true; + // break; - case Accessibility.ProtectedAndInternal: - node[Properties.IsProtected] = true; - node[Properties.IsInternal] = true; - break; + // case Accessibility.ProtectedAndInternal: + // node[Properties.IsProtected] = true; + // node[Properties.IsInternal] = true; + // break; - case Accessibility.NotApplicable: - break; - } + // case Accessibility.NotApplicable: + // break; + // } - // Set common properties - if (symbol.IsAbstract) - { - node[Properties.IsAbstract] = true; - } + // // Set common properties + // if (symbol.IsAbstract) + // { + // node[Properties.IsAbstract] = true; + // } - if (symbol.IsSealed) - { - // For VB module, do not set IsFinal since it's not inheritable. - if (!symbol.IsModuleType()) - { - node[Properties.IsFinal] = true; - } - } + // if (symbol.IsSealed) + // { + // // For VB module, do not set IsFinal since it's not inheritable. + // if (!symbol.IsModuleType()) + // { + // node[Properties.IsFinal] = true; + // } + // } - if (symbol.IsStatic) - { - node[Properties.IsStatic] = true; - } + // if (symbol.IsStatic) + // { + // node[Properties.IsStatic] = true; + // } - if (symbol.IsVirtual) - { - node[Properties.IsVirtual] = true; - } + // if (symbol.IsVirtual) + // { + // node[Properties.IsVirtual] = true; + // } - if (symbol.IsOverride) - { - // The property name is a misnomer, but this is what the previous providers do. - node[Microsoft.VisualStudio.Progression.DgmlProperties.IsOverloaded] = true; - } + // if (symbol.IsOverride) + // { + // // The property name is a misnomer, but this is what the previous providers do. + // node[Microsoft.VisualStudio.Progression.DgmlProperties.IsOverloaded] = true; + // } - // Set type-specific properties - if (symbol is ITypeSymbol typeSymbol && typeSymbol.IsAnonymousType) - { - node[Properties.IsAnonymous] = true; - } - else if (symbol is IMethodSymbol methodSymbol) - { - UpdateMethodPropertiesForNode(methodSymbol, node); - } - } + // // Set type-specific properties + // if (symbol is ITypeSymbol typeSymbol && typeSymbol.IsAnonymousType) + // { + // node[Properties.IsAnonymous] = true; + // } + // else if (symbol is IMethodSymbol methodSymbol) + // { + // UpdateMethodPropertiesForNode(methodSymbol, node); + // } + //} - private static void UpdateMethodPropertiesForNode(IMethodSymbol symbol, GraphNode node) - { - if (symbol.HidesBaseMethodsByName) - { - node[Properties.IsHideBySignature] = true; - } + //private static void UpdateMethodPropertiesForNode(IMethodSymbol symbol, GraphNode node) + //{ + // if (symbol.HidesBaseMethodsByName) + // { + // node[Properties.IsHideBySignature] = true; + // } - if (symbol.IsExtensionMethod) - { - node[Properties.IsExtension] = true; - } + // if (symbol.IsExtensionMethod) + // { + // node[Properties.IsExtension] = true; + // } - switch (symbol.MethodKind) - { - case MethodKind.AnonymousFunction: - node[Properties.IsAnonymous] = true; - break; - - case MethodKind.BuiltinOperator: - case MethodKind.UserDefinedOperator: - node[Properties.IsOperator] = true; - break; - - case MethodKind.Constructor: - case MethodKind.StaticConstructor: - node[Properties.IsConstructor] = true; - break; - - case MethodKind.Conversion: - // Operator implicit/explicit - node[Properties.IsOperator] = true; - break; - - case MethodKind.Destructor: - node[Properties.IsFinalizer] = true; - break; - - case MethodKind.PropertyGet: - node[Properties.IsPropertyGet] = true; - break; - - case MethodKind.PropertySet: - node[Properties.IsPropertySet] = true; - break; - } - } + // switch (symbol.MethodKind) + // { + // case MethodKind.AnonymousFunction: + // node[Properties.IsAnonymous] = true; + // break; - private static async Task GetOrCreateNodeForNamespaceAsync(Graph graph, INamespaceSymbol symbol, Solution solution, CancellationToken cancellationToken) - { - var id = await GraphNodeIdCreation.GetIdForNamespaceAsync(symbol, solution, cancellationToken).ConfigureAwait(false); - var node = graph.Nodes.GetOrCreate(id); - node.AddCategory(CodeNodeCategories.Namespace); + // case MethodKind.BuiltinOperator: + // case MethodKind.UserDefinedOperator: + // node[Properties.IsOperator] = true; + // break; - return node; - } + // case MethodKind.Constructor: + // case MethodKind.StaticConstructor: + // node[Properties.IsConstructor] = true; + // break; - private static async Task GetOrCreateNodeForNamedTypeAsync(Graph graph, INamedTypeSymbol namedType, Solution solution, CancellationToken cancellationToken) - { - var id = await GraphNodeIdCreation.GetIdForTypeAsync(namedType, solution, cancellationToken).ConfigureAwait(false); - var node = graph.Nodes.GetOrCreate(id); - string iconGroupName; + // case MethodKind.Conversion: + // // Operator implicit/explicit + // node[Properties.IsOperator] = true; + // break; - switch (namedType.TypeKind) - { - case TypeKind.Class: - node.AddCategory(CodeNodeCategories.Class); - iconGroupName = "Class"; - break; - - case TypeKind.Delegate: - node.AddCategory(CodeNodeCategories.Delegate); - iconGroupName = "Delegate"; - break; - - case TypeKind.Enum: - node.AddCategory(CodeNodeCategories.Enum); - iconGroupName = "Enum"; - break; - - case TypeKind.Interface: - node.AddCategory(CodeNodeCategories.Interface); - iconGroupName = "Interface"; - break; - - case TypeKind.Module: - node.AddCategory(CodeNodeCategories.Module); - iconGroupName = "Module"; - break; - - case TypeKind.Struct: - node.AddCategory(CodeNodeCategories.Struct); - iconGroupName = "Struct"; - break; - - case TypeKind.Error: - node.AddCategory(CodeNodeCategories.Type); - iconGroupName = "Error"; - break; - - default: - throw ExceptionUtilities.UnexpectedValue(namedType.TypeKind); - } + // case MethodKind.Destructor: + // node[Properties.IsFinalizer] = true; + // break; - node[DgmlNodeProperties.Icon] = IconHelper.GetIconName(iconGroupName, namedType.DeclaredAccessibility); - node[RoslynGraphProperties.TypeKind] = namedType.TypeKind; + // case MethodKind.PropertyGet: + // node[Properties.IsPropertyGet] = true; + // break; - return node; - } + // case MethodKind.PropertySet: + // node[Properties.IsPropertySet] = true; + // break; + // } + //} - private static async Task GetOrCreateNodeForMethodAsync(Graph graph, IMethodSymbol method, Solution solution, CancellationToken cancellationToken) - { - var id = await GraphNodeIdCreation.GetIdForMemberAsync(method, solution, cancellationToken).ConfigureAwait(false); - var node = graph.Nodes.GetOrCreate(id); + //private static async Task GetOrCreateNodeForNamespaceAsync(Graph graph, INamespaceSymbol symbol, Solution solution, CancellationToken cancellationToken) + //{ + // var id = await GraphNodeIdCreation.GetIdForNamespaceAsync(symbol, solution, cancellationToken).ConfigureAwait(false); + // var node = graph.Nodes.GetOrCreate(id); + // node.AddCategory(CodeNodeCategories.Namespace); - node.AddCategory(CodeNodeCategories.Method); + // return node; + //} - var isOperator = method.MethodKind is MethodKind.UserDefinedOperator or MethodKind.Conversion; - node[DgmlNodeProperties.Icon] = isOperator - ? IconHelper.GetIconName("Operator", method.DeclaredAccessibility) - : IconHelper.GetIconName("Method", method.DeclaredAccessibility); + //private static async Task GetOrCreateNodeForNamedTypeAsync(Graph graph, INamedTypeSymbol namedType, Solution solution, CancellationToken cancellationToken) + //{ + // var id = await GraphNodeIdCreation.GetIdForTypeAsync(namedType, solution, cancellationToken).ConfigureAwait(false); + // var node = graph.Nodes.GetOrCreate(id); + // string iconGroupName; - node[RoslynGraphProperties.TypeKind] = method.ContainingType.TypeKind; - node[RoslynGraphProperties.MethodKind] = method.MethodKind; + // switch (namedType.TypeKind) + // { + // case TypeKind.Class: + // node.AddCategory(CodeNodeCategories.Class); + // iconGroupName = "Class"; + // break; - return node; - } + // case TypeKind.Delegate: + // node.AddCategory(CodeNodeCategories.Delegate); + // iconGroupName = "Delegate"; + // break; - private static async Task GetOrCreateNodeForFieldAsync(Graph graph, IFieldSymbol field, Solution solution, CancellationToken cancellationToken) - { - var id = await GraphNodeIdCreation.GetIdForMemberAsync(field, solution, cancellationToken).ConfigureAwait(false); - var node = graph.Nodes.GetOrCreate(id); + // case TypeKind.Enum: + // node.AddCategory(CodeNodeCategories.Enum); + // iconGroupName = "Enum"; + // break; - node.AddCategory(CodeNodeCategories.Field); + // case TypeKind.Interface: + // node.AddCategory(CodeNodeCategories.Interface); + // iconGroupName = "Interface"; + // break; - if (field.ContainingType.TypeKind == TypeKind.Enum) - { - node[DgmlNodeProperties.Icon] = IconHelper.GetIconName("EnumMember", field.DeclaredAccessibility); - } - else - { - node[DgmlNodeProperties.Icon] = IconHelper.GetIconName("Field", field.DeclaredAccessibility); - } + // case TypeKind.Module: + // node.AddCategory(CodeNodeCategories.Module); + // iconGroupName = "Module"; + // break; - return node; - } + // case TypeKind.Struct: + // node.AddCategory(CodeNodeCategories.Struct); + // iconGroupName = "Struct"; + // break; - private static async Task GetOrCreateNodeForPropertyAsync(Graph graph, IPropertySymbol property, Solution solution, CancellationToken cancellationToken) - { - var id = await GraphNodeIdCreation.GetIdForMemberAsync(property, solution, cancellationToken).ConfigureAwait(false); - var node = graph.Nodes.GetOrCreate(id); + // case TypeKind.Error: + // node.AddCategory(CodeNodeCategories.Type); + // iconGroupName = "Error"; + // break; - node.AddCategory(CodeNodeCategories.Property); + // default: + // throw ExceptionUtilities.UnexpectedValue(namedType.TypeKind); + // } - node[DgmlNodeProperties.Icon] = IconHelper.GetIconName("Property", property.DeclaredAccessibility); - node[RoslynGraphProperties.TypeKind] = property.ContainingType.TypeKind; + // node[DgmlNodeProperties.Icon] = IconHelper.GetIconName(iconGroupName, namedType.DeclaredAccessibility); + // node[RoslynGraphProperties.TypeKind] = namedType.TypeKind; - return node; - } + // return node; + //} - private static async Task GetOrCreateNodeForEventAsync(Graph graph, IEventSymbol eventSymbol, Solution solution, CancellationToken cancellationToken) - { - var id = await GraphNodeIdCreation.GetIdForMemberAsync(eventSymbol, solution, cancellationToken).ConfigureAwait(false); - var node = graph.Nodes.GetOrCreate(id); + //private static async Task GetOrCreateNodeForMethodAsync(Graph graph, IMethodSymbol method, Solution solution, CancellationToken cancellationToken) + //{ + // var id = await GraphNodeIdCreation.GetIdForMemberAsync(method, solution, cancellationToken).ConfigureAwait(false); + // var node = graph.Nodes.GetOrCreate(id); - node.AddCategory(CodeNodeCategories.Event); + // node.AddCategory(CodeNodeCategories.Method); - node[DgmlNodeProperties.Icon] = IconHelper.GetIconName("Event", eventSymbol.DeclaredAccessibility); - node[RoslynGraphProperties.TypeKind] = eventSymbol.ContainingType.TypeKind; + // var isOperator = method.MethodKind is MethodKind.UserDefinedOperator or MethodKind.Conversion; + // node[DgmlNodeProperties.Icon] = isOperator + // ? IconHelper.GetIconName("Operator", method.DeclaredAccessibility) + // : IconHelper.GetIconName("Method", method.DeclaredAccessibility); - return node; - } + // node[RoslynGraphProperties.TypeKind] = method.ContainingType.TypeKind; + // node[RoslynGraphProperties.MethodKind] = method.MethodKind; + + // return node; + //} + + //private static async Task GetOrCreateNodeForFieldAsync(Graph graph, IFieldSymbol field, Solution solution, CancellationToken cancellationToken) + //{ + // var id = await GraphNodeIdCreation.GetIdForMemberAsync(field, solution, cancellationToken).ConfigureAwait(false); + // var node = graph.Nodes.GetOrCreate(id); + + // node.AddCategory(CodeNodeCategories.Field); + + // if (field.ContainingType.TypeKind == TypeKind.Enum) + // { + // node[DgmlNodeProperties.Icon] = IconHelper.GetIconName("EnumMember", field.DeclaredAccessibility); + // } + // else + // { + // node[DgmlNodeProperties.Icon] = IconHelper.GetIconName("Field", field.DeclaredAccessibility); + // } + + // return node; + //} + + //private static async Task GetOrCreateNodeForPropertyAsync(Graph graph, IPropertySymbol property, Solution solution, CancellationToken cancellationToken) + //{ + // var id = await GraphNodeIdCreation.GetIdForMemberAsync(property, solution, cancellationToken).ConfigureAwait(false); + // var node = graph.Nodes.GetOrCreate(id); + + // node.AddCategory(CodeNodeCategories.Property); + + // node[DgmlNodeProperties.Icon] = IconHelper.GetIconName("Property", property.DeclaredAccessibility); + // node[RoslynGraphProperties.TypeKind] = property.ContainingType.TypeKind; + + // return node; + //} + + //private static async Task GetOrCreateNodeForEventAsync(Graph graph, IEventSymbol eventSymbol, Solution solution, CancellationToken cancellationToken) + //{ + // var id = await GraphNodeIdCreation.GetIdForMemberAsync(eventSymbol, solution, cancellationToken).ConfigureAwait(false); + // var node = graph.Nodes.GetOrCreate(id); + + // node.AddCategory(CodeNodeCategories.Event); + + // node[DgmlNodeProperties.Icon] = IconHelper.GetIconName("Event", eventSymbol.DeclaredAccessibility); + // node[RoslynGraphProperties.TypeKind] = eventSymbol.ContainingType.TypeKind; + + // return node; + //} public void AddLink(GraphNode from, GraphCategory category, GraphNode to, CancellationToken cancellationToken) { From 87fe2400f3606e3025b20934ecb450220c6a3925 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:12:25 +0200 Subject: [PATCH 003/353] Remove more unused code --- .../Core/Def/Progression/GraphBuilder.cs | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs b/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs index 04ec44d639718..b10a07378214b 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs @@ -148,38 +148,38 @@ private async Task PopulateMapsForSymbolInputNodeAsync(GraphNode inputNode, Canc } } - public Project GetContextProject(GraphNode node, CancellationToken cancellationToken) - { - using (_gate.DisposableWait(cancellationToken)) - { - _nodeToContextProjectMap.TryGetValue(node, out var project); - return project; - } - } + //public Project GetContextProject(GraphNode node, CancellationToken cancellationToken) + //{ + // using (_gate.DisposableWait(cancellationToken)) + // { + // _nodeToContextProjectMap.TryGetValue(node, out var project); + // return project; + // } + //} - public ProjectId GetContextProjectId(Project project, ISymbol symbol) - { - var thisProject = project.Solution.GetProject(symbol.ContainingAssembly) ?? project; - return thisProject.Id; - } + //public ProjectId GetContextProjectId(Project project, ISymbol symbol) + //{ + // var thisProject = project.Solution.GetProject(symbol.ContainingAssembly) ?? project; + // return thisProject.Id; + //} - public Document GetContextDocument(GraphNode node, CancellationToken cancellationToken) - { - using (_gate.DisposableWait(cancellationToken)) - { - _nodeToContextDocumentMap.TryGetValue(node, out var document); - return document; - } - } + //public Document GetContextDocument(GraphNode node, CancellationToken cancellationToken) + //{ + // using (_gate.DisposableWait(cancellationToken)) + // { + // _nodeToContextDocumentMap.TryGetValue(node, out var document); + // return document; + // } + //} - public ISymbol GetSymbol(GraphNode node, CancellationToken cancellationToken) - { - using (_gate.DisposableWait(cancellationToken)) - { - _nodeToSymbolMap.TryGetValue(node, out var symbol); - return symbol; - } - } + //public ISymbol GetSymbol(GraphNode node, CancellationToken cancellationToken) + //{ + // using (_gate.DisposableWait(cancellationToken)) + // { + // _nodeToSymbolMap.TryGetValue(node, out var symbol); + // return symbol; + // } + //} //public Task AddNodeAsync(ISymbol symbol, GraphNode relatedNode, CancellationToken cancellationToken) //{ @@ -835,13 +835,13 @@ public void ApplyToGraph(Graph graph, CancellationToken cancellationToken) } } - public void AddDeferredPropertySet(GraphNode node, GraphProperty property, object value, CancellationToken cancellationToken) - { - using (_gate.DisposableWait(cancellationToken)) - { - _deferredPropertySets.Add(Tuple.Create(node, property, value)); - } - } + //public void AddDeferredPropertySet(GraphNode node, GraphProperty property, object value, CancellationToken cancellationToken) + //{ + // using (_gate.DisposableWait(cancellationToken)) + // { + // _deferredPropertySets.Add(Tuple.Create(node, property, value)); + // } + //} public Graph Graph { get; } = new(); From acc738b832f890d6dce01e058e96ceb8813959ea Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:14:36 +0200 Subject: [PATCH 004/353] Remove more unused code --- .../Core/Def/Progression/GraphNodeCreation.cs | 128 +++++++++--------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs b/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs index fef47a425b614..1ce605e787370 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs @@ -1,79 +1,79 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. -using System; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.VisualStudio.GraphModel; -using Microsoft.VisualStudio.LanguageServices.Implementation.Progression; +//using System; +//using System.Threading; +//using System.Threading.Tasks; +//using Microsoft.CodeAnalysis; +//using Microsoft.VisualStudio.GraphModel; +//using Microsoft.VisualStudio.LanguageServices.Implementation.Progression; -namespace Microsoft.VisualStudio.LanguageServices.Progression; +//namespace Microsoft.VisualStudio.LanguageServices.Progression; -/// -/// A helper class that implements the creation of s. -/// -public static class GraphNodeCreation -{ - public static async Task CreateNodeIdAsync(ISymbol symbol, Solution solution, CancellationToken cancellationToken) - { - if (symbol == null) - { - throw new ArgumentNullException(nameof(symbol)); - } +///// +///// A helper class that implements the creation of s. +///// +//public static class GraphNodeCreation +//{ +// public static async Task CreateNodeIdAsync(ISymbol symbol, Solution solution, CancellationToken cancellationToken) +// { +// if (symbol == null) +// { +// throw new ArgumentNullException(nameof(symbol)); +// } - if (solution == null) - { - throw new ArgumentNullException(nameof(solution)); - } +// if (solution == null) +// { +// throw new ArgumentNullException(nameof(solution)); +// } - switch (symbol.Kind) - { - case SymbolKind.Assembly: - return await GraphNodeIdCreation.GetIdForAssemblyAsync((IAssemblySymbol)symbol, solution, cancellationToken).ConfigureAwait(false); +// switch (symbol.Kind) +// { +// case SymbolKind.Assembly: +// return await GraphNodeIdCreation.GetIdForAssemblyAsync((IAssemblySymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - case SymbolKind.Namespace: - return await GraphNodeIdCreation.GetIdForNamespaceAsync((INamespaceSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); +// case SymbolKind.Namespace: +// return await GraphNodeIdCreation.GetIdForNamespaceAsync((INamespaceSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - case SymbolKind.NamedType: - return await GraphNodeIdCreation.GetIdForTypeAsync((ITypeSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); +// case SymbolKind.NamedType: +// return await GraphNodeIdCreation.GetIdForTypeAsync((ITypeSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - case SymbolKind.Method: - case SymbolKind.Field: - case SymbolKind.Property: - case SymbolKind.Event: - return await GraphNodeIdCreation.GetIdForMemberAsync(symbol, solution, cancellationToken).ConfigureAwait(false); +// case SymbolKind.Method: +// case SymbolKind.Field: +// case SymbolKind.Property: +// case SymbolKind.Event: +// return await GraphNodeIdCreation.GetIdForMemberAsync(symbol, solution, cancellationToken).ConfigureAwait(false); - case SymbolKind.Parameter: - return await GraphNodeIdCreation.GetIdForParameterAsync((IParameterSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); +// case SymbolKind.Parameter: +// return await GraphNodeIdCreation.GetIdForParameterAsync((IParameterSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - case SymbolKind.Local: - case SymbolKind.RangeVariable: - return await GraphNodeIdCreation.GetIdForLocalVariableAsync(symbol, solution, cancellationToken).ConfigureAwait(false); +// case SymbolKind.Local: +// case SymbolKind.RangeVariable: +// return await GraphNodeIdCreation.GetIdForLocalVariableAsync(symbol, solution, cancellationToken).ConfigureAwait(false); - default: - throw new ArgumentException(string.Format(ServicesVSResources.Can_t_create_a_node_id_for_this_symbol_kind_colon_0, symbol)); - } - } +// default: +// throw new ArgumentException(string.Format(ServicesVSResources.Can_t_create_a_node_id_for_this_symbol_kind_colon_0, symbol)); +// } +// } - //public static async Task CreateNodeAsync(this Graph graph, ISymbol symbol, Solution solution, CancellationToken cancellationToken) - //{ - // if (graph == null) - // { - // throw new ArgumentNullException(nameof(graph)); - // } +// //public static async Task CreateNodeAsync(this Graph graph, ISymbol symbol, Solution solution, CancellationToken cancellationToken) +// //{ +// // if (graph == null) +// // { +// // throw new ArgumentNullException(nameof(graph)); +// // } - // if (symbol == null) - // { - // throw new ArgumentNullException(nameof(symbol)); - // } +// // if (symbol == null) +// // { +// // throw new ArgumentNullException(nameof(symbol)); +// // } - // if (solution == null) - // { - // throw new ArgumentNullException(nameof(solution)); - // } +// // if (solution == null) +// // { +// // throw new ArgumentNullException(nameof(solution)); +// // } - // return await GraphBuilder.GetOrCreateNodeAsync(graph, symbol, solution, cancellationToken).ConfigureAwait(false); - //} -} +// // return await GraphBuilder.GetOrCreateNodeAsync(graph, symbol, solution, cancellationToken).ConfigureAwait(false); +// //} +//} From bbb88fb66bcacae69848277015fdcba30c4c02c5 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:15:33 +0200 Subject: [PATCH 005/353] Remove more unused code --- .../Def/Progression/GraphNodeIdCreation.cs | 124 +++++++++--------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs b/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs index 7038949464e5f..23b25d8c91b93 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs @@ -443,68 +443,68 @@ private static async Task GetAssemblyFullPathAsync(IAssemblySymbol containi return null; } - internal static async Task GetIdForAssemblyAsync(IAssemblySymbol assemblySymbol, Solution solution, CancellationToken cancellationToken) - { - var assembly = await GetAssemblyFullPathAsync(assemblySymbol, solution, cancellationToken).ConfigureAwait(false); - if (assembly != null) - { - var builder = new CodeQualifiedIdentifierBuilder(); - builder.Assembly = assembly; - return builder.ToQualifiedIdentifier(); - } - - return null; - } - - internal static async Task GetIdForParameterAsync(IParameterSymbol symbol, Solution solution, CancellationToken cancellationToken) - { - if (symbol.ContainingSymbol == null || - (symbol.ContainingSymbol.Kind != SymbolKind.Method && symbol.ContainingSymbol.Kind != SymbolKind.Property)) - { - // We are only support parameters inside methods or properties. - throw new ArgumentException("symbol"); - } - - var containingSymbol = symbol.ContainingSymbol; - if (containingSymbol is IMethodSymbol method && method.AssociatedSymbol != null && method.AssociatedSymbol.Kind == SymbolKind.Property) - { - var property = (IPropertySymbol)method.AssociatedSymbol; - if (property.Parameters.Any(static (p, symbol) => p.Name == symbol.Name, symbol)) - { - containingSymbol = property; - } - } - - var memberId = await GetIdForMemberAsync(containingSymbol, solution, cancellationToken).ConfigureAwait(false); - if (memberId != null) - { - return memberId + GraphNodeId.GetPartial(CodeGraphNodeIdName.Parameter, symbol.Name); - } - - return null; - } - - internal static async Task GetIdForLocalVariableAsync(ISymbol symbol, Solution solution, CancellationToken cancellationToken) - { - if (symbol.ContainingSymbol == null || - (symbol.ContainingSymbol.Kind != SymbolKind.Method && symbol.ContainingSymbol.Kind != SymbolKind.Property)) - { - // We are only support local variables inside methods or properties. - throw new ArgumentException("symbol"); - } - - var memberId = await GetIdForMemberAsync(symbol.ContainingSymbol, solution, cancellationToken).ConfigureAwait(false); - if (memberId != null) - { - var builder = new CodeQualifiedIdentifierBuilder(memberId); - builder.LocalVariable = symbol.Name; - builder.LocalVariableIndex = await GetLocalVariableIndexAsync(symbol, solution, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); - - return builder.ToQualifiedIdentifier(); - } - - return null; - } + //internal static async Task GetIdForAssemblyAsync(IAssemblySymbol assemblySymbol, Solution solution, CancellationToken cancellationToken) + //{ + // var assembly = await GetAssemblyFullPathAsync(assemblySymbol, solution, cancellationToken).ConfigureAwait(false); + // if (assembly != null) + // { + // var builder = new CodeQualifiedIdentifierBuilder(); + // builder.Assembly = assembly; + // return builder.ToQualifiedIdentifier(); + // } + + // return null; + //} + + //internal static async Task GetIdForParameterAsync(IParameterSymbol symbol, Solution solution, CancellationToken cancellationToken) + //{ + // if (symbol.ContainingSymbol == null || + // (symbol.ContainingSymbol.Kind != SymbolKind.Method && symbol.ContainingSymbol.Kind != SymbolKind.Property)) + // { + // // We are only support parameters inside methods or properties. + // throw new ArgumentException("symbol"); + // } + + // var containingSymbol = symbol.ContainingSymbol; + // if (containingSymbol is IMethodSymbol method && method.AssociatedSymbol != null && method.AssociatedSymbol.Kind == SymbolKind.Property) + // { + // var property = (IPropertySymbol)method.AssociatedSymbol; + // if (property.Parameters.Any(static (p, symbol) => p.Name == symbol.Name, symbol)) + // { + // containingSymbol = property; + // } + // } + + // var memberId = await GetIdForMemberAsync(containingSymbol, solution, cancellationToken).ConfigureAwait(false); + // if (memberId != null) + // { + // return memberId + GraphNodeId.GetPartial(CodeGraphNodeIdName.Parameter, symbol.Name); + // } + + // return null; + //} + + //internal static async Task GetIdForLocalVariableAsync(ISymbol symbol, Solution solution, CancellationToken cancellationToken) + //{ + // if (symbol.ContainingSymbol == null || + // (symbol.ContainingSymbol.Kind != SymbolKind.Method && symbol.ContainingSymbol.Kind != SymbolKind.Property)) + // { + // // We are only support local variables inside methods or properties. + // throw new ArgumentException("symbol"); + // } + + // var memberId = await GetIdForMemberAsync(symbol.ContainingSymbol, solution, cancellationToken).ConfigureAwait(false); + // if (memberId != null) + // { + // var builder = new CodeQualifiedIdentifierBuilder(memberId); + // builder.LocalVariable = symbol.Name; + // builder.LocalVariableIndex = await GetLocalVariableIndexAsync(symbol, solution, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); + + // return builder.ToQualifiedIdentifier(); + // } + + // return null; + //} /// /// Get the position of where a given local variable is defined considering there could be multiple variables with the same name in method body. From 8df2d5ab688658aa8e61347ad21a34619923082b Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:17:04 +0200 Subject: [PATCH 006/353] Remove more unused code --- .../Def/Progression/GraphNodeIdCreation.cs | 272 +++++++++--------- 1 file changed, 136 insertions(+), 136 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs b/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs index 23b25d8c91b93..a7379c4678b72 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs @@ -33,35 +33,35 @@ public static GraphNodeId GetIdForDocument(Document document) GraphNodeId.GetPartial(CodeGraphNodeIdName.File, new Uri(document.FilePath, UriKind.RelativeOrAbsolute))); } - internal static async Task GetIdForNamespaceAsync(INamespaceSymbol symbol, Solution solution, CancellationToken cancellationToken) - { - var builder = new CodeQualifiedIdentifierBuilder(); + //internal static async Task GetIdForNamespaceAsync(INamespaceSymbol symbol, Solution solution, CancellationToken cancellationToken) + //{ + // var builder = new CodeQualifiedIdentifierBuilder(); - var assembly = await GetAssemblyFullPathAsync(symbol, solution, cancellationToken).ConfigureAwait(false); - if (assembly != null) - { - builder.Assembly = assembly; - } + // var assembly = await GetAssemblyFullPathAsync(symbol, solution, cancellationToken).ConfigureAwait(false); + // if (assembly != null) + // { + // builder.Assembly = assembly; + // } - builder.Namespace = symbol.ToDisplayString(); + // builder.Namespace = symbol.ToDisplayString(); - return builder.ToQualifiedIdentifier(); - } + // return builder.ToQualifiedIdentifier(); + //} - internal static async Task GetIdForTypeAsync(ITypeSymbol symbol, Solution solution, CancellationToken cancellationToken) - { - var nodes = await GetPartialsForNamespaceAndTypeAsync(symbol, true, solution, cancellationToken).ConfigureAwait(false); - var partials = nodes.ToArray(); + //internal static async Task GetIdForTypeAsync(ITypeSymbol symbol, Solution solution, CancellationToken cancellationToken) + //{ + // var nodes = await GetPartialsForNamespaceAndTypeAsync(symbol, true, solution, cancellationToken).ConfigureAwait(false); + // var partials = nodes.ToArray(); - if (partials.Length == 1) - { - return partials[0]; - } - else - { - return GraphNodeId.GetNested(partials); - } - } + // if (partials.Length == 1) + // { + // return partials[0]; + // } + // else + // { + // return GraphNodeId.GetNested(partials); + // } + //} private static async Task> GetPartialsForNamespaceAndTypeAsync(ITypeSymbol symbol, bool includeNamespace, Solution solution, CancellationToken cancellationToken, bool isInGenericArguments = false) { @@ -285,76 +285,76 @@ private static ITypeSymbol ChaseToUnderlyingType(ITypeSymbol symbol) return symbol; } - public static async Task GetIdForMemberAsync(ISymbol member, Solution solution, CancellationToken cancellationToken) - { - var partials = new List(); - - partials.AddRange(await GetPartialsForNamespaceAndTypeAsync(member.ContainingType, true, solution, cancellationToken).ConfigureAwait(false)); - - var parameters = member.GetParameters(); - if (parameters.Any() || member.GetArity() > 0) - { - var memberPartials = new List - { - GraphNodeId.GetPartial(CodeQualifiedName.Name, member.MetadataName) - }; - - if (member.GetArity() > 0) - { - memberPartials.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.GenericParameterCountIdentifier, member.GetArity().ToString())); - } + //public static async Task GetIdForMemberAsync(ISymbol member, Solution solution, CancellationToken cancellationToken) + //{ + // var partials = new List(); - if (parameters.Any()) - { - var parameterTypeIds = new List(); - foreach (var p in parameters) - { - var parameterIds = await GetPartialsForNamespaceAndTypeAsync(p.Type, true, solution, cancellationToken).ConfigureAwait(false); - var nodes = parameterIds.ToList(); - if (p.IsRefOrOut()) - { - nodes.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.ParamKind, ParamKind.Ref)); - } + // partials.AddRange(await GetPartialsForNamespaceAndTypeAsync(member.ContainingType, true, solution, cancellationToken).ConfigureAwait(false)); - parameterTypeIds.Add(GraphNodeId.GetNested([.. nodes])); - } + // var parameters = member.GetParameters(); + // if (parameters.Any() || member.GetArity() > 0) + // { + // var memberPartials = new List + // { + // GraphNodeId.GetPartial(CodeQualifiedName.Name, member.MetadataName) + // }; - if (member is IMethodSymbol methodSymbol && methodSymbol.MethodKind == MethodKind.Conversion) - { - // For explicit/implicit conversion operators, we need to include the return type in the method Id, - // because there can be several conversion operators with same parameters and only differ by return type. - // For example, - // - // public class Class1 - // { - // public static explicit (explicit) operator int(Class1 c) { ... } - // public static explicit (explicit) operator double(Class1 c) { ... } - // } - - var nodes = await GetPartialsForNamespaceAndTypeAsync(methodSymbol.ReturnType, true, solution, cancellationToken).ConfigureAwait(false); - var returnTypePartial = nodes.ToList(); - returnTypePartial.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.ParamKind, Microsoft.VisualStudio.GraphModel.CodeSchema.ParamKind.Return)); - - var returnCollection = GraphNodeId.GetNested([.. returnTypePartial]); - parameterTypeIds.Add(returnCollection); - } + // if (member.GetArity() > 0) + // { + // memberPartials.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.GenericParameterCountIdentifier, member.GetArity().ToString())); + // } - memberPartials.Add(GraphNodeId.GetArray( - CodeGraphNodeIdName.OverloadingParameters, - [.. parameterTypeIds])); - } + // if (parameters.Any()) + // { + // var parameterTypeIds = new List(); + // foreach (var p in parameters) + // { + // var parameterIds = await GetPartialsForNamespaceAndTypeAsync(p.Type, true, solution, cancellationToken).ConfigureAwait(false); + // var nodes = parameterIds.ToList(); + // if (p.IsRefOrOut()) + // { + // nodes.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.ParamKind, ParamKind.Ref)); + // } + + // parameterTypeIds.Add(GraphNodeId.GetNested([.. nodes])); + // } + + // if (member is IMethodSymbol methodSymbol && methodSymbol.MethodKind == MethodKind.Conversion) + // { + // // For explicit/implicit conversion operators, we need to include the return type in the method Id, + // // because there can be several conversion operators with same parameters and only differ by return type. + // // For example, + // // + // // public class Class1 + // // { + // // public static explicit (explicit) operator int(Class1 c) { ... } + // // public static explicit (explicit) operator double(Class1 c) { ... } + // // } + + // var nodes = await GetPartialsForNamespaceAndTypeAsync(methodSymbol.ReturnType, true, solution, cancellationToken).ConfigureAwait(false); + // var returnTypePartial = nodes.ToList(); + // returnTypePartial.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.ParamKind, Microsoft.VisualStudio.GraphModel.CodeSchema.ParamKind.Return)); + + // var returnCollection = GraphNodeId.GetNested([.. returnTypePartial]); + // parameterTypeIds.Add(returnCollection); + // } + + // memberPartials.Add(GraphNodeId.GetArray( + // CodeGraphNodeIdName.OverloadingParameters, + // [.. parameterTypeIds])); + // } - partials.Add(GraphNodeId.GetPartial( - CodeGraphNodeIdName.Member, - MakeCollectionIfNecessary([.. memberPartials]))); - } - else - { - partials.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Member, member.MetadataName)); - } + // partials.Add(GraphNodeId.GetPartial( + // CodeGraphNodeIdName.Member, + // MakeCollectionIfNecessary([.. memberPartials]))); + // } + // else + // { + // partials.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Member, member.MetadataName)); + // } - return GraphNodeId.GetNested([.. partials]); - } + // return GraphNodeId.GetNested([.. partials]); + //} private static object MakeCollectionIfNecessary(GraphNodeId[] array) { @@ -506,56 +506,56 @@ private static async Task GetAssemblyFullPathAsync(IAssemblySymbol containi // return null; //} - /// - /// Get the position of where a given local variable is defined considering there could be multiple variables with the same name in method body. - /// For example, in "int M() { { int goo = 0; ...} { int goo = 1; ...} }", - /// the return value for the first "goo" would be 0 while the value for the second one would be 1. - /// It will be used to create a node with LocalVariableIndex for a non-zero value. - /// In the above example, hence, a node id for the first "goo" would look like (... Member=M LocalVariable=bar) - /// but an id for the second "goo" would be (... Member=M LocalVariable=bar LocalVariableIndex=1) - /// - private static async Task GetLocalVariableIndexAsync(ISymbol symbol, Solution solution, CancellationToken cancellationToken) - { - var pos = 0; - - foreach (var reference in symbol.ContainingSymbol.DeclaringSyntaxReferences) - { - var currentNode = await reference.GetSyntaxAsync(cancellationToken).ConfigureAwait(false); + ///// + ///// Get the position of where a given local variable is defined considering there could be multiple variables with the same name in method body. + ///// For example, in "int M() { { int goo = 0; ...} { int goo = 1; ...} }", + ///// the return value for the first "goo" would be 0 while the value for the second one would be 1. + ///// It will be used to create a node with LocalVariableIndex for a non-zero value. + ///// In the above example, hence, a node id for the first "goo" would look like (... Member=M LocalVariable=bar) + ///// but an id for the second "goo" would be (... Member=M LocalVariable=bar LocalVariableIndex=1) + ///// + //private static async Task GetLocalVariableIndexAsync(ISymbol symbol, Solution solution, CancellationToken cancellationToken) + //{ + // var pos = 0; - // For VB, we have to ask its parent to get local variables within this method body - // since DeclaringSyntaxReferences return statement rather than enclosing block. - if (currentNode != null && symbol.Language == LanguageNames.VisualBasic) - { - currentNode = currentNode.Parent; - } + // foreach (var reference in symbol.ContainingSymbol.DeclaringSyntaxReferences) + // { + // var currentNode = await reference.GetSyntaxAsync(cancellationToken).ConfigureAwait(false); - if (currentNode != null) - { - var document = solution.GetDocument(currentNode.SyntaxTree); - if (document == null) - { - continue; - } + // // For VB, we have to ask its parent to get local variables within this method body + // // since DeclaringSyntaxReferences return statement rather than enclosing block. + // if (currentNode != null && symbol.Language == LanguageNames.VisualBasic) + // { + // currentNode = currentNode.Parent; + // } - var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); - foreach (var node in currentNode.DescendantNodes()) - { - var current = semanticModel.GetDeclaredSymbol(node, cancellationToken); - if (current is { Kind: SymbolKind.Local or SymbolKind.RangeVariable } && current.Name == symbol.Name) - { - if (!current.Equals(symbol)) - { - pos++; - } - else - { - return pos; - } - } - } - } - } + // if (currentNode != null) + // { + // var document = solution.GetDocument(currentNode.SyntaxTree); + // if (document == null) + // { + // continue; + // } + + // var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + // foreach (var node in currentNode.DescendantNodes()) + // { + // var current = semanticModel.GetDeclaredSymbol(node, cancellationToken); + // if (current is { Kind: SymbolKind.Local or SymbolKind.RangeVariable } && current.Name == symbol.Name) + // { + // if (!current.Equals(symbol)) + // { + // pos++; + // } + // else + // { + // return pos; + // } + // } + // } + // } + // } - throw ExceptionUtilities.Unreachable(); - } + // throw ExceptionUtilities.Unreachable(); + //} } From 8a638322bdd4e364020f90522e870f629495f4b2 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:17:51 +0200 Subject: [PATCH 007/353] Remove more unused code --- .../Def/Progression/GraphNodeIdCreation.cs | 580 +++++++++--------- 1 file changed, 290 insertions(+), 290 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs b/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs index a7379c4678b72..04c77ad78c2cf 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs @@ -63,227 +63,227 @@ public static GraphNodeId GetIdForDocument(Document document) // } //} - private static async Task> GetPartialsForNamespaceAndTypeAsync(ITypeSymbol symbol, bool includeNamespace, Solution solution, CancellationToken cancellationToken, bool isInGenericArguments = false) - { - var items = new List(); - - Uri assembly = null; - if (includeNamespace) - { - assembly = await GetAssemblyFullPathAsync(symbol, solution, cancellationToken).ConfigureAwait(false); - } - - var underlyingType = ChaseToUnderlyingType(symbol); - - if (symbol.TypeKind == TypeKind.TypeParameter) - { - var typeParameter = (ITypeParameterSymbol)symbol; - - if (typeParameter.TypeParameterKind == TypeParameterKind.Type) - { - if (includeNamespace && !typeParameter.ContainingNamespace.IsGlobalNamespace) - { - if (assembly != null) - { - items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Assembly, assembly)); - } - - items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Namespace, typeParameter.ContainingNamespace.ToDisplayString())); - } - - items.Add(await GetPartialForTypeAsync(symbol.ContainingType, CodeGraphNodeIdName.Type, solution, cancellationToken).ConfigureAwait(false)); - } - - items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Parameter, ((ITypeParameterSymbol)symbol).Ordinal.ToString())); - } - else - { - if (assembly != null) - { - items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Assembly, assembly)); - } - - if (underlyingType.TypeKind == TypeKind.Dynamic) - { - items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Namespace, "System")); - } - else if (underlyingType.ContainingNamespace != null && !underlyingType.ContainingNamespace.IsGlobalNamespace) - { - items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Namespace, underlyingType.ContainingNamespace.ToDisplayString())); - } - - items.Add(await GetPartialForTypeAsync(symbol, CodeGraphNodeIdName.Type, solution, cancellationToken, isInGenericArguments).ConfigureAwait(false)); - } - - return items; - } + //private static async Task> GetPartialsForNamespaceAndTypeAsync(ITypeSymbol symbol, bool includeNamespace, Solution solution, CancellationToken cancellationToken, bool isInGenericArguments = false) + //{ + // var items = new List(); - private static async Task GetPartialForTypeAsync(ITypeSymbol symbol, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken, bool isInGenericArguments = false) - { - if (symbol is IArrayTypeSymbol arrayType) - { - return await GetPartialForArrayTypeAsync(arrayType, nodeName, solution, cancellationToken).ConfigureAwait(false); - } - else if (symbol is INamedTypeSymbol namedType) - { - return await GetPartialForNamedTypeAsync(namedType, nodeName, solution, cancellationToken, isInGenericArguments).ConfigureAwait(false); - } - else if (symbol is IPointerTypeSymbol pointerType) - { - return await GetPartialForPointerTypeAsync(pointerType, nodeName, solution, cancellationToken).ConfigureAwait(false); - } - else if (symbol is ITypeParameterSymbol typeParameter) - { - return await GetPartialForTypeParameterSymbolAsync(typeParameter, nodeName, solution, cancellationToken).ConfigureAwait(false); - } - else if (symbol is IDynamicTypeSymbol) - { - return GetPartialForDynamicType(nodeName); - } - - throw ExceptionUtilities.Unreachable(); - } + // Uri assembly = null; + // if (includeNamespace) + // { + // assembly = await GetAssemblyFullPathAsync(symbol, solution, cancellationToken).ConfigureAwait(false); + // } - private static GraphNodeId GetPartialForDynamicType(GraphNodeIdName nodeName) - { - // We always consider this to be the "Object" type since Progression takes a very metadata-ish view of the type - return GraphNodeId.GetPartial(nodeName, "Object"); - } + // var underlyingType = ChaseToUnderlyingType(symbol); - private static async Task GetPartialForNamedTypeAsync(INamedTypeSymbol namedType, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken, bool isInGenericArguments = false) - { - // If this is a simple type, then we don't have much to do - if (namedType.ContainingType == null && Equals(namedType.ConstructedFrom, namedType) && namedType.Arity == 0) - { - return GraphNodeId.GetPartial(nodeName, namedType.Name); - } - else - { - // For a generic type, we need to populate "type" property with the following form: - // - // Type = (Name =...GenericParameterCount = GenericArguments =...ParentType =...) - // - // where "Name" contains a symbol name - // and "GenericParameterCount" contains the number of type parameters, - // and "GenericArguments" contains its type parameters' node information. - // and "ParentType" contains its containing type's node information. - - var partials = new List - { - GraphNodeId.GetPartial(CodeQualifiedName.Name, namedType.Name) - }; - - if (namedType.Arity > 0) - { - partials.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.GenericParameterCountIdentifier, namedType.Arity.ToString())); - } - - // For the property "GenericArguments", we only populate them - // when type parameters are constructed using instance types (i.e., namedType.ConstructedFrom != namedType). - // However, there is a case where we need to populate "GenericArguments" even though arguments are not marked as "constructed" - // because a symbol is not marked as "constructed" when a type is constructed using its own type parameters. - // To distinguish this case, we use "isInGenericArguments" flag which we pass either to populate arguments recursively or to populate "ParentType". - - var hasGenericArguments = (!Equals(namedType.ConstructedFrom, namedType) || isInGenericArguments) && namedType.TypeArguments != null && namedType.TypeArguments.Any(); - - if (hasGenericArguments) - { - var genericArguments = new List(); - foreach (var arg in namedType.TypeArguments) - { - var nodes = await GetPartialsForNamespaceAndTypeAsync(arg, includeNamespace: true, solution: solution, cancellationToken: cancellationToken, isInGenericArguments: true).ConfigureAwait(false); - genericArguments.Add(GraphNodeId.GetNested([.. nodes])); - } - - partials.Add(GraphNodeId.GetArray( - CodeGraphNodeIdName.GenericArgumentsIdentifier, - [.. genericArguments])); - } - - if (namedType.ContainingType != null) - { - partials.Add(await GetPartialForTypeAsync(namedType.ContainingType, CodeGraphNodeIdName.ParentType, solution, cancellationToken, hasGenericArguments).ConfigureAwait(false)); - } - - return GraphNodeId.GetPartial(nodeName, MakeCollectionIfNecessary([.. partials])); - } - } + // if (symbol.TypeKind == TypeKind.TypeParameter) + // { + // var typeParameter = (ITypeParameterSymbol)symbol; - private static async Task GetPartialForPointerTypeAsync(IPointerTypeSymbol pointerType, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken) - { - var indirection = 1; - - while (pointerType.PointedAtType.TypeKind == TypeKind.Pointer) - { - indirection++; - pointerType = (IPointerTypeSymbol)pointerType.PointedAtType; - } - - var partials = new List - { - GraphNodeId.GetPartial(CodeQualifiedName.Name, pointerType.PointedAtType.Name), - GraphNodeId.GetPartial(CodeQualifiedName.Indirection, indirection.ToString()) - }; - - if (pointerType.PointedAtType.ContainingType != null) - { - partials.Add(await GetPartialForTypeAsync(pointerType.PointedAtType.ContainingType, CodeGraphNodeIdName.ParentType, solution, cancellationToken).ConfigureAwait(false)); - } - - return GraphNodeId.GetPartial(nodeName, MakeCollectionIfNecessary([.. partials])); - } + // if (typeParameter.TypeParameterKind == TypeParameterKind.Type) + // { + // if (includeNamespace && !typeParameter.ContainingNamespace.IsGlobalNamespace) + // { + // if (assembly != null) + // { + // items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Assembly, assembly)); + // } - private static async Task GetPartialForArrayTypeAsync(IArrayTypeSymbol arrayType, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken) - { - var partials = new List(); + // items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Namespace, typeParameter.ContainingNamespace.ToDisplayString())); + // } - var underlyingType = ChaseToUnderlyingType(arrayType); + // items.Add(await GetPartialForTypeAsync(symbol.ContainingType, CodeGraphNodeIdName.Type, solution, cancellationToken).ConfigureAwait(false)); + // } - if (underlyingType.TypeKind == TypeKind.Dynamic) - { - partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.Name, "Object")); - } - else if (underlyingType.TypeKind != TypeKind.TypeParameter) - { - partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.Name, underlyingType.Name)); - } + // items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Parameter, ((ITypeParameterSymbol)symbol).Ordinal.ToString())); + // } + // else + // { + // if (assembly != null) + // { + // items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Assembly, assembly)); + // } - partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.ArrayRank, arrayType.Rank.ToString())); - partials.Add(await GetPartialForTypeAsync(arrayType.ElementType, CodeGraphNodeIdName.ParentType, solution, cancellationToken).ConfigureAwait(false)); + // if (underlyingType.TypeKind == TypeKind.Dynamic) + // { + // items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Namespace, "System")); + // } + // else if (underlyingType.ContainingNamespace != null && !underlyingType.ContainingNamespace.IsGlobalNamespace) + // { + // items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Namespace, underlyingType.ContainingNamespace.ToDisplayString())); + // } - return GraphNodeId.GetPartial(nodeName, MakeCollectionIfNecessary([.. partials])); - } + // items.Add(await GetPartialForTypeAsync(symbol, CodeGraphNodeIdName.Type, solution, cancellationToken, isInGenericArguments).ConfigureAwait(false)); + // } - private static async Task GetPartialForTypeParameterSymbolAsync(ITypeParameterSymbol typeParameterSymbol, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken) - { - if (typeParameterSymbol.TypeParameterKind == TypeParameterKind.Method) - { - return GraphNodeId.GetPartial(nodeName, - new GraphNodeIdCollection(false, - GraphNodeId.GetPartial(CodeGraphNodeIdName.Parameter, typeParameterSymbol.Ordinal.ToString()))); - } - else - { - var nodes = await GetPartialsForNamespaceAndTypeAsync(typeParameterSymbol, false, solution, cancellationToken).ConfigureAwait(false); - return GraphNodeId.GetPartial(nodeName, - new GraphNodeIdCollection(false, [.. nodes])); - } - } + // return items; + //} - private static ITypeSymbol ChaseToUnderlyingType(ITypeSymbol symbol) - { - while (symbol.TypeKind == TypeKind.Array) - { - symbol = ((IArrayTypeSymbol)symbol).ElementType; - } + //private static async Task GetPartialForTypeAsync(ITypeSymbol symbol, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken, bool isInGenericArguments = false) + //{ + // if (symbol is IArrayTypeSymbol arrayType) + // { + // return await GetPartialForArrayTypeAsync(arrayType, nodeName, solution, cancellationToken).ConfigureAwait(false); + // } + // else if (symbol is INamedTypeSymbol namedType) + // { + // return await GetPartialForNamedTypeAsync(namedType, nodeName, solution, cancellationToken, isInGenericArguments).ConfigureAwait(false); + // } + // else if (symbol is IPointerTypeSymbol pointerType) + // { + // return await GetPartialForPointerTypeAsync(pointerType, nodeName, solution, cancellationToken).ConfigureAwait(false); + // } + // else if (symbol is ITypeParameterSymbol typeParameter) + // { + // return await GetPartialForTypeParameterSymbolAsync(typeParameter, nodeName, solution, cancellationToken).ConfigureAwait(false); + // } + // else if (symbol is IDynamicTypeSymbol) + // { + // return GetPartialForDynamicType(nodeName); + // } - while (symbol.TypeKind == TypeKind.Pointer) - { - symbol = ((IPointerTypeSymbol)symbol).PointedAtType; - } + // throw ExceptionUtilities.Unreachable(); + //} - return symbol; - } + //private static GraphNodeId GetPartialForDynamicType(GraphNodeIdName nodeName) + //{ + // // We always consider this to be the "Object" type since Progression takes a very metadata-ish view of the type + // return GraphNodeId.GetPartial(nodeName, "Object"); + //} + + //private static async Task GetPartialForNamedTypeAsync(INamedTypeSymbol namedType, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken, bool isInGenericArguments = false) + //{ + // // If this is a simple type, then we don't have much to do + // if (namedType.ContainingType == null && Equals(namedType.ConstructedFrom, namedType) && namedType.Arity == 0) + // { + // return GraphNodeId.GetPartial(nodeName, namedType.Name); + // } + // else + // { + // // For a generic type, we need to populate "type" property with the following form: + // // + // // Type = (Name =...GenericParameterCount = GenericArguments =...ParentType =...) + // // + // // where "Name" contains a symbol name + // // and "GenericParameterCount" contains the number of type parameters, + // // and "GenericArguments" contains its type parameters' node information. + // // and "ParentType" contains its containing type's node information. + + // var partials = new List + // { + // GraphNodeId.GetPartial(CodeQualifiedName.Name, namedType.Name) + // }; + + // if (namedType.Arity > 0) + // { + // partials.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.GenericParameterCountIdentifier, namedType.Arity.ToString())); + // } + + // // For the property "GenericArguments", we only populate them + // // when type parameters are constructed using instance types (i.e., namedType.ConstructedFrom != namedType). + // // However, there is a case where we need to populate "GenericArguments" even though arguments are not marked as "constructed" + // // because a symbol is not marked as "constructed" when a type is constructed using its own type parameters. + // // To distinguish this case, we use "isInGenericArguments" flag which we pass either to populate arguments recursively or to populate "ParentType". + + // var hasGenericArguments = (!Equals(namedType.ConstructedFrom, namedType) || isInGenericArguments) && namedType.TypeArguments != null && namedType.TypeArguments.Any(); + + // if (hasGenericArguments) + // { + // var genericArguments = new List(); + // foreach (var arg in namedType.TypeArguments) + // { + // var nodes = await GetPartialsForNamespaceAndTypeAsync(arg, includeNamespace: true, solution: solution, cancellationToken: cancellationToken, isInGenericArguments: true).ConfigureAwait(false); + // genericArguments.Add(GraphNodeId.GetNested([.. nodes])); + // } + + // partials.Add(GraphNodeId.GetArray( + // CodeGraphNodeIdName.GenericArgumentsIdentifier, + // [.. genericArguments])); + // } + + // if (namedType.ContainingType != null) + // { + // partials.Add(await GetPartialForTypeAsync(namedType.ContainingType, CodeGraphNodeIdName.ParentType, solution, cancellationToken, hasGenericArguments).ConfigureAwait(false)); + // } + + // return GraphNodeId.GetPartial(nodeName, MakeCollectionIfNecessary([.. partials])); + // } + //} + + //private static async Task GetPartialForPointerTypeAsync(IPointerTypeSymbol pointerType, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken) + //{ + // var indirection = 1; + + // while (pointerType.PointedAtType.TypeKind == TypeKind.Pointer) + // { + // indirection++; + // pointerType = (IPointerTypeSymbol)pointerType.PointedAtType; + // } + + // var partials = new List + // { + // GraphNodeId.GetPartial(CodeQualifiedName.Name, pointerType.PointedAtType.Name), + // GraphNodeId.GetPartial(CodeQualifiedName.Indirection, indirection.ToString()) + // }; + + // if (pointerType.PointedAtType.ContainingType != null) + // { + // partials.Add(await GetPartialForTypeAsync(pointerType.PointedAtType.ContainingType, CodeGraphNodeIdName.ParentType, solution, cancellationToken).ConfigureAwait(false)); + // } + + // return GraphNodeId.GetPartial(nodeName, MakeCollectionIfNecessary([.. partials])); + //} + + //private static async Task GetPartialForArrayTypeAsync(IArrayTypeSymbol arrayType, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken) + //{ + // var partials = new List(); + + // var underlyingType = ChaseToUnderlyingType(arrayType); + + // if (underlyingType.TypeKind == TypeKind.Dynamic) + // { + // partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.Name, "Object")); + // } + // else if (underlyingType.TypeKind != TypeKind.TypeParameter) + // { + // partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.Name, underlyingType.Name)); + // } + + // partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.ArrayRank, arrayType.Rank.ToString())); + // partials.Add(await GetPartialForTypeAsync(arrayType.ElementType, CodeGraphNodeIdName.ParentType, solution, cancellationToken).ConfigureAwait(false)); + + // return GraphNodeId.GetPartial(nodeName, MakeCollectionIfNecessary([.. partials])); + //} + + //private static async Task GetPartialForTypeParameterSymbolAsync(ITypeParameterSymbol typeParameterSymbol, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken) + //{ + // if (typeParameterSymbol.TypeParameterKind == TypeParameterKind.Method) + // { + // return GraphNodeId.GetPartial(nodeName, + // new GraphNodeIdCollection(false, + // GraphNodeId.GetPartial(CodeGraphNodeIdName.Parameter, typeParameterSymbol.Ordinal.ToString()))); + // } + // else + // { + // var nodes = await GetPartialsForNamespaceAndTypeAsync(typeParameterSymbol, false, solution, cancellationToken).ConfigureAwait(false); + // return GraphNodeId.GetPartial(nodeName, + // new GraphNodeIdCollection(false, [.. nodes])); + // } + //} + + //private static ITypeSymbol ChaseToUnderlyingType(ITypeSymbol symbol) + //{ + // while (symbol.TypeKind == TypeKind.Array) + // { + // symbol = ((IArrayTypeSymbol)symbol).ElementType; + // } + + // while (symbol.TypeKind == TypeKind.Pointer) + // { + // symbol = ((IPointerTypeSymbol)symbol).PointedAtType; + // } + + // return symbol; + //} //public static async Task GetIdForMemberAsync(ISymbol member, Solution solution, CancellationToken cancellationToken) //{ @@ -356,92 +356,92 @@ private static ITypeSymbol ChaseToUnderlyingType(ITypeSymbol symbol) // return GraphNodeId.GetNested([.. partials]); //} - private static object MakeCollectionIfNecessary(GraphNodeId[] array) - { - // Place the array of GraphNodeId's into the collection if necessary, so to make them appear in VS Properties Panel - if (array.Length > 1) - { - return new GraphNodeIdCollection(false, array); - } + //private static object MakeCollectionIfNecessary(GraphNodeId[] array) + //{ + // // Place the array of GraphNodeId's into the collection if necessary, so to make them appear in VS Properties Panel + // if (array.Length > 1) + // { + // return new GraphNodeIdCollection(false, array); + // } - return GraphNodeId.GetNested(array); - } + // return GraphNodeId.GetNested(array); + //} - private static IAssemblySymbol GetContainingAssembly(ISymbol symbol) - { - if (symbol.ContainingAssembly != null) - { - return symbol.ContainingAssembly; - } - - if (symbol is not ITypeSymbol typeSymbol) - { - return null; - } - - var underlyingType = ChaseToUnderlyingType(typeSymbol); - if (Equals(typeSymbol, underlyingType)) - { - // when symbol is for dynamic type - return null; - } - - return GetContainingAssembly(underlyingType); - } + //private static IAssemblySymbol GetContainingAssembly(ISymbol symbol) + //{ + // if (symbol.ContainingAssembly != null) + // { + // return symbol.ContainingAssembly; + // } - private static async Task GetAssemblyFullPathAsync(ISymbol symbol, Solution solution, CancellationToken cancellationToken) - { - var containingAssembly = GetContainingAssembly(symbol); - return await GetAssemblyFullPathAsync(containingAssembly, solution, cancellationToken).ConfigureAwait(false); - } + // if (symbol is not ITypeSymbol typeSymbol) + // { + // return null; + // } - private static async Task GetAssemblyFullPathAsync(IAssemblySymbol containingAssembly, Solution solution, CancellationToken cancellationToken) - { - if (containingAssembly == null) - { - return null; - } - - var foundProject = solution.GetProject(containingAssembly, cancellationToken); - if (foundProject != null) - { - if (solution.Workspace is VisualStudioWorkspace) - { - // TODO: audit the OutputFilePath and whether this is bin or obj - if (!string.IsNullOrWhiteSpace(foundProject.OutputFilePath)) - { - return new Uri(foundProject.OutputFilePath, UriKind.RelativeOrAbsolute); - } - - return null; - } - } - else - { - // This symbol is not present in the source code, we need to resolve it from the references! - // If a MetadataReference returned by Compilation.GetMetadataReference(AssemblySymbol) has a path, we could use it. - foreach (var project in solution.Projects) - { - var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); - if (compilation != null) - { - if (compilation.GetMetadataReference(containingAssembly) is PortableExecutableReference reference && !string.IsNullOrEmpty(reference.FilePath)) - { - return new Uri(reference.FilePath, UriKind.RelativeOrAbsolute); - } - } - } - } - - // If we are not in VS, return project.OutputFilePath as a reasonable fallback. - // For an example, it could be AdhocWorkspace for unit tests. - if (foundProject != null && !string.IsNullOrEmpty(foundProject.OutputFilePath)) - { - return new Uri(foundProject.OutputFilePath, UriKind.Absolute); - } - - return null; - } + // var underlyingType = ChaseToUnderlyingType(typeSymbol); + // if (Equals(typeSymbol, underlyingType)) + // { + // // when symbol is for dynamic type + // return null; + // } + + // return GetContainingAssembly(underlyingType); + //} + + //private static async Task GetAssemblyFullPathAsync(ISymbol symbol, Solution solution, CancellationToken cancellationToken) + //{ + // var containingAssembly = GetContainingAssembly(symbol); + // return await GetAssemblyFullPathAsync(containingAssembly, solution, cancellationToken).ConfigureAwait(false); + //} + + //private static async Task GetAssemblyFullPathAsync(IAssemblySymbol containingAssembly, Solution solution, CancellationToken cancellationToken) + //{ + // if (containingAssembly == null) + // { + // return null; + // } + + // var foundProject = solution.GetProject(containingAssembly, cancellationToken); + // if (foundProject != null) + // { + // if (solution.Workspace is VisualStudioWorkspace) + // { + // // TODO: audit the OutputFilePath and whether this is bin or obj + // if (!string.IsNullOrWhiteSpace(foundProject.OutputFilePath)) + // { + // return new Uri(foundProject.OutputFilePath, UriKind.RelativeOrAbsolute); + // } + + // return null; + // } + // } + // else + // { + // // This symbol is not present in the source code, we need to resolve it from the references! + // // If a MetadataReference returned by Compilation.GetMetadataReference(AssemblySymbol) has a path, we could use it. + // foreach (var project in solution.Projects) + // { + // var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + // if (compilation != null) + // { + // if (compilation.GetMetadataReference(containingAssembly) is PortableExecutableReference reference && !string.IsNullOrEmpty(reference.FilePath)) + // { + // return new Uri(reference.FilePath, UriKind.RelativeOrAbsolute); + // } + // } + // } + // } + + // // If we are not in VS, return project.OutputFilePath as a reasonable fallback. + // // For an example, it could be AdhocWorkspace for unit tests. + // if (foundProject != null && !string.IsNullOrEmpty(foundProject.OutputFilePath)) + // { + // return new Uri(foundProject.OutputFilePath, UriKind.Absolute); + // } + + // return null; + //} //internal static async Task GetIdForAssemblyAsync(IAssemblySymbol assemblySymbol, Solution solution, CancellationToken cancellationToken) //{ From eb2746caba95c800c0cf14e47e609985c7bc995e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:20:22 +0200 Subject: [PATCH 008/353] Remove more unused code --- .../Core/Def/Progression/GraphProvider.cs | 254 +++++++++--------- 1 file changed, 128 insertions(+), 126 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs index 484eb0ea3a098..7d5b156288a17 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs @@ -175,144 +175,146 @@ public void BeginGetGraphData(IGraphContext context) public IEnumerable GetCommands(IEnumerable nodes) { - EnsureInitialized(); + yield break; - // Only nodes that explicitly state that they contain children (e.g., source files) and named types should - // be expandable. - if (nodes.Any(n => n.Properties.Any(p => p.Key == DgmlNodeProperties.ContainsChildren)) || - nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType))) - { - yield return new GraphCommand( - GraphCommandDefinition.Contains, - targetCategories: null, - linkCategories: [GraphCommonSchema.Contains], - trackChanges: true); - } + //EnsureInitialized(); - // All graph commands below this point apply only to Roslyn-owned nodes. - if (!nodes.All(n => IsRoslynNode(n))) - { - yield break; - } + //// Only nodes that explicitly state that they contain children (e.g., source files) and named types should + //// be expandable. + //if (nodes.Any(n => n.Properties.Any(p => p.Key == DgmlNodeProperties.ContainsChildren)) || + // nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType))) + //{ + // yield return new GraphCommand( + // GraphCommandDefinition.Contains, + // targetCategories: null, + // linkCategories: [GraphCommonSchema.Contains], + // trackChanges: true); + //} - // Only show 'Base Types' and 'Derived Types' on a class or interface. - if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && - IsAnyTypeKind(n, TypeKind.Class, TypeKind.Interface, TypeKind.Struct, TypeKind.Enum, TypeKind.Delegate))) - { - yield return new GraphCommand( - GraphCommandDefinition.BaseTypes, - targetCategories: null, - linkCategories: [CodeLinkCategories.InheritsFrom], - trackChanges: true); - - yield return new GraphCommand( - GraphCommandDefinition.DerivedTypes, - targetCategories: null, - linkCategories: [CodeLinkCategories.InheritsFrom], - trackChanges: true); - } + //// All graph commands below this point apply only to Roslyn-owned nodes. + //if (!nodes.All(n => IsRoslynNode(n))) + //{ + // yield break; + //} - // Only show 'Calls' on an applicable member in a class or struct - if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property, SymbolKind.Field))) - { - yield return new GraphCommand( - GraphCommandDefinition.Calls, - targetCategories: null, - linkCategories: [CodeLinkCategories.Calls], - trackChanges: true); - } + //// Only show 'Base Types' and 'Derived Types' on a class or interface. + //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && + // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Interface, TypeKind.Struct, TypeKind.Enum, TypeKind.Delegate))) + //{ + // yield return new GraphCommand( + // GraphCommandDefinition.BaseTypes, + // targetCategories: null, + // linkCategories: [CodeLinkCategories.InheritsFrom], + // trackChanges: true); + + // yield return new GraphCommand( + // GraphCommandDefinition.DerivedTypes, + // targetCategories: null, + // linkCategories: [CodeLinkCategories.InheritsFrom], + // trackChanges: true); + //} - // Only show 'Is Called By' on an applicable member in a class or struct - if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && - IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct))) - { - yield return new GraphCommand( - GraphCommandDefinition.IsCalledBy, - targetCategories: null, - linkCategories: [CodeLinkCategories.Calls], - trackChanges: true); - } + //// Only show 'Calls' on an applicable member in a class or struct + //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property, SymbolKind.Field))) + //{ + // yield return new GraphCommand( + // GraphCommandDefinition.Calls, + // targetCategories: null, + // linkCategories: [CodeLinkCategories.Calls], + // trackChanges: true); + //} - // Show 'Is Used By' - yield return new GraphCommand( - GraphCommandDefinition.IsUsedBy, - targetCategories: [CodeNodeCategories.SourceLocation], - linkCategories: [CodeLinkCategories.SourceReferences], - trackChanges: true); + //// Only show 'Is Called By' on an applicable member in a class or struct + //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && + // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct))) + //{ + // yield return new GraphCommand( + // GraphCommandDefinition.IsCalledBy, + // targetCategories: null, + // linkCategories: [CodeLinkCategories.Calls], + // trackChanges: true); + //} - // Show 'Implements' on a class or struct, or an applicable member in a class or struct. - if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && - IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct))) - { - yield return new GraphCommand( - s_implementsCommandDefinition, - targetCategories: null, - linkCategories: [CodeLinkCategories.Implements], - trackChanges: true); - } + //// Show 'Is Used By' + //yield return new GraphCommand( + // GraphCommandDefinition.IsUsedBy, + // targetCategories: [CodeNodeCategories.SourceLocation], + // linkCategories: [CodeLinkCategories.SourceReferences], + // trackChanges: true); - // Show 'Implements' on public, non-static members of a class or struct. Note: we should - // also show it on explicit interface impls in C#. - if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && - IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && - !GetModifiers(n).IsStatic)) - { - if (nodes.Any(n => CheckAccessibility(n, Accessibility.Public) || - HasExplicitInterfaces(n))) - { - yield return new GraphCommand( - s_implementsCommandDefinition, - targetCategories: null, - linkCategories: [CodeLinkCategories.Implements], - trackChanges: true); - } - } + //// Show 'Implements' on a class or struct, or an applicable member in a class or struct. + //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && + // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct))) + //{ + // yield return new GraphCommand( + // s_implementsCommandDefinition, + // targetCategories: null, + // linkCategories: [CodeLinkCategories.Implements], + // trackChanges: true); + //} - // Show 'Implemented By' on an interface. - if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && - IsAnyTypeKind(n, TypeKind.Interface))) - { - yield return new GraphCommand( - s_implementedByCommandDefinition, - targetCategories: null, - linkCategories: [CodeLinkCategories.Implements], - trackChanges: true); - } + //// Show 'Implements' on public, non-static members of a class or struct. Note: we should + //// also show it on explicit interface impls in C#. + //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && + // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && + // !GetModifiers(n).IsStatic)) + //{ + // if (nodes.Any(n => CheckAccessibility(n, Accessibility.Public) || + // HasExplicitInterfaces(n))) + // { + // yield return new GraphCommand( + // s_implementsCommandDefinition, + // targetCategories: null, + // linkCategories: [CodeLinkCategories.Implements], + // trackChanges: true); + // } + //} - // Show 'Implemented By' on any member of an interface. - if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && - IsAnyTypeKind(n, TypeKind.Interface))) - { - yield return new GraphCommand( - s_implementedByCommandDefinition, - targetCategories: null, - linkCategories: [CodeLinkCategories.Implements], - trackChanges: true); - } + //// Show 'Implemented By' on an interface. + //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && + // IsAnyTypeKind(n, TypeKind.Interface))) + //{ + // yield return new GraphCommand( + // s_implementedByCommandDefinition, + // targetCategories: null, + // linkCategories: [CodeLinkCategories.Implements], + // trackChanges: true); + //} - // Show 'Overrides' on any applicable member of a class or struct - if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && - IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && - GetModifiers(n).IsOverride)) - { - yield return new GraphCommand( - s_overridesCommandDefinition, - targetCategories: null, - linkCategories: [RoslynGraphCategories.Overrides], - trackChanges: true); - } + //// Show 'Implemented By' on any member of an interface. + //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && + // IsAnyTypeKind(n, TypeKind.Interface))) + //{ + // yield return new GraphCommand( + // s_implementedByCommandDefinition, + // targetCategories: null, + // linkCategories: [CodeLinkCategories.Implements], + // trackChanges: true); + //} - // Show 'Overridden By' on any applicable member of a class or struct - if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && - IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && - IsOverridable(n))) - { - yield return new GraphCommand( - s_overriddenByCommandDefinition, - targetCategories: null, - linkCategories: [RoslynGraphCategories.Overrides], - trackChanges: true); - } + //// Show 'Overrides' on any applicable member of a class or struct + //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && + // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && + // GetModifiers(n).IsOverride)) + //{ + // yield return new GraphCommand( + // s_overridesCommandDefinition, + // targetCategories: null, + // linkCategories: [RoslynGraphCategories.Overrides], + // trackChanges: true); + //} + + //// Show 'Overridden By' on any applicable member of a class or struct + //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && + // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && + // IsOverridable(n))) + //{ + // yield return new GraphCommand( + // s_overriddenByCommandDefinition, + // targetCategories: null, + // linkCategories: [RoslynGraphCategories.Overrides], + // trackChanges: true); + //} } private static bool IsOverridable(GraphNode node) From 1a85c082e4a1ab1d7bd12dd59cf8611b46f2718c Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:20:46 +0200 Subject: [PATCH 009/353] Remove more unused code --- .../Core/Def/Progression/GraphProvider.cs | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs index 7d5b156288a17..d212f13c86a07 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs @@ -317,45 +317,45 @@ public IEnumerable GetCommands(IEnumerable nodes) //} } - private static bool IsOverridable(GraphNode node) - { - var modifiers = GetModifiers(node); - return (modifiers.IsVirtual || modifiers.IsAbstract || modifiers.IsOverride) && - !modifiers.IsSealed; - } + //private static bool IsOverridable(GraphNode node) + //{ + // var modifiers = GetModifiers(node); + // return (modifiers.IsVirtual || modifiers.IsAbstract || modifiers.IsOverride) && + // !modifiers.IsSealed; + //} - private static DeclarationModifiers GetModifiers(GraphNode node) - => (DeclarationModifiers)node[RoslynGraphProperties.SymbolModifiers]; + //private static DeclarationModifiers GetModifiers(GraphNode node) + // => (DeclarationModifiers)node[RoslynGraphProperties.SymbolModifiers]; - private static bool CheckAccessibility(GraphNode node, Accessibility accessibility) - => node[RoslynGraphProperties.DeclaredAccessibility].Equals(accessibility); + //private static bool CheckAccessibility(GraphNode node, Accessibility accessibility) + // => node[RoslynGraphProperties.DeclaredAccessibility].Equals(accessibility); - private static bool HasExplicitInterfaces(GraphNode node) - => ((IList)node[RoslynGraphProperties.ExplicitInterfaceImplementations]).Count > 0; + //private static bool HasExplicitInterfaces(GraphNode node) + // => ((IList)node[RoslynGraphProperties.ExplicitInterfaceImplementations]).Count > 0; - private static bool IsRoslynNode(GraphNode node) - { - return node[RoslynGraphProperties.SymbolKind] != null - && node[RoslynGraphProperties.TypeKind] != null; - } + //private static bool IsRoslynNode(GraphNode node) + //{ + // return node[RoslynGraphProperties.SymbolKind] != null + // && node[RoslynGraphProperties.TypeKind] != null; + //} - private static bool IsAnySymbolKind(GraphNode node, params SymbolKind[] symbolKinds) - => symbolKinds.Any(k => k.Equals(node[RoslynGraphProperties.SymbolKind])); + //private static bool IsAnySymbolKind(GraphNode node, params SymbolKind[] symbolKinds) + // => symbolKinds.Any(k => k.Equals(node[RoslynGraphProperties.SymbolKind])); - private static bool IsAnyTypeKind(GraphNode node, params TypeKind[] typeKinds) - => typeKinds.Any(k => node[RoslynGraphProperties.TypeKind].Equals(k)); + //private static bool IsAnyTypeKind(GraphNode node, params TypeKind[] typeKinds) + // => typeKinds.Any(k => node[RoslynGraphProperties.TypeKind].Equals(k)); - private static readonly GraphCommandDefinition s_overridesCommandDefinition = - new("Overrides", EditorFeaturesResources.Overrides_, GraphContextDirection.Target, 700); + //private static readonly GraphCommandDefinition s_overridesCommandDefinition = + // new("Overrides", EditorFeaturesResources.Overrides_, GraphContextDirection.Target, 700); - private static readonly GraphCommandDefinition s_overriddenByCommandDefinition = - new("OverriddenBy", EditorFeaturesResources.Overridden_By, GraphContextDirection.Source, 700); + //private static readonly GraphCommandDefinition s_overriddenByCommandDefinition = + // new("OverriddenBy", EditorFeaturesResources.Overridden_By, GraphContextDirection.Source, 700); - private static readonly GraphCommandDefinition s_implementsCommandDefinition = - new("Implements", EditorFeaturesResources.Implements_, GraphContextDirection.Target, 600); + //private static readonly GraphCommandDefinition s_implementsCommandDefinition = + // new("Implements", EditorFeaturesResources.Implements_, GraphContextDirection.Target, 600); - private static readonly GraphCommandDefinition s_implementedByCommandDefinition = - new("ImplementedBy", EditorFeaturesResources.Implemented_By, GraphContextDirection.Source, 600); + //private static readonly GraphCommandDefinition s_implementedByCommandDefinition = + // new("ImplementedBy", EditorFeaturesResources.Implemented_By, GraphContextDirection.Source, 600); public T? GetExtension(GraphObject graphObject, T previous) where T : class { From 14da4aa2cf9c10fa8a76f975b636c2b071cf0bdb Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:21:58 +0200 Subject: [PATCH 010/353] Remove more unused code --- .../Def/Progression/RoslynGraphProperties.cs | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs b/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs index 4cdf37c577932..9e07b1c19821d 100644 --- a/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs +++ b/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs @@ -57,46 +57,46 @@ internal static class RoslynGraphProperties /// public static readonly GraphProperty DescriptionWithContainingSymbol; - public static readonly GraphProperty SymbolKind; - public static readonly GraphProperty TypeKind; - public static readonly GraphProperty MethodKind; - public static readonly GraphProperty DeclaredAccessibility; - public static readonly GraphProperty SymbolModifiers; - public static readonly GraphProperty ExplicitInterfaceImplementations; + //public static readonly GraphProperty SymbolKind; + //public static readonly GraphProperty TypeKind; + //public static readonly GraphProperty MethodKind; + //public static readonly GraphProperty DeclaredAccessibility; + //public static readonly GraphProperty SymbolModifiers; + //public static readonly GraphProperty ExplicitInterfaceImplementations; static RoslynGraphProperties() { Schema = new GraphSchema("Roslyn"); - SymbolKind = Schema.Properties.AddNewProperty( - id: "SymbolKind", - dataType: typeof(SymbolKind), - callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - TypeKind = Schema.Properties.AddNewProperty( - id: "TypeKind", - dataType: typeof(TypeKind), - callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - MethodKind = Schema.Properties.AddNewProperty( - id: "MethodKind", - dataType: typeof(MethodKind), - callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - DeclaredAccessibility = Schema.Properties.AddNewProperty( - id: "DeclaredAccessibility", - dataType: typeof(Accessibility), - callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - SymbolModifiers = Schema.Properties.AddNewProperty( - id: "SymbolModifiers", - dataType: typeof(DeclarationModifiers), - callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - ExplicitInterfaceImplementations = Schema.Properties.AddNewProperty( - id: "ExplicitInterfaceImplementations", - dataType: typeof(IList), - callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); + //SymbolKind = Schema.Properties.AddNewProperty( + // id: "SymbolKind", + // dataType: typeof(SymbolKind), + // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); + + //TypeKind = Schema.Properties.AddNewProperty( + // id: "TypeKind", + // dataType: typeof(TypeKind), + // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); + + //MethodKind = Schema.Properties.AddNewProperty( + // id: "MethodKind", + // dataType: typeof(MethodKind), + // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); + + //DeclaredAccessibility = Schema.Properties.AddNewProperty( + // id: "DeclaredAccessibility", + // dataType: typeof(Accessibility), + // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); + + //SymbolModifiers = Schema.Properties.AddNewProperty( + // id: "SymbolModifiers", + // dataType: typeof(DeclarationModifiers), + // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); + + //ExplicitInterfaceImplementations = Schema.Properties.AddNewProperty( + // id: "ExplicitInterfaceImplementations", + // dataType: typeof(IList), + // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); SymbolId = Schema.Properties.AddNewProperty( id: "SymbolId", From 9e031efb04822672988d495ab98dd9346760f080 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:27:17 +0200 Subject: [PATCH 011/353] Remove more unused code --- .../GraphFormattedLabelExtension.cs | 95 +++++++++---------- .../Core/Def/Progression/GraphProvider.cs | 4 +- .../Def/Progression/RoslynGraphProperties.cs | 70 +++++++------- 3 files changed, 84 insertions(+), 85 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphFormattedLabelExtension.cs b/src/VisualStudio/Core/Def/Progression/GraphFormattedLabelExtension.cs index e1f517d8ca36c..030813a85ef32 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphFormattedLabelExtension.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphFormattedLabelExtension.cs @@ -1,48 +1,47 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#nullable disable - -using Microsoft.VisualStudio.GraphModel; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -internal sealed class GraphFormattedLabelExtension : IGraphFormattedLabel -{ - public string Description(GraphObject graphObject, string graphCommandDefinitionIdentifier) - { - return GetStringPropertyForGraphObject( - graphObject, - graphCommandDefinitionIdentifier, - RoslynGraphProperties.Description, - RoslynGraphProperties.DescriptionWithContainingSymbol); - } - - public string Label(GraphObject graphObject, string graphCommandDefinitionIdentifier) - { - return GetStringPropertyForGraphObject( - graphObject, - graphCommandDefinitionIdentifier, - RoslynGraphProperties.FormattedLabelWithoutContainingSymbol, - RoslynGraphProperties.FormattedLabelWithContainingSymbol); - } - - private static string GetStringPropertyForGraphObject(GraphObject graphObject, string graphCommandDefinitionIdentifier, GraphProperty propertyWithoutContainingSymbol, GraphProperty propertyWithContainingSymbol) - { - - if (graphObject is GraphNode graphNode) - { - if (graphCommandDefinitionIdentifier != GraphCommandDefinition.Contains.Id) - { - return graphNode.GetValue(propertyWithContainingSymbol); - } - else - { - return graphNode.GetValue(propertyWithoutContainingSymbol); - } - } - - return null; - } -} +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. + +//#nullable disable + +//using Microsoft.VisualStudio.GraphModel; + +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; + +//internal sealed class GraphFormattedLabelExtension : IGraphFormattedLabel +//{ +// public string Description(GraphObject graphObject, string graphCommandDefinitionIdentifier) +// { +// return GetStringPropertyForGraphObject( +// graphObject, +// graphCommandDefinitionIdentifier, +// RoslynGraphProperties.Description, +// RoslynGraphProperties.DescriptionWithContainingSymbol); +// } + +// public string Label(GraphObject graphObject, string graphCommandDefinitionIdentifier) +// { +// return GetStringPropertyForGraphObject( +// graphObject, +// graphCommandDefinitionIdentifier, +// RoslynGraphProperties.FormattedLabelWithoutContainingSymbol, +// RoslynGraphProperties.FormattedLabelWithContainingSymbol); +// } + +// private static string GetStringPropertyForGraphObject(GraphObject graphObject, string graphCommandDefinitionIdentifier, GraphProperty propertyWithoutContainingSymbol, GraphProperty propertyWithContainingSymbol) +// { +// if (graphObject is GraphNode graphNode) +// { +// if (graphCommandDefinitionIdentifier != GraphCommandDefinition.Contains.Id) +// { +// return graphNode.GetValue(propertyWithContainingSymbol); +// } +// else +// { +// return graphNode.GetValue(propertyWithoutContainingSymbol); +// } +// } + +// return null; +// } +//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs index d212f13c86a07..fc50d68bf13ec 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs @@ -375,8 +375,8 @@ public IEnumerable GetCommands(IEnumerable nodes) if (typeof(T) == typeof(IGraphNavigateToItem)) return new GraphNavigatorExtension(_threadingContext, _workspace, _streamingPresenter) as T; - if (typeof(T) == typeof(IGraphFormattedLabel)) - return new GraphFormattedLabelExtension() as T; + //if (typeof(T) == typeof(IGraphFormattedLabel)) + // return new GraphFormattedLabelExtension() as T; } return null; diff --git a/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs b/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs index 9e07b1c19821d..19bc5e54460e5 100644 --- a/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs +++ b/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs @@ -37,25 +37,25 @@ internal static class RoslynGraphProperties /// public static readonly GraphProperty Label; - /// - /// A graph property to hold the formatted label we have generated for the node. - /// - public static readonly GraphProperty FormattedLabelWithoutContainingSymbol; - - /// - /// A graph property to hold the formatted label that has the containing symbol name. - /// - public static readonly GraphProperty FormattedLabelWithContainingSymbol; - - /// - /// A graph property to hold the description we have generated for the node. - /// - public static readonly GraphProperty Description; - - /// - /// A graph property to hold the description that has the containing symbol name. - /// - public static readonly GraphProperty DescriptionWithContainingSymbol; + ///// + ///// A graph property to hold the formatted label we have generated for the node. + ///// + //public static readonly GraphProperty FormattedLabelWithoutContainingSymbol; + + ///// + ///// A graph property to hold the formatted label that has the containing symbol name. + ///// + //public static readonly GraphProperty FormattedLabelWithContainingSymbol; + + ///// + ///// A graph property to hold the description we have generated for the node. + ///// + //public static readonly GraphProperty Description; + + ///// + ///// A graph property to hold the description that has the containing symbol name. + ///// + //public static readonly GraphProperty DescriptionWithContainingSymbol; //public static readonly GraphProperty SymbolKind; //public static readonly GraphProperty TypeKind; @@ -118,24 +118,24 @@ static RoslynGraphProperties() dataType: typeof(string), callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - FormattedLabelWithoutContainingSymbol = Schema.Properties.AddNewProperty( - id: "FormattedLabelWithoutContainingSymbol", - dataType: typeof(string), - callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); + //FormattedLabelWithoutContainingSymbol = Schema.Properties.AddNewProperty( + // id: "FormattedLabelWithoutContainingSymbol", + // dataType: typeof(string), + // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - FormattedLabelWithContainingSymbol = Schema.Properties.AddNewProperty( - id: "FormattedLabelWithContainingSymbol", - dataType: typeof(string), - callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); + //FormattedLabelWithContainingSymbol = Schema.Properties.AddNewProperty( + // id: "FormattedLabelWithContainingSymbol", + // dataType: typeof(string), + // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - Description = Schema.Properties.AddNewProperty( - id: "Description", - dataType: typeof(string), - callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); + //Description = Schema.Properties.AddNewProperty( + // id: "Description", + // dataType: typeof(string), + // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - DescriptionWithContainingSymbol = Schema.Properties.AddNewProperty( - id: "DescriptionWithContainingSymbol", - dataType: typeof(string), - callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); + //DescriptionWithContainingSymbol = Schema.Properties.AddNewProperty( + // id: "DescriptionWithContainingSymbol", + // dataType: typeof(string), + // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); } } From a2dccba3aec79274b3bdf5d69ef3b3fcf3a81567 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:28:22 +0200 Subject: [PATCH 012/353] Remove more unused code --- .../GraphQueries/ProgressionNavigateToSearchCallback.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/ProgressionNavigateToSearchCallback.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/ProgressionNavigateToSearchCallback.cs index ec9b40e83ed8e..41fee3a23b167 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/ProgressionNavigateToSearchCallback.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphQueries/ProgressionNavigateToSearchCallback.cs @@ -33,7 +33,7 @@ public void Done(bool isFullyLoaded) } public void ReportProgress(int current, int maximum) - => _context.ReportProgress(current, maximum, null); + => _context.ReportProgress(current, maximum, message: null); public void ReportIncomplete() { From 3a320bbebbc697a3183b3efa8cf8daa7b31b0950 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:31:09 +0200 Subject: [PATCH 013/353] Remove more unused code --- .../Core/Def/Progression/GraphBuilder.cs | 16 +++++----- .../Progression/GraphNavigatorExtension.cs | 32 +++++++++---------- .../Core/Def/Progression/GraphProvider.cs | 2 +- .../Def/Progression/RoslynGraphProperties.cs | 16 +++++----- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs b/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs index b10a07378214b..dd6b0a04fc896 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs @@ -35,7 +35,7 @@ internal sealed partial class GraphBuilder private readonly Dictionary _nodeToContextProjectMap = []; private readonly Dictionary _nodeToContextDocumentMap = []; - private readonly Dictionary _nodeToSymbolMap = []; + // private readonly Dictionary _nodeToSymbolMap = []; /// /// The input solution. Never null. @@ -128,13 +128,13 @@ private async Task PopulateMapsForSymbolInputNodeAsync(GraphNode inputNode, Canc _nodeToContextProjectMap.Add(inputNode, project); - var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); - var symbolId = (SymbolKey?)inputNode[RoslynGraphProperties.SymbolId]; - var symbol = symbolId.Value.Resolve(compilation, cancellationToken: cancellationToken).Symbol; - if (symbol != null) - { - _nodeToSymbolMap.Add(inputNode, symbol); - } + //var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); + //var symbolId = (SymbolKey?)inputNode[RoslynGraphProperties.SymbolId]; + //var symbol = symbolId.Value.Resolve(compilation, cancellationToken: cancellationToken).Symbol; + //if (symbol != null) + //{ + // _nodeToSymbolMap.Add(inputNode, symbol); + //} var documentId = (DocumentId)inputNode[RoslynGraphProperties.ContextDocumentId]; if (documentId != null) diff --git a/src/VisualStudio/Core/Def/Progression/GraphNavigatorExtension.cs b/src/VisualStudio/Core/Def/Progression/GraphNavigatorExtension.cs index 70cb966833785..ed3ccb34086fd 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphNavigatorExtension.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphNavigatorExtension.cs @@ -26,7 +26,7 @@ internal sealed class GraphNavigatorExtension( { private readonly IThreadingContext _threadingContext = threadingContext; private readonly Workspace _workspace = workspace; - private readonly Lazy _streamingPresenter = streamingPresenter; + // private readonly Lazy _streamingPresenter = streamingPresenter; public void NavigateTo(GraphObject graphObject) { @@ -50,21 +50,21 @@ private async Task NavigateToAsync(GraphNode graphNode, CancellationToken cancel // Go through the mainline symbol id path if we have it. That way we notify third parties, and we can navigate // to metadata. - var symbolId = graphNode.GetValue(RoslynGraphProperties.SymbolId); - if (symbolId is not null) - { - var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); - if (compilation is not null) - { - var symbol = symbolId.Value.Resolve(compilation, cancellationToken: cancellationToken).GetAnySymbol(); - if (symbol is not null) - { - await GoToDefinitionHelpers.TryNavigateToLocationAsync( - symbol, project.Solution, _threadingContext, _streamingPresenter.Value, cancellationToken).ConfigureAwait(false); - return; - } - } - } + //var symbolId = graphNode.GetValue(RoslynGraphProperties.SymbolId); + //if (symbolId is not null) + //{ + // var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + // if (compilation is not null) + // { + // var symbol = symbolId.Value.Resolve(compilation, cancellationToken: cancellationToken).GetAnySymbol(); + // if (symbol is not null) + // { + // await GoToDefinitionHelpers.TryNavigateToLocationAsync( + // symbol, project.Solution, _threadingContext, _streamingPresenter.Value, cancellationToken).ConfigureAwait(false); + // return; + // } + // } + //} // If we didn't have a symbol id, attempt to navigate to the source location directly if the node includes one. var sourceLocation = graphNode.GetValue(CodeNodeProperties.SourceLocation); diff --git a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs index fc50d68bf13ec..d87f28129f0b9 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs @@ -366,7 +366,7 @@ public IEnumerable GetCommands(IEnumerable nodes) return null; // Has to have at least a symbolid, or source location to navigate to. - if (graphNode.GetValue(RoslynGraphProperties.SymbolId) == null && + if (// graphNode.GetValue(RoslynGraphProperties.SymbolId) == null && graphNode.GetValue(CodeNodeProperties.SourceLocation).FileName == null) { return null; diff --git a/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs b/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs index 19bc5e54460e5..8f06fc0fe8fe4 100644 --- a/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs +++ b/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs @@ -13,10 +13,10 @@ internal static class RoslynGraphProperties { public static readonly GraphSchema Schema; - /// - /// A graph property that holds the SymbolId of the symbol. - /// - public static readonly GraphProperty SymbolId; + ///// + ///// A graph property that holds the SymbolId of the symbol. + ///// + //public static readonly GraphProperty SymbolId; /// /// A graph property that holds the ProjectId where you can find the symbol. Note this is @@ -98,10 +98,10 @@ static RoslynGraphProperties() // dataType: typeof(IList), // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - SymbolId = Schema.Properties.AddNewProperty( - id: "SymbolId", - dataType: typeof(SymbolKey?), - callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); + //SymbolId = Schema.Properties.AddNewProperty( + // id: "SymbolId", + // dataType: typeof(SymbolKey?), + // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); ContextProjectId = Schema.Properties.AddNewProperty( id: "ContextProjectId", From 8b342d2c87974869e7a1181cff28348a1e75e168 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:32:19 +0200 Subject: [PATCH 014/353] Remove more unused code --- .../Core/Def/Progression/RoslynGraphProperties.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs b/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs index 8f06fc0fe8fe4..cb8ff82299f31 100644 --- a/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs +++ b/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs @@ -35,7 +35,7 @@ internal static class RoslynGraphProperties /// /// A graph property to hold the label we have generated for the node. /// - public static readonly GraphProperty Label; + // public static readonly GraphProperty Label; ///// ///// A graph property to hold the formatted label we have generated for the node. @@ -113,10 +113,10 @@ static RoslynGraphProperties() dataType: typeof(DocumentId), callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - Label = Schema.Properties.AddNewProperty( - id: "Label", - dataType: typeof(string), - callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); + //Label = Schema.Properties.AddNewProperty( + // id: "Label", + // dataType: typeof(string), + // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); //FormattedLabelWithoutContainingSymbol = Schema.Properties.AddNewProperty( // id: "FormattedLabelWithoutContainingSymbol", From 9d5a8bb3331d0627031e98d3a3159ea7f146804b Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:36:35 +0200 Subject: [PATCH 015/353] Remove more unused code --- .../Core/Def/Progression/GraphBuilder.cs | 186 +++++++++--------- .../GraphQueries/SearchGraphQuery.cs | 2 +- 2 files changed, 94 insertions(+), 94 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs b/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs index dd6b0a04fc896..b762396a40d30 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs @@ -33,120 +33,120 @@ internal sealed partial class GraphBuilder private readonly ISet _createdNodes = new HashSet(); private readonly IList> _deferredPropertySets = []; - private readonly Dictionary _nodeToContextProjectMap = []; - private readonly Dictionary _nodeToContextDocumentMap = []; + // private readonly Dictionary _nodeToContextProjectMap = []; + // private readonly Dictionary _nodeToContextDocumentMap = []; // private readonly Dictionary _nodeToSymbolMap = []; /// /// The input solution. Never null. /// - private readonly Solution _solution; + // private readonly Solution _solution; public GraphBuilder(Solution solution) { - _solution = solution; + // _solution = solution; } - public static async Task CreateForInputNodesAsync( - Solution solution, IEnumerable inputNodes, CancellationToken cancellationToken) - { - var builder = new GraphBuilder(solution); + //public static async Task CreateForInputNodesAsync( + // Solution solution, IEnumerable inputNodes, CancellationToken cancellationToken) + //{ + // var builder = new GraphBuilder(solution); - foreach (var inputNode in inputNodes) - { - if (inputNode.HasCategory(CodeNodeCategories.File)) - { - builder.PopulateMapsForFileInputNode(inputNode, cancellationToken); - } - else if (!inputNode.HasCategory(CodeNodeCategories.SourceLocation)) - { - await builder.PopulateMapsForSymbolInputNodeAsync(inputNode, cancellationToken).ConfigureAwait(false); - } - } + // foreach (var inputNode in inputNodes) + // { + // if (inputNode.HasCategory(CodeNodeCategories.File)) + // { + // // builder.PopulateMapsForFileInputNode(inputNode, cancellationToken); + // } + // else if (!inputNode.HasCategory(CodeNodeCategories.SourceLocation)) + // { + // await builder.PopulateMapsForSymbolInputNodeAsync(inputNode, cancellationToken).ConfigureAwait(false); + // } + // } - return builder; - } + // return builder; + //} - private void PopulateMapsForFileInputNode(GraphNode inputNode, CancellationToken cancellationToken) - { - using (_gate.DisposableWait(cancellationToken)) - { - var projectPath = inputNode.Id.GetNestedValueByName(CodeGraphNodeIdName.Assembly); - var filePath = inputNode.Id.GetNestedValueByName(CodeGraphNodeIdName.File); + //private void PopulateMapsForFileInputNode(GraphNode inputNode, CancellationToken cancellationToken) + //{ + // using (_gate.DisposableWait(cancellationToken)) + // { + // var projectPath = inputNode.Id.GetNestedValueByName(CodeGraphNodeIdName.Assembly); + // var filePath = inputNode.Id.GetNestedValueByName(CodeGraphNodeIdName.File); - if (projectPath == null || filePath == null) - { - return; - } + // if (projectPath == null || filePath == null) + // { + // return; + // } - var docIdsWithPath = _solution.GetDocumentIdsWithFilePath(filePath.OriginalString); - Document? document = null; - Project? project = null; + // var docIdsWithPath = _solution.GetDocumentIdsWithFilePath(filePath.OriginalString); + // Document? document = null; + // Project? project = null; - foreach (var docIdWithPath in docIdsWithPath) - { - var projectState = _solution.GetProjectState(docIdWithPath.ProjectId); - if (projectState == null) - { - FatalError.ReportAndCatch(new Exception("GetDocumentIdsWithFilePath returned a document in a project that does not exist.")); - continue; - } - - if (string.Equals(projectState.FilePath, projectPath.OriginalString)) - { - project = _solution.GetRequiredProject(projectState.Id); - document = project.GetDocument(docIdWithPath); - break; - } - } + // foreach (var docIdWithPath in docIdsWithPath) + // { + // var projectState = _solution.GetProjectState(docIdWithPath.ProjectId); + // if (projectState == null) + // { + // FatalError.ReportAndCatch(new Exception("GetDocumentIdsWithFilePath returned a document in a project that does not exist.")); + // continue; + // } - if (document == null || project == null) - { - return; - } + // if (string.Equals(projectState.FilePath, projectPath.OriginalString)) + // { + // project = _solution.GetRequiredProject(projectState.Id); + // document = project.GetDocument(docIdWithPath); + // break; + // } + // } - _nodeToContextProjectMap.Add(inputNode, project); - _nodeToContextDocumentMap.Add(inputNode, document); - } - } + // if (document == null || project == null) + // { + // return; + // } - private async Task PopulateMapsForSymbolInputNodeAsync(GraphNode inputNode, CancellationToken cancellationToken) - { - using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) - { - var projectId = (ProjectId)inputNode[RoslynGraphProperties.ContextProjectId]; - if (projectId == null) - { - return; - } + // _nodeToContextProjectMap.Add(inputNode, project); + // // _nodeToContextDocumentMap.Add(inputNode, document); + // } + //} - var project = _solution.GetProject(projectId); - if (project == null) - { - return; - } + //private async Task PopulateMapsForSymbolInputNodeAsync(GraphNode inputNode, CancellationToken cancellationToken) + //{ + // using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) + // { + // var projectId = (ProjectId)inputNode[RoslynGraphProperties.ContextProjectId]; + // if (projectId == null) + // { + // return; + // } - _nodeToContextProjectMap.Add(inputNode, project); + // var project = _solution.GetProject(projectId); + // if (project == null) + // { + // return; + // } - //var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); - //var symbolId = (SymbolKey?)inputNode[RoslynGraphProperties.SymbolId]; - //var symbol = symbolId.Value.Resolve(compilation, cancellationToken: cancellationToken).Symbol; - //if (symbol != null) - //{ - // _nodeToSymbolMap.Add(inputNode, symbol); - //} + // // _nodeToContextProjectMap.Add(inputNode, project); - var documentId = (DocumentId)inputNode[RoslynGraphProperties.ContextDocumentId]; - if (documentId != null) - { - var document = project.GetDocument(documentId); - if (document != null) - { - _nodeToContextDocumentMap.Add(inputNode, document); - } - } - } - } + // //var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); + // //var symbolId = (SymbolKey?)inputNode[RoslynGraphProperties.SymbolId]; + // //var symbol = symbolId.Value.Resolve(compilation, cancellationToken: cancellationToken).Symbol; + // //if (symbol != null) + // //{ + // // _nodeToSymbolMap.Add(inputNode, symbol); + // //} + + // var documentId = (DocumentId)inputNode[RoslynGraphProperties.ContextDocumentId]; + // if (documentId != null) + // { + // var document = project.GetDocument(documentId); + // if (document != null) + // { + // // _nodeToContextDocumentMap.Add(inputNode, document); + // } + // } + // } + //} //public Project GetContextProject(GraphNode node, CancellationToken cancellationToken) //{ @@ -702,8 +702,8 @@ public void AddLink(GraphNode from, GraphCategory category, GraphNode to, Cancel var node = Graph.Nodes.GetOrCreate(id, fileName, CodeNodeCategories.ProjectItem); - _nodeToContextDocumentMap[node] = document; - _nodeToContextProjectMap[node] = document.Project; + // _nodeToContextDocumentMap[node] = document; + // _nodeToContextProjectMap[node] = document.Project; _createdNodes.Add(node); diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/SearchGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/SearchGraphQuery.cs index 526dd59ef0bd8..f9d40e4b7498f 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/SearchGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphQueries/SearchGraphQuery.cs @@ -21,7 +21,7 @@ public async Task GetGraphAsync(Solution solution, IGraphContext c { using var _ = Logger.LogBlock(FunctionId.GraphQuery_Search, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); - var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); + var graphBuilder = new GraphBuilder(solution); // await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); var callback = new ProgressionNavigateToSearchCallback(solution, context, graphBuilder); // We have a specialized host for progression vs normal nav-to. Progression itself will tell the client if From 5d722b03f9fd01a0d62faa956dc55b6d7e67cf47 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:38:49 +0200 Subject: [PATCH 016/353] Remove more unused code --- .../Core/Def/Progression/GraphBuilder.cs | 2 +- .../Def/Progression/RoslynGraphCategories.cs | 34 +++++++++---------- .../Def/Progression/RoslynGraphProperties.cs | 20 +++++------ 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs b/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs index b762396a40d30..92d5c42a0f7b2 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs @@ -769,7 +769,7 @@ NavigateToItemKind.EnumItem or symbolNode.Label = label; symbolNode.AddCategory(category); symbolNode[DgmlNodeProperties.Icon] = GetIconString(result.NavigableItem.Glyph); - symbolNode[RoslynGraphProperties.ContextDocumentId] = document.Id; + // symbolNode[RoslynGraphProperties.ContextDocumentId] = document.Id; symbolNode[RoslynGraphProperties.ContextProjectId] = document.Project.Id; symbolNode[CodeNodeProperties.SourceLocation] = sourceLocation.Value; diff --git a/src/VisualStudio/Core/Def/Progression/RoslynGraphCategories.cs b/src/VisualStudio/Core/Def/Progression/RoslynGraphCategories.cs index 040f6671f1af3..f4ab130359f01 100644 --- a/src/VisualStudio/Core/Def/Progression/RoslynGraphCategories.cs +++ b/src/VisualStudio/Core/Def/Progression/RoslynGraphCategories.cs @@ -1,23 +1,23 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. -using Microsoft.VisualStudio.GraphModel; +//using Microsoft.VisualStudio.GraphModel; -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; -internal static class RoslynGraphCategories -{ - public static readonly GraphSchema Schema; +//internal static class RoslynGraphCategories +//{ +// public static readonly GraphSchema Schema; - public static readonly GraphCategory Overrides; +// public static readonly GraphCategory Overrides; - static RoslynGraphCategories() - { - Schema = RoslynGraphProperties.Schema; +// static RoslynGraphCategories() +// { +// Schema = RoslynGraphProperties.Schema; - Overrides = Schema.Categories.AddNewCategory( - "Overrides", - () => new GraphMetadata(GraphMetadataOptions.Sharable)); - } -} +// Overrides = Schema.Categories.AddNewCategory( +// "Overrides", +// () => new GraphMetadata(GraphMetadataOptions.Sharable)); +// } +//} diff --git a/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs b/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs index cb8ff82299f31..9e5b8a19625da 100644 --- a/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs +++ b/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs @@ -25,12 +25,12 @@ internal static class RoslynGraphProperties /// public static readonly GraphProperty ContextProjectId; - /// - /// A graph property that holds the DocumentId where you can find the symbol. This is used - /// to distinguish between multiple locations for partial types. This will only exist - /// for symbols in source that have partial implementations. - /// - public static readonly GraphProperty ContextDocumentId; + ///// + ///// A graph property that holds the DocumentId where you can find the symbol. This is used + ///// to distinguish between multiple locations for partial types. This will only exist + ///// for symbols in source that have partial implementations. + ///// + //public static readonly GraphProperty ContextDocumentId; /// /// A graph property to hold the label we have generated for the node. @@ -108,10 +108,10 @@ static RoslynGraphProperties() dataType: typeof(ProjectId), callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - ContextDocumentId = Schema.Properties.AddNewProperty( - id: "ContextDocumentId", - dataType: typeof(DocumentId), - callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); + //ContextDocumentId = Schema.Properties.AddNewProperty( + // id: "ContextDocumentId", + // dataType: typeof(DocumentId), + // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); //Label = Schema.Properties.AddNewProperty( // id: "Label", From de9db43cbbf268193673833721267f524241b24c Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:44:56 +0200 Subject: [PATCH 017/353] Remove more unused code --- .../Core/Def/Progression/GraphBuilder.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs b/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs index 92d5c42a0f7b2..89f943433beb7 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs @@ -31,7 +31,7 @@ internal sealed partial class GraphBuilder #pragma warning restore RS0030 // Do not use banned APIs private readonly ISet _createdNodes = new HashSet(); - private readonly IList> _deferredPropertySets = []; + // private readonly IList> _deferredPropertySets = []; // private readonly Dictionary _nodeToContextProjectMap = []; // private readonly Dictionary _nodeToContextDocumentMap = []; @@ -825,11 +825,11 @@ public void ApplyToGraph(Graph graph, CancellationToken cancellationToken) using var graphTransaction = new GraphTransactionScope(); graph.Merge(this.Graph); - foreach (var deferredProperty in _deferredPropertySets) - { - var nodeToSet = graph.Nodes.Get(deferredProperty.Item1.Id); - nodeToSet.SetValue(deferredProperty.Item2, deferredProperty.Item3); - } + //foreach (var deferredProperty in _deferredPropertySets) + //{ + // var nodeToSet = graph.Nodes.Get(deferredProperty.Item1.Id); + // nodeToSet.SetValue(deferredProperty.Item2, deferredProperty.Item3); + //} graphTransaction.Complete(); } From aede48d8871b50f33866432341c0b054c6b9f6b7 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 12:48:41 +0200 Subject: [PATCH 018/353] Remove tracking support. It is not used --- .../Core/Def/Progression/GraphQueryManager.cs | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueryManager.cs b/src/VisualStudio/Core/Def/Progression/GraphQueryManager.cs index e5c81b32345f2..e1ac7aee5dc91 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphQueryManager.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphQueryManager.cs @@ -29,7 +29,7 @@ internal sealed class GraphQueryManager private readonly object _gate = new(); private ImmutableArray<(WeakReference context, ImmutableArray queries)> _trackedQueries = []; - private readonly AsyncBatchingWorkQueue _updateQueue; + // private readonly AsyncBatchingWorkQueue _updateQueue; internal GraphQueryManager( Workspace workspace, @@ -38,19 +38,19 @@ internal GraphQueryManager( { _workspace = workspace; - // Update any existing live/tracking queries 1.5 seconds after every workspace changes. - _updateQueue = new AsyncBatchingWorkQueue( - DelayTimeSpan.Idle, - UpdateExistingQueriesAsync, - asyncListener, - threadingContext.DisposalToken); + //// Update any existing live/tracking queries 1.5 seconds after every workspace changes. + //_updateQueue = new AsyncBatchingWorkQueue( + // DelayTimeSpan.Idle, + // UpdateExistingQueriesAsync, + // asyncListener, + // threadingContext.DisposalToken); // Note: this ends up always listening for workspace events, even if we have no active 'live' queries that // need updating. But this should basically be practically no cost. The queue just holds a single item // indicating a change happened. And when UpdateExistingQueriesAsync fires, it will just see that there are // no live queries and immediately return. So it's just simple to do things this way instead of trying to // have state management where we try to decide if we should listen or not. - _ = _workspace.RegisterWorkspaceChangedHandler((_) => _updateQueue.AddWork()); + //_ = _workspace.RegisterWorkspaceChangedHandler((_) => _updateQueue.AddWork()); } public async Task AddQueriesAsync(IGraphContext context, ImmutableArray graphQueries, CancellationToken disposalToken) @@ -79,31 +79,31 @@ public async Task AddQueriesAsync(IGraphContext context, ImmutableArray queries)> liveQueries; - lock (_gate) - { - // First, grab the set of contexts that are still live. We'll update them below. - liveQueries = _trackedQueries - .SelectAsArray(t => (context: t.context.GetTarget(), t.queries)) - .WhereAsArray(t => t.context != null)!; - - // Next, clear out any context that are now no longer alive (or have been canceled). We no longer care - // about these. - _trackedQueries = _trackedQueries.RemoveAll(t => - { - var target = t.context.GetTarget(); - return target is null || target.CancelToken.IsCancellationRequested; - }); - } - - var solution = _workspace.CurrentSolution; - - // Update all the live queries in parallel. - var tasks = liveQueries.Select(t => PopulateContextGraphAsync(solution, t.context, t.queries, disposalToken)).ToArray(); - await Task.WhenAll(tasks).ConfigureAwait(false); - } + //private async ValueTask UpdateExistingQueriesAsync(CancellationToken disposalToken) + //{ + // ImmutableArray<(IGraphContext context, ImmutableArray queries)> liveQueries; + // lock (_gate) + // { + // // First, grab the set of contexts that are still live. We'll update them below. + // liveQueries = _trackedQueries + // .SelectAsArray(t => (context: t.context.GetTarget(), t.queries)) + // .WhereAsArray(t => t.context != null)!; + + // // Next, clear out any context that are now no longer alive (or have been canceled). We no longer care + // // about these. + // _trackedQueries = _trackedQueries.RemoveAll(t => + // { + // var target = t.context.GetTarget(); + // return target is null || target.CancelToken.IsCancellationRequested; + // }); + // } + + // var solution = _workspace.CurrentSolution; + + // // Update all the live queries in parallel. + // var tasks = liveQueries.Select(t => PopulateContextGraphAsync(solution, t.context, t.queries, disposalToken)).ToArray(); + // await Task.WhenAll(tasks).ConfigureAwait(false); + //} /// /// Populate the graph of the context with the values for the given Solution. From c7ba2c7263eacbf1c73bfa231f7da8a83d50b771 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 15:05:51 +0200 Subject: [PATCH 019/353] IN progress --- .../HierarchyItemToProjectIdMap.cs | 60 +++++--- .../IHierarchyItemToProjectIdMap.cs | 2 + .../SymbolTreeItemSourceProvider.cs | 133 ++++++++++++++++++ .../Shared/TestHooks/FeatureAttribute.cs | 1 + 4 files changed, 179 insertions(+), 17 deletions(-) create mode 100644 src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs diff --git a/src/VisualStudio/Core/Def/Implementation/HierarchyItemToProjectIdMap.cs b/src/VisualStudio/Core/Def/Implementation/HierarchyItemToProjectIdMap.cs index 5d94975eaf2ac..3c61e6f887c85 100644 --- a/src/VisualStudio/Core/Def/Implementation/HierarchyItemToProjectIdMap.cs +++ b/src/VisualStudio/Core/Def/Implementation/HierarchyItemToProjectIdMap.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections.Immutable; using System.Composition; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -14,17 +15,47 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation; [ExportWorkspaceService(typeof(IHierarchyItemToProjectIdMap), ServiceLayer.Host), Shared] -internal sealed class HierarchyItemToProjectIdMap : IHierarchyItemToProjectIdMap +[method: ImportingConstructor] +[method: SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] +internal sealed class HierarchyItemToProjectIdMap(VisualStudioWorkspaceImpl workspace) : IHierarchyItemToProjectIdMap { - private readonly VisualStudioWorkspaceImpl _workspace; + private readonly VisualStudioWorkspaceImpl _workspace = workspace; - [ImportingConstructor] - [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] - public HierarchyItemToProjectIdMap(VisualStudioWorkspaceImpl workspace) - => _workspace = workspace; + public bool TryGetDocumentId(IVsHierarchyItem hierarchyItem, string? targetFrameworkMoniker, [NotNullWhen(true)] out DocumentId? documentId) + { + documentId = null; + + var identity = hierarchyItem.HierarchyIdentity; + //if (!identity.IsNestedItem) + // return false; + + TryGetProjectId(hierarchyItem.Parent, targetFrameworkMoniker, out var projectId3); + + var solution = _workspace.CurrentSolution; + var project1 = solution.ProjectIds.FirstOrDefault(projectId => _workspace.GetHierarchy(projectId) == hierarchyItem.Parent.HierarchyIdentity.Hierarchy); + var project2 = solution.ProjectIds.FirstOrDefault(projectId => _workspace.GetHierarchy(projectId) == hierarchyItem.Parent.HierarchyIdentity.NestedHierarchy); + + if (project1 is null) + return false; + + var hierarchy = identity.Hierarchy; + var itemId = identity.ItemID; + + if (!hierarchy.TryGetCanonicalName(itemId, out var itemName)) + return false; - public bool TryGetProjectId(IVsHierarchyItem hierarchyItem, string? targetFrameworkMoniker, [NotNullWhen(true)] out ProjectId? projectId) + //var document = project1.Documents.FirstOrDefault(d => d.FilePath == itemName); + //documentId = document?.Id; + return documentId != null; + } + + public bool TryGetProjectId(IVsHierarchyItem? hierarchyItem, string? targetFrameworkMoniker, [NotNullWhen(true)] out ProjectId? projectId) { + projectId = null; + + if (hierarchyItem is null) + return false; + // A project node is represented in two different hierarchies: the solution's IVsHierarchy (where it is a leaf node) // and the project's own IVsHierarchy (where it is the root node). The IVsHierarchyItem joins them together for the // purpose of creating the tree displayed in Solution Explorer. The project's hierarchy is what is passed from the @@ -41,23 +72,19 @@ public bool TryGetProjectId(IVsHierarchyItem hierarchyItem, string? targetFramew // The properties supported and the interpretation of their values varies from one project system // to another. This code is designed with C# and VB in mind, so we need to filter out everything // else. - if (p.Language is not LanguageNames.CSharp - and not LanguageNames.VisualBasic) - { + if (p.Language is not LanguageNames.CSharp and not LanguageNames.VisualBasic) return false; - } var hierarchy = _workspace.GetHierarchy(p.Id); - return hierarchy == nestedHierarchy; }) - .ToArray(); + .ToImmutableArray(); // If we only have one candidate then no further checks are required. if (candidateProjects.Length == 1) { projectId = candidateProjects[0].Id; - return true; + return projectId != null; } // For CPS projects, we may have a string we extracted from a $TFM-prefixed capability; compare that to the string we're given @@ -69,7 +96,7 @@ public bool TryGetProjectId(IVsHierarchyItem hierarchyItem, string? targetFramew if (matchingProject != null) { projectId = matchingProject.Id; - return true; + return projectId != null; } } @@ -82,11 +109,10 @@ public bool TryGetProjectId(IVsHierarchyItem hierarchyItem, string? targetFramew if (!candidateProject.DocumentIds.Any(id => ContainedDocument.TryGetContainedDocument(id) != null)) { projectId = candidateProject.Id; - return true; + return projectId != null; } } - projectId = null; return false; } } diff --git a/src/VisualStudio/Core/Def/Implementation/IHierarchyItemToProjectIdMap.cs b/src/VisualStudio/Core/Def/Implementation/IHierarchyItemToProjectIdMap.cs index 0006128b2b7c9..fc0b028ae32bf 100644 --- a/src/VisualStudio/Core/Def/Implementation/IHierarchyItemToProjectIdMap.cs +++ b/src/VisualStudio/Core/Def/Implementation/IHierarchyItemToProjectIdMap.cs @@ -14,6 +14,8 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation; /// internal interface IHierarchyItemToProjectIdMap : IWorkspaceService { + bool TryGetDocumentId(IVsHierarchyItem parent, string? targetFrameworkMoniker, out DocumentId documentId); + /// /// Given an representing a project and an optional target framework moniker, /// returns the of the equivalent Roslyn . diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs new file mode 100644 index 0000000000000..f8d541bf233a3 --- /dev/null +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs @@ -0,0 +1,133 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections; +using System.Collections.Immutable; +using System.ComponentModel.Composition; +using System.Diagnostics.CodeAnalysis; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.Shared.TestHooks; +using Microsoft.CodeAnalysis.Threading; +using Microsoft.Internal.VisualStudio.PlatformUI; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; +using Microsoft.VisualStudio.Utilities; +using Roslyn.Utilities; + +namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; + +[Export(typeof(IAttachedCollectionSourceProvider))] +[Name(nameof(SymbolTreeItemSourceProvider))] +[Order(Before = HierarchyItemsProviderNames.Contains)] +[AppliesToProject("CSharp | VB")] +internal sealed class SymbolTreeItemSourceProvider : AttachedCollectionSourceProvider +{ + private readonly IThreadingContext _threadingContext; + private readonly Workspace _workspace; + + private readonly ConcurrentSet> _weakCollectionSources = []; + + private readonly AsyncBatchingWorkQueue _updateSourcesQueue; + + // private readonly IAnalyzersCommandHandler _commandHandler = commandHandler; + + // private IHierarchyItemToProjectIdMap? _projectMap; + + [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] + [ImportingConstructor] + public SymbolTreeItemSourceProvider( + IThreadingContext threadingContext, + VisualStudioWorkspace workspace, + IAsynchronousOperationListenerProvider listenerProvider + /*, + [Import(typeof(AnalyzersCommandHandler))] IAnalyzersCommandHandler commandHandler*/) + { + _threadingContext = threadingContext; + _workspace = workspace; + + _updateSourcesQueue = new AsyncBatchingWorkQueue( + DelayTimeSpan.Medium, + UpdateCollectionSourcesAsync, + listenerProvider.GetListener(FeatureAttribute.SolutionExplorer), + _threadingContext.DisposalToken); + + _workspace.RegisterWorkspaceChangedHandler( + e => _updateSourcesQueue.AddWork(cancelExistingWork: true), + options: new WorkspaceEventOptions(RequiresMainThread: false)); + } + + //private IHierarchyItemToProjectIdMap? TryGetProjectMap() + // => _projectMap ??= _workspace.Services.GetService(); + + protected override IAttachedCollectionSource? CreateCollectionSource(IVsHierarchyItem item, string relationshipName) + { + if (item == null || + item.HierarchyIdentity == null || + item.HierarchyIdentity.NestedHierarchy == null || + relationshipName != KnownRelationships.Contains) + { + return null; + } + + var hierarchy = item.HierarchyIdentity.NestedHierarchy; + var itemId = item.HierarchyIdentity.NestedItemID; + + if (hierarchy.GetProperty(itemId, (int)__VSHPROPID7.VSHPROPID_ProjectTreeCapabilities, out var capabilitiesObj) != VSConstants.S_OK || + capabilitiesObj is not string capabilities) + { + return null; + } + + if (!capabilities.Contains(nameof(VisualStudio.ProjectSystem.ProjectTreeFlags.SourceFile)) || + !capabilities.Contains(nameof(VisualStudio.ProjectSystem.ProjectTreeFlags.FileOnDisk))) + { + return null; + } + + var source = new SymbolTreeItemCollectionSource(this, item); + _weakCollectionSources.Add(new WeakReference(source)); + return source; + //var hierarchyMapper = TryGetProjectMap(); + //if (hierarchyMapper == null || + // !hierarchyMapper.TryGetDocumentId(item, targetFrameworkMoniker: null, out var documentId)) + //{ + // return null; + //} + + //return null; + } + + private sealed class SymbolTreeItemCollectionSource( + SymbolTreeItemSourceProvider provider, + IVsHierarchyItem hierarchyItem) + : IAttachedCollectionSource + { + public object SourceItem => hierarchyItem; + + public bool HasItems => true; + + public IEnumerable Items => Array.Empty(); + } + + private sealed class SymbolTreeItem() : BaseItem(nameof(SymbolTreeItem)) + { + + } + + //private static ImmutableArray GetProjectTreeCapabilities(IVsHierarchy hierarchy, uint itemId) + //{ + // if (hierarchy.GetProperty(itemId, (int)__VSHPROPID7.VSHPROPID_ProjectTreeCapabilities, out var capabilitiesObj) == VSConstants.S_OK) + // { + // var capabilitiesString = (string)capabilitiesObj; + // return ImmutableArray.Create(capabilitiesString.Split(' ')); + // } + // else + // { + // return []; + // } + //} + +} diff --git a/src/Workspaces/Core/Portable/Shared/TestHooks/FeatureAttribute.cs b/src/Workspaces/Core/Portable/Shared/TestHooks/FeatureAttribute.cs index 1d19cac5f4bd5..87ade22811eaf 100644 --- a/src/Workspaces/Core/Portable/Shared/TestHooks/FeatureAttribute.cs +++ b/src/Workspaces/Core/Portable/Shared/TestHooks/FeatureAttribute.cs @@ -68,6 +68,7 @@ internal static class FeatureAttribute public const string SolutionChecksumUpdater = nameof(SolutionChecksumUpdater); public const string SolutionCrawlerLegacy = nameof(SolutionCrawlerLegacy); public const string SolutionCrawlerUnitTesting = nameof(SolutionCrawlerUnitTesting); + public const string SolutionExplorer = nameof(SolutionExplorer); public const string SourceGenerators = nameof(SourceGenerators); public const string StringIndentation = nameof(StringIndentation); public const string Tagger = nameof(Tagger); From eaa604866a9ca360d268899d39537581e7796aaf Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 15:20:20 +0200 Subject: [PATCH 020/353] IN progress --- .../SymbolTreeItemSourceProvider.cs | 56 ++++++++++++++++++- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs index f8d541bf233a3..66fa431ac4edd 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs @@ -4,14 +4,22 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel.Composition; using System.Diagnostics.CodeAnalysis; +using System.Threading; +using System.Threading.Tasks; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.ErrorReporting; +using Microsoft.CodeAnalysis.ForEachCast; using Microsoft.CodeAnalysis.Shared.TestHooks; +using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Threading; using Microsoft.Internal.VisualStudio.PlatformUI; +using Microsoft.VisualStudio.Language.Intellisense; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Utilities; @@ -30,7 +38,7 @@ internal sealed class SymbolTreeItemSourceProvider : AttachedCollectionSourcePro private readonly ConcurrentSet> _weakCollectionSources = []; - private readonly AsyncBatchingWorkQueue _updateSourcesQueue; + private readonly AsyncBatchingWorkQueue _updateSourcesQueue; // private readonly IAnalyzersCommandHandler _commandHandler = commandHandler; @@ -48,17 +56,57 @@ IAsynchronousOperationListenerProvider listenerProvider _threadingContext = threadingContext; _workspace = workspace; - _updateSourcesQueue = new AsyncBatchingWorkQueue( + _updateSourcesQueue = new AsyncBatchingWorkQueue( DelayTimeSpan.Medium, UpdateCollectionSourcesAsync, + EqualityComparer.Default, listenerProvider.GetListener(FeatureAttribute.SolutionExplorer), _threadingContext.DisposalToken); _workspace.RegisterWorkspaceChangedHandler( - e => _updateSourcesQueue.AddWork(cancelExistingWork: true), + e => + { + if (e is { Kind: WorkspaceChangeKind.DocumentChanged, DocumentId: not null }) + _updateSourcesQueue.AddWork(e.DocumentId); + }, options: new WorkspaceEventOptions(RequiresMainThread: false)); } + private async ValueTask UpdateCollectionSourcesAsync( + ImmutableSegmentedList documentIds, CancellationToken cancellationToken) + { + using var _1 = Microsoft.CodeAnalysis.PooledObjects.PooledHashSet.GetInstance(out var documentIdSet); + using var _2 = Microsoft.CodeAnalysis.PooledObjects.ArrayBuilder.GetInstance(out var sources); + + documentIdSet.AddRange(documentIds); + + foreach (var weakSource in _weakCollectionSources) + { + // If solution explorer has released this collection source, we can drop it as well. + if (!weakSource.TryGetTarget(out var source)) + { + _weakCollectionSources.Remove(weakSource); + continue; + } + + sources.Add(source); + } + + await RoslynParallel.ForEachAsync( + sources, + cancellationToken, + async (source, cancellationToken) => + { + try + { + await source.UpdateIfAffectedAsync(documentIdSet, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) when (FatalError.ReportAndCatchUnlessCanceled(ex)) + { + } + }).ConfigureAwait(false); + } + //private IHierarchyItemToProjectIdMap? TryGetProjectMap() // => _projectMap ??= _workspace.Services.GetService(); @@ -105,6 +153,8 @@ private sealed class SymbolTreeItemCollectionSource( IVsHierarchyItem hierarchyItem) : IAttachedCollectionSource { + private readonly BulkObservableCollection _symbolTreeItems; + public object SourceItem => hierarchyItem; public bool HasItems => true; From beeaca7fa494ed1b5e5626bec00c2e049077624f Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 16:04:39 +0200 Subject: [PATCH 021/353] IN progress --- .../BulkObservableCollectionExtensions.cs | 24 +++++++ .../HierarchyItemToProjectIdMap.cs | 21 +++--- .../IHierarchyItemToProjectIdMap.cs | 2 +- .../SymbolTreeItemSourceProvider.cs | 69 ++++++++++++++++++- 4 files changed, 100 insertions(+), 16 deletions(-) create mode 100644 src/VisualStudio/Core/Def/Extensions/BulkObservableCollectionExtensions.cs diff --git a/src/VisualStudio/Core/Def/Extensions/BulkObservableCollectionExtensions.cs b/src/VisualStudio/Core/Def/Extensions/BulkObservableCollectionExtensions.cs new file mode 100644 index 0000000000000..66f56c864436d --- /dev/null +++ b/src/VisualStudio/Core/Def/Extensions/BulkObservableCollectionExtensions.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.VisualStudio.Language.Intellisense; + +namespace Microsoft.VisualStudio.LanguageServices.Extensions; + +internal static class BulkObservableCollectionExtensions +{ + public static BulkOperationDisposable GetBulkOperation(this BulkObservableCollection collection) + { + collection.BeginBulkOperation(); + return new BulkOperationDisposable(collection); + } + + public readonly struct BulkOperationDisposable(BulkObservableCollection collection) + : IDisposable + { + public void Dispose() + => collection.EndBulkOperation(); + } +} diff --git a/src/VisualStudio/Core/Def/Implementation/HierarchyItemToProjectIdMap.cs b/src/VisualStudio/Core/Def/Implementation/HierarchyItemToProjectIdMap.cs index 3c61e6f887c85..cd6424af66f27 100644 --- a/src/VisualStudio/Core/Def/Implementation/HierarchyItemToProjectIdMap.cs +++ b/src/VisualStudio/Core/Def/Implementation/HierarchyItemToProjectIdMap.cs @@ -26,16 +26,8 @@ public bool TryGetDocumentId(IVsHierarchyItem hierarchyItem, string? targetFrame documentId = null; var identity = hierarchyItem.HierarchyIdentity; - //if (!identity.IsNestedItem) - // return false; - - TryGetProjectId(hierarchyItem.Parent, targetFrameworkMoniker, out var projectId3); - var solution = _workspace.CurrentSolution; - var project1 = solution.ProjectIds.FirstOrDefault(projectId => _workspace.GetHierarchy(projectId) == hierarchyItem.Parent.HierarchyIdentity.Hierarchy); - var project2 = solution.ProjectIds.FirstOrDefault(projectId => _workspace.GetHierarchy(projectId) == hierarchyItem.Parent.HierarchyIdentity.NestedHierarchy); - - if (project1 is null) + if (!TryGetProjectId(solution, hierarchyItem.Parent, targetFrameworkMoniker, out var projectId)) return false; var hierarchy = identity.Hierarchy; @@ -44,12 +36,17 @@ public bool TryGetDocumentId(IVsHierarchyItem hierarchyItem, string? targetFrame if (!hierarchy.TryGetCanonicalName(itemId, out var itemName)) return false; - //var document = project1.Documents.FirstOrDefault(d => d.FilePath == itemName); - //documentId = document?.Id; + var documentIds = solution.GetDocumentIdsWithFilePath(itemName); + documentId = documentIds.FirstOrDefault(d => d.ProjectId == projectId); + return documentId != null; } public bool TryGetProjectId(IVsHierarchyItem? hierarchyItem, string? targetFrameworkMoniker, [NotNullWhen(true)] out ProjectId? projectId) + => TryGetProjectId(_workspace.CurrentSolution, hierarchyItem, targetFrameworkMoniker, out projectId); + + private bool TryGetProjectId( + Solution solution, IVsHierarchyItem? hierarchyItem, string? targetFrameworkMoniker, [NotNullWhen(true)] out ProjectId? projectId) { projectId = null; @@ -65,7 +62,7 @@ public bool TryGetProjectId(IVsHierarchyItem? hierarchyItem, string? targetFrame // First filter the projects by matching up properties on the input hierarchy against properties on each // project's hierarchy. - var candidateProjects = _workspace.CurrentSolution.Projects + var candidateProjects = solution.Projects .Where(p => { // We're about to access various properties of the IVsHierarchy associated with the project. diff --git a/src/VisualStudio/Core/Def/Implementation/IHierarchyItemToProjectIdMap.cs b/src/VisualStudio/Core/Def/Implementation/IHierarchyItemToProjectIdMap.cs index fc0b028ae32bf..79b01d5904d51 100644 --- a/src/VisualStudio/Core/Def/Implementation/IHierarchyItemToProjectIdMap.cs +++ b/src/VisualStudio/Core/Def/Implementation/IHierarchyItemToProjectIdMap.cs @@ -14,7 +14,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation; /// internal interface IHierarchyItemToProjectIdMap : IWorkspaceService { - bool TryGetDocumentId(IVsHierarchyItem parent, string? targetFrameworkMoniker, out DocumentId documentId); + bool TryGetDocumentId(IVsHierarchyItem parent, string? targetFrameworkMoniker, [NotNullWhen(true)] out DocumentId? documentId); /// /// Given an representing a project and an optional target framework moniker, diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs index 66fa431ac4edd..fcc9cd305f77c 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs @@ -24,6 +24,10 @@ using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Utilities; using Roslyn.Utilities; +using Microsoft.VisualStudio.LanguageServices.Extensions; +using Microsoft.VisualStudio.Debugger.ComponentInterfaces; +using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -66,7 +70,7 @@ IAsynchronousOperationListenerProvider listenerProvider _workspace.RegisterWorkspaceChangedHandler( e => { - if (e is { Kind: WorkspaceChangeKind.DocumentChanged, DocumentId: not null }) + if (e is { Kind: WorkspaceChangeKind.DocumentChanged or WorkspaceChangeKind.DocumentAdded, DocumentId: not null }) _updateSourcesQueue.AddWork(e.DocumentId); }, options: new WorkspaceEventOptions(RequiresMainThread: false)); @@ -153,13 +157,67 @@ private sealed class SymbolTreeItemCollectionSource( IVsHierarchyItem hierarchyItem) : IAttachedCollectionSource { + private readonly SymbolTreeItemSourceProvider _provider = provider; + private readonly IVsHierarchyItem _hierarchyItem = hierarchyItem; + private readonly BulkObservableCollection _symbolTreeItems; - public object SourceItem => hierarchyItem; + private DocumentId? _documentId; + public object SourceItem => _hierarchyItem; public bool HasItems => true; + public IEnumerable Items => _symbolTreeItems; + + internal async Task UpdateIfAffectedAsync( + HashSet updateSet, CancellationToken cancellationToken) + { + var documentId = DetermineDocumentId(); + + // If we successfully handle this request, we're done. + if (await TryUpdateItemsAsync(updateSet, documentId).ConfigureAwait(false)) + return; + + // If we failed for any reason, clear out all our items. + using (_symbolTreeItems.GetBulkOperation()) + _symbolTreeItems.Clear(); + } + private async ValueTask TryUpdateItemsAsync( + HashSet updateSet, DocumentId? documentId, CancellationToken cancellationToken) + { + if (documentId is null) + return false; + + if (!updateSet.Contains(documentId)) + { + // Note: we intentionally return 'true' here. There was no failure here. We just got a notification + // to update a different document than our own. So we can just ignore this. + return true; + } + + var solution = _provider._workspace.CurrentSolution; + var document = solution.GetDocument(documentId); + + // If we can't find this document anymore, clear everything out. + if (document is null) + return false; - public IEnumerable Items => Array.Empty(); + var service = document.Project.GetLanguageService(); + if (service is null) + return false; + + var items = await service.GetItemsAsync(document, cancellationToken).ConfigureAwait(false); + } + + private DocumentId? DetermineDocumentId() + { + if (_documentId == null) + { + var idMap = _provider._workspace.Services.GetService(); + idMap?.TryGetDocumentId(_hierarchyItem, targetFrameworkMoniker: null, out _documentId); + } + + return _documentId; + } } private sealed class SymbolTreeItem() : BaseItem(nameof(SymbolTreeItem)) @@ -181,3 +239,8 @@ private sealed class SymbolTreeItem() : BaseItem(nameof(SymbolTreeItem)) //} } + +internal interface ISolutionExplorerSymbolTreeItemProvider : ILanguageService +{ + +} From 0b198d10aeeb925245601ced4089d3b6730e2d78 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 16:16:43 +0200 Subject: [PATCH 022/353] IN progress --- .../Core/Impl/SolutionExplorer/BaseItem.cs | 5 ++-- .../SymbolTreeItemSourceProvider.cs | 24 ++++++++++++------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs index ae051779293c0..16572274337d1 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs @@ -35,14 +35,15 @@ public virtual event PropertyChangedEventHandler PropertyChanged { add { } remov protected readonly string Name; - public BaseItem(string name) + public BaseItem(string name, bool isExpandable = true) { Name = name; + IsExpandable = isExpandable; } public IEnumerable Children => []; - public bool IsExpandable => true; + public bool IsExpandable { get; } public FontStyle FontStyle => FontStyles.Normal; public FontWeight FontWeight => FontWeights.Normal; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs index fcc9cd305f77c..e4385485a2e25 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs @@ -160,7 +160,7 @@ private sealed class SymbolTreeItemCollectionSource( private readonly SymbolTreeItemSourceProvider _provider = provider; private readonly IVsHierarchyItem _hierarchyItem = hierarchyItem; - private readonly BulkObservableCollection _symbolTreeItems; + private readonly BulkObservableCollection _symbolTreeItems = []; private DocumentId? _documentId; @@ -174,7 +174,7 @@ internal async Task UpdateIfAffectedAsync( var documentId = DetermineDocumentId(); // If we successfully handle this request, we're done. - if (await TryUpdateItemsAsync(updateSet, documentId).ConfigureAwait(false)) + if (await TryUpdateItemsAsync(updateSet, documentId, cancellationToken).ConfigureAwait(false)) return; // If we failed for any reason, clear out all our items. @@ -206,6 +206,14 @@ private async ValueTask TryUpdateItemsAsync( return false; var items = await service.GetItemsAsync(document, cancellationToken).ConfigureAwait(false); + + using (_symbolTreeItems.GetBulkOperation()) + { + _symbolTreeItems.Clear(); + _symbolTreeItems.AddRange(items); + } + + return true; } private DocumentId? DetermineDocumentId() @@ -220,11 +228,6 @@ private async ValueTask TryUpdateItemsAsync( } } - private sealed class SymbolTreeItem() : BaseItem(nameof(SymbolTreeItem)) - { - - } - //private static ImmutableArray GetProjectTreeCapabilities(IVsHierarchy hierarchy, uint itemId) //{ // if (hierarchy.GetProperty(itemId, (int)__VSHPROPID7.VSHPROPID_ProjectTreeCapabilities, out var capabilitiesObj) == VSConstants.S_OK) @@ -240,7 +243,12 @@ private sealed class SymbolTreeItem() : BaseItem(nameof(SymbolTreeItem)) } -internal interface ISolutionExplorerSymbolTreeItemProvider : ILanguageService +internal sealed class SymbolTreeItem() : BaseItem(nameof(SymbolTreeItem)) { } + +internal interface ISolutionExplorerSymbolTreeItemProvider : ILanguageService +{ + Task> GetItemsAsync(Document document, CancellationToken cancellationToken); +} From eba2e4dd34a1d3bc8873a2903293653eb6eb52b3 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 17:03:51 +0200 Subject: [PATCH 023/353] IN progress --- .../Core/Portable/Common/GlyphExtensions.cs | 51 +++++++ .../NavigateTo/RoslynNavigateToItem.cs | 52 +------ ...isualStudio.LanguageServices.CSharp.csproj | 2 +- ...pSolutionExplorerSymbolTreeItemProvider.cs | 131 ++++++++++++++++++ .../SymbolTreeItemSourceProvider.cs | 10 +- .../CSharpDeclaredSymbolInfoFactoryService.cs | 46 +----- .../FindSymbols/FindSymbolsUtilities.cs | 59 ++++++++ 7 files changed, 254 insertions(+), 97 deletions(-) create mode 100644 src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs create mode 100644 src/Workspaces/CSharp/Portable/FindSymbols/FindSymbolsUtilities.cs diff --git a/src/Features/Core/Portable/Common/GlyphExtensions.cs b/src/Features/Core/Portable/Common/GlyphExtensions.cs index b778db2472e9f..86b1e96d36730 100644 --- a/src/Features/Core/Portable/Common/GlyphExtensions.cs +++ b/src/Features/Core/Portable/Common/GlyphExtensions.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Immutable; +using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Tags; @@ -238,4 +239,54 @@ public static Accessibility GetAccessibility(ReadOnlySpan tags) return Accessibility.NotApplicable; } + + public static Glyph GetGlyph(DeclaredSymbolInfoKind kind, Accessibility accessibility) + { + // Glyphs are stored in this order: + // ClassPublic, + // ClassProtected, + // ClassPrivate, + // ClassInternal, + + var rawGlyph = GetPublicGlyph(kind); + + switch (accessibility) + { + case Accessibility.Private: + rawGlyph += (Glyph.ClassPrivate - Glyph.ClassPublic); + break; + case Accessibility.Internal: + rawGlyph += (Glyph.ClassInternal - Glyph.ClassPublic); + break; + case Accessibility.Protected: + case Accessibility.ProtectedOrInternal: + case Accessibility.ProtectedAndInternal: + rawGlyph += (Glyph.ClassProtected - Glyph.ClassPublic); + break; + } + + return rawGlyph; + } + + private static Glyph GetPublicGlyph(DeclaredSymbolInfoKind kind) + => kind switch + { + DeclaredSymbolInfoKind.Class => Glyph.ClassPublic, + DeclaredSymbolInfoKind.Constant => Glyph.ConstantPublic, + DeclaredSymbolInfoKind.Constructor => Glyph.MethodPublic, + DeclaredSymbolInfoKind.Delegate => Glyph.DelegatePublic, + DeclaredSymbolInfoKind.Enum => Glyph.EnumPublic, + DeclaredSymbolInfoKind.EnumMember => Glyph.EnumMemberPublic, + DeclaredSymbolInfoKind.Event => Glyph.EventPublic, + DeclaredSymbolInfoKind.ExtensionMethod => Glyph.ExtensionMethodPublic, + DeclaredSymbolInfoKind.Field => Glyph.FieldPublic, + DeclaredSymbolInfoKind.Indexer => Glyph.PropertyPublic, + DeclaredSymbolInfoKind.Interface => Glyph.InterfacePublic, + DeclaredSymbolInfoKind.Method => Glyph.MethodPublic, + DeclaredSymbolInfoKind.Module => Glyph.ModulePublic, + DeclaredSymbolInfoKind.Property => Glyph.PropertyPublic, + DeclaredSymbolInfoKind.Struct => Glyph.StructurePublic, + DeclaredSymbolInfoKind.RecordStruct => Glyph.StructurePublic, + _ => Glyph.ClassPublic, + }; } diff --git a/src/Features/Core/Portable/NavigateTo/RoslynNavigateToItem.cs b/src/Features/Core/Portable/NavigateTo/RoslynNavigateToItem.cs index 325b107a6cf29..b55f11f73a38d 100644 --- a/src/Features/Core/Portable/NavigateTo/RoslynNavigateToItem.cs +++ b/src/Features/Core/Portable/NavigateTo/RoslynNavigateToItem.cs @@ -280,57 +280,7 @@ int GetCommonFolderCount() #region INavigableItem - Glyph INavigableItem.Glyph => GetGlyph(_item.DeclaredSymbolInfo.Kind, _item.DeclaredSymbolInfo.Accessibility); - - private static Glyph GetPublicGlyph(DeclaredSymbolInfoKind kind) - => kind switch - { - DeclaredSymbolInfoKind.Class => Glyph.ClassPublic, - DeclaredSymbolInfoKind.Constant => Glyph.ConstantPublic, - DeclaredSymbolInfoKind.Constructor => Glyph.MethodPublic, - DeclaredSymbolInfoKind.Delegate => Glyph.DelegatePublic, - DeclaredSymbolInfoKind.Enum => Glyph.EnumPublic, - DeclaredSymbolInfoKind.EnumMember => Glyph.EnumMemberPublic, - DeclaredSymbolInfoKind.Event => Glyph.EventPublic, - DeclaredSymbolInfoKind.ExtensionMethod => Glyph.ExtensionMethodPublic, - DeclaredSymbolInfoKind.Field => Glyph.FieldPublic, - DeclaredSymbolInfoKind.Indexer => Glyph.PropertyPublic, - DeclaredSymbolInfoKind.Interface => Glyph.InterfacePublic, - DeclaredSymbolInfoKind.Method => Glyph.MethodPublic, - DeclaredSymbolInfoKind.Module => Glyph.ModulePublic, - DeclaredSymbolInfoKind.Property => Glyph.PropertyPublic, - DeclaredSymbolInfoKind.Struct => Glyph.StructurePublic, - DeclaredSymbolInfoKind.RecordStruct => Glyph.StructurePublic, - _ => Glyph.ClassPublic, - }; - - private static Glyph GetGlyph(DeclaredSymbolInfoKind kind, Accessibility accessibility) - { - // Glyphs are stored in this order: - // ClassPublic, - // ClassProtected, - // ClassPrivate, - // ClassInternal, - - var rawGlyph = GetPublicGlyph(kind); - - switch (accessibility) - { - case Accessibility.Private: - rawGlyph += (Glyph.ClassPrivate - Glyph.ClassPublic); - break; - case Accessibility.Internal: - rawGlyph += (Glyph.ClassInternal - Glyph.ClassPublic); - break; - case Accessibility.Protected: - case Accessibility.ProtectedOrInternal: - case Accessibility.ProtectedAndInternal: - rawGlyph += (Glyph.ClassProtected - Glyph.ClassPublic); - break; - } - - return rawGlyph; - } + Glyph INavigableItem.Glyph => GlyphExtensions.GetGlyph(_item.DeclaredSymbolInfo.Kind, _item.DeclaredSymbolInfo.Accessibility); ImmutableArray INavigableItem.DisplayTaggedParts => [new TaggedText( diff --git a/src/VisualStudio/CSharp/Impl/Microsoft.VisualStudio.LanguageServices.CSharp.csproj b/src/VisualStudio/CSharp/Impl/Microsoft.VisualStudio.LanguageServices.CSharp.csproj index 151a0533819f1..255175874d81e 100644 --- a/src/VisualStudio/CSharp/Impl/Microsoft.VisualStudio.LanguageServices.CSharp.csproj +++ b/src/VisualStudio/CSharp/Impl/Microsoft.VisualStudio.LanguageServices.CSharp.csproj @@ -55,7 +55,7 @@ - + true VSPackage Designer diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs new file mode 100644 index 0000000000000..4074494799c1c --- /dev/null +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -0,0 +1,131 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Composition; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using ICSharpCode.Decompiler.CSharp.Syntax; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Editor.Shared.Extensions; +using Microsoft.CodeAnalysis.FindSymbols; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; +using static Microsoft.CodeAnalysis.CSharp.FindSymbols.FindSymbolsUtilities; + +namespace Microsoft.VisualStudio.LanguageServices.CSharp.SolutionExplorer; + +[ExportLanguageService(typeof(ISolutionExplorerSymbolTreeItemProvider), LanguageNames.CSharp), Shared] +[method: ImportingConstructor] +[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] +internal sealed class CSharpSolutionExplorerSymbolTreeItemProvider() : ISolutionExplorerSymbolTreeItemProvider +{ + public async Task> GetItemsAsync( + Document document, CancellationToken cancellationToken) + { + var root = (CompilationUnitSyntax)await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + using var _ = ArrayBuilder.GetInstance(out var items); + + AddTopLevelTypes(root, items, cancellationToken); + + return items.ToImmutableAndClear(); + } + + private void AddTopLevelTypes(CompilationUnitSyntax root, ArrayBuilder items, CancellationToken cancellationToken) + { + foreach (var member in root.Members) + { + cancellationToken.ThrowIfCancellationRequested(); + + if (member is BaseNamespaceDeclarationSyntax baseNamespace) + AddTopLevelTypes(baseNamespace, items, cancellationToken); + else if (member is BaseTypeDeclarationSyntax baseType) + AddType(baseType, items, cancellationToken); + } + } + + private void AddTopLevelTypes(BaseNamespaceDeclarationSyntax baseNamespace, ArrayBuilder items, CancellationToken cancellationToken) + { + foreach (var member in baseNamespace.Members) + { + cancellationToken.ThrowIfCancellationRequested(); + + if (member is BaseNamespaceDeclarationSyntax childNamespace) + AddTopLevelTypes(childNamespace, items, cancellationToken); + else if (member is BaseTypeDeclarationSyntax baseType) + AddType(baseType, items, cancellationToken); + else if (member is DelegateDeclarationSyntax delegateType) + AddType(delegateType, items, cancellationToken); + } + } + + private void AddType(MemberDeclarationSyntax baseType, ArrayBuilder items, CancellationToken cancellationToken) + { + switch (baseType) + { + case ExtensionBlockDeclarationSyntax extensionBlock: + AddExtensionBlock(extensionBlock, items, cancellationToken); + return; + + case TypeDeclarationSyntax typeDeclaration: + AddTypeDeclaration(typeDeclaration, items, cancellationToken); + return; + + case EnumDeclarationSyntax enumDeclaration: + AddEnumDeclaration(enumDeclaration, items, cancellationToken); + return; + + case DelegateDeclarationSyntax delegateDeclaration: + AddDelegateDeclaration(delegateDeclaration, items, cancellationToken); + return; + } + } + + private void AddTypeDeclaration( + TypeDeclarationSyntax typeDeclaration, + ArrayBuilder items, + CancellationToken cancellationToken) + { + var name = GetName( + typeDeclaration.Identifier.ValueText, "<", ">", + typeDeclaration.TypeParameterList, + static typeParameterList => typeParameterList.Parameters.Select(p => p.Identifier.ValueText)); + + var accessibility = GetAccessibility(typeDeclaration, typeDeclaration.Modifiers); + var kind = typeDeclaration.Kind() switch + { + SyntaxKind.ClassDeclaration => DeclaredSymbolInfoKind.Class, + SyntaxKind.InterfaceDeclaration => DeclaredSymbolInfoKind.Interface, + SyntaxKind.StructDeclaration => DeclaredSymbolInfoKind.Struct, + SyntaxKind.RecordDeclaration => DeclaredSymbolInfoKind.Record, + SyntaxKind.RecordStructDeclaration => DeclaredSymbolInfoKind.RecordStruct, + _ => throw ExceptionUtilities.UnexpectedValue(typeDeclaration.Kind()), + }; + + var glyph = Microsoft.CodeAnalysis.GlyphExtensions.GetGlyph(kind, accessibility); + items.Add(new(name, glyph, typeDeclaration)); + } + + private static string GetName( + string baseName, + string openBrace, + string closeBrace, + TArguments? arguments, + Func> getPieces) where TArguments : SyntaxNode + { + if (arguments is null) + return baseName; + + return $"{baseName}{openBrace}{string.Join(", ", getPieces(arguments))}{closeBrace}"; + } +} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs index e4385485a2e25..35805438c5fea 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs @@ -28,6 +28,8 @@ using Microsoft.VisualStudio.Debugger.ComponentInterfaces; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.VisualStudio.Imaging.Interop; +using Microsoft.CodeAnalysis.Editor.Wpf; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -243,9 +245,15 @@ private async ValueTask TryUpdateItemsAsync( } -internal sealed class SymbolTreeItem() : BaseItem(nameof(SymbolTreeItem)) +internal sealed class SymbolTreeItem( + string name, + Glyph glyph, + SyntaxNode syntaxNode) + : BaseItem(name) { + public override ImageMoniker IconMoniker { get; } = glyph.GetImageMoniker(); + public readonly SyntaxNode SyntaxNode = syntaxNode; } internal interface ISolutionExplorerSymbolTreeItemProvider : ILanguageService diff --git a/src/Workspaces/CSharp/Portable/FindSymbols/CSharpDeclaredSymbolInfoFactoryService.cs b/src/Workspaces/CSharp/Portable/FindSymbols/CSharpDeclaredSymbolInfoFactoryService.cs index 09d3d8e4dbe6b..6b45130ad6c94 100644 --- a/src/Workspaces/CSharp/Portable/FindSymbols/CSharpDeclaredSymbolInfoFactoryService.cs +++ b/src/Workspaces/CSharp/Portable/FindSymbols/CSharpDeclaredSymbolInfoFactoryService.cs @@ -24,6 +24,8 @@ namespace Microsoft.CodeAnalysis.CSharp.FindSymbols; +using static FindSymbolsUtilities; + [ExportLanguageService(typeof(IDeclaredSymbolInfoFactoryService), LanguageNames.CSharp), Shared] internal sealed class CSharpDeclaredSymbolInfoFactoryService : AbstractDeclaredSymbolInfoFactoryService< CompilationUnitSyntax, @@ -600,50 +602,6 @@ protected override string GetContainerDisplayName(MemberDeclarationSyntax node) protected override string GetFullyQualifiedContainerName(MemberDeclarationSyntax node, string rootNamespace) => CSharpSyntaxFacts.Instance.GetDisplayName(node, DisplayNameOptions.IncludeNamespaces); - private static Accessibility GetAccessibility(SyntaxNode container, SyntaxTokenList modifiers) - { - var sawInternal = false; - foreach (var modifier in modifiers) - { - switch (modifier.Kind()) - { - case SyntaxKind.PublicKeyword: return Accessibility.Public; - case SyntaxKind.PrivateKeyword: return Accessibility.Private; - case SyntaxKind.ProtectedKeyword: return Accessibility.Protected; - case SyntaxKind.InternalKeyword: - sawInternal = true; - continue; - } - } - - if (sawInternal) - return Accessibility.Internal; - - // No accessibility modifiers: - switch (container.Kind()) - { - case SyntaxKind.ClassDeclaration: - case SyntaxKind.RecordDeclaration: - case SyntaxKind.StructDeclaration: - case SyntaxKind.RecordStructDeclaration: - // Anything without modifiers is private if it's in a class/struct declaration. - return Accessibility.Private; - case SyntaxKind.InterfaceDeclaration: - // Anything without modifiers is public if it's in an interface declaration. - return Accessibility.Public; - case SyntaxKind.CompilationUnit: - // Things are private by default in script - if (((CSharpParseOptions)container.SyntaxTree.Options).Kind == SourceCodeKind.Script) - return Accessibility.Private; - - return Accessibility.Internal; - - default: - // Otherwise it's internal - return Accessibility.Internal; - } - } - private static string GetTypeName(TypeSyntax type) { if (type is SimpleNameSyntax simpleName) diff --git a/src/Workspaces/CSharp/Portable/FindSymbols/FindSymbolsUtilities.cs b/src/Workspaces/CSharp/Portable/FindSymbols/FindSymbolsUtilities.cs new file mode 100644 index 0000000000000..a235057937a59 --- /dev/null +++ b/src/Workspaces/CSharp/Portable/FindSymbols/FindSymbolsUtilities.cs @@ -0,0 +1,59 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Microsoft.CodeAnalysis.CSharp.FindSymbols; + +internal static class FindSymbolsUtilities +{ + public static Accessibility GetAccessibility(SyntaxNode container, SyntaxTokenList modifiers) + { + var sawInternal = false; + foreach (var modifier in modifiers) + { + switch (modifier.Kind()) + { + case SyntaxKind.PublicKeyword: return Accessibility.Public; + case SyntaxKind.PrivateKeyword: return Accessibility.Private; + case SyntaxKind.ProtectedKeyword: return Accessibility.Protected; + case SyntaxKind.InternalKeyword: + sawInternal = true; + continue; + } + } + + if (sawInternal) + return Accessibility.Internal; + + // No accessibility modifiers: + switch (container.Kind()) + { + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ExtensionBlockDeclaration: + case SyntaxKind.RecordDeclaration: + case SyntaxKind.StructDeclaration: + case SyntaxKind.RecordStructDeclaration: + // Anything without modifiers is private if it's in a class/struct declaration. + return Accessibility.Private; + case SyntaxKind.InterfaceDeclaration: + // Anything without modifiers is public if it's in an interface declaration. + return Accessibility.Public; + case SyntaxKind.CompilationUnit: + // Things are private by default in script + if (((CSharpParseOptions)container.SyntaxTree.Options).Kind == SourceCodeKind.Script) + return Accessibility.Private; + + return Accessibility.Internal; + + default: + // Otherwise it's internal + return Accessibility.Internal; + } + } +} From 0654d4e55afed8e9096f620291edae24e62c0614 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 17:14:25 +0200 Subject: [PATCH 024/353] IN progress --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 73 +++++++++++++++---- 1 file changed, 58 insertions(+), 15 deletions(-) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index 4074494799c1c..053bb02bb884f 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -7,14 +7,11 @@ using System.Collections.Immutable; using System.Composition; using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; -using ICSharpCode.Decompiler.CSharp.Syntax; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.PooledObjects; @@ -71,35 +68,63 @@ private void AddTopLevelTypes(BaseNamespaceDeclarationSyntax baseNamespace, Arra private void AddType(MemberDeclarationSyntax baseType, ArrayBuilder items, CancellationToken cancellationToken) { + cancellationToken.ThrowIfCancellationRequested(); switch (baseType) { case ExtensionBlockDeclarationSyntax extensionBlock: - AddExtensionBlock(extensionBlock, items, cancellationToken); + AddExtensionBlock(extensionBlock, items); return; case TypeDeclarationSyntax typeDeclaration: - AddTypeDeclaration(typeDeclaration, items, cancellationToken); + AddTypeDeclaration(typeDeclaration, items); return; case EnumDeclarationSyntax enumDeclaration: - AddEnumDeclaration(enumDeclaration, items, cancellationToken); + AddEnumDeclaration(enumDeclaration, items); return; case DelegateDeclarationSyntax delegateDeclaration: - AddDelegateDeclaration(delegateDeclaration, items, cancellationToken); + AddDelegateDeclaration(delegateDeclaration, items); return; } } - private void AddTypeDeclaration( + private static void AddEnumDeclaration(EnumDeclarationSyntax enumDeclaration, ArrayBuilder items) + { + var glyph = Microsoft.CodeAnalysis.GlyphExtensions.GetGlyph( + DeclaredSymbolInfoKind.Enum, GetAccessibility(enumDeclaration, enumDeclaration.Modifiers)); + + items.Add(new(enumDeclaration.Identifier.ValueText, glyph, enumDeclaration)); + } + + private static void AddExtensionBlock( + ExtensionBlockDeclarationSyntax extensionBlock, + ArrayBuilder items) + { + var baseName = WithTypeParameterList("extension", extensionBlock.TypeParameterList); + var name = WithParameterList(baseName, extensionBlock.ParameterList); + + items.Add(new(name, Glyph.ClassPublic, extensionBlock)); + } + + private static void AddDelegateDeclaration( + DelegateDeclarationSyntax delegateDeclaration, + ArrayBuilder items) + { + var baseName = WithTypeParameterList(delegateDeclaration.Identifier.ValueText, delegateDeclaration.TypeParameterList); + var name = WithParameterList(baseName, delegateDeclaration.ParameterList); + + var glyph = Microsoft.CodeAnalysis.GlyphExtensions.GetGlyph( + DeclaredSymbolInfoKind.Delegate, GetAccessibility(delegateDeclaration, delegateDeclaration.Modifiers)); + + items.Add(new(name, glyph, delegateDeclaration)); + } + + private static void AddTypeDeclaration( TypeDeclarationSyntax typeDeclaration, - ArrayBuilder items, - CancellationToken cancellationToken) + ArrayBuilder items) { - var name = GetName( - typeDeclaration.Identifier.ValueText, "<", ">", - typeDeclaration.TypeParameterList, - static typeParameterList => typeParameterList.Parameters.Select(p => p.Identifier.ValueText)); + var name = WithTypeParameterList(typeDeclaration.Identifier.ValueText, typeDeclaration.TypeParameterList); var accessibility = GetAccessibility(typeDeclaration, typeDeclaration.Modifiers); var kind = typeDeclaration.Kind() switch @@ -116,7 +141,7 @@ private void AddTypeDeclaration( items.Add(new(name, glyph, typeDeclaration)); } - private static string GetName( + private static string BuildText( string baseName, string openBrace, string closeBrace, @@ -128,4 +153,22 @@ private static string GetName( return $"{baseName}{openBrace}{string.Join(", ", getPieces(arguments))}{closeBrace}"; } + + private static string WithTypeParameterList( + string baseText, + TypeParameterListSyntax? typeParameterList) + { + return BuildText( + baseText, "<", ">", typeParameterList, + static typeParameterList => typeParameterList.Parameters.Select(p => p.Identifier.ValueText)); + } + + private static string WithParameterList( + string baseText, + ParameterListSyntax? parameterList) + { + return BuildText( + baseText, "(", ")", parameterList, + static parameterList => parameterList.Parameters.Select(p => GetDisplayText(p.Type))); + } } From 1d60d6217aedbe8515176d9c13c0f40450863880 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 17:45:40 +0200 Subject: [PATCH 025/353] IN progress --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 178 +++++++++++++++--- .../Extensions/StringBuilderExtensions.cs | 18 ++ 2 files changed, 165 insertions(+), 31 deletions(-) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index 053bb02bb884f..0613d656a20aa 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -6,7 +6,9 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Composition; +using System.Diagnostics; using System.Linq; +using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; @@ -38,7 +40,7 @@ public async Task> GetItemsAsync( return items.ToImmutableAndClear(); } - private void AddTopLevelTypes(CompilationUnitSyntax root, ArrayBuilder items, CancellationToken cancellationToken) + private static void AddTopLevelTypes(CompilationUnitSyntax root, ArrayBuilder items, CancellationToken cancellationToken) { foreach (var member in root.Members) { @@ -51,7 +53,7 @@ private void AddTopLevelTypes(CompilationUnitSyntax root, ArrayBuilder items, CancellationToken cancellationToken) + private static void AddTopLevelTypes(BaseNamespaceDeclarationSyntax baseNamespace, ArrayBuilder items, CancellationToken cancellationToken) { foreach (var member in baseNamespace.Members) { @@ -66,7 +68,7 @@ private void AddTopLevelTypes(BaseNamespaceDeclarationSyntax baseNamespace, Arra } } - private void AddType(MemberDeclarationSyntax baseType, ArrayBuilder items, CancellationToken cancellationToken) + private static void AddType(MemberDeclarationSyntax baseType, ArrayBuilder items, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); switch (baseType) @@ -91,7 +93,7 @@ private void AddType(MemberDeclarationSyntax baseType, ArrayBuilder items) { - var glyph = Microsoft.CodeAnalysis.GlyphExtensions.GetGlyph( + var glyph = GlyphExtensions.GetGlyph( DeclaredSymbolInfoKind.Enum, GetAccessibility(enumDeclaration, enumDeclaration.Modifiers)); items.Add(new(enumDeclaration.Identifier.ValueText, glyph, enumDeclaration)); @@ -101,30 +103,39 @@ private static void AddExtensionBlock( ExtensionBlockDeclarationSyntax extensionBlock, ArrayBuilder items) { - var baseName = WithTypeParameterList("extension", extensionBlock.TypeParameterList); - var name = WithParameterList(baseName, extensionBlock.ParameterList); + using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); - items.Add(new(name, Glyph.ClassPublic, extensionBlock)); + nameBuilder.Append("extension"); + AppendTypeParameterList(nameBuilder, extensionBlock.TypeParameterList); + AppendParameterList(nameBuilder, extensionBlock.ParameterList); + + items.Add(new(nameBuilder.ToString(), Glyph.ClassPublic, extensionBlock)); } private static void AddDelegateDeclaration( DelegateDeclarationSyntax delegateDeclaration, ArrayBuilder items) { - var baseName = WithTypeParameterList(delegateDeclaration.Identifier.ValueText, delegateDeclaration.TypeParameterList); - var name = WithParameterList(baseName, delegateDeclaration.ParameterList); + using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); + + nameBuilder.Append(delegateDeclaration.Identifier.ValueText); + AppendTypeParameterList(nameBuilder, delegateDeclaration.TypeParameterList); + AppendParameterList(nameBuilder, delegateDeclaration.ParameterList); - var glyph = Microsoft.CodeAnalysis.GlyphExtensions.GetGlyph( + var glyph = GlyphExtensions.GetGlyph( DeclaredSymbolInfoKind.Delegate, GetAccessibility(delegateDeclaration, delegateDeclaration.Modifiers)); - items.Add(new(name, glyph, delegateDeclaration)); + items.Add(new(nameBuilder.ToString(), glyph, delegateDeclaration)); } private static void AddTypeDeclaration( TypeDeclarationSyntax typeDeclaration, ArrayBuilder items) { - var name = WithTypeParameterList(typeDeclaration.Identifier.ValueText, typeDeclaration.TypeParameterList); + using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); + + nameBuilder.Append(typeDeclaration.Identifier.ValueText); + AppendTypeParameterList(nameBuilder, typeDeclaration.TypeParameterList); var accessibility = GetAccessibility(typeDeclaration, typeDeclaration.Modifiers); var kind = typeDeclaration.Kind() switch @@ -137,38 +148,143 @@ private static void AddTypeDeclaration( _ => throw ExceptionUtilities.UnexpectedValue(typeDeclaration.Kind()), }; - var glyph = Microsoft.CodeAnalysis.GlyphExtensions.GetGlyph(kind, accessibility); - items.Add(new(name, glyph, typeDeclaration)); + var glyph = GlyphExtensions.GetGlyph(kind, accessibility); + items.Add(new(nameBuilder.ToString(), glyph, typeDeclaration)); } - private static string BuildText( - string baseName, + private static void AppendCommaSeparatedList( + StringBuilder builder, string openBrace, string closeBrace, - TArguments? arguments, - Func> getPieces) where TArguments : SyntaxNode + TArgumentList? argumentList, + Func> getArguments, + Action append) + where TArgumentList : SyntaxNode + where TArgument : SyntaxNode { - if (arguments is null) - return baseName; + if (argumentList is null) + return; - return $"{baseName}{openBrace}{string.Join(", ", getPieces(arguments))}{closeBrace}"; + builder.Append(openBrace); + builder.AppendJoinedValues(", ", getArguments(argumentList), append); + builder.Append(closeBrace); } - private static string WithTypeParameterList( - string baseText, + private static void AppendTypeParameterList( + StringBuilder builder, TypeParameterListSyntax? typeParameterList) { - return BuildText( - baseText, "<", ">", typeParameterList, - static typeParameterList => typeParameterList.Parameters.Select(p => p.Identifier.ValueText)); + AppendCommaSeparatedList( + builder, "<", ">", typeParameterList, + static typeParameterList => typeParameterList.Parameters, + static (parameter, builder) => builder.Append(parameter.Identifier.ValueText)); } - private static string WithParameterList( - string baseText, + private static void AppendParameterList( + StringBuilder builder, ParameterListSyntax? parameterList) { - return BuildText( - baseText, "(", ")", parameterList, - static parameterList => parameterList.Parameters.Select(p => GetDisplayText(p.Type))); + AppendCommaSeparatedList( + builder, "(", ")", parameterList, + static parameterList => parameterList.Parameters, + static (parameter, builder) => BuildDisplayText(builder, parameter.Type)); + } + + private static string GetDisplayText(TypeSyntax? type) + { + using var _ = PooledStringBuilder.GetInstance(out var builder); + BuildDisplayText(builder, type); + return builder.ToString(); + } + + private static void BuildDisplayText(StringBuilder builder, TypeSyntax? type) + { + if (type is null) + return; + + if (type is ArrayTypeSyntax arrayType) + { + BuildDisplayText(builder, arrayType.ElementType); + builder.Append('['); + builder.Append(',', arrayType.RankSpecifiers.Count); + builder.Append(']'); + } + else if (type is PointerTypeSyntax pointerType) + { + BuildDisplayText(builder, pointerType.ElementType); + builder.Append('*'); + } + else if (type is NullableTypeSyntax nullableType) + { + BuildDisplayText(builder, nullableType.ElementType); + builder.Append('?'); + } + else if (type is TupleTypeSyntax tupleType) + { + builder.Append('('); + builder.AppendJoinedValues(", ", tupleType.Elements, static (tupleElement, builder) => BuildDisplayText(builder, tupleElement)); + builder.Append(')'); + } + else if (type is RefTypeSyntax refType) + { + builder.Append("ref "); + BuildDisplayText(builder, refType.Type); + } + else if (type is ScopedTypeSyntax scopedType) + { + builder.Append("scoped "); + BuildDisplayText(builder, scopedType.Type); + } + else if (type is PredefinedTypeSyntax predefinedType) + { + builder.Append(predefinedType.ToString()); + } + else if (type is FunctionPointerTypeSyntax functionPointerType) + { + builder.Append("delegate"); + builder.Append("*("); + builder.AppendJoinedValues( + ", ", functionPointerType.ParameterList.Parameters, + static (parameter, builder) => BuildDisplayText(builder, parameter.Type)); + builder.Append(')'); + } + else if (type is OmittedTypeArgumentSyntax) + { + // nothing to do here. + } + else if (type is QualifiedNameSyntax qualifiedName) + { + BuildDisplayText(builder, qualifiedName.Right); + } + else if (type is AliasQualifiedNameSyntax aliasQualifiedName) + { + BuildDisplayText(builder, aliasQualifiedName.Name); + } + else if (type is IdentifierNameSyntax identifierName) + { + builder.Append(identifierName.Identifier.ValueText); + } + else if (type is GenericNameSyntax genericName) + { + builder.Append(genericName.Identifier.ValueText); + builder.Append('<'); + builder.AppendJoinedValues( + ", ", genericName.TypeArgumentList.Arguments, static (type, builder) => BuildDisplayText(builder, type)); + builder.Append('>'); + } + else + { + Debug.Fail("Unhandled type: " + type.GetType().FullName); + } + } + + private static void BuildDisplayText(StringBuilder builder, TupleElementSyntax tupleElement) + { + BuildDisplayText(builder, tupleElement.Type); + if (tupleElement.Identifier != default) + { + builder.Append(' '); + builder.Append(tupleElement.Identifier.ValueText); + } } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/StringBuilderExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/StringBuilderExtensions.cs index 05735ef7839b7..052ebabcda671 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/StringBuilderExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/StringBuilderExtensions.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections.Generic; using System.Collections.Immutable; using System.Text; @@ -10,6 +11,23 @@ namespace Microsoft.CodeAnalysis.Shared.Extensions; internal static class StringBuilderExtensions { + public static StringBuilder AppendJoinedValues(this StringBuilder builder, string separator, IEnumerable values, Action append) + { + var first = true; + foreach (var value in values) + { + if (!first) + { + builder.Append(separator); + } + + first = false; + append(value, builder); + } + + return builder; + } + public static StringBuilder AppendJoinedValues(this StringBuilder builder, string separator, ImmutableArray values, Action append) { var first = true; From 40f6e4bd97e38a999305958fd1a173465d01c4a9 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 17:56:39 +0200 Subject: [PATCH 026/353] IN progress --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 73 ++++++++++--------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index 0613d656a20aa..138c95eefae26 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -158,15 +158,28 @@ private static void AppendCommaSeparatedList( string closeBrace, TArgumentList? argumentList, Func> getArguments, - Action append) + Action append, + string separator = ", ") where TArgumentList : SyntaxNode where TArgument : SyntaxNode { if (argumentList is null) return; + AppendCommaSeparatedList(builder, openBrace, closeBrace, getArguments(argumentList), append, separator); + } + + private static void AppendCommaSeparatedList( + StringBuilder builder, + string openBrace, + string closeBrace, + IEnumerable arguments, + Action append, + string separator = ", ") + where TArgument : SyntaxNode + { builder.Append(openBrace); - builder.AppendJoinedValues(", ", getArguments(argumentList), append); + builder.AppendJoinedValues(separator, arguments, append); builder.Append(closeBrace); } @@ -187,53 +200,45 @@ private static void AppendParameterList( AppendCommaSeparatedList( builder, "(", ")", parameterList, static parameterList => parameterList.Parameters, - static (parameter, builder) => BuildDisplayText(builder, parameter.Type)); - } - - private static string GetDisplayText(TypeSyntax? type) - { - using var _ = PooledStringBuilder.GetInstance(out var builder); - BuildDisplayText(builder, type); - return builder.ToString(); + static (parameter, builder) => BuildDisplayText(parameter.Type, builder)); } - private static void BuildDisplayText(StringBuilder builder, TypeSyntax? type) + private static void BuildDisplayText(TypeSyntax? type, StringBuilder builder) { if (type is null) return; if (type is ArrayTypeSyntax arrayType) { - BuildDisplayText(builder, arrayType.ElementType); - builder.Append('['); - builder.Append(',', arrayType.RankSpecifiers.Count); - builder.Append(']'); + BuildDisplayText(arrayType.ElementType, builder); + AppendCommaSeparatedList( + builder, "[", "]", arrayType.RankSpecifiers, + static (_, _) => { }, ","); } else if (type is PointerTypeSyntax pointerType) { - BuildDisplayText(builder, pointerType.ElementType); + BuildDisplayText(pointerType.ElementType, builder); builder.Append('*'); } else if (type is NullableTypeSyntax nullableType) { - BuildDisplayText(builder, nullableType.ElementType); + BuildDisplayText(nullableType.ElementType, builder); builder.Append('?'); } else if (type is TupleTypeSyntax tupleType) { - builder.Append('('); - builder.AppendJoinedValues(", ", tupleType.Elements, static (tupleElement, builder) => BuildDisplayText(builder, tupleElement)); - builder.Append(')'); + AppendCommaSeparatedList( + builder, "(", ")", tupleType.Elements, BuildDisplayText); } else if (type is RefTypeSyntax refType) { builder.Append("ref "); - BuildDisplayText(builder, refType.Type); + BuildDisplayText(refType.Type, builder); } else if (type is ScopedTypeSyntax scopedType) { builder.Append("scoped "); - BuildDisplayText(builder, scopedType.Type); + BuildDisplayText(scopedType.Type, builder); } else if (type is PredefinedTypeSyntax predefinedType) { @@ -241,12 +246,10 @@ private static void BuildDisplayText(StringBuilder builder, TypeSyntax? type) } else if (type is FunctionPointerTypeSyntax functionPointerType) { - builder.Append("delegate"); - builder.Append("*("); - builder.AppendJoinedValues( - ", ", functionPointerType.ParameterList.Parameters, - static (parameter, builder) => BuildDisplayText(builder, parameter.Type)); - builder.Append(')'); + builder.Append("delegate*"); + AppendCommaSeparatedList( + builder, "(", ")", functionPointerType.ParameterList.Parameters, + static (parameter, builder) => BuildDisplayText(parameter.Type, builder)); } else if (type is OmittedTypeArgumentSyntax) { @@ -254,11 +257,11 @@ private static void BuildDisplayText(StringBuilder builder, TypeSyntax? type) } else if (type is QualifiedNameSyntax qualifiedName) { - BuildDisplayText(builder, qualifiedName.Right); + BuildDisplayText(qualifiedName.Right, builder); } else if (type is AliasQualifiedNameSyntax aliasQualifiedName) { - BuildDisplayText(builder, aliasQualifiedName.Name); + BuildDisplayText(aliasQualifiedName.Name, builder); } else if (type is IdentifierNameSyntax identifierName) { @@ -267,10 +270,8 @@ private static void BuildDisplayText(StringBuilder builder, TypeSyntax? type) else if (type is GenericNameSyntax genericName) { builder.Append(genericName.Identifier.ValueText); - builder.Append('<'); - builder.AppendJoinedValues( - ", ", genericName.TypeArgumentList.Arguments, static (type, builder) => BuildDisplayText(builder, type)); - builder.Append('>'); + AppendCommaSeparatedList( + builder, "<", ">", genericName.TypeArgumentList.Arguments, BuildDisplayText); } else { @@ -278,9 +279,9 @@ private static void BuildDisplayText(StringBuilder builder, TypeSyntax? type) } } - private static void BuildDisplayText(StringBuilder builder, TupleElementSyntax tupleElement) + private static void BuildDisplayText(TupleElementSyntax tupleElement, StringBuilder builder) { - BuildDisplayText(builder, tupleElement.Type); + BuildDisplayText(tupleElement.Type, builder); if (tupleElement.Identifier != default) { builder.Append(' '); From a9c4c1ae34033519b50c2dd7133ac354cd4b736d Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 18:05:37 +0200 Subject: [PATCH 027/353] Add expandability bool --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 24 +++++++++++++++---- .../SymbolTreeItemSourceProvider.cs | 3 ++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index 138c95eefae26..7d74f3c09b55e 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -96,7 +96,11 @@ private static void AddEnumDeclaration(EnumDeclarationSyntax enumDeclaration, Ar var glyph = GlyphExtensions.GetGlyph( DeclaredSymbolInfoKind.Enum, GetAccessibility(enumDeclaration, enumDeclaration.Modifiers)); - items.Add(new(enumDeclaration.Identifier.ValueText, glyph, enumDeclaration)); + items.Add(new( + enumDeclaration.Identifier.ValueText, + isExpandable: enumDeclaration.Members.Count > 0, + glyph, + enumDeclaration)); } private static void AddExtensionBlock( @@ -109,7 +113,11 @@ private static void AddExtensionBlock( AppendTypeParameterList(nameBuilder, extensionBlock.TypeParameterList); AppendParameterList(nameBuilder, extensionBlock.ParameterList); - items.Add(new(nameBuilder.ToString(), Glyph.ClassPublic, extensionBlock)); + items.Add(new( + nameBuilder.ToString(), + isExpandable: extensionBlock.Members.Count > 0, + Glyph.ClassPublic, + extensionBlock)); } private static void AddDelegateDeclaration( @@ -125,7 +133,11 @@ private static void AddDelegateDeclaration( var glyph = GlyphExtensions.GetGlyph( DeclaredSymbolInfoKind.Delegate, GetAccessibility(delegateDeclaration, delegateDeclaration.Modifiers)); - items.Add(new(nameBuilder.ToString(), glyph, delegateDeclaration)); + items.Add(new( + nameBuilder.ToString(), + isExpandable: false, + glyph, + delegateDeclaration)); } private static void AddTypeDeclaration( @@ -149,7 +161,11 @@ private static void AddTypeDeclaration( }; var glyph = GlyphExtensions.GetGlyph(kind, accessibility); - items.Add(new(nameBuilder.ToString(), glyph, typeDeclaration)); + items.Add(new( + nameBuilder.ToString(), + isExpandable: typeDeclaration.Members.Count > 0, + glyph, + typeDeclaration)); } private static void AppendCommaSeparatedList( diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs index 35805438c5fea..603dfba15e317 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs @@ -247,9 +247,10 @@ private async ValueTask TryUpdateItemsAsync( internal sealed class SymbolTreeItem( string name, + bool isExpandable, Glyph glyph, SyntaxNode syntaxNode) - : BaseItem(name) + : BaseItem(name, isExpandable) { public override ImageMoniker IconMoniker { get; } = glyph.GetImageMoniker(); From e4ccfb8865cea2ef426978a56023b2c83069a8b2 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 18:06:38 +0200 Subject: [PATCH 028/353] Add return type --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index 7d74f3c09b55e..94c73c59c26c8 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -130,6 +130,9 @@ private static void AddDelegateDeclaration( AppendTypeParameterList(nameBuilder, delegateDeclaration.TypeParameterList); AppendParameterList(nameBuilder, delegateDeclaration.ParameterList); + nameBuilder.Append(" : "); + AppendType(delegateDeclaration.ReturnType, nameBuilder); + var glyph = GlyphExtensions.GetGlyph( DeclaredSymbolInfoKind.Delegate, GetAccessibility(delegateDeclaration, delegateDeclaration.Modifiers)); @@ -216,29 +219,29 @@ private static void AppendParameterList( AppendCommaSeparatedList( builder, "(", ")", parameterList, static parameterList => parameterList.Parameters, - static (parameter, builder) => BuildDisplayText(parameter.Type, builder)); + static (parameter, builder) => AppendType(parameter.Type, builder)); } - private static void BuildDisplayText(TypeSyntax? type, StringBuilder builder) + private static void AppendType(TypeSyntax? type, StringBuilder builder) { if (type is null) return; if (type is ArrayTypeSyntax arrayType) { - BuildDisplayText(arrayType.ElementType, builder); + AppendType(arrayType.ElementType, builder); AppendCommaSeparatedList( builder, "[", "]", arrayType.RankSpecifiers, static (_, _) => { }, ","); } else if (type is PointerTypeSyntax pointerType) { - BuildDisplayText(pointerType.ElementType, builder); + AppendType(pointerType.ElementType, builder); builder.Append('*'); } else if (type is NullableTypeSyntax nullableType) { - BuildDisplayText(nullableType.ElementType, builder); + AppendType(nullableType.ElementType, builder); builder.Append('?'); } else if (type is TupleTypeSyntax tupleType) @@ -249,12 +252,12 @@ private static void BuildDisplayText(TypeSyntax? type, StringBuilder builder) else if (type is RefTypeSyntax refType) { builder.Append("ref "); - BuildDisplayText(refType.Type, builder); + AppendType(refType.Type, builder); } else if (type is ScopedTypeSyntax scopedType) { builder.Append("scoped "); - BuildDisplayText(scopedType.Type, builder); + AppendType(scopedType.Type, builder); } else if (type is PredefinedTypeSyntax predefinedType) { @@ -265,7 +268,7 @@ private static void BuildDisplayText(TypeSyntax? type, StringBuilder builder) builder.Append("delegate*"); AppendCommaSeparatedList( builder, "(", ")", functionPointerType.ParameterList.Parameters, - static (parameter, builder) => BuildDisplayText(parameter.Type, builder)); + static (parameter, builder) => AppendType(parameter.Type, builder)); } else if (type is OmittedTypeArgumentSyntax) { @@ -273,11 +276,11 @@ private static void BuildDisplayText(TypeSyntax? type, StringBuilder builder) } else if (type is QualifiedNameSyntax qualifiedName) { - BuildDisplayText(qualifiedName.Right, builder); + AppendType(qualifiedName.Right, builder); } else if (type is AliasQualifiedNameSyntax aliasQualifiedName) { - BuildDisplayText(aliasQualifiedName.Name, builder); + AppendType(aliasQualifiedName.Name, builder); } else if (type is IdentifierNameSyntax identifierName) { @@ -287,7 +290,7 @@ private static void BuildDisplayText(TypeSyntax? type, StringBuilder builder) { builder.Append(genericName.Identifier.ValueText); AppendCommaSeparatedList( - builder, "<", ">", genericName.TypeArgumentList.Arguments, BuildDisplayText); + builder, "<", ">", genericName.TypeArgumentList.Arguments, AppendType); } else { @@ -297,7 +300,7 @@ private static void BuildDisplayText(TypeSyntax? type, StringBuilder builder) private static void BuildDisplayText(TupleElementSyntax tupleElement, StringBuilder builder) { - BuildDisplayText(tupleElement.Type, builder); + AppendType(tupleElement.Type, builder); if (tupleElement.Identifier != default) { builder.Append(' '); From 576b71e082461b15fe8f160841f9baf9c30da7c6 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 18:12:00 +0200 Subject: [PATCH 029/353] Simplify --- .../CSharpSolutionExplorerSymbolTreeItemProvider.cs | 4 ---- src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs | 5 ++--- .../SymbolTree/SymbolTreeItemSourceProvider.cs | 3 +-- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index 94c73c59c26c8..c86377be21864 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -98,7 +98,6 @@ private static void AddEnumDeclaration(EnumDeclarationSyntax enumDeclaration, Ar items.Add(new( enumDeclaration.Identifier.ValueText, - isExpandable: enumDeclaration.Members.Count > 0, glyph, enumDeclaration)); } @@ -115,7 +114,6 @@ private static void AddExtensionBlock( items.Add(new( nameBuilder.ToString(), - isExpandable: extensionBlock.Members.Count > 0, Glyph.ClassPublic, extensionBlock)); } @@ -138,7 +136,6 @@ private static void AddDelegateDeclaration( items.Add(new( nameBuilder.ToString(), - isExpandable: false, glyph, delegateDeclaration)); } @@ -166,7 +163,6 @@ private static void AddTypeDeclaration( var glyph = GlyphExtensions.GetGlyph(kind, accessibility); items.Add(new( nameBuilder.ToString(), - isExpandable: typeDeclaration.Members.Count > 0, glyph, typeDeclaration)); } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs index 16572274337d1..ae051779293c0 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs @@ -35,15 +35,14 @@ public virtual event PropertyChangedEventHandler PropertyChanged { add { } remov protected readonly string Name; - public BaseItem(string name, bool isExpandable = true) + public BaseItem(string name) { Name = name; - IsExpandable = isExpandable; } public IEnumerable Children => []; - public bool IsExpandable { get; } + public bool IsExpandable => true; public FontStyle FontStyle => FontStyles.Normal; public FontWeight FontWeight => FontWeights.Normal; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs index 603dfba15e317..35805438c5fea 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs @@ -247,10 +247,9 @@ private async ValueTask TryUpdateItemsAsync( internal sealed class SymbolTreeItem( string name, - bool isExpandable, Glyph glyph, SyntaxNode syntaxNode) - : BaseItem(name, isExpandable) + : BaseItem(name) { public override ImageMoniker IconMoniker { get; } = glyph.GetImageMoniker(); From 9e3013731bb9659387450581b4f19ffd00d8d904 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 18:42:22 +0200 Subject: [PATCH 030/353] Mostly working --- .../Core/Impl/SolutionExplorer/BaseItem.cs | 5 +- .../SymbolTreeItemSourceProvider.cs | 50 ++++++++++++++++++- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs index ae051779293c0..e1b9cdfacaa2c 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs @@ -35,9 +35,10 @@ public virtual event PropertyChangedEventHandler PropertyChanged { add { } remov protected readonly string Name; - public BaseItem(string name) + public BaseItem(string name, bool canPreview = false) { Name = name; + CanPreview = canPreview; } public IEnumerable Children => []; @@ -103,7 +104,7 @@ public BaseItem(string name) return null; } - public bool CanPreview => false; + public bool CanPreview { get; } public virtual IInvocationController? InvocationController => null; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs index 35805438c5fea..6a1f53510c208 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs @@ -30,6 +30,9 @@ using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.VisualStudio.Imaging.Interop; using Microsoft.CodeAnalysis.Editor.Wpf; +using System.Linq; +using Microsoft.CodeAnalysis.Navigation; +using Microsoft.Internal.VisualStudio.Shell.Interop; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -45,6 +48,8 @@ internal sealed class SymbolTreeItemSourceProvider : AttachedCollectionSourcePro private readonly ConcurrentSet> _weakCollectionSources = []; private readonly AsyncBatchingWorkQueue _updateSourcesQueue; + private readonly CancellationSeries _cancellationSeries; + private readonly IAsynchronousOperationListener _listener; // private readonly IAnalyzersCommandHandler _commandHandler = commandHandler; @@ -61,12 +66,14 @@ IAsynchronousOperationListenerProvider listenerProvider { _threadingContext = threadingContext; _workspace = workspace; + _cancellationSeries = new(_threadingContext.DisposalToken); + _listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); _updateSourcesQueue = new AsyncBatchingWorkQueue( DelayTimeSpan.Medium, UpdateCollectionSourcesAsync, EqualityComparer.Default, - listenerProvider.GetListener(FeatureAttribute.SolutionExplorer), + _listener, _threadingContext.DisposalToken); _workspace.RegisterWorkspaceChangedHandler( @@ -78,6 +85,25 @@ IAsynchronousOperationListenerProvider listenerProvider options: new WorkspaceEventOptions(RequiresMainThread: false)); } + public void NavigateTo(SymbolTreeItem item, bool preview) + { + // Cancel any in flight navigation and kick off a new one. + var cancellationToken = _cancellationSeries.CreateNext(); + var navigationService = _workspace.Services.GetRequiredService(); + + var token = _listener.BeginAsyncOperation(nameof(NavigateTo)); + navigationService.TryNavigateToPositionAsync( + _threadingContext, + _workspace, + item.DocumentId, + item.SyntaxNode.SpanStart, + virtualSpace: 0, + // May be calling this on stale data. Allow the position to be invalid + allowInvalidPosition: true, + new NavigationOptions(PreferProvisionalTab: preview), + cancellationToken).ReportNonFatalErrorUnlessCancelledAsync(cancellationToken).CompletesAsyncOperation(token); + } + private async ValueTask UpdateCollectionSourcesAsync( ImmutableSegmentedList documentIds, CancellationToken cancellationToken) { @@ -208,6 +234,11 @@ private async ValueTask TryUpdateItemsAsync( return false; var items = await service.GetItemsAsync(document, cancellationToken).ConfigureAwait(false); + foreach (var item in items) + { + item.Provider = _provider; + item.DocumentId = document.Id; + } using (_symbolTreeItems.GetBulkOperation()) { @@ -249,11 +280,26 @@ internal sealed class SymbolTreeItem( string name, Glyph glyph, SyntaxNode syntaxNode) - : BaseItem(name) + : BaseItem(name, canPreview: true), + IInvocationController { + public SymbolTreeItemSourceProvider Provider = null!; + public DocumentId DocumentId = null!; + public override ImageMoniker IconMoniker { get; } = glyph.GetImageMoniker(); public readonly SyntaxNode SyntaxNode = syntaxNode; + + public override IInvocationController? InvocationController => this; + + public bool Invoke(IEnumerable items, InputSource inputSource, bool preview) + { + if (items.FirstOrDefault() is not SymbolTreeItem item) + return false; + + Provider.NavigateTo(item, preview); + return true; + } } internal interface ISolutionExplorerSymbolTreeItemProvider : ILanguageService From 40a3b3c353b25cd1ef645850e5f3dbcf1f3773d2 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 18:48:10 +0200 Subject: [PATCH 031/353] Break into individual files --- ...ISolutionExplorerSymbolTreeItemProvider.cs | 16 +++++++ .../SymbolTree/SymbolTreeItem.cs | 39 +++++++++++++++++ .../SymbolTreeItemSourceProvider.cs | 42 +++---------------- 3 files changed, 60 insertions(+), 37 deletions(-) create mode 100644 src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs create mode 100644 src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs new file mode 100644 index 0000000000000..73e16b05c43f8 --- /dev/null +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Host; + +namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; + +internal interface ISolutionExplorerSymbolTreeItemProvider : ILanguageService +{ + Task> GetItemsAsync(Document document, CancellationToken cancellationToken); +} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs new file mode 100644 index 0000000000000..b8750323282ba --- /dev/null +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using Microsoft.CodeAnalysis; +using Microsoft.Internal.VisualStudio.PlatformUI; +using Roslyn.Utilities; +using Microsoft.VisualStudio.Imaging.Interop; +using Microsoft.CodeAnalysis.Editor.Wpf; +using System.Linq; + +namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; + +internal sealed class SymbolTreeItem( + string name, + Glyph glyph, + SyntaxNode syntaxNode) + : BaseItem(name, canPreview: true), + IInvocationController +{ + public SymbolTreeItemSourceProvider Provider = null!; + public DocumentId DocumentId = null!; + + public override ImageMoniker IconMoniker { get; } = glyph.GetImageMoniker(); + + public readonly SyntaxNode SyntaxNode = syntaxNode; + + public override IInvocationController? InvocationController => this; + + public bool Invoke(IEnumerable items, InputSource inputSource, bool preview) + { + if (items.FirstOrDefault() is not SymbolTreeItem item) + return false; + + Provider.NavigateTo(item, preview); + return true; + } +} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs index 6a1f53510c208..47857490f5c98 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs @@ -28,9 +28,6 @@ using Microsoft.VisualStudio.Debugger.ComponentInterfaces; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Shared.Extensions; -using Microsoft.VisualStudio.Imaging.Interop; -using Microsoft.CodeAnalysis.Editor.Wpf; -using System.Linq; using Microsoft.CodeAnalysis.Navigation; using Microsoft.Internal.VisualStudio.Shell.Interop; @@ -48,9 +45,11 @@ internal sealed class SymbolTreeItemSourceProvider : AttachedCollectionSourcePro private readonly ConcurrentSet> _weakCollectionSources = []; private readonly AsyncBatchingWorkQueue _updateSourcesQueue; - private readonly CancellationSeries _cancellationSeries; private readonly IAsynchronousOperationListener _listener; + + private readonly CancellationSeries _navigationCancellationSeries; + // private readonly IAnalyzersCommandHandler _commandHandler = commandHandler; // private IHierarchyItemToProjectIdMap? _projectMap; @@ -66,7 +65,7 @@ IAsynchronousOperationListenerProvider listenerProvider { _threadingContext = threadingContext; _workspace = workspace; - _cancellationSeries = new(_threadingContext.DisposalToken); + _navigationCancellationSeries = new(_threadingContext.DisposalToken); _listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); _updateSourcesQueue = new AsyncBatchingWorkQueue( @@ -88,7 +87,7 @@ IAsynchronousOperationListenerProvider listenerProvider public void NavigateTo(SymbolTreeItem item, bool preview) { // Cancel any in flight navigation and kick off a new one. - var cancellationToken = _cancellationSeries.CreateNext(); + var cancellationToken = _navigationCancellationSeries.CreateNext(); var navigationService = _workspace.Services.GetRequiredService(); var token = _listener.BeginAsyncOperation(nameof(NavigateTo)); @@ -275,34 +274,3 @@ private async ValueTask TryUpdateItemsAsync( //} } - -internal sealed class SymbolTreeItem( - string name, - Glyph glyph, - SyntaxNode syntaxNode) - : BaseItem(name, canPreview: true), - IInvocationController -{ - public SymbolTreeItemSourceProvider Provider = null!; - public DocumentId DocumentId = null!; - - public override ImageMoniker IconMoniker { get; } = glyph.GetImageMoniker(); - - public readonly SyntaxNode SyntaxNode = syntaxNode; - - public override IInvocationController? InvocationController => this; - - public bool Invoke(IEnumerable items, InputSource inputSource, bool preview) - { - if (items.FirstOrDefault() is not SymbolTreeItem item) - return false; - - Provider.NavigateTo(item, preview); - return true; - } -} - -internal interface ISolutionExplorerSymbolTreeItemProvider : ILanguageService -{ - Task> GetItemsAsync(Document document, CancellationToken cancellationToken); -} From 465042c884f87ed5240cf718ce8e5a78904ad4c2 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 18:49:00 +0200 Subject: [PATCH 032/353] Rename --- .../Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs | 2 +- .../SymbolTree/SymbolTreeItemSourceProvider.cs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index b8750323282ba..1c856738c2ef4 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -19,7 +19,7 @@ internal sealed class SymbolTreeItem( : BaseItem(name, canPreview: true), IInvocationController { - public SymbolTreeItemSourceProvider Provider = null!; + public RootSymbolTreeItemSourceProvider Provider = null!; public DocumentId DocumentId = null!; public override ImageMoniker IconMoniker { get; } = glyph.GetImageMoniker(); diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs index 47857490f5c98..1d6f9232162f0 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs @@ -34,10 +34,10 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; [Export(typeof(IAttachedCollectionSourceProvider))] -[Name(nameof(SymbolTreeItemSourceProvider))] +[Name(nameof(RootSymbolTreeItemSourceProvider))] [Order(Before = HierarchyItemsProviderNames.Contains)] [AppliesToProject("CSharp | VB")] -internal sealed class SymbolTreeItemSourceProvider : AttachedCollectionSourceProvider +internal sealed class RootSymbolTreeItemSourceProvider : AttachedCollectionSourceProvider { private readonly IThreadingContext _threadingContext; private readonly Workspace _workspace; @@ -56,7 +56,7 @@ internal sealed class SymbolTreeItemSourceProvider : AttachedCollectionSourcePro [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] [ImportingConstructor] - public SymbolTreeItemSourceProvider( + public RootSymbolTreeItemSourceProvider( IThreadingContext threadingContext, VisualStudioWorkspace workspace, IAsynchronousOperationListenerProvider listenerProvider @@ -180,11 +180,11 @@ await RoslynParallel.ForEachAsync( } private sealed class SymbolTreeItemCollectionSource( - SymbolTreeItemSourceProvider provider, + RootSymbolTreeItemSourceProvider provider, IVsHierarchyItem hierarchyItem) : IAttachedCollectionSource { - private readonly SymbolTreeItemSourceProvider _provider = provider; + private readonly RootSymbolTreeItemSourceProvider _provider = provider; private readonly IVsHierarchyItem _hierarchyItem = hierarchyItem; private readonly BulkObservableCollection _symbolTreeItems = []; From 98aa4ed2ae059e9fb93dbfe45ab95e3b081a034e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 18:51:16 +0200 Subject: [PATCH 033/353] Delete --- ....cs => RootSymbolTreeItemSourceProvider.cs} | 18 ------------------ 1 file changed, 18 deletions(-) rename src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/{SymbolTreeItemSourceProvider.cs => RootSymbolTreeItemSourceProvider.cs} (94%) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs similarity index 94% rename from src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs rename to src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index 1d6f9232162f0..9ef71750db60a 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -47,7 +47,6 @@ internal sealed class RootSymbolTreeItemSourceProvider : AttachedCollectionSourc private readonly AsyncBatchingWorkQueue _updateSourcesQueue; private readonly IAsynchronousOperationListener _listener; - private readonly CancellationSeries _navigationCancellationSeries; // private readonly IAnalyzersCommandHandler _commandHandler = commandHandler; @@ -138,9 +137,6 @@ await RoslynParallel.ForEachAsync( }).ConfigureAwait(false); } - //private IHierarchyItemToProjectIdMap? TryGetProjectMap() - // => _projectMap ??= _workspace.Services.GetService(); - protected override IAttachedCollectionSource? CreateCollectionSource(IVsHierarchyItem item, string relationshipName) { if (item == null || @@ -259,18 +255,4 @@ private async ValueTask TryUpdateItemsAsync( return _documentId; } } - - //private static ImmutableArray GetProjectTreeCapabilities(IVsHierarchy hierarchy, uint itemId) - //{ - // if (hierarchy.GetProperty(itemId, (int)__VSHPROPID7.VSHPROPID_ProjectTreeCapabilities, out var capabilitiesObj) == VSConstants.S_OK) - // { - // var capabilitiesString = (string)capabilitiesObj; - // return ImmutableArray.Create(capabilitiesString.Split(' ')); - // } - // else - // { - // return []; - // } - //} - } From 565e2284b2309000d090e267b3e5f375eaf0ff18 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 18:59:59 +0200 Subject: [PATCH 034/353] in progress --- .../RootSymbolTreeItemSourceProvider.cs | 237 +++++++++++++++--- 1 file changed, 198 insertions(+), 39 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index 9ef71750db60a..2799a5e2931a4 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -33,21 +33,61 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; +internal abstract class AbstractSymbolTreeItemSourceProvider : AttachedCollectionSourceProvider +{ + protected readonly IThreadingContext ThreadingContext; + protected readonly Workspace Workspace; + + protected readonly IAsynchronousOperationListener Listener; + + private readonly CancellationSeries _navigationCancellationSeries; + + // private readonly IAnalyzersCommandHandler _commandHandler = commandHandler; + + // private IHierarchyItemToProjectIdMap? _projectMap; + + protected AbstractSymbolTreeItemSourceProvider( + IThreadingContext threadingContext, + VisualStudioWorkspace workspace, + IAsynchronousOperationListenerProvider listenerProvider + /*, +[Import(typeof(AnalyzersCommandHandler))] IAnalyzersCommandHandler commandHandler*/) + { + ThreadingContext = threadingContext; + Workspace = workspace; + _navigationCancellationSeries = new(ThreadingContext.DisposalToken); + Listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); + } + + public void NavigateTo(SymbolTreeItem item, bool preview) + { + // Cancel any in flight navigation and kick off a new one. + var cancellationToken = _navigationCancellationSeries.CreateNext(); + var navigationService = Workspace.Services.GetRequiredService(); + + var token = Listener.BeginAsyncOperation(nameof(NavigateTo)); + navigationService.TryNavigateToPositionAsync( + ThreadingContext, + Workspace, + item.DocumentId, + item.SyntaxNode.SpanStart, + virtualSpace: 0, + // May be calling this on stale data. Allow the position to be invalid + allowInvalidPosition: true, + new NavigationOptions(PreferProvisionalTab: preview), + cancellationToken).ReportNonFatalErrorUnlessCancelledAsync(cancellationToken).CompletesAsyncOperation(token); + } +} + [Export(typeof(IAttachedCollectionSourceProvider))] [Name(nameof(RootSymbolTreeItemSourceProvider))] [Order(Before = HierarchyItemsProviderNames.Contains)] [AppliesToProject("CSharp | VB")] -internal sealed class RootSymbolTreeItemSourceProvider : AttachedCollectionSourceProvider +internal sealed class RootSymbolTreeItemSourceProvider : AbstractSymbolTreeItemSourceProvider { - private readonly IThreadingContext _threadingContext; - private readonly Workspace _workspace; - - private readonly ConcurrentSet> _weakCollectionSources = []; + private readonly ConcurrentSet> _weakCollectionSources = []; private readonly AsyncBatchingWorkQueue _updateSourcesQueue; - private readonly IAsynchronousOperationListener _listener; - - private readonly CancellationSeries _navigationCancellationSeries; // private readonly IAnalyzersCommandHandler _commandHandler = commandHandler; @@ -61,20 +101,16 @@ public RootSymbolTreeItemSourceProvider( IAsynchronousOperationListenerProvider listenerProvider /*, [Import(typeof(AnalyzersCommandHandler))] IAnalyzersCommandHandler commandHandler*/) + : base(threadingContext, workspace, listenerProvider) { - _threadingContext = threadingContext; - _workspace = workspace; - _navigationCancellationSeries = new(_threadingContext.DisposalToken); - _listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); - _updateSourcesQueue = new AsyncBatchingWorkQueue( DelayTimeSpan.Medium, UpdateCollectionSourcesAsync, EqualityComparer.Default, - _listener, - _threadingContext.DisposalToken); + this.Listener, + this.ThreadingContext.DisposalToken); - _workspace.RegisterWorkspaceChangedHandler( + this.Workspace.RegisterWorkspaceChangedHandler( e => { if (e is { Kind: WorkspaceChangeKind.DocumentChanged or WorkspaceChangeKind.DocumentAdded, DocumentId: not null }) @@ -83,30 +119,11 @@ IAsynchronousOperationListenerProvider listenerProvider options: new WorkspaceEventOptions(RequiresMainThread: false)); } - public void NavigateTo(SymbolTreeItem item, bool preview) - { - // Cancel any in flight navigation and kick off a new one. - var cancellationToken = _navigationCancellationSeries.CreateNext(); - var navigationService = _workspace.Services.GetRequiredService(); - - var token = _listener.BeginAsyncOperation(nameof(NavigateTo)); - navigationService.TryNavigateToPositionAsync( - _threadingContext, - _workspace, - item.DocumentId, - item.SyntaxNode.SpanStart, - virtualSpace: 0, - // May be calling this on stale data. Allow the position to be invalid - allowInvalidPosition: true, - new NavigationOptions(PreferProvisionalTab: preview), - cancellationToken).ReportNonFatalErrorUnlessCancelledAsync(cancellationToken).CompletesAsyncOperation(token); - } - private async ValueTask UpdateCollectionSourcesAsync( ImmutableSegmentedList documentIds, CancellationToken cancellationToken) { using var _1 = Microsoft.CodeAnalysis.PooledObjects.PooledHashSet.GetInstance(out var documentIdSet); - using var _2 = Microsoft.CodeAnalysis.PooledObjects.ArrayBuilder.GetInstance(out var sources); + using var _2 = Microsoft.CodeAnalysis.PooledObjects.ArrayBuilder.GetInstance(out var sources); documentIdSet.AddRange(documentIds); @@ -162,8 +179,8 @@ await RoslynParallel.ForEachAsync( return null; } - var source = new SymbolTreeItemCollectionSource(this, item); - _weakCollectionSources.Add(new WeakReference(source)); + var source = new RootSymbolTreeItemCollectionSource(this, item); + _weakCollectionSources.Add(new WeakReference(source)); return source; //var hierarchyMapper = TryGetProjectMap(); //if (hierarchyMapper == null || @@ -175,6 +192,148 @@ await RoslynParallel.ForEachAsync( //return null; } + private sealed class RootSymbolTreeItemCollectionSource( + RootSymbolTreeItemSourceProvider provider, + IVsHierarchyItem hierarchyItem) + : IAttachedCollectionSource + { + private readonly RootSymbolTreeItemSourceProvider _provider = provider; + private readonly IVsHierarchyItem _hierarchyItem = hierarchyItem; + + private readonly BulkObservableCollection _symbolTreeItems = []; + + private DocumentId? _documentId; + + public object SourceItem => _hierarchyItem; + public bool HasItems => true; + public IEnumerable Items => _symbolTreeItems; + + internal async Task UpdateIfAffectedAsync( + HashSet updateSet, CancellationToken cancellationToken) + { + var documentId = DetermineDocumentId(); + + // If we successfully handle this request, we're done. + if (await TryUpdateItemsAsync(updateSet, documentId, cancellationToken).ConfigureAwait(false)) + return; + + // If we failed for any reason, clear out all our items. + using (_symbolTreeItems.GetBulkOperation()) + _symbolTreeItems.Clear(); + } + private async ValueTask TryUpdateItemsAsync( + HashSet updateSet, DocumentId? documentId, CancellationToken cancellationToken) + { + if (documentId is null) + return false; + + if (!updateSet.Contains(documentId)) + { + // Note: we intentionally return 'true' here. There was no failure here. We just got a notification + // to update a different document than our own. So we can just ignore this. + return true; + } + + var solution = _provider.Workspace.CurrentSolution; + var document = solution.GetDocument(documentId); + + // If we can't find this document anymore, clear everything out. + if (document is null) + return false; + + var service = document.Project.GetLanguageService(); + if (service is null) + return false; + + var items = await service.GetItemsAsync(document, cancellationToken).ConfigureAwait(false); + foreach (var item in items) + { + item.Provider = _provider; + item.DocumentId = document.Id; + } + + using (_symbolTreeItems.GetBulkOperation()) + { + _symbolTreeItems.Clear(); + _symbolTreeItems.AddRange(items); + } + + return true; + } + + private DocumentId? DetermineDocumentId() + { + if (_documentId == null) + { + var idMap = _provider.Workspace.Services.GetService(); + idMap?.TryGetDocumentId(_hierarchyItem, targetFrameworkMoniker: null, out _documentId); + } + + return _documentId; + } + } +} + + + +[Export(typeof(IAttachedCollectionSourceProvider))] +[Name(nameof(NonRootSymbolTreeItemSourceProvider))] +[Order(Before = HierarchyItemsProviderNames.Contains)] +[AppliesToProject("CSharp | VB")] +internal sealed class NonRootSymbolTreeItemSourceProvider : AttachedCollectionSourceProvider +{ + private readonly IThreadingContext _threadingContext; + private readonly Workspace _workspace; + + private readonly ConcurrentSet> _weakCollectionSources = []; + + // private readonly AsyncBatchingWorkQueue _updateSourcesQueue; + private readonly IAsynchronousOperationListener _listener; + + private readonly CancellationSeries _navigationCancellationSeries; + + // private readonly IAnalyzersCommandHandler _commandHandler = commandHandler; + + // private IHierarchyItemToProjectIdMap? _projectMap; + + [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] + [ImportingConstructor] + public NonRootSymbolTreeItemSourceProvider( + IThreadingContext threadingContext, + VisualStudioWorkspace workspace, + IAsynchronousOperationListenerProvider listenerProvider + /*, +[Import(typeof(AnalyzersCommandHandler))] IAnalyzersCommandHandler commandHandler*/) + { + _threadingContext = threadingContext; + _workspace = workspace; + _navigationCancellationSeries = new(_threadingContext.DisposalToken); + _listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); + + //_updateSourcesQueue = new AsyncBatchingWorkQueue( + // DelayTimeSpan.Medium, + // UpdateCollectionSourcesAsync, + // EqualityComparer.Default, + // _listener, + // _threadingContext.DisposalToken); + + //_workspace.RegisterWorkspaceChangedHandler( + // e => + // { + // if (e is { Kind: WorkspaceChangeKind.DocumentChanged or WorkspaceChangeKind.DocumentAdded, DocumentId: not null }) + // _updateSourcesQueue.AddWork(e.DocumentId); + // }, + // options: new WorkspaceEventOptions(RequiresMainThread: false)); + } + + protected override IAttachedCollectionSource? CreateCollectionSource(SymbolTreeItem item, string relationshipName) + { + if (relationshipName != KnownRelationships.Contains) + return null; + + return null; + } + private sealed class SymbolTreeItemCollectionSource( RootSymbolTreeItemSourceProvider provider, IVsHierarchyItem hierarchyItem) @@ -217,7 +376,7 @@ private async ValueTask TryUpdateItemsAsync( return true; } - var solution = _provider._workspace.CurrentSolution; + var solution = _provider.Workspace.CurrentSolution; var document = solution.GetDocument(documentId); // If we can't find this document anymore, clear everything out. From f934877864f5ee614532ad45ed11e2d8e9cfa858 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 19:10:48 +0200 Subject: [PATCH 035/353] in progress --- .../AbstractSymbolTreeItemSourceProvider.cs | 58 ++++++ .../NonRootSymbolTreeItemSourceProvider.cs | 135 ++++++++++++ .../RootSymbolTreeItemSourceProvider.cs | 192 +----------------- .../SymbolTree/SymbolTreeItem.cs | 5 +- 4 files changed, 198 insertions(+), 192 deletions(-) create mode 100644 src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs create mode 100644 src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs new file mode 100644 index 0000000000000..fd7d6edf66b85 --- /dev/null +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs @@ -0,0 +1,58 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.ErrorReporting; +using Microsoft.CodeAnalysis.Shared.TestHooks; +using Microsoft.CodeAnalysis.Threading; +using Microsoft.Internal.VisualStudio.PlatformUI; +using Microsoft.CodeAnalysis.Navigation; + +namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; + +internal abstract class AbstractSymbolTreeItemSourceProvider : AttachedCollectionSourceProvider +{ + protected readonly IThreadingContext ThreadingContext; + protected readonly Workspace Workspace; + + protected readonly IAsynchronousOperationListener Listener; + + private static readonly CancellationSeries s_navigationCancellationSeries = new(); + + // private readonly IAnalyzersCommandHandler _commandHandler = commandHandler; + + // private IHierarchyItemToProjectIdMap? _projectMap; + + protected AbstractSymbolTreeItemSourceProvider( + IThreadingContext threadingContext, + VisualStudioWorkspace workspace, + IAsynchronousOperationListenerProvider listenerProvider + /*, +[Import(typeof(AnalyzersCommandHandler))] IAnalyzersCommandHandler commandHandler*/) + { + ThreadingContext = threadingContext; + Workspace = workspace; + Listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); + } + + public void NavigateTo(SymbolTreeItem item, bool preview) + { + // Cancel any in flight navigation and kick off a new one. + var cancellationToken = s_navigationCancellationSeries.CreateNext(this.ThreadingContext.DisposalToken); + var navigationService = Workspace.Services.GetRequiredService(); + + var token = Listener.BeginAsyncOperation(nameof(NavigateTo)); + navigationService.TryNavigateToPositionAsync( + ThreadingContext, + Workspace, + item.DocumentId, + item.SyntaxNode.SpanStart, + virtualSpace: 0, + // May be calling this on stale data. Allow the position to be invalid + allowInvalidPosition: true, + new NavigationOptions(PreferProvisionalTab: preview), + cancellationToken).ReportNonFatalErrorUnlessCancelledAsync(cancellationToken).CompletesAsyncOperation(token); + } +} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs new file mode 100644 index 0000000000000..26426d58f53c3 --- /dev/null +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs @@ -0,0 +1,135 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.ComponentModel.Composition; +using System.Diagnostics.CodeAnalysis; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.Shared.TestHooks; +using Microsoft.CodeAnalysis.Threading; +using Microsoft.Internal.VisualStudio.PlatformUI; +using Microsoft.VisualStudio.Language.Intellisense; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Utilities; +using Roslyn.Utilities; +using Microsoft.VisualStudio.LanguageServices.Extensions; +using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Shared.Extensions; + +namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; + +[Export(typeof(IAttachedCollectionSourceProvider))] +[Name(nameof(NonRootSymbolTreeItemSourceProvider))] +[Order(Before = HierarchyItemsProviderNames.Contains)] +[AppliesToProject("CSharp | VB")] +internal sealed class NonRootSymbolTreeItemSourceProvider : AbstractSymbolTreeItemSourceProvider +{ + [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] + [ImportingConstructor] + public NonRootSymbolTreeItemSourceProvider( + IThreadingContext threadingContext, + VisualStudioWorkspace workspace, + IAsynchronousOperationListenerProvider listenerProvider + /*, +[Import(typeof(AnalyzersCommandHandler))] IAnalyzersCommandHandler commandHandler*/) + : base(threadingContext, workspace, listenerProvider) + { + + } + + protected override IAttachedCollectionSource? CreateCollectionSource(SymbolTreeItem item, string relationshipName) + { + if (relationshipName != KnownRelationships.Contains) + return null; + + return null; + } + + private sealed class SymbolTreeItemCollectionSource( + RootSymbolTreeItemSourceProvider provider, + SymbolTreeItem symbolTreeItem) + : IAttachedCollectionSource + { + private readonly RootSymbolTreeItemSourceProvider _provider = provider; + private readonly IVsHierarchyItem _hierarchyItem = hierarchyItem; + + private readonly BulkObservableCollection _symbolTreeItems = []; + + private DocumentId? _documentId; + + public object SourceItem => _hierarchyItem; + public bool HasItems => true; + public IEnumerable Items => _symbolTreeItems; + + internal async Task UpdateIfAffectedAsync( + HashSet updateSet, CancellationToken cancellationToken) + { + var documentId = DetermineDocumentId(); + + // If we successfully handle this request, we're done. + if (await TryUpdateItemsAsync(updateSet, documentId, cancellationToken).ConfigureAwait(false)) + return; + + // If we failed for any reason, clear out all our items. + using (_symbolTreeItems.GetBulkOperation()) + _symbolTreeItems.Clear(); + } + private async ValueTask TryUpdateItemsAsync( + HashSet updateSet, DocumentId? documentId, CancellationToken cancellationToken) + { + if (documentId is null) + return false; + + if (!updateSet.Contains(documentId)) + { + // Note: we intentionally return 'true' here. There was no failure here. We just got a notification + // to update a different document than our own. So we can just ignore this. + return true; + } + + var solution = _provider.Workspace.CurrentSolution; + var document = solution.GetDocument(documentId); + + // If we can't find this document anymore, clear everything out. + if (document is null) + return false; + + var service = document.Project.GetLanguageService(); + if (service is null) + return false; + + var items = await service.GetItemsAsync(document, cancellationToken).ConfigureAwait(false); + foreach (var item in items) + { + item.Provider = _provider; + item.DocumentId = document.Id; + } + + using (_symbolTreeItems.GetBulkOperation()) + { + _symbolTreeItems.Clear(); + _symbolTreeItems.AddRange(items); + } + + return true; + } + + private DocumentId? DetermineDocumentId() + { + if (_documentId == null) + { + var idMap = _provider._workspace.Services.GetService(); + idMap?.TryGetDocumentId(_hierarchyItem, targetFrameworkMoniker: null, out _documentId); + } + + return _documentId; + } + } +} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index 2799a5e2931a4..b490d908ab4e6 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -28,57 +28,10 @@ using Microsoft.VisualStudio.Debugger.ComponentInterfaces; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Shared.Extensions; -using Microsoft.CodeAnalysis.Navigation; using Microsoft.Internal.VisualStudio.Shell.Interop; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; -internal abstract class AbstractSymbolTreeItemSourceProvider : AttachedCollectionSourceProvider -{ - protected readonly IThreadingContext ThreadingContext; - protected readonly Workspace Workspace; - - protected readonly IAsynchronousOperationListener Listener; - - private readonly CancellationSeries _navigationCancellationSeries; - - // private readonly IAnalyzersCommandHandler _commandHandler = commandHandler; - - // private IHierarchyItemToProjectIdMap? _projectMap; - - protected AbstractSymbolTreeItemSourceProvider( - IThreadingContext threadingContext, - VisualStudioWorkspace workspace, - IAsynchronousOperationListenerProvider listenerProvider - /*, -[Import(typeof(AnalyzersCommandHandler))] IAnalyzersCommandHandler commandHandler*/) - { - ThreadingContext = threadingContext; - Workspace = workspace; - _navigationCancellationSeries = new(ThreadingContext.DisposalToken); - Listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); - } - - public void NavigateTo(SymbolTreeItem item, bool preview) - { - // Cancel any in flight navigation and kick off a new one. - var cancellationToken = _navigationCancellationSeries.CreateNext(); - var navigationService = Workspace.Services.GetRequiredService(); - - var token = Listener.BeginAsyncOperation(nameof(NavigateTo)); - navigationService.TryNavigateToPositionAsync( - ThreadingContext, - Workspace, - item.DocumentId, - item.SyntaxNode.SpanStart, - virtualSpace: 0, - // May be calling this on stale data. Allow the position to be invalid - allowInvalidPosition: true, - new NavigationOptions(PreferProvisionalTab: preview), - cancellationToken).ReportNonFatalErrorUnlessCancelledAsync(cancellationToken).CompletesAsyncOperation(token); - } -} - [Export(typeof(IAttachedCollectionSourceProvider))] [Name(nameof(RootSymbolTreeItemSourceProvider))] [Order(Before = HierarchyItemsProviderNames.Contains)] @@ -248,7 +201,8 @@ private async ValueTask TryUpdateItemsAsync( var items = await service.GetItemsAsync(document, cancellationToken).ConfigureAwait(false); foreach (var item in items) { - item.Provider = _provider; + item.SourceProvider = _provider; + item.ItemProvider = service; item.DocumentId = document.Id; } @@ -273,145 +227,3 @@ private async ValueTask TryUpdateItemsAsync( } } } - - - -[Export(typeof(IAttachedCollectionSourceProvider))] -[Name(nameof(NonRootSymbolTreeItemSourceProvider))] -[Order(Before = HierarchyItemsProviderNames.Contains)] -[AppliesToProject("CSharp | VB")] -internal sealed class NonRootSymbolTreeItemSourceProvider : AttachedCollectionSourceProvider -{ - private readonly IThreadingContext _threadingContext; - private readonly Workspace _workspace; - - private readonly ConcurrentSet> _weakCollectionSources = []; - - // private readonly AsyncBatchingWorkQueue _updateSourcesQueue; - private readonly IAsynchronousOperationListener _listener; - - private readonly CancellationSeries _navigationCancellationSeries; - - // private readonly IAnalyzersCommandHandler _commandHandler = commandHandler; - - // private IHierarchyItemToProjectIdMap? _projectMap; - - [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] - [ImportingConstructor] - public NonRootSymbolTreeItemSourceProvider( - IThreadingContext threadingContext, - VisualStudioWorkspace workspace, - IAsynchronousOperationListenerProvider listenerProvider - /*, -[Import(typeof(AnalyzersCommandHandler))] IAnalyzersCommandHandler commandHandler*/) - { - _threadingContext = threadingContext; - _workspace = workspace; - _navigationCancellationSeries = new(_threadingContext.DisposalToken); - _listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); - - //_updateSourcesQueue = new AsyncBatchingWorkQueue( - // DelayTimeSpan.Medium, - // UpdateCollectionSourcesAsync, - // EqualityComparer.Default, - // _listener, - // _threadingContext.DisposalToken); - - //_workspace.RegisterWorkspaceChangedHandler( - // e => - // { - // if (e is { Kind: WorkspaceChangeKind.DocumentChanged or WorkspaceChangeKind.DocumentAdded, DocumentId: not null }) - // _updateSourcesQueue.AddWork(e.DocumentId); - // }, - // options: new WorkspaceEventOptions(RequiresMainThread: false)); - } - - protected override IAttachedCollectionSource? CreateCollectionSource(SymbolTreeItem item, string relationshipName) - { - if (relationshipName != KnownRelationships.Contains) - return null; - - return null; - } - - private sealed class SymbolTreeItemCollectionSource( - RootSymbolTreeItemSourceProvider provider, - IVsHierarchyItem hierarchyItem) - : IAttachedCollectionSource - { - private readonly RootSymbolTreeItemSourceProvider _provider = provider; - private readonly IVsHierarchyItem _hierarchyItem = hierarchyItem; - - private readonly BulkObservableCollection _symbolTreeItems = []; - - private DocumentId? _documentId; - - public object SourceItem => _hierarchyItem; - public bool HasItems => true; - public IEnumerable Items => _symbolTreeItems; - - internal async Task UpdateIfAffectedAsync( - HashSet updateSet, CancellationToken cancellationToken) - { - var documentId = DetermineDocumentId(); - - // If we successfully handle this request, we're done. - if (await TryUpdateItemsAsync(updateSet, documentId, cancellationToken).ConfigureAwait(false)) - return; - - // If we failed for any reason, clear out all our items. - using (_symbolTreeItems.GetBulkOperation()) - _symbolTreeItems.Clear(); - } - private async ValueTask TryUpdateItemsAsync( - HashSet updateSet, DocumentId? documentId, CancellationToken cancellationToken) - { - if (documentId is null) - return false; - - if (!updateSet.Contains(documentId)) - { - // Note: we intentionally return 'true' here. There was no failure here. We just got a notification - // to update a different document than our own. So we can just ignore this. - return true; - } - - var solution = _provider.Workspace.CurrentSolution; - var document = solution.GetDocument(documentId); - - // If we can't find this document anymore, clear everything out. - if (document is null) - return false; - - var service = document.Project.GetLanguageService(); - if (service is null) - return false; - - var items = await service.GetItemsAsync(document, cancellationToken).ConfigureAwait(false); - foreach (var item in items) - { - item.Provider = _provider; - item.DocumentId = document.Id; - } - - using (_symbolTreeItems.GetBulkOperation()) - { - _symbolTreeItems.Clear(); - _symbolTreeItems.AddRange(items); - } - - return true; - } - - private DocumentId? DetermineDocumentId() - { - if (_documentId == null) - { - var idMap = _provider._workspace.Services.GetService(); - idMap?.TryGetDocumentId(_hierarchyItem, targetFrameworkMoniker: null, out _documentId); - } - - return _documentId; - } - } -} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index 1c856738c2ef4..c88806f575ed3 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -19,8 +19,9 @@ internal sealed class SymbolTreeItem( : BaseItem(name, canPreview: true), IInvocationController { - public RootSymbolTreeItemSourceProvider Provider = null!; + public RootSymbolTreeItemSourceProvider SourceProvider = null!; public DocumentId DocumentId = null!; + public ISolutionExplorerSymbolTreeItemProvider ItemProvider = null!; public override ImageMoniker IconMoniker { get; } = glyph.GetImageMoniker(); @@ -33,7 +34,7 @@ public bool Invoke(IEnumerable items, InputSource inputSource, bool prev if (items.FirstOrDefault() is not SymbolTreeItem item) return false; - Provider.NavigateTo(item, preview); + SourceProvider.NavigateTo(item, preview); return true; } } From ad3c948854a2c740a0a1445a1591a8eed9eae8ec Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 19:17:42 +0200 Subject: [PATCH 036/353] extract type --- .../BulkObservableCollectionWithInit.cs | 39 +++++++++++++++++++ .../SourceGeneratedFileItemSource.cs | 32 --------------- .../NonRootSymbolTreeItemSourceProvider.cs | 20 +++++----- .../SymbolTree/SymbolTreeItem.cs | 4 +- 4 files changed, 51 insertions(+), 44 deletions(-) create mode 100644 src/VisualStudio/Core/Impl/SolutionExplorer/BulkObservableCollectionWithInit.cs diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/BulkObservableCollectionWithInit.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/BulkObservableCollectionWithInit.cs new file mode 100644 index 0000000000000..d390ad3ae45dd --- /dev/null +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/BulkObservableCollectionWithInit.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.ObjectModel; +using System.ComponentModel; +using Microsoft.VisualStudio.Language.Intellisense; + +namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; + +/// +/// This derivation of also supports raising an initialized event through +/// . This is used to show the spinning icon in the solution explorer +/// the first time you expand it. +/// +internal sealed class BulkObservableCollectionWithInit : BulkObservableCollection, ISupportInitializeNotification +{ + public bool IsInitialized { get; private set; } = false; + + public event EventHandler? Initialized; + + void ISupportInitialize.BeginInit() + { + } + + void ISupportInitialize.EndInit() + { + } + + public void MarkAsInitialized() + { + if (!IsInitialized) + { + IsInitialized = true; + Initialized?.Invoke(this, EventArgs.Empty); + } + } +} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/SourceGeneratedFileItemSource.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/SourceGeneratedFileItemSource.cs index 9ec77585af733..9aefa417d935d 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/SourceGeneratedFileItemSource.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/SourceGeneratedFileItemSource.cs @@ -4,8 +4,6 @@ using System; using System.Collections; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -14,7 +12,6 @@ using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.Threading; using Microsoft.Internal.VisualStudio.PlatformUI; -using Microsoft.VisualStudio.Language.Intellisense; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -237,33 +234,4 @@ private void OnWorkspaceChanged(WorkspaceChangeEventArgs e) } } } - - /// - /// This derivation of also supports raising an initialized event through - /// . This is used to show the spinning icon in the solution explorer - /// the first time you expand it. - /// - private sealed class BulkObservableCollectionWithInit : BulkObservableCollection, ISupportInitializeNotification - { - public bool IsInitialized { get; private set; } = false; - - public event EventHandler? Initialized; - - void ISupportInitialize.BeginInit() - { - } - - void ISupportInitialize.EndInit() - { - } - - public void MarkAsInitialized() - { - if (!IsInitialized) - { - IsInitialized = true; - Initialized?.Invoke(this, EventArgs.Empty); - } - } - } } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs index 26426d58f53c3..e31cf689a6ce3 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs @@ -49,24 +49,22 @@ IAsynchronousOperationListenerProvider listenerProvider if (relationshipName != KnownRelationships.Contains) return null; - return null; + return new NonRootSymbolTreeItemCollectionSource; } - private sealed class SymbolTreeItemCollectionSource( - RootSymbolTreeItemSourceProvider provider, + private sealed class NonRootSymbolTreeItemCollectionSource( + NonRootSymbolTreeItemSourceProvider provider, SymbolTreeItem symbolTreeItem) - : IAttachedCollectionSource + : IAttachedCollectionSource, ISupportExpansionEvents { - private readonly RootSymbolTreeItemSourceProvider _provider = provider; - private readonly IVsHierarchyItem _hierarchyItem = hierarchyItem; + private readonly NonRootSymbolTreeItemSourceProvider _provider = provider; + private readonly SymbolTreeItem _symbolTreeItem = symbolTreeItem; private readonly BulkObservableCollection _symbolTreeItems = []; - private DocumentId? _documentId; - - public object SourceItem => _hierarchyItem; - public bool HasItems => true; - public IEnumerable Items => _symbolTreeItems; + public object SourceItem => _symbolTreeItem; + public bool HasItems => _symbolTreeItem.HasItems; + public IEnumerable Items => _symbolTreeItem.GetItems(); internal async Task UpdateIfAffectedAsync( HashSet updateSet, CancellationToken cancellationToken) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index c88806f575ed3..1b3203e3be3eb 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -15,7 +15,8 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore internal sealed class SymbolTreeItem( string name, Glyph glyph, - SyntaxNode syntaxNode) + SyntaxNode syntaxNode, + bool hasItems) : BaseItem(name, canPreview: true), IInvocationController { @@ -26,6 +27,7 @@ internal sealed class SymbolTreeItem( public override ImageMoniker IconMoniker { get; } = glyph.GetImageMoniker(); public readonly SyntaxNode SyntaxNode = syntaxNode; + public readonly bool HasItems = hasItems; public override IInvocationController? InvocationController => this; From 69b918a54242e15dd726302344bd9a335430cce3 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 20:05:08 +0200 Subject: [PATCH 037/353] Add field support --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 127 ++++++++++++++---- .../AbstractSymbolTreeItemSourceProvider.cs | 4 +- ...ISolutionExplorerSymbolTreeItemProvider.cs | 1 + .../ISymbolTreeItemNavigationProvider.cs | 10 ++ .../NonRootSymbolTreeItemSourceProvider.cs | 75 ++++------- .../CSharpDeclaredSymbolInfoFactoryService.cs | 10 +- .../FindSymbols/FindSymbolsUtilities.cs | 15 +++ 7 files changed, 152 insertions(+), 90 deletions(-) create mode 100644 src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISymbolTreeItemNavigationProvider.cs diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index c86377be21864..d12bfa4130a5e 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -7,12 +7,10 @@ using System.Collections.Immutable; using System.Composition; using System.Diagnostics; -using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.Host.Mef; @@ -48,8 +46,8 @@ private static void AddTopLevelTypes(CompilationUnitSyntax root, ArrayBuilder items, CancellationToken cancellationToken) + private static bool TryAddType(MemberDeclarationSyntax member, ArrayBuilder items, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - switch (baseType) + switch (member) { case ExtensionBlockDeclarationSyntax extensionBlock: AddExtensionBlock(extensionBlock, items); - return; + return true; case TypeDeclarationSyntax typeDeclaration: AddTypeDeclaration(typeDeclaration, items); - return; + return true; case EnumDeclarationSyntax enumDeclaration: AddEnumDeclaration(enumDeclaration, items); - return; + return true; case DelegateDeclarationSyntax delegateDeclaration: AddDelegateDeclaration(delegateDeclaration, items); + return true; + } + + return false; + } + + public ImmutableArray GetItems(SymbolTreeItem item, CancellationToken cancellationToken) + { + using var _ = ArrayBuilder.GetInstance(out var items); + + var memberDeclaration = (MemberDeclarationSyntax)item.SyntaxNode; + switch (memberDeclaration) + { + case EnumDeclarationSyntax enumDeclaration: + AddEnumDeclarationMembers(enumDeclaration, items, cancellationToken); + break; + + case TypeDeclarationSyntax typeDeclaration: + AddTypeDeclarationMembers(typeDeclaration, items, cancellationToken); + break; + } + + return items.ToImmutableAndClear(); + } + + private void AddTypeDeclarationMembers(TypeDeclarationSyntax typeDeclaration, ArrayBuilder items, CancellationToken cancellationToken) + { + foreach (var member in typeDeclaration.Members) + { + if (TryAddType(member, items, cancellationToken)) + continue; + + AddMemberDeclaration(member, items, cancellationToken); + } + } + + private void AddMemberDeclaration(MemberDeclarationSyntax member, ArrayBuilder items, CancellationToken cancellationToken) + { + switch (member) + { + case FieldDeclarationSyntax fieldDeclaration: + AddFieldDeclaration(fieldDeclaration, items, cancellationToken); return; } } + private static void AddFieldDeclaration(FieldDeclarationSyntax fieldDeclaration, ArrayBuilder items, CancellationToken cancellationToken) + { + using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); + + foreach (var variable in fieldDeclaration.Declaration.Variables) + { + nameBuilder.Clear(); + + nameBuilder.Append(variable.Identifier.ValueText); + nameBuilder.Append(" : "); + AppendType(fieldDeclaration.Declaration.Type, nameBuilder); + + var accessibility = GetAccessibility(fieldDeclaration, fieldDeclaration.Modifiers); + var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Field, accessibility); + + items.Add(new( + nameBuilder.ToString(), + glyph, + variable, + hasItems: false)); + } + } + + private static void AddEnumDeclarationMembers(EnumDeclarationSyntax enumDeclaration, ArrayBuilder items, CancellationToken cancellationToken) + { + foreach (var member in enumDeclaration.Members) + { + cancellationToken.ThrowIfCancellationRequested(); + items.Add(new( + member.Identifier.ValueText, + Glyph.EnumMemberPublic, + member, + hasItems: false)); + } + } + private static void AddEnumDeclaration(EnumDeclarationSyntax enumDeclaration, ArrayBuilder items) { var glyph = GlyphExtensions.GetGlyph( @@ -99,7 +173,8 @@ private static void AddEnumDeclaration(EnumDeclarationSyntax enumDeclaration, Ar items.Add(new( enumDeclaration.Identifier.ValueText, glyph, - enumDeclaration)); + enumDeclaration, + hasItems: enumDeclaration.Members.Count > 0)); } private static void AddExtensionBlock( @@ -115,7 +190,8 @@ private static void AddExtensionBlock( items.Add(new( nameBuilder.ToString(), Glyph.ClassPublic, - extensionBlock)); + extensionBlock, + hasItems: extensionBlock.Members.Count > 0)); } private static void AddDelegateDeclaration( @@ -137,7 +213,8 @@ private static void AddDelegateDeclaration( items.Add(new( nameBuilder.ToString(), glyph, - delegateDeclaration)); + delegateDeclaration, + hasItems: false)); } private static void AddTypeDeclaration( @@ -149,22 +226,14 @@ private static void AddTypeDeclaration( nameBuilder.Append(typeDeclaration.Identifier.ValueText); AppendTypeParameterList(nameBuilder, typeDeclaration.TypeParameterList); - var accessibility = GetAccessibility(typeDeclaration, typeDeclaration.Modifiers); - var kind = typeDeclaration.Kind() switch - { - SyntaxKind.ClassDeclaration => DeclaredSymbolInfoKind.Class, - SyntaxKind.InterfaceDeclaration => DeclaredSymbolInfoKind.Interface, - SyntaxKind.StructDeclaration => DeclaredSymbolInfoKind.Struct, - SyntaxKind.RecordDeclaration => DeclaredSymbolInfoKind.Record, - SyntaxKind.RecordStructDeclaration => DeclaredSymbolInfoKind.RecordStruct, - _ => throw ExceptionUtilities.UnexpectedValue(typeDeclaration.Kind()), - }; - - var glyph = GlyphExtensions.GetGlyph(kind, accessibility); + var glyph = GlyphExtensions.GetGlyph( + GetDeclaredSymbolInfoKind(typeDeclaration), + GetAccessibility(typeDeclaration, typeDeclaration.Modifiers)); items.Add(new( nameBuilder.ToString(), glyph, - typeDeclaration)); + typeDeclaration, + hasItems: typeDeclaration.Members.Count > 0)); } private static void AppendCommaSeparatedList( diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs index fd7d6edf66b85..2282d4b4bcca8 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs @@ -14,10 +14,10 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore internal abstract class AbstractSymbolTreeItemSourceProvider : AttachedCollectionSourceProvider { - protected readonly IThreadingContext ThreadingContext; + public readonly IThreadingContext ThreadingContext; protected readonly Workspace Workspace; - protected readonly IAsynchronousOperationListener Listener; + public readonly IAsynchronousOperationListener Listener; private static readonly CancellationSeries s_navigationCancellationSeries = new(); diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs index 73e16b05c43f8..0666444fcc700 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs @@ -13,4 +13,5 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore internal interface ISolutionExplorerSymbolTreeItemProvider : ILanguageService { Task> GetItemsAsync(Document document, CancellationToken cancellationToken); + ImmutableArray GetItems(SymbolTreeItem item, CancellationToken cancellationToken); } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISymbolTreeItemNavigationProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISymbolTreeItemNavigationProvider.cs new file mode 100644 index 0000000000000..bf287971ca2f3 --- /dev/null +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISymbolTreeItemNavigationProvider.cs @@ -0,0 +1,10 @@ +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. + +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; + +//internal interface ISymbolTreeItemNavigationProvider +//{ +// void NavigateTo(SymbolTreeItem item, bool preview); +//} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs index e31cf689a6ce3..a3e200fc6c4fe 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs @@ -22,6 +22,7 @@ using Microsoft.VisualStudio.LanguageServices.Extensions; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.ErrorReporting; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -49,65 +50,45 @@ IAsynchronousOperationListenerProvider listenerProvider if (relationshipName != KnownRelationships.Contains) return null; - return new NonRootSymbolTreeItemCollectionSource; + return new NonRootSymbolTreeItemCollectionSource(item); } private sealed class NonRootSymbolTreeItemCollectionSource( - NonRootSymbolTreeItemSourceProvider provider, SymbolTreeItem symbolTreeItem) : IAttachedCollectionSource, ISupportExpansionEvents { - private readonly NonRootSymbolTreeItemSourceProvider _provider = provider; private readonly SymbolTreeItem _symbolTreeItem = symbolTreeItem; - private readonly BulkObservableCollection _symbolTreeItems = []; + private readonly BulkObservableCollectionWithInit _symbolTreeItems = []; + + private int _expanded = 0; public object SourceItem => _symbolTreeItem; public bool HasItems => _symbolTreeItem.HasItems; - public IEnumerable Items => _symbolTreeItem.GetItems(); - - internal async Task UpdateIfAffectedAsync( - HashSet updateSet, CancellationToken cancellationToken) - { - var documentId = DetermineDocumentId(); - - // If we successfully handle this request, we're done. - if (await TryUpdateItemsAsync(updateSet, documentId, cancellationToken).ConfigureAwait(false)) - return; + public IEnumerable Items => _symbolTreeItems; - // If we failed for any reason, clear out all our items. - using (_symbolTreeItems.GetBulkOperation()) - _symbolTreeItems.Clear(); - } - private async ValueTask TryUpdateItemsAsync( - HashSet updateSet, DocumentId? documentId, CancellationToken cancellationToken) + public void BeforeExpand() { - if (documentId is null) - return false; - - if (!updateSet.Contains(documentId)) + if (Interlocked.CompareExchange(ref _expanded, 1, 0) == 0) { - // Note: we intentionally return 'true' here. There was no failure here. We just got a notification - // to update a different document than our own. So we can just ignore this. - return true; + var provider = _symbolTreeItem.SourceProvider; + var token = provider.Listener.BeginAsyncOperation(nameof(BeforeExpand)); + var cancellationToken = provider.ThreadingContext.DisposalToken; + BeforeExpandAsync(cancellationToken) + .ReportNonFatalErrorUnlessCancelledAsync(cancellationToken) + .CompletesAsyncOperation(token); } + } - var solution = _provider.Workspace.CurrentSolution; - var document = solution.GetDocument(documentId); - - // If we can't find this document anymore, clear everything out. - if (document is null) - return false; - - var service = document.Project.GetLanguageService(); - if (service is null) - return false; - - var items = await service.GetItemsAsync(document, cancellationToken).ConfigureAwait(false); + private async Task BeforeExpandAsync(CancellationToken cancellationToken) + { + var items = await _symbolTreeItem.ItemProvider.GetItemsAsync( + _symbolTreeItem, cancellationToken).ConfigureAwait(false); foreach (var item in items) { - item.Provider = _provider; - item.DocumentId = document.Id; + item.SourceProvider = _symbolTreeItem.SourceProvider; + item.ItemProvider = _symbolTreeItem.ItemProvider; + item.DocumentId = _symbolTreeItem.DocumentId; } using (_symbolTreeItems.GetBulkOperation()) @@ -116,18 +97,12 @@ private async ValueTask TryUpdateItemsAsync( _symbolTreeItems.AddRange(items); } - return true; + _symbolTreeItems.MarkAsInitialized(); } - private DocumentId? DetermineDocumentId() + public void AfterCollapse() { - if (_documentId == null) - { - var idMap = _provider._workspace.Services.GetService(); - idMap?.TryGetDocumentId(_hierarchyItem, targetFrameworkMoniker: null, out _documentId); - } - - return _documentId; + // No op } } } diff --git a/src/Workspaces/CSharp/Portable/FindSymbols/CSharpDeclaredSymbolInfoFactoryService.cs b/src/Workspaces/CSharp/Portable/FindSymbols/CSharpDeclaredSymbolInfoFactoryService.cs index 6b45130ad6c94..9f2bb68d9c374 100644 --- a/src/Workspaces/CSharp/Portable/FindSymbols/CSharpDeclaredSymbolInfoFactoryService.cs +++ b/src/Workspaces/CSharp/Portable/FindSymbols/CSharpDeclaredSymbolInfoFactoryService.cs @@ -234,15 +234,7 @@ protected override void AddLocalFunctionInfos( fullyQualifiedContainerName, typeDeclaration.Modifiers.Any(SyntaxKind.PartialKeyword), typeDeclaration.AttributeLists.Any(), - typeDeclaration.Kind() switch - { - SyntaxKind.ClassDeclaration => DeclaredSymbolInfoKind.Class, - SyntaxKind.InterfaceDeclaration => DeclaredSymbolInfoKind.Interface, - SyntaxKind.StructDeclaration => DeclaredSymbolInfoKind.Struct, - SyntaxKind.RecordDeclaration => DeclaredSymbolInfoKind.Record, - SyntaxKind.RecordStructDeclaration => DeclaredSymbolInfoKind.RecordStruct, - _ => throw ExceptionUtilities.UnexpectedValue(typeDeclaration.Kind()), - }, + GetDeclaredSymbolInfoKind(typeDeclaration), GetAccessibility(container, typeDeclaration.Modifiers), typeDeclaration.Identifier.Span, GetInheritanceNames(stringTable, typeDeclaration.BaseList), diff --git a/src/Workspaces/CSharp/Portable/FindSymbols/FindSymbolsUtilities.cs b/src/Workspaces/CSharp/Portable/FindSymbols/FindSymbolsUtilities.cs index a235057937a59..5d4db96c73a7b 100644 --- a/src/Workspaces/CSharp/Portable/FindSymbols/FindSymbolsUtilities.cs +++ b/src/Workspaces/CSharp/Portable/FindSymbols/FindSymbolsUtilities.cs @@ -7,6 +7,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.FindSymbols; namespace Microsoft.CodeAnalysis.CSharp.FindSymbols; @@ -56,4 +58,17 @@ public static Accessibility GetAccessibility(SyntaxNode container, SyntaxTokenLi return Accessibility.Internal; } } + + public static DeclaredSymbolInfoKind GetDeclaredSymbolInfoKind(TypeDeclarationSyntax typeDeclaration) + { + return typeDeclaration.Kind() switch + { + SyntaxKind.ClassDeclaration => DeclaredSymbolInfoKind.Class, + SyntaxKind.InterfaceDeclaration => DeclaredSymbolInfoKind.Interface, + SyntaxKind.StructDeclaration => DeclaredSymbolInfoKind.Struct, + SyntaxKind.RecordDeclaration => DeclaredSymbolInfoKind.Record, + SyntaxKind.RecordStructDeclaration => DeclaredSymbolInfoKind.RecordStruct, + _ => throw ExceptionUtilities.UnexpectedValue(typeDeclaration.Kind()), + }; + } } From 8685bdb38bd1f8d844cd21a9dee0314d24585a96 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 20:15:36 +0200 Subject: [PATCH 038/353] Add field support --- .../Core/Portable/Common/GlyphExtensions.cs | 5 ++ ...stractNavigateToSearchService.InProcess.cs | 2 + ...pSolutionExplorerSymbolTreeItemProvider.cs | 73 +++++++++++++++++-- .../TopLevelSyntaxTree/DeclaredSymbolInfo.cs | 1 + .../Portable/Workspace/Solution/Project.cs | 1 + 5 files changed, 74 insertions(+), 8 deletions(-) diff --git a/src/Features/Core/Portable/Common/GlyphExtensions.cs b/src/Features/Core/Portable/Common/GlyphExtensions.cs index 86b1e96d36730..7b46d0e5c7141 100644 --- a/src/Features/Core/Portable/Common/GlyphExtensions.cs +++ b/src/Features/Core/Portable/Common/GlyphExtensions.cs @@ -250,6 +250,10 @@ public static Glyph GetGlyph(DeclaredSymbolInfoKind kind, Accessibility accessib var rawGlyph = GetPublicGlyph(kind); + // No accessibility supported for operators yet. + if (rawGlyph == Glyph.Operator) + return rawGlyph; + switch (accessibility) { case Accessibility.Private: @@ -284,6 +288,7 @@ private static Glyph GetPublicGlyph(DeclaredSymbolInfoKind kind) DeclaredSymbolInfoKind.Interface => Glyph.InterfacePublic, DeclaredSymbolInfoKind.Method => Glyph.MethodPublic, DeclaredSymbolInfoKind.Module => Glyph.ModulePublic, + DeclaredSymbolInfoKind.Operator => Glyph.Operator, DeclaredSymbolInfoKind.Property => Glyph.PropertyPublic, DeclaredSymbolInfoKind.Struct => Glyph.StructurePublic, DeclaredSymbolInfoKind.RecordStruct => Glyph.StructurePublic, diff --git a/src/Features/Core/Portable/NavigateTo/AbstractNavigateToSearchService.InProcess.cs b/src/Features/Core/Portable/NavigateTo/AbstractNavigateToSearchService.InProcess.cs index 28a36f547a68c..8736055214edf 100644 --- a/src/Features/Core/Portable/NavigateTo/AbstractNavigateToSearchService.InProcess.cs +++ b/src/Features/Core/Portable/NavigateTo/AbstractNavigateToSearchService.InProcess.cs @@ -215,6 +215,8 @@ private static string GetItemKind(DeclaredSymbolInfo declaredSymbolInfo) return NavigateToItemKind.Property; case DeclaredSymbolInfoKind.Struct: return NavigateToItemKind.Structure; + case DeclaredSymbolInfoKind.Operator: + return NavigateToItemKind.OtherSymbol; default: throw ExceptionUtilities.UnexpectedValue(declaredSymbolInfo.Kind); } diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index d12bfa4130a5e..31a0c6f14f0d0 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -10,6 +10,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using ICSharpCode.Decompiler.CSharp.Syntax; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.FindSymbols; @@ -108,28 +109,82 @@ public ImmutableArray GetItems(SymbolTreeItem item, Cancellation return items.ToImmutableAndClear(); } - private void AddTypeDeclarationMembers(TypeDeclarationSyntax typeDeclaration, ArrayBuilder items, CancellationToken cancellationToken) + private static void AddTypeDeclarationMembers(TypeDeclarationSyntax typeDeclaration, ArrayBuilder items, CancellationToken cancellationToken) { foreach (var member in typeDeclaration.Members) { + cancellationToken.ThrowIfCancellationRequested(); + if (TryAddType(member, items, cancellationToken)) continue; - AddMemberDeclaration(member, items, cancellationToken); + AddMemberDeclaration(member, items); } } - private void AddMemberDeclaration(MemberDeclarationSyntax member, ArrayBuilder items, CancellationToken cancellationToken) + private static void AddMemberDeclaration( + MemberDeclarationSyntax member, ArrayBuilder items) { switch (member) { - case FieldDeclarationSyntax fieldDeclaration: - AddFieldDeclaration(fieldDeclaration, items, cancellationToken); + case BaseFieldDeclarationSyntax fieldDeclaration: + AddFieldDeclaration(fieldDeclaration, items); + return; + + case MethodDeclarationSyntax methodDeclaration: + AddMethodDeclaration(methodDeclaration, items); + return; + + case OperatorDeclarationSyntax operatorDeclaration: + AddOperatorDeclaration(operatorDeclaration, items); return; } } - private static void AddFieldDeclaration(FieldDeclarationSyntax fieldDeclaration, ArrayBuilder items, CancellationToken cancellationToken) + private static void AddOperatorDeclaration( + OperatorDeclarationSyntax operatorDeclaration, ArrayBuilder items) + { + using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); + + nameBuilder.Append("operator "); + nameBuilder.Append(operatorDeclaration.OperatorToken.ToString()); + AppendParameterList(nameBuilder, operatorDeclaration.ParameterList); + nameBuilder.Append(" : "); + AppendType(operatorDeclaration.ReturnType, nameBuilder); + + var accessibility = GetAccessibility(operatorDeclaration, operatorDeclaration.Modifiers); + var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Operator, accessibility); + + items.Add(new( + nameBuilder.ToString(), + glyph, + operatorDeclaration, + hasItems: false)); + } + + private static void AddMethodDeclaration( + MethodDeclarationSyntax methodDeclaration, ArrayBuilder items) + { + using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); + + nameBuilder.Append(methodDeclaration.Identifier.ValueText); + AppendTypeParameterList(nameBuilder, methodDeclaration.TypeParameterList); + AppendParameterList(nameBuilder, methodDeclaration.ParameterList); + nameBuilder.Append(" : "); + AppendType(methodDeclaration.ReturnType, nameBuilder); + + var accessibility = GetAccessibility(methodDeclaration, methodDeclaration.Modifiers); + var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Method, accessibility); + + items.Add(new( + nameBuilder.ToString(), + glyph, + methodDeclaration, + hasItems: false)); + } + + private static void AddFieldDeclaration( + BaseFieldDeclarationSyntax fieldDeclaration, ArrayBuilder items) { using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); @@ -142,11 +197,13 @@ private static void AddFieldDeclaration(FieldDeclarationSyntax fieldDeclaration, AppendType(fieldDeclaration.Declaration.Type, nameBuilder); var accessibility = GetAccessibility(fieldDeclaration, fieldDeclaration.Modifiers); - var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Field, accessibility); + var kind = fieldDeclaration is EventFieldDeclarationSyntax + ? DeclaredSymbolInfoKind.Event + : DeclaredSymbolInfoKind.Field; items.Add(new( nameBuilder.ToString(), - glyph, + GlyphExtensions.GetGlyph(kind, accessibility), variable, hasItems: false)); } diff --git a/src/Workspaces/Core/Portable/FindSymbols/TopLevelSyntaxTree/DeclaredSymbolInfo.cs b/src/Workspaces/Core/Portable/FindSymbols/TopLevelSyntaxTree/DeclaredSymbolInfo.cs index 89f45b723e2ae..bb6492341618b 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/TopLevelSyntaxTree/DeclaredSymbolInfo.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/TopLevelSyntaxTree/DeclaredSymbolInfo.cs @@ -30,6 +30,7 @@ internal enum DeclaredSymbolInfoKind : byte Method, Module, Namespace, + Operator, Property, Record, RecordStruct, diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/Project.cs b/src/Workspaces/Core/Portable/Workspace/Solution/Project.cs index f16b7dbf2463a..b71d70bace636 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/Project.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/Project.cs @@ -456,6 +456,7 @@ static bool FilterMatches(DeclaredSymbolInfo info, SymbolFilter filter) case DeclaredSymbolInfoKind.Indexer: case DeclaredSymbolInfoKind.Method: case DeclaredSymbolInfoKind.Property: + case DeclaredSymbolInfoKind.Operator: return (filter & SymbolFilter.Member) != 0; default: throw ExceptionUtilities.UnexpectedValue(info.Kind); From de6784d773519b11f69117efcc644352c96cdc35 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 26 May 2025 20:18:58 +0200 Subject: [PATCH 039/353] Add operator support --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index 31a0c6f14f0d0..2afb604965c8e 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -12,6 +12,7 @@ using System.Threading.Tasks; using ICSharpCode.Decompiler.CSharp.Syntax; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.Host.Mef; @@ -138,9 +139,33 @@ private static void AddMemberDeclaration( case OperatorDeclarationSyntax operatorDeclaration: AddOperatorDeclaration(operatorDeclaration, items); return; + + case ConversionOperatorDeclarationSyntax conversionOperatorDeclaration: + AddConversionOperatorDeclaration(conversionOperatorDeclaration, items); + return; } } + private static void AddConversionOperatorDeclaration(ConversionOperatorDeclarationSyntax operatorDeclaration, ArrayBuilder items) + { + using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); + + nameBuilder.Append(operatorDeclaration.ImplicitOrExplicitKeyword.Kind() == SyntaxKind.ImplicitKeyword + ? "implicit operator " + : "explicit operator "); + AppendType(operatorDeclaration.Type, nameBuilder); + AppendParameterList(nameBuilder, operatorDeclaration.ParameterList); + + var accessibility = GetAccessibility(operatorDeclaration, operatorDeclaration.Modifiers); + var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Operator, accessibility); + + items.Add(new( + nameBuilder.ToString(), + glyph, + operatorDeclaration, + hasItems: false)); + } + private static void AddOperatorDeclaration( OperatorDeclarationSyntax operatorDeclaration, ArrayBuilder items) { From fd335eb4c48e0c8e6a78d0bc51d21fbccce6654c Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 11:01:37 +0200 Subject: [PATCH 040/353] Share code --- .../AnalyzerItem/AnalyzerItem.cs | 4 +- .../AnalyzersFolderItem.cs | 5 +- .../Core/Impl/SolutionExplorer/BaseItem.cs | 15 +- .../DiagnosticItem/DiagnosticItem.cs | 4 +- .../DiagnosticItem/SourceGeneratorItem.cs | 4 +- .../NoSourceGeneratedFilesPlaceholderItem.cs | 5 +- .../SourceGeneratedFileItem.cs | 4 +- .../AbstractSymbolTreeItemSourceProvider.cs | 2 +- ...ISolutionExplorerSymbolTreeItemProvider.cs | 4 +- .../NonRootSymbolTreeItemSourceProvider.cs | 2 +- .../RootSymbolTreeItemSourceProvider.cs | 149 +++++++++++++----- .../SymbolTree/SymbolTreeItem.cs | 43 +++-- 12 files changed, 167 insertions(+), 74 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzerItem/AnalyzerItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzerItem/AnalyzerItem.cs index a937acffd58cd..8c008faa79296 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzerItem/AnalyzerItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzerItem/AnalyzerItem.cs @@ -13,8 +13,10 @@ internal sealed partial class AnalyzerItem( AnalyzersFolderItem analyzersFolder, AnalyzerReference analyzerReference, IContextMenuController contextMenuController) - : BaseItem(GetNameText(analyzerReference)) + : BaseItem { + public override string Name { get; } = GetNameText(analyzerReference); + public AnalyzersFolderItem AnalyzersFolder { get; } = analyzersFolder; public AnalyzerReference AnalyzerReference { get; } = analyzerReference; public override IContextMenuController ContextMenuController { get; } = contextMenuController; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersFolderItem/AnalyzersFolderItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersFolderItem/AnalyzersFolderItem.cs index b2542ef39e496..b46a4e67f00fd 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersFolderItem/AnalyzersFolderItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersFolderItem/AnalyzersFolderItem.cs @@ -18,12 +18,15 @@ internal sealed partial class AnalyzersFolderItem( Workspace workspace, ProjectId projectId, IVsHierarchyItem parentItem, - IContextMenuController contextMenuController) : BaseItem(SolutionExplorerShim.Analyzers) + IContextMenuController contextMenuController) : BaseItem { public readonly IThreadingContext ThreadingContext = threadingContext; public Workspace Workspace { get; } = workspace; public ProjectId ProjectId { get; } = projectId; public IVsHierarchyItem ParentItem { get; } = parentItem; + + public override string Name => SolutionExplorerShim.Analyzers; + public override IContextMenuController ContextMenuController { get; } = contextMenuController; public override ImageMoniker IconMoniker => KnownMonikers.CodeInformation; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs index e1b9cdfacaa2c..b57324d7512d4 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs @@ -19,7 +19,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore /// Microsoft.VisualStudio.Shell.TreeNavigation.HierarchyProvider.dll and /// Microsoft.VisualStudio.Shell.TreeNavigation.GraphProvider.dll. /// -internal abstract class BaseItem : +internal abstract class BaseItem(bool canPreview = false) : LocalizableProperties, ITreeDisplayItem, IInteractionPatternProvider, @@ -31,15 +31,12 @@ internal abstract class BaseItem : ISupportDisposalNotification, IPrioritizedComparable { - public virtual event PropertyChangedEventHandler PropertyChanged { add { } remove { } } - protected readonly string Name; + public bool CanPreview { get; } = canPreview; - public BaseItem(string name, bool canPreview = false) - { - Name = name; - CanPreview = canPreview; - } + public abstract string Name { get; } + + public virtual event PropertyChangedEventHandler PropertyChanged { add { } remove { } } public IEnumerable Children => []; @@ -104,8 +101,6 @@ public BaseItem(string name, bool canPreview = false) return null; } - public bool CanPreview { get; } - public virtual IInvocationController? InvocationController => null; public virtual IContextMenuController? ContextMenuController => null; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/DiagnosticItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/DiagnosticItem.cs index 79544dd6610a0..e209cabcf5fe4 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/DiagnosticItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/DiagnosticItem.cs @@ -22,11 +22,13 @@ internal sealed partial class DiagnosticItem( DiagnosticDescriptor descriptor, ReportDiagnostic effectiveSeverity, IAnalyzersCommandHandler commandHandler) - : BaseItem(descriptor.Id + ": " + descriptor.Title), IEquatable + : BaseItem, IEquatable { private readonly AnalyzerReference _analyzerReference = analyzerReference; private readonly IAnalyzersCommandHandler _commandHandler = commandHandler; + public override string Name { get; } = descriptor.Id + ": " + descriptor.Title; + public ProjectId ProjectId { get; } = projectId; public DiagnosticDescriptor Descriptor { get; } = descriptor; private readonly ReportDiagnostic _effectiveSeverity = effectiveSeverity; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/SourceGeneratorItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/SourceGeneratorItem.cs index d7a8ce4a0d773..9ed838781d810 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/SourceGeneratorItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/SourceGeneratorItem.cs @@ -13,12 +13,14 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore internal sealed partial class SourceGeneratorItem( ProjectId projectId, SourceGeneratorIdentity identity, - string? path) : BaseItem(identity.TypeName), IEquatable + string? path) : BaseItem, IEquatable { public ProjectId ProjectId { get; } = projectId; public SourceGeneratorIdentity Identity { get; } = identity; private readonly string? _path = path; + public override string Name { get; } = identity.TypeName; + // TODO: do we need an icon for our use? public override ImageMoniker IconMoniker => KnownMonikers.Process; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/NoSourceGeneratedFilesPlaceholderItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/NoSourceGeneratedFilesPlaceholderItem.cs index 9c8b2e5cc5265..8084cd50d1224 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/NoSourceGeneratedFilesPlaceholderItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/NoSourceGeneratedFilesPlaceholderItem.cs @@ -7,9 +7,10 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; -internal sealed class NoSourceGeneratedFilesPlaceholderItem() - : BaseItem(SolutionExplorerShim.This_generator_is_not_generating_files) +internal sealed class NoSourceGeneratedFilesPlaceholderItem : BaseItem { + public override string Name => SolutionExplorerShim.This_generator_is_not_generating_files; + public override ImageMoniker IconMoniker => KnownMonikers.StatusInformationNoColor; } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/SourceGeneratedFileItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/SourceGeneratedFileItem.cs index 3d88e6dbcd0cf..d718a369eac4e 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/SourceGeneratedFileItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/SourceGeneratedFileItem.cs @@ -20,11 +20,13 @@ internal sealed partial class SourceGeneratedFileItem( string hintName, string languageName, Workspace workspace) - : BaseItem(name: hintName) + : BaseItem { private readonly IThreadingContext _threadingContext = threadingContext; private readonly string _languageName = languageName; + public override string Name { get; } = hintName; + public DocumentId DocumentId { get; } = documentId; public string HintName { get; } = hintName; public Workspace Workspace { get; } = workspace; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs index 2282d4b4bcca8..98fedc61df8cf 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs @@ -48,7 +48,7 @@ public void NavigateTo(SymbolTreeItem item, bool preview) ThreadingContext, Workspace, item.DocumentId, - item.SyntaxNode.SpanStart, + item.Data.NavigationToken.SpanStart, virtualSpace: 0, // May be calling this on stale data. Allow the position to be invalid allowInvalidPosition: true, diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs index 0666444fcc700..dd6df7aa4f21a 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs @@ -12,6 +12,6 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore internal interface ISolutionExplorerSymbolTreeItemProvider : ILanguageService { - Task> GetItemsAsync(Document document, CancellationToken cancellationToken); - ImmutableArray GetItems(SymbolTreeItem item, CancellationToken cancellationToken); + Task> GetItemsAsync(Document document, CancellationToken cancellationToken); + ImmutableArray GetItems(SymbolTreeItemData item, CancellationToken cancellationToken); } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs index a3e200fc6c4fe..a1d27d8d17aaa 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs @@ -64,7 +64,7 @@ private sealed class NonRootSymbolTreeItemCollectionSource( private int _expanded = 0; public object SourceItem => _symbolTreeItem; - public bool HasItems => _symbolTreeItem.HasItems; + public bool HasItems => _symbolTreeItem.Data.HasItems; public IEnumerable Items => _symbolTreeItems; public void BeforeExpand() diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index b490d908ab4e6..96f98685cda9c 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -6,29 +6,33 @@ using System.Collections; using System.Collections.Generic; using System.Collections.Immutable; +using System.ComponentModel; using System.ComponentModel.Composition; using System.Diagnostics.CodeAnalysis; +using System.Reflection.Metadata; using System.Threading; using System.Threading.Tasks; +using EnvDTE; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.ForEachCast; +using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Threading; using Microsoft.Internal.VisualStudio.PlatformUI; +using Microsoft.Internal.VisualStudio.Shell.Interop; +using Microsoft.VisualStudio.Debugger.ComponentInterfaces; using Microsoft.VisualStudio.Language.Intellisense; +using Microsoft.VisualStudio.LanguageServices.Extensions; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Utilities; using Roslyn.Utilities; -using Microsoft.VisualStudio.LanguageServices.Extensions; -using Microsoft.VisualStudio.Debugger.ComponentInterfaces; -using Microsoft.CodeAnalysis.Host; -using Microsoft.CodeAnalysis.Shared.Extensions; -using Microsoft.Internal.VisualStudio.Shell.Interop; +using static Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer.RootSymbolTreeItemSourceProvider; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -145,21 +149,96 @@ await RoslynParallel.ForEachAsync( //return null; } - private sealed class RootSymbolTreeItemCollectionSource( + internal abstract class AbstractSymbolTreeItemCollectionSource( RootSymbolTreeItemSourceProvider provider, - IVsHierarchyItem hierarchyItem) - : IAttachedCollectionSource + TItem parentItem) : IAttachedCollectionSource, INotifyPropertyChanged { - private readonly RootSymbolTreeItemSourceProvider _provider = provider; - private readonly IVsHierarchyItem _hierarchyItem = hierarchyItem; + protected readonly RootSymbolTreeItemSourceProvider RootProvider = provider; + protected readonly TItem ParentItem = parentItem; - private readonly BulkObservableCollection _symbolTreeItems = []; + protected readonly BulkObservableCollectionWithInit SymbolTreeItems = []; - private DocumentId? _documentId; + public object SourceItem { get; } = parentItem!; + public bool HasItems => !SymbolTreeItems.IsInitialized || SymbolTreeItems.Count > 0; + public IEnumerable Items => SymbolTreeItems; - public object SourceItem => _hierarchyItem; - public bool HasItems => true; - public IEnumerable Items => _symbolTreeItems; + public event PropertyChangedEventHandler PropertyChanged = null!; + + protected void UpdateItems( + DocumentId documentId, + ISolutionExplorerSymbolTreeItemProvider itemProvider, + ImmutableArray items) + { + using (this.SymbolTreeItems.GetBulkOperation()) + { + if (items.Length == 0) + { + // If we got no items, clear everything out. + this.SymbolTreeItems.Clear(); + } + else + { + // We got some item datas. Attempt to reuse existing symbol tree items that match up to preserve + // identity in the tree between changes. + IncorporateNewItems(documentId, itemProvider, items); + } + } + + // Once we've been initialized once, mark us that way so that we we move out of the 'spinning/computing' state. + this.SymbolTreeItems.MarkAsInitialized(); + + // Notify any listenerrs that we may or may not have items now. + this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HasItems))); + } + + private void IncorporateNewItems( + DocumentId documentId, + ISolutionExplorerSymbolTreeItemProvider itemProvider, + ImmutableArray datas) + { + using var _ = Microsoft.CodeAnalysis.PooledObjects.PooledDictionary>.GetInstance(out var keyToItems); + foreach (var item in this.SymbolTreeItems) + keyToItems.MultiAdd(item.ItemKey, item); + + this.SymbolTreeItems.Clear(); + + foreach (var data in datas) + { + if (keyToItems.TryGetValue(data.Key, out var matchingItems)) + { + // Found a matching item we can use. Remove it from the list of items so we don't reuse it again. + var matchingItem = matchingItems[0]; + matchingItems.RemoveAt(0); + if (matchingItems.Count == 0) + keyToItems.Remove(data.Key); + + // And update it to point to the new data. + Contract.ThrowIfFalse(matchingItem.DocumentId == documentId); + Contract.ThrowIfFalse(matchingItem.ItemProvider == itemProvider); + Contract.ThrowIfFalse(matchingItem.ItemKey == data.Key); + + matchingItem.ItemSyntax = new(data.DeclarationNode, data.NavigationToken); + this.SymbolTreeItems.Add(matchingItem); + } + else + { + // If we didn't find an existing item, create a new one. + this.SymbolTreeItems.Add(new(this.RootProvider, documentId, itemProvider) + { + ItemKey = data.Key, + ItemSyntax = new(data.DeclarationNode, data.NavigationToken) + }); + } + } + } + } + + private sealed class RootSymbolTreeItemCollectionSource( + RootSymbolTreeItemSourceProvider provider, + IVsHierarchyItem hierarchyItem) + : AbstractSymbolTreeItemCollectionSource(provider, hierarchyItem) + { + private DocumentId? _documentId; internal async Task UpdateIfAffectedAsync( HashSet updateSet, CancellationToken cancellationToken) @@ -167,19 +246,17 @@ internal async Task UpdateIfAffectedAsync( var documentId = DetermineDocumentId(); // If we successfully handle this request, we're done. - if (await TryUpdateItemsAsync(updateSet, documentId, cancellationToken).ConfigureAwait(false)) + if (documentId != null && await TryUpdateItemsAsync(updateSet, documentId, cancellationToken).ConfigureAwait(false)) return; - // If we failed for any reason, clear out all our items. - using (_symbolTreeItems.GetBulkOperation()) - _symbolTreeItems.Clear(); + // If we didn't have a doc id, or we failed for any reason, clear out all our items. + using (this.SymbolTreeItems.GetBulkOperation()) + SymbolTreeItems.Clear(); } + private async ValueTask TryUpdateItemsAsync( - HashSet updateSet, DocumentId? documentId, CancellationToken cancellationToken) + HashSet updateSet, DocumentId documentId, CancellationToken cancellationToken) { - if (documentId is null) - return false; - if (!updateSet.Contains(documentId)) { // Note: we intentionally return 'true' here. There was no failure here. We just got a notification @@ -187,31 +264,19 @@ private async ValueTask TryUpdateItemsAsync( return true; } - var solution = _provider.Workspace.CurrentSolution; + var solution = this.RootProvider.Workspace.CurrentSolution; var document = solution.GetDocument(documentId); // If we can't find this document anymore, clear everything out. if (document is null) return false; - var service = document.Project.GetLanguageService(); - if (service is null) + var itemProvider = document.Project.GetLanguageService(); + if (itemProvider is null) return false; - var items = await service.GetItemsAsync(document, cancellationToken).ConfigureAwait(false); - foreach (var item in items) - { - item.SourceProvider = _provider; - item.ItemProvider = service; - item.DocumentId = document.Id; - } - - using (_symbolTreeItems.GetBulkOperation()) - { - _symbolTreeItems.Clear(); - _symbolTreeItems.AddRange(items); - } - + var items = await itemProvider.GetItemsAsync(document, cancellationToken).ConfigureAwait(false); + this.UpdateItems(documentId, itemProvider, items); return true; } @@ -219,8 +284,8 @@ private async ValueTask TryUpdateItemsAsync( { if (_documentId == null) { - var idMap = _provider.Workspace.Services.GetService(); - idMap?.TryGetDocumentId(_hierarchyItem, targetFrameworkMoniker: null, out _documentId); + var idMap = this.RootProvider.Workspace.Services.GetService(); + idMap?.TryGetDocumentId(this.ParentItem, targetFrameworkMoniker: null, out _documentId); } return _documentId; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index 1b3203e3be3eb..0b9928cd59b36 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -9,25 +9,46 @@ using Microsoft.VisualStudio.Imaging.Interop; using Microsoft.CodeAnalysis.Editor.Wpf; using System.Linq; +using System; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; +internal readonly record struct SymbolTreeItemKey( + string Name, + Glyph Glyph, + bool HasItems); + +internal readonly record struct SymbolTreeItemSyntax( + SyntaxNode DeclarationNode, + SyntaxToken NavigationToken); + +internal readonly record struct SymbolTreeItemData( + string Name, + Glyph Glyph, + bool HasItems, + SyntaxNode DeclarationNode, + SyntaxToken NavigationToken) +{ + public SymbolTreeItemKey Key => new(Name, Glyph, HasItems); +} + internal sealed class SymbolTreeItem( - string name, - Glyph glyph, - SyntaxNode syntaxNode, - bool hasItems) - : BaseItem(name, canPreview: true), + RootSymbolTreeItemSourceProvider sourceProvider, + DocumentId documentId, + ISolutionExplorerSymbolTreeItemProvider itemProvider) + : BaseItem(canPreview: true), IInvocationController { - public RootSymbolTreeItemSourceProvider SourceProvider = null!; - public DocumentId DocumentId = null!; - public ISolutionExplorerSymbolTreeItemProvider ItemProvider = null!; + public readonly RootSymbolTreeItemSourceProvider SourceProvider = sourceProvider; + public readonly DocumentId DocumentId = documentId; + public readonly ISolutionExplorerSymbolTreeItemProvider ItemProvider = itemProvider; + + public SymbolTreeItemKey ItemKey; + public SymbolTreeItemSyntax ItemSyntax; - public override ImageMoniker IconMoniker { get; } = glyph.GetImageMoniker(); + public override string Name => this.ItemKey.Name; - public readonly SyntaxNode SyntaxNode = syntaxNode; - public readonly bool HasItems = hasItems; + public override ImageMoniker IconMoniker => this.ItemKey.Glyph.GetImageMoniker(); public override IInvocationController? InvocationController => this; From 141f3e4bed1515b9b93fabfab476df81bd52998d Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 11:03:28 +0200 Subject: [PATCH 041/353] move into own file --- .../AbstractSymbolTreeItemCollectionSource.cs | 100 ++++++++++++++++++ .../RootSymbolTreeItemSourceProvider.cs | 93 ---------------- 2 files changed, 100 insertions(+), 93 deletions(-) create mode 100644 src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemCollectionSource.cs diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemCollectionSource.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemCollectionSource.cs new file mode 100644 index 0000000000000..0201370173c23 --- /dev/null +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemCollectionSource.cs @@ -0,0 +1,100 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections; +using System.Collections.Immutable; +using System.ComponentModel; +using Microsoft.CodeAnalysis; +using Microsoft.VisualStudio.LanguageServices.Extensions; +using Microsoft.VisualStudio.Shell; +using Roslyn.Utilities; +using Microsoft.CodeAnalysis.PooledObjects; + +namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; + +internal abstract class AbstractSymbolTreeItemCollectionSource( + RootSymbolTreeItemSourceProvider provider, + TItem parentItem) : IAttachedCollectionSource, INotifyPropertyChanged +{ + protected readonly RootSymbolTreeItemSourceProvider RootProvider = provider; + protected readonly TItem ParentItem = parentItem; + + protected readonly BulkObservableCollectionWithInit SymbolTreeItems = []; + + public object SourceItem { get; } = parentItem!; + public bool HasItems => !SymbolTreeItems.IsInitialized || SymbolTreeItems.Count > 0; + public IEnumerable Items => SymbolTreeItems; + + public event PropertyChangedEventHandler PropertyChanged = null!; + + protected void UpdateItems( + DocumentId documentId, + ISolutionExplorerSymbolTreeItemProvider itemProvider, + ImmutableArray items) + { + using (this.SymbolTreeItems.GetBulkOperation()) + { + if (items.Length == 0) + { + // If we got no items, clear everything out. + this.SymbolTreeItems.Clear(); + } + else + { + // We got some item datas. Attempt to reuse existing symbol tree items that match up to preserve + // identity in the tree between changes. + IncorporateNewItems(documentId, itemProvider, items); + } + } + + // Once we've been initialized once, mark us that way so that we we move out of the 'spinning/computing' state. + this.SymbolTreeItems.MarkAsInitialized(); + + // Notify any listenerrs that we may or may not have items now. + this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HasItems))); + } + + private void IncorporateNewItems( + DocumentId documentId, + ISolutionExplorerSymbolTreeItemProvider itemProvider, + ImmutableArray datas) + { + using var _ = PooledDictionary>.GetInstance(out var keyToItems); + foreach (var item in this.SymbolTreeItems) + keyToItems.MultiAdd(item.ItemKey, item); + + this.SymbolTreeItems.Clear(); + + foreach (var data in datas) + { + if (keyToItems.TryGetValue(data.Key, out var matchingItems)) + { + // Found a matching item we can use. Remove it from the list of items so we don't reuse it again. + var matchingItem = matchingItems[0]; + matchingItems.RemoveAt(0); + if (matchingItems.Count == 0) + keyToItems.Remove(data.Key); + + // And update it to point to the new data. + Contract.ThrowIfFalse(matchingItem.DocumentId == documentId); + Contract.ThrowIfFalse(matchingItem.ItemProvider == itemProvider); + Contract.ThrowIfFalse(matchingItem.ItemKey == data.Key); + + matchingItem.ItemSyntax = new(data.DeclarationNode, data.NavigationToken); + this.SymbolTreeItems.Add(matchingItem); + } + else + { + // If we didn't find an existing item, create a new one. + this.SymbolTreeItems.Add(new(this.RootProvider, documentId, itemProvider) + { + ItemKey = data.Key, + ItemSyntax = new(data.DeclarationNode, data.NavigationToken) + }); + } + } + + keyToItems.FreeValues(); + } +} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index 96f98685cda9c..f6f7c88c8c330 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -3,36 +3,27 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections; using System.Collections.Generic; using System.Collections.Immutable; -using System.ComponentModel; using System.ComponentModel.Composition; using System.Diagnostics.CodeAnalysis; -using System.Reflection.Metadata; using System.Threading; using System.Threading.Tasks; -using EnvDTE; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.ErrorReporting; -using Microsoft.CodeAnalysis.ForEachCast; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Threading; using Microsoft.Internal.VisualStudio.PlatformUI; -using Microsoft.Internal.VisualStudio.Shell.Interop; -using Microsoft.VisualStudio.Debugger.ComponentInterfaces; -using Microsoft.VisualStudio.Language.Intellisense; using Microsoft.VisualStudio.LanguageServices.Extensions; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Utilities; using Roslyn.Utilities; -using static Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer.RootSymbolTreeItemSourceProvider; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -149,90 +140,6 @@ await RoslynParallel.ForEachAsync( //return null; } - internal abstract class AbstractSymbolTreeItemCollectionSource( - RootSymbolTreeItemSourceProvider provider, - TItem parentItem) : IAttachedCollectionSource, INotifyPropertyChanged - { - protected readonly RootSymbolTreeItemSourceProvider RootProvider = provider; - protected readonly TItem ParentItem = parentItem; - - protected readonly BulkObservableCollectionWithInit SymbolTreeItems = []; - - public object SourceItem { get; } = parentItem!; - public bool HasItems => !SymbolTreeItems.IsInitialized || SymbolTreeItems.Count > 0; - public IEnumerable Items => SymbolTreeItems; - - public event PropertyChangedEventHandler PropertyChanged = null!; - - protected void UpdateItems( - DocumentId documentId, - ISolutionExplorerSymbolTreeItemProvider itemProvider, - ImmutableArray items) - { - using (this.SymbolTreeItems.GetBulkOperation()) - { - if (items.Length == 0) - { - // If we got no items, clear everything out. - this.SymbolTreeItems.Clear(); - } - else - { - // We got some item datas. Attempt to reuse existing symbol tree items that match up to preserve - // identity in the tree between changes. - IncorporateNewItems(documentId, itemProvider, items); - } - } - - // Once we've been initialized once, mark us that way so that we we move out of the 'spinning/computing' state. - this.SymbolTreeItems.MarkAsInitialized(); - - // Notify any listenerrs that we may or may not have items now. - this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HasItems))); - } - - private void IncorporateNewItems( - DocumentId documentId, - ISolutionExplorerSymbolTreeItemProvider itemProvider, - ImmutableArray datas) - { - using var _ = Microsoft.CodeAnalysis.PooledObjects.PooledDictionary>.GetInstance(out var keyToItems); - foreach (var item in this.SymbolTreeItems) - keyToItems.MultiAdd(item.ItemKey, item); - - this.SymbolTreeItems.Clear(); - - foreach (var data in datas) - { - if (keyToItems.TryGetValue(data.Key, out var matchingItems)) - { - // Found a matching item we can use. Remove it from the list of items so we don't reuse it again. - var matchingItem = matchingItems[0]; - matchingItems.RemoveAt(0); - if (matchingItems.Count == 0) - keyToItems.Remove(data.Key); - - // And update it to point to the new data. - Contract.ThrowIfFalse(matchingItem.DocumentId == documentId); - Contract.ThrowIfFalse(matchingItem.ItemProvider == itemProvider); - Contract.ThrowIfFalse(matchingItem.ItemKey == data.Key); - - matchingItem.ItemSyntax = new(data.DeclarationNode, data.NavigationToken); - this.SymbolTreeItems.Add(matchingItem); - } - else - { - // If we didn't find an existing item, create a new one. - this.SymbolTreeItems.Add(new(this.RootProvider, documentId, itemProvider) - { - ItemKey = data.Key, - ItemSyntax = new(data.DeclarationNode, data.NavigationToken) - }); - } - } - } - } - private sealed class RootSymbolTreeItemCollectionSource( RootSymbolTreeItemSourceProvider provider, IVsHierarchyItem hierarchyItem) From 39588a22e2da1a71156e4b44197aa9a0a1e3a3af Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 11:04:11 +0200 Subject: [PATCH 042/353] Simplify --- .../AbstractSymbolTreeItemSourceProvider.cs | 29 +++++-------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs index 98fedc61df8cf..4ff4c2eb15c98 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs @@ -12,31 +12,18 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; -internal abstract class AbstractSymbolTreeItemSourceProvider : AttachedCollectionSourceProvider +internal abstract class AbstractSymbolTreeItemSourceProvider( + IThreadingContext threadingContext, + VisualStudioWorkspace workspace, + IAsynchronousOperationListenerProvider listenerProvider) : AttachedCollectionSourceProvider { - public readonly IThreadingContext ThreadingContext; - protected readonly Workspace Workspace; + public readonly IThreadingContext ThreadingContext = threadingContext; + protected readonly Workspace Workspace = workspace; - public readonly IAsynchronousOperationListener Listener; + public readonly IAsynchronousOperationListener Listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); private static readonly CancellationSeries s_navigationCancellationSeries = new(); - // private readonly IAnalyzersCommandHandler _commandHandler = commandHandler; - - // private IHierarchyItemToProjectIdMap? _projectMap; - - protected AbstractSymbolTreeItemSourceProvider( - IThreadingContext threadingContext, - VisualStudioWorkspace workspace, - IAsynchronousOperationListenerProvider listenerProvider - /*, -[Import(typeof(AnalyzersCommandHandler))] IAnalyzersCommandHandler commandHandler*/) - { - ThreadingContext = threadingContext; - Workspace = workspace; - Listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); - } - public void NavigateTo(SymbolTreeItem item, bool preview) { // Cancel any in flight navigation and kick off a new one. @@ -48,7 +35,7 @@ public void NavigateTo(SymbolTreeItem item, bool preview) ThreadingContext, Workspace, item.DocumentId, - item.Data.NavigationToken.SpanStart, + item.ItemSyntax.NavigationToken.SpanStart, virtualSpace: 0, // May be calling this on stale data. Allow the position to be invalid allowInvalidPosition: true, From 89908c8796f55f369a0d43107f160f3904757838 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 11:08:45 +0200 Subject: [PATCH 043/353] Simplify --- .../NonRootSymbolTreeItemSourceProvider.cs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs index a1d27d8d17aaa..cf9d14453812f 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs @@ -54,26 +54,19 @@ IAsynchronousOperationListenerProvider listenerProvider } private sealed class NonRootSymbolTreeItemCollectionSource( - SymbolTreeItem symbolTreeItem) - : IAttachedCollectionSource, ISupportExpansionEvents + RootSymbolTreeItemSourceProvider rootProvider, + SymbolTreeItem parentItem) + : AbstractSymbolTreeItemCollectionSource( + rootProvider, parentItem), ISupportExpansionEvents { - private readonly SymbolTreeItem _symbolTreeItem = symbolTreeItem; - - private readonly BulkObservableCollectionWithInit _symbolTreeItems = []; - private int _expanded = 0; - public object SourceItem => _symbolTreeItem; - public bool HasItems => _symbolTreeItem.Data.HasItems; - public IEnumerable Items => _symbolTreeItems; - public void BeforeExpand() { if (Interlocked.CompareExchange(ref _expanded, 1, 0) == 0) { - var provider = _symbolTreeItem.SourceProvider; - var token = provider.Listener.BeginAsyncOperation(nameof(BeforeExpand)); - var cancellationToken = provider.ThreadingContext.DisposalToken; + var token = this.RootProvider.Listener.BeginAsyncOperation(nameof(BeforeExpand)); + var cancellationToken = this.RootProvider.ThreadingContext.DisposalToken; BeforeExpandAsync(cancellationToken) .ReportNonFatalErrorUnlessCancelledAsync(cancellationToken) .CompletesAsyncOperation(token); From 11fbe8ab94d6fa42ce954a9a27117afa238ccf82 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 11:40:33 +0200 Subject: [PATCH 044/353] in progress --- .../SymbolTree/NonRootSymbolTreeItemSourceProvider.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs index cf9d14453812f..12165af3900c8 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs @@ -63,6 +63,7 @@ private sealed class NonRootSymbolTreeItemCollectionSource( public void BeforeExpand() { + // The very first time we are expanded, kick off the work to determine if (Interlocked.CompareExchange(ref _expanded, 1, 0) == 0) { var token = this.RootProvider.Listener.BeginAsyncOperation(nameof(BeforeExpand)); From f225e95c4b35e87dba11b7c391e63a0c4da466c5 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 12:08:06 +0200 Subject: [PATCH 045/353] in progress --- .../AbstractSymbolTreeItemCollectionSource.cs | 55 +++++++++---------- .../SymbolTree/SymbolTreeItem.cs | 46 ++++++++++++++-- 2 files changed, 68 insertions(+), 33 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemCollectionSource.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemCollectionSource.cs index 0201370173c23..dfa3ac69ff906 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemCollectionSource.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemCollectionSource.cs @@ -13,43 +13,30 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; -internal abstract class AbstractSymbolTreeItemCollectionSource( - RootSymbolTreeItemSourceProvider provider, - TItem parentItem) : IAttachedCollectionSource, INotifyPropertyChanged +internal sealed class SymbolTreeChildCollection(object parentItem) : IAttachedCollectionSource, INotifyPropertyChanged { - protected readonly RootSymbolTreeItemSourceProvider RootProvider = provider; - protected readonly TItem ParentItem = parentItem; - - protected readonly BulkObservableCollectionWithInit SymbolTreeItems = []; + private readonly BulkObservableCollectionWithInit _symbolTreeItems = []; - public object SourceItem { get; } = parentItem!; - public bool HasItems => !SymbolTreeItems.IsInitialized || SymbolTreeItems.Count > 0; - public IEnumerable Items => SymbolTreeItems; + public object SourceItem { get; } = parentItem; + public bool HasItems => !_symbolTreeItems.IsInitialized || _symbolTreeItems.Count > 0; + public IEnumerable Items => _symbolTreeItems; public event PropertyChangedEventHandler PropertyChanged = null!; - protected void UpdateItems( + public void UpdateItems( DocumentId documentId, ISolutionExplorerSymbolTreeItemProvider itemProvider, ImmutableArray items) { - using (this.SymbolTreeItems.GetBulkOperation()) + using (this._symbolTreeItems.GetBulkOperation()) { - if (items.Length == 0) - { - // If we got no items, clear everything out. - this.SymbolTreeItems.Clear(); - } - else - { - // We got some item datas. Attempt to reuse existing symbol tree items that match up to preserve - // identity in the tree between changes. - IncorporateNewItems(documentId, itemProvider, items); - } + // We got some item datas. Attempt to reuse existing symbol tree items that match up to preserve + // identity in the tree between changes. + IncorporateNewItems(documentId, itemProvider, items); } // Once we've been initialized once, mark us that way so that we we move out of the 'spinning/computing' state. - this.SymbolTreeItems.MarkAsInitialized(); + _symbolTreeItems.MarkAsInitialized(); // Notify any listenerrs that we may or may not have items now. this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HasItems))); @@ -61,10 +48,10 @@ private void IncorporateNewItems( ImmutableArray datas) { using var _ = PooledDictionary>.GetInstance(out var keyToItems); - foreach (var item in this.SymbolTreeItems) + foreach (var item in _symbolTreeItems) keyToItems.MultiAdd(item.ItemKey, item); - this.SymbolTreeItems.Clear(); + _symbolTreeItems.Clear(); foreach (var data in datas) { @@ -82,14 +69,13 @@ private void IncorporateNewItems( Contract.ThrowIfFalse(matchingItem.ItemKey == data.Key); matchingItem.ItemSyntax = new(data.DeclarationNode, data.NavigationToken); - this.SymbolTreeItems.Add(matchingItem); + _symbolTreeItems.Add(matchingItem); } else { // If we didn't find an existing item, create a new one. - this.SymbolTreeItems.Add(new(this.RootProvider, documentId, itemProvider) + _symbolTreeItems.Add(new(this.RootProvider, documentId, itemProvider, data.Key) { - ItemKey = data.Key, ItemSyntax = new(data.DeclarationNode, data.NavigationToken) }); } @@ -98,3 +84,14 @@ private void IncorporateNewItems( keyToItems.FreeValues(); } } + +internal abstract class AbstractSymbolTreeItemCollectionSource( + RootSymbolTreeItemSourceProvider provider, + TItem parentItem) : IAttachedCollectionSource, INotifyPropertyChanged +{ + protected readonly RootSymbolTreeItemSourceProvider RootProvider = provider; + protected readonly TItem ParentItem = parentItem; + + + +} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index 0b9928cd59b36..fff6dd9105064 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -10,6 +10,8 @@ using Microsoft.CodeAnalysis.Editor.Wpf; using System.Linq; using System; +using Microsoft.VisualStudio.Shell; +using System.Collections; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -35,16 +37,34 @@ internal readonly record struct SymbolTreeItemData( internal sealed class SymbolTreeItem( RootSymbolTreeItemSourceProvider sourceProvider, DocumentId documentId, - ISolutionExplorerSymbolTreeItemProvider itemProvider) + ISolutionExplorerSymbolTreeItemProvider itemProvider, + SymbolTreeItemKey itemKey) : BaseItem(canPreview: true), - IInvocationController + IInvocationController, + IAttachedCollectionSource, + ISupportExpansionEvents { public readonly RootSymbolTreeItemSourceProvider SourceProvider = sourceProvider; public readonly DocumentId DocumentId = documentId; public readonly ISolutionExplorerSymbolTreeItemProvider ItemProvider = itemProvider; + public readonly SymbolTreeItemKey ItemKey = itemKey; - public SymbolTreeItemKey ItemKey; - public SymbolTreeItemSyntax ItemSyntax; + private bool _expanded; + private SymbolTreeItemSyntax _itemSyntax; + + public SymbolTreeItemSyntax ItemSyntax + { + get => _itemSyntax; + set + { + _itemSyntax = value; + + // When we update the item syntax we can reset ourselves to the initial state (if collapsed). + // Then when we're expanded the next time, we'll recompute the child items properly. If we + // are already expanded, then recompute our children which will recursively push the change + // down further. + } + } public override string Name => this.ItemKey.Name; @@ -60,4 +80,22 @@ public bool Invoke(IEnumerable items, InputSource inputSource, bool prev SourceProvider.NavigateTo(item, preview); return true; } + + public void BeforeExpand() + { + Contract.ThrowIfFalse(SourceProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); + _expanded = true; + } + + public void AfterCollapse() + { + Contract.ThrowIfFalse(SourceProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); + _expanded = false; + } + + object IAttachedCollectionSource.SourceItem => this; + + bool IAttachedCollectionSource.HasItems => ; + + IEnumerable IAttachedCollectionSource.Items => throw new NotImplementedException(); } From 8b9ca75fc37db8aad9c459d4fdab242c430b2618 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 12:18:14 +0200 Subject: [PATCH 046/353] make the item into its own source --- ...ISolutionExplorerSymbolTreeItemProvider.cs | 2 +- .../SymbolTree/SymbolTreeItem.cs | 70 +++++++++++++------ 2 files changed, 51 insertions(+), 21 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs index dd6df7aa4f21a..effebaff332a5 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs @@ -13,5 +13,5 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore internal interface ISolutionExplorerSymbolTreeItemProvider : ILanguageService { Task> GetItemsAsync(Document document, CancellationToken cancellationToken); - ImmutableArray GetItems(SymbolTreeItemData item, CancellationToken cancellationToken); + ImmutableArray GetItems(SyntaxNode declarationNode, CancellationToken cancellationToken); } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index fff6dd9105064..526ce2c4f68f1 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -12,6 +12,7 @@ using System; using Microsoft.VisualStudio.Shell; using System.Collections; +using System.ComponentModel; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -25,33 +26,49 @@ internal readonly record struct SymbolTreeItemSyntax( SyntaxToken NavigationToken); internal readonly record struct SymbolTreeItemData( - string Name, - Glyph Glyph, - bool HasItems, - SyntaxNode DeclarationNode, - SyntaxToken NavigationToken) + SymbolTreeItemKey ItemKey, + SymbolTreeItemSyntax ItemSyntax) { - public SymbolTreeItemKey Key => new(Name, Glyph, HasItems); + public SymbolTreeItemData( + string name, + Glyph glyph, + bool hasItems, + SyntaxNode declarationNode, + SyntaxToken navigationToken) + : this(new(name, glyph, hasItems), new(declarationNode, navigationToken)) + { + } } -internal sealed class SymbolTreeItem( - RootSymbolTreeItemSourceProvider sourceProvider, - DocumentId documentId, - ISolutionExplorerSymbolTreeItemProvider itemProvider, - SymbolTreeItemKey itemKey) - : BaseItem(canPreview: true), +internal sealed class SymbolTreeItem : BaseItem, IInvocationController, IAttachedCollectionSource, - ISupportExpansionEvents + ISupportExpansionEvents, + INotifyPropertyChanged { - public readonly RootSymbolTreeItemSourceProvider SourceProvider = sourceProvider; - public readonly DocumentId DocumentId = documentId; - public readonly ISolutionExplorerSymbolTreeItemProvider ItemProvider = itemProvider; - public readonly SymbolTreeItemKey ItemKey = itemKey; + public readonly RootSymbolTreeItemSourceProvider SourceProvider; + public readonly DocumentId DocumentId; + public readonly ISolutionExplorerSymbolTreeItemProvider ItemProvider; + public readonly SymbolTreeItemKey ItemKey; + + private readonly SymbolTreeChildCollection _childCollection; private bool _expanded; private SymbolTreeItemSyntax _itemSyntax; + public SymbolTreeItem( + RootSymbolTreeItemSourceProvider sourceProvider, + DocumentId documentId, + ISolutionExplorerSymbolTreeItemProvider itemProvider, + SymbolTreeItemKey itemKey) : base(canPreview: true) + { + SourceProvider = sourceProvider; + DocumentId = documentId; + ItemProvider = itemProvider; + ItemKey = itemKey; + _childCollection = new(this); + } + public SymbolTreeItemSyntax ItemSyntax { get => _itemSyntax; @@ -63,6 +80,12 @@ public SymbolTreeItemSyntax ItemSyntax // Then when we're expanded the next time, we'll recompute the child items properly. If we // are already expanded, then recompute our children which will recursively push the change // down further. + if (_expanded) + { + var items = this.ItemProvider.GetItems( + value.DeclarationNode, this.SourceProvider.ThreadingContext.DisposalToken); + _childCollection.UpdateItems(this.DocumentId, this.ItemProvider, items); + } } } @@ -91,11 +114,18 @@ public void AfterCollapse() { Contract.ThrowIfFalse(SourceProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); _expanded = false; + _childCollection.Reset(); } - object IAttachedCollectionSource.SourceItem => this; + object IAttachedCollectionSource.SourceItem => _childCollection.SourceItem; - bool IAttachedCollectionSource.HasItems => ; + bool IAttachedCollectionSource.HasItems => _childCollection.HasItems; - IEnumerable IAttachedCollectionSource.Items => throw new NotImplementedException(); + IEnumerable IAttachedCollectionSource.Items => _childCollection.Items; + + event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged + { + add => _childCollection.PropertyChanged += value; + remove => _childCollection.PropertyChanged -= value; + } } From 4ada41b1ef6754f02c5cfd2dbb6ad81cb9ecc59d Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 12:30:41 +0200 Subject: [PATCH 047/353] in progress --- .../BulkObservableCollectionWithInit.cs | 24 ++++---- .../AbstractSymbolTreeItemCollectionSource.cs | 46 +++++++++----- .../NonRootSymbolTreeItemSourceProvider.cs | 60 +++++-------------- .../SymbolTree/SymbolTreeItem.cs | 45 ++++++++------ 4 files changed, 86 insertions(+), 89 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/BulkObservableCollectionWithInit.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/BulkObservableCollectionWithInit.cs index d390ad3ae45dd..5f3f57c922e5a 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/BulkObservableCollectionWithInit.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/BulkObservableCollectionWithInit.cs @@ -16,7 +16,20 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore /// internal sealed class BulkObservableCollectionWithInit : BulkObservableCollection, ISupportInitializeNotification { - public bool IsInitialized { get; private set; } = false; + private bool _isInitialized; + + public bool IsInitialized + { + get => _isInitialized; + set + { + if (_isInitialized != value) + { + _isInitialized = value; + Initialized?.Invoke(this, EventArgs.Empty); + } + } + } public event EventHandler? Initialized; @@ -27,13 +40,4 @@ void ISupportInitialize.BeginInit() void ISupportInitialize.EndInit() { } - - public void MarkAsInitialized() - { - if (!IsInitialized) - { - IsInitialized = true; - Initialized?.Invoke(this, EventArgs.Empty); - } - } } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemCollectionSource.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemCollectionSource.cs index dfa3ac69ff906..7b60388986ee8 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemCollectionSource.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemCollectionSource.cs @@ -23,7 +23,20 @@ internal sealed class SymbolTreeChildCollection(object parentItem) : IAttachedCo public event PropertyChangedEventHandler PropertyChanged = null!; + public void Reset() + { + _symbolTreeItems.Clear(); + + // Move back to the state where the children are not initialized. That way the next attemp to open + // them will compute them. + _symbolTreeItems.IsInitialized = false; + + // Notify any listenerrs that we may or may not have items now. + this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HasItems))); + } + public void UpdateItems( + RootSymbolTreeItemSourceProvider rootProvider, DocumentId documentId, ISolutionExplorerSymbolTreeItemProvider itemProvider, ImmutableArray items) @@ -32,17 +45,18 @@ public void UpdateItems( { // We got some item datas. Attempt to reuse existing symbol tree items that match up to preserve // identity in the tree between changes. - IncorporateNewItems(documentId, itemProvider, items); + IncorporateNewItems(rootProvider, documentId, itemProvider, items); } // Once we've been initialized once, mark us that way so that we we move out of the 'spinning/computing' state. - _symbolTreeItems.MarkAsInitialized(); + _symbolTreeItems.IsInitialized = true; // Notify any listenerrs that we may or may not have items now. this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HasItems))); } private void IncorporateNewItems( + RootSymbolTreeItemSourceProvider rootProvider, DocumentId documentId, ISolutionExplorerSymbolTreeItemProvider itemProvider, ImmutableArray datas) @@ -55,28 +69,28 @@ private void IncorporateNewItems( foreach (var data in datas) { - if (keyToItems.TryGetValue(data.Key, out var matchingItems)) + if (keyToItems.TryGetValue(data.ItemKey, out var matchingItems)) { // Found a matching item we can use. Remove it from the list of items so we don't reuse it again. var matchingItem = matchingItems[0]; matchingItems.RemoveAt(0); if (matchingItems.Count == 0) - keyToItems.Remove(data.Key); + keyToItems.Remove(data.ItemKey); - // And update it to point to the new data. + // And update it to point to the new syntax information. Contract.ThrowIfFalse(matchingItem.DocumentId == documentId); Contract.ThrowIfFalse(matchingItem.ItemProvider == itemProvider); - Contract.ThrowIfFalse(matchingItem.ItemKey == data.Key); + Contract.ThrowIfFalse(matchingItem.ItemKey == data.ItemKey); - matchingItem.ItemSyntax = new(data.DeclarationNode, data.NavigationToken); + matchingItem.ItemSyntax = data.ItemSyntax; _symbolTreeItems.Add(matchingItem); } else { // If we didn't find an existing item, create a new one. - _symbolTreeItems.Add(new(this.RootProvider, documentId, itemProvider, data.Key) + _symbolTreeItems.Add(new(rootProvider, documentId, itemProvider, data.ItemKey) { - ItemSyntax = new(data.DeclarationNode, data.NavigationToken) + ItemSyntax = data.ItemSyntax }); } } @@ -85,13 +99,13 @@ private void IncorporateNewItems( } } -internal abstract class AbstractSymbolTreeItemCollectionSource( - RootSymbolTreeItemSourceProvider provider, - TItem parentItem) : IAttachedCollectionSource, INotifyPropertyChanged -{ - protected readonly RootSymbolTreeItemSourceProvider RootProvider = provider; - protected readonly TItem ParentItem = parentItem; +//internal abstract class AbstractSymbolTreeItemCollectionSource( +// RootSymbolTreeItemSourceProvider provider, +// TItem parentItem) : IAttachedCollectionSource, INotifyPropertyChanged +//{ +// protected readonly RootSymbolTreeItemSourceProvider RootProvider = provider; +// protected readonly TItem ParentItem = parentItem; -} +//} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs index 12165af3900c8..371adfa6078c6 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs @@ -50,53 +50,23 @@ IAsynchronousOperationListenerProvider listenerProvider if (relationshipName != KnownRelationships.Contains) return null; - return new NonRootSymbolTreeItemCollectionSource(item); + // A SymbolTreeItem is its own collection source. In other words, it points at its own children + // and can be queried directly for them. + return item; } - private sealed class NonRootSymbolTreeItemCollectionSource( - RootSymbolTreeItemSourceProvider rootProvider, - SymbolTreeItem parentItem) - : AbstractSymbolTreeItemCollectionSource( - rootProvider, parentItem), ISupportExpansionEvents - { - private int _expanded = 0; - - public void BeforeExpand() - { - // The very first time we are expanded, kick off the work to determine - if (Interlocked.CompareExchange(ref _expanded, 1, 0) == 0) - { - var token = this.RootProvider.Listener.BeginAsyncOperation(nameof(BeforeExpand)); - var cancellationToken = this.RootProvider.ThreadingContext.DisposalToken; - BeforeExpandAsync(cancellationToken) - .ReportNonFatalErrorUnlessCancelledAsync(cancellationToken) - .CompletesAsyncOperation(token); - } - } - - private async Task BeforeExpandAsync(CancellationToken cancellationToken) - { - var items = await _symbolTreeItem.ItemProvider.GetItemsAsync( - _symbolTreeItem, cancellationToken).ConfigureAwait(false); - foreach (var item in items) - { - item.SourceProvider = _symbolTreeItem.SourceProvider; - item.ItemProvider = _symbolTreeItem.ItemProvider; - item.DocumentId = _symbolTreeItem.DocumentId; - } + //private sealed class NonRootSymbolTreeItemCollectionSource( + // RootSymbolTreeItemSourceProvider rootProvider, + // SymbolTreeItem parentItem) + // : AbstractSymbolTreeItemCollectionSource( + // rootProvider, parentItem), ISupportExpansionEvents + //{ + // private int _expanded = 0; - using (_symbolTreeItems.GetBulkOperation()) - { - _symbolTreeItems.Clear(); - _symbolTreeItems.AddRange(items); - } - _symbolTreeItems.MarkAsInitialized(); - } - - public void AfterCollapse() - { - // No op - } - } + // public void AfterCollapse() + // { + // // No op + // } + //} } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index 526ce2c4f68f1..27f3105f40a46 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -2,17 +2,16 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections; using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.Wpf; using Microsoft.Internal.VisualStudio.PlatformUI; -using Roslyn.Utilities; using Microsoft.VisualStudio.Imaging.Interop; -using Microsoft.CodeAnalysis.Editor.Wpf; -using System.Linq; -using System; using Microsoft.VisualStudio.Shell; -using System.Collections; -using System.ComponentModel; +using Roslyn.Utilities; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -75,17 +74,7 @@ public SymbolTreeItemSyntax ItemSyntax set { _itemSyntax = value; - - // When we update the item syntax we can reset ourselves to the initial state (if collapsed). - // Then when we're expanded the next time, we'll recompute the child items properly. If we - // are already expanded, then recompute our children which will recursively push the change - // down further. - if (_expanded) - { - var items = this.ItemProvider.GetItems( - value.DeclarationNode, this.SourceProvider.ThreadingContext.DisposalToken); - _childCollection.UpdateItems(this.DocumentId, this.ItemProvider, items); - } + UpdateChildren(); } } @@ -108,13 +97,33 @@ public void BeforeExpand() { Contract.ThrowIfFalse(SourceProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); _expanded = true; + UpdateChildren(); } public void AfterCollapse() { Contract.ThrowIfFalse(SourceProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); _expanded = false; - _childCollection.Reset(); + UpdateChildren(); + } + + private void UpdateChildren() + { + if (_expanded) + { + // When we update the item syntax we can reset ourselves to the initial state (if collapsed). + // Then when we're expanded the next time, we'll recompute the child items properly. If we + // are already expanded, then recompute our children which will recursively push the change + // down further. + var items = this.ItemProvider.GetItems( + _itemSyntax.DeclarationNode, this.SourceProvider.ThreadingContext.DisposalToken); + _childCollection.UpdateItems(this.DocumentId, this.ItemProvider, items); + } + else + { + // Otherwise, return the child collection to the uninitialized state. + _childCollection.Reset(); + } } object IAttachedCollectionSource.SourceItem => _childCollection.SourceItem; From b3310d4a995e27fd8a8995cbfddfd4f5590c49a2 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 12:36:00 +0200 Subject: [PATCH 048/353] in progress --- .../RootSymbolTreeItemSourceProvider.cs | 48 ++++++++++++++----- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index f6f7c88c8c330..895e2656cd572 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -3,8 +3,10 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections; using System.Collections.Generic; using System.Collections.Immutable; +using System.ComponentModel; using System.ComponentModel.Composition; using System.Diagnostics.CodeAnalysis; using System.Threading; @@ -46,9 +48,7 @@ internal sealed class RootSymbolTreeItemSourceProvider : AbstractSymbolTreeItemS public RootSymbolTreeItemSourceProvider( IThreadingContext threadingContext, VisualStudioWorkspace workspace, - IAsynchronousOperationListenerProvider listenerProvider - /*, - [Import(typeof(AnalyzersCommandHandler))] IAnalyzersCommandHandler commandHandler*/) + IAsynchronousOperationListenerProvider listenerProvider) : base(threadingContext, workspace, listenerProvider) { _updateSourcesQueue = new AsyncBatchingWorkQueue( @@ -140,13 +140,24 @@ await RoslynParallel.ForEachAsync( //return null; } - private sealed class RootSymbolTreeItemCollectionSource( - RootSymbolTreeItemSourceProvider provider, - IVsHierarchyItem hierarchyItem) - : AbstractSymbolTreeItemCollectionSource(provider, hierarchyItem) + private sealed class RootSymbolTreeItemCollectionSource : IAttachedCollectionSource, INotifyPropertyChanged { + private readonly RootSymbolTreeItemSourceProvider _rootProvider; + private readonly IVsHierarchyItem _hierarchyItem; + + private readonly SymbolTreeChildCollection _childCollection; + private DocumentId? _documentId; + public RootSymbolTreeItemCollectionSource( + RootSymbolTreeItemSourceProvider rootProvider, + IVsHierarchyItem hierarchyItem) + { + _rootProvider = rootProvider; + _hierarchyItem = hierarchyItem; + _childCollection = new(hierarchyItem); + } + internal async Task UpdateIfAffectedAsync( HashSet updateSet, CancellationToken cancellationToken) { @@ -157,8 +168,7 @@ internal async Task UpdateIfAffectedAsync( return; // If we didn't have a doc id, or we failed for any reason, clear out all our items. - using (this.SymbolTreeItems.GetBulkOperation()) - SymbolTreeItems.Clear(); + _childCollection.Clear(); } private async ValueTask TryUpdateItemsAsync( @@ -171,7 +181,7 @@ private async ValueTask TryUpdateItemsAsync( return true; } - var solution = this.RootProvider.Workspace.CurrentSolution; + var solution = _rootProvider.Workspace.CurrentSolution; var document = solution.GetDocument(documentId); // If we can't find this document anymore, clear everything out. @@ -183,7 +193,7 @@ private async ValueTask TryUpdateItemsAsync( return false; var items = await itemProvider.GetItemsAsync(document, cancellationToken).ConfigureAwait(false); - this.UpdateItems(documentId, itemProvider, items); + _childCollection.UpdateItems(_rootProvider, documentId, itemProvider, items); return true; } @@ -191,11 +201,23 @@ private async ValueTask TryUpdateItemsAsync( { if (_documentId == null) { - var idMap = this.RootProvider.Workspace.Services.GetService(); - idMap?.TryGetDocumentId(this.ParentItem, targetFrameworkMoniker: null, out _documentId); + var idMap = _rootProvider.Workspace.Services.GetService(); + idMap?.TryGetDocumentId(_hierarchyItem, targetFrameworkMoniker: null, out _documentId); } return _documentId; } + + object IAttachedCollectionSource.SourceItem => _childCollection.SourceItem; + + bool IAttachedCollectionSource.HasItems => _childCollection.HasItems; + + IEnumerable IAttachedCollectionSource.Items => _childCollection.Items; + + event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged + { + add => _childCollection.PropertyChanged += value; + remove => _childCollection.PropertyChanged -= value; + } } } From d34f33dba50b3966bd1f1e60a8403aea3be7c13e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 12:36:24 +0200 Subject: [PATCH 049/353] Rename --- ...TreeItemCollectionSource.cs => SymbolTreeChildCollection.cs} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/{AbstractSymbolTreeItemCollectionSource.cs => SymbolTreeChildCollection.cs} (98%) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemCollectionSource.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs similarity index 98% rename from src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemCollectionSource.cs rename to src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs index 7b60388986ee8..6092431a231bc 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemCollectionSource.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs @@ -21,7 +21,7 @@ internal sealed class SymbolTreeChildCollection(object parentItem) : IAttachedCo public bool HasItems => !_symbolTreeItems.IsInitialized || _symbolTreeItems.Count > 0; public IEnumerable Items => _symbolTreeItems; - public event PropertyChangedEventHandler PropertyChanged = null!; + public event PropertyChangedEventHandler? PropertyChanged; public void Reset() { From 70cf486446a2e58754cbc638395498287c28bfbc Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 12:39:52 +0200 Subject: [PATCH 050/353] Simplify --- .../SymbolTree/SymbolTreeChildCollection.cs | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs index 6092431a231bc..264b19f3ff9c1 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs @@ -6,10 +6,10 @@ using System.Collections.Immutable; using System.ComponentModel; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.VisualStudio.LanguageServices.Extensions; using Microsoft.VisualStudio.Shell; using Roslyn.Utilities; -using Microsoft.CodeAnalysis.PooledObjects; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -18,12 +18,18 @@ internal sealed class SymbolTreeChildCollection(object parentItem) : IAttachedCo private readonly BulkObservableCollectionWithInit _symbolTreeItems = []; public object SourceItem { get; } = parentItem; + + /// + /// Whether or not we think we have items. If we aren't fully initialized, then we'll guess that we do have items. + /// Once fully initialized, we'll return the real result based on what is in our child item list. + /// public bool HasItems => !_symbolTreeItems.IsInitialized || _symbolTreeItems.Count > 0; + public IEnumerable Items => _symbolTreeItems; public event PropertyChangedEventHandler? PropertyChanged; - public void Reset() + public void ResetToUncomputedState() { _symbolTreeItems.Clear(); @@ -35,7 +41,7 @@ public void Reset() this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HasItems))); } - public void UpdateItems( + public void SetItems( RootSymbolTreeItemSourceProvider rootProvider, DocumentId documentId, ISolutionExplorerSymbolTreeItemProvider itemProvider, @@ -48,6 +54,22 @@ public void UpdateItems( IncorporateNewItems(rootProvider, documentId, itemProvider, items); } + MarkComputed(); + } + + public void Clear() + { + using (this._symbolTreeItems.GetBulkOperation()) + { + _symbolTreeItems.Clear(); + } + + + MarkComputed(); + } + + private void MarkComputed() + { // Once we've been initialized once, mark us that way so that we we move out of the 'spinning/computing' state. _symbolTreeItems.IsInitialized = true; @@ -65,6 +87,8 @@ private void IncorporateNewItems( foreach (var item in _symbolTreeItems) keyToItems.MultiAdd(item.ItemKey, item); + // Clear out the old items we have. Then go through setting the final list of items. + // Attempt to reuse old items if they have the same visible data from before. _symbolTreeItems.Clear(); foreach (var data in datas) @@ -77,11 +101,11 @@ private void IncorporateNewItems( if (matchingItems.Count == 0) keyToItems.Remove(data.ItemKey); - // And update it to point to the new syntax information. Contract.ThrowIfFalse(matchingItem.DocumentId == documentId); Contract.ThrowIfFalse(matchingItem.ItemProvider == itemProvider); Contract.ThrowIfFalse(matchingItem.ItemKey == data.ItemKey); + // And update it to point to the new syntax information. matchingItem.ItemSyntax = data.ItemSyntax; _symbolTreeItems.Add(matchingItem); } From a18a20c87164230364972f584aed10a7adc7369d Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 12:43:33 +0200 Subject: [PATCH 051/353] Compute --- .../ISymbolTreeItemNavigationProvider.cs | 10 ------- .../SymbolTree/SymbolTreeItem.cs | 26 ++++++++++++------- 2 files changed, 17 insertions(+), 19 deletions(-) delete mode 100644 src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISymbolTreeItemNavigationProvider.cs diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISymbolTreeItemNavigationProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISymbolTreeItemNavigationProvider.cs deleted file mode 100644 index bf287971ca2f3..0000000000000 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISymbolTreeItemNavigationProvider.cs +++ /dev/null @@ -1,10 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; - -//internal interface ISymbolTreeItemNavigationProvider -//{ -// void NavigateTo(SymbolTreeItem item, bool preview); -//} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index 27f3105f40a46..194f5d17a29e4 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -39,13 +39,18 @@ public SymbolTreeItemData( } } +/// +/// Actual in-memory object that will be presented in the solution explorer tree. Note: +/// we attempt to reuse instances of these to maintain visual persistence (like selection state) +/// when items are recomputed. +/// internal sealed class SymbolTreeItem : BaseItem, IInvocationController, IAttachedCollectionSource, ISupportExpansionEvents, INotifyPropertyChanged { - public readonly RootSymbolTreeItemSourceProvider SourceProvider; + public readonly RootSymbolTreeItemSourceProvider RootProvider; public readonly DocumentId DocumentId; public readonly ISolutionExplorerSymbolTreeItemProvider ItemProvider; public readonly SymbolTreeItemKey ItemKey; @@ -56,12 +61,12 @@ internal sealed class SymbolTreeItem : BaseItem, private SymbolTreeItemSyntax _itemSyntax; public SymbolTreeItem( - RootSymbolTreeItemSourceProvider sourceProvider, + RootSymbolTreeItemSourceProvider rootProvider, DocumentId documentId, ISolutionExplorerSymbolTreeItemProvider itemProvider, SymbolTreeItemKey itemKey) : base(canPreview: true) { - SourceProvider = sourceProvider; + RootProvider = rootProvider; DocumentId = documentId; ItemProvider = itemProvider; ItemKey = itemKey; @@ -73,6 +78,9 @@ public SymbolTreeItemSyntax ItemSyntax get => _itemSyntax; set { + // When the syntax node for this item is changed, we want to recompute the children for it + // (if this node is expanded). Otherwise, we can just throw away what we have and recompute + // the next time when asked. _itemSyntax = value; UpdateChildren(); } @@ -89,20 +97,20 @@ public bool Invoke(IEnumerable items, InputSource inputSource, bool prev if (items.FirstOrDefault() is not SymbolTreeItem item) return false; - SourceProvider.NavigateTo(item, preview); + RootProvider.NavigateTo(item, preview); return true; } public void BeforeExpand() { - Contract.ThrowIfFalse(SourceProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); + Contract.ThrowIfFalse(RootProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); _expanded = true; UpdateChildren(); } public void AfterCollapse() { - Contract.ThrowIfFalse(SourceProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); + Contract.ThrowIfFalse(RootProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); _expanded = false; UpdateChildren(); } @@ -116,13 +124,13 @@ private void UpdateChildren() // are already expanded, then recompute our children which will recursively push the change // down further. var items = this.ItemProvider.GetItems( - _itemSyntax.DeclarationNode, this.SourceProvider.ThreadingContext.DisposalToken); - _childCollection.UpdateItems(this.DocumentId, this.ItemProvider, items); + _itemSyntax.DeclarationNode, this.RootProvider.ThreadingContext.DisposalToken); + _childCollection.SetItems(this.RootProvider, this.DocumentId, this.ItemProvider, items); } else { // Otherwise, return the child collection to the uninitialized state. - _childCollection.Reset(); + _childCollection.ResetToUncomputedState(); } } From a81eb060b5f5042bc2c8762fcaddcb5e00d9bed7 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 12:44:09 +0200 Subject: [PATCH 052/353] Simplify --- .../NonRootSymbolTreeItemSourceProvider.cs | 50 +++---------------- 1 file changed, 7 insertions(+), 43 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs index 371adfa6078c6..821e6dcbf27d3 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs @@ -2,27 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Immutable; using System.ComponentModel.Composition; using System.Diagnostics.CodeAnalysis; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Shared.TestHooks; -using Microsoft.CodeAnalysis.Threading; using Microsoft.Internal.VisualStudio.PlatformUI; -using Microsoft.VisualStudio.Language.Intellisense; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Utilities; -using Roslyn.Utilities; -using Microsoft.VisualStudio.LanguageServices.Extensions; -using Microsoft.CodeAnalysis.Host; -using Microsoft.CodeAnalysis.Shared.Extensions; -using Microsoft.CodeAnalysis.ErrorReporting; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -30,21 +16,14 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore [Name(nameof(NonRootSymbolTreeItemSourceProvider))] [Order(Before = HierarchyItemsProviderNames.Contains)] [AppliesToProject("CSharp | VB")] -internal sealed class NonRootSymbolTreeItemSourceProvider : AbstractSymbolTreeItemSourceProvider +[method: SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] +[method: ImportingConstructor] +internal sealed class NonRootSymbolTreeItemSourceProvider( + IThreadingContext threadingContext, + VisualStudioWorkspace workspace, + IAsynchronousOperationListenerProvider listenerProvider) + : AbstractSymbolTreeItemSourceProvider(threadingContext, workspace, listenerProvider) { - [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] - [ImportingConstructor] - public NonRootSymbolTreeItemSourceProvider( - IThreadingContext threadingContext, - VisualStudioWorkspace workspace, - IAsynchronousOperationListenerProvider listenerProvider - /*, -[Import(typeof(AnalyzersCommandHandler))] IAnalyzersCommandHandler commandHandler*/) - : base(threadingContext, workspace, listenerProvider) - { - - } - protected override IAttachedCollectionSource? CreateCollectionSource(SymbolTreeItem item, string relationshipName) { if (relationshipName != KnownRelationships.Contains) @@ -54,19 +33,4 @@ IAsynchronousOperationListenerProvider listenerProvider // and can be queried directly for them. return item; } - - //private sealed class NonRootSymbolTreeItemCollectionSource( - // RootSymbolTreeItemSourceProvider rootProvider, - // SymbolTreeItem parentItem) - // : AbstractSymbolTreeItemCollectionSource( - // rootProvider, parentItem), ISupportExpansionEvents - //{ - // private int _expanded = 0; - - - // public void AfterCollapse() - // { - // // No op - // } - //} } From 96a5b41e13e99c38b0c396234a43123c77afeba9 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 12:48:28 +0200 Subject: [PATCH 053/353] Simplify --- .../SymbolTree/SymbolTreeChildCollection.cs | 36 +++++++++++-------- .../SymbolTree/SymbolTreeItem.cs | 2 +- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs index 264b19f3ff9c1..64fbd6f97c9bd 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs @@ -13,7 +13,11 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; -internal sealed class SymbolTreeChildCollection(object parentItem) : IAttachedCollectionSource, INotifyPropertyChanged +/// If non-null, the known value for . If null, +/// then only known once is initialized +internal sealed class SymbolTreeChildCollection( + object parentItem, + bool? hasItems) : IAttachedCollectionSource, INotifyPropertyChanged { private readonly BulkObservableCollectionWithInit _symbolTreeItems = []; @@ -23,7 +27,23 @@ internal sealed class SymbolTreeChildCollection(object parentItem) : IAttachedCo /// Whether or not we think we have items. If we aren't fully initialized, then we'll guess that we do have items. /// Once fully initialized, we'll return the real result based on what is in our child item list. /// - public bool HasItems => !_symbolTreeItems.IsInitialized || _symbolTreeItems.Count > 0; + public bool HasItems + { + get + { + // Owner initialized us with a known value for this property. Can just return that value. + if (hasItems.HasValue) + return hasItems.Value; + + // If we're not initialized yet, we don't know if we have values or not. Return that we are + // so the user can at least try to expand this node. + if (!_symbolTreeItems.IsInitialized) + return true; + + // We are initialized. So return the actual state based on what has been computed. + return _symbolTreeItems.Count > 0; + } + } public IEnumerable Items => _symbolTreeItems; @@ -64,7 +84,6 @@ public void Clear() _symbolTreeItems.Clear(); } - MarkComputed(); } @@ -122,14 +141,3 @@ private void IncorporateNewItems( keyToItems.FreeValues(); } } - -//internal abstract class AbstractSymbolTreeItemCollectionSource( -// RootSymbolTreeItemSourceProvider provider, -// TItem parentItem) : IAttachedCollectionSource, INotifyPropertyChanged -//{ -// protected readonly RootSymbolTreeItemSourceProvider RootProvider = provider; -// protected readonly TItem ParentItem = parentItem; - - - -//} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index 194f5d17a29e4..ed425dcbee431 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -70,7 +70,7 @@ public SymbolTreeItem( DocumentId = documentId; ItemProvider = itemProvider; ItemKey = itemKey; - _childCollection = new(this); + _childCollection = new(this, hasItems: ItemKey.HasItems); } public SymbolTreeItemSyntax ItemSyntax From 3c442aea1db00bee5e93e0fa4cab9902fc806561 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 12:51:02 +0200 Subject: [PATCH 054/353] Simplify --- .../RootSymbolTreeItemSourceProvider.cs | 24 ++++++------------- .../SymbolTree/SymbolTreeChildCollection.cs | 4 ++-- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index 895e2656cd572..2d635c62bce58 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -21,7 +21,6 @@ using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Threading; using Microsoft.Internal.VisualStudio.PlatformUI; -using Microsoft.VisualStudio.LanguageServices.Extensions; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Utilities; @@ -39,10 +38,6 @@ internal sealed class RootSymbolTreeItemSourceProvider : AbstractSymbolTreeItemS private readonly AsyncBatchingWorkQueue _updateSourcesQueue; - // private readonly IAnalyzersCommandHandler _commandHandler = commandHandler; - - // private IHierarchyItemToProjectIdMap? _projectMap; - [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] [ImportingConstructor] public RootSymbolTreeItemSourceProvider( @@ -130,14 +125,6 @@ await RoslynParallel.ForEachAsync( var source = new RootSymbolTreeItemCollectionSource(this, item); _weakCollectionSources.Add(new WeakReference(source)); return source; - //var hierarchyMapper = TryGetProjectMap(); - //if (hierarchyMapper == null || - // !hierarchyMapper.TryGetDocumentId(item, targetFrameworkMoniker: null, out var documentId)) - //{ - // return null; - //} - - //return null; } private sealed class RootSymbolTreeItemCollectionSource : IAttachedCollectionSource, INotifyPropertyChanged @@ -155,7 +142,9 @@ public RootSymbolTreeItemCollectionSource( { _rootProvider = rootProvider; _hierarchyItem = hierarchyItem; - _childCollection = new(hierarchyItem); + + // Mark hasItems as null as we don't know up front if we have items, and instead have to compute it on demand. + _childCollection = new(hierarchyItem, hasItems: null); } internal async Task UpdateIfAffectedAsync( @@ -167,8 +156,9 @@ internal async Task UpdateIfAffectedAsync( if (documentId != null && await TryUpdateItemsAsync(updateSet, documentId, cancellationToken).ConfigureAwait(false)) return; - // If we didn't have a doc id, or we failed for any reason, clear out all our items. - _childCollection.Clear(); + // If we didn't have a doc id, or we failed for any reason, clear out all our items and set that as our + // current state. + _childCollection.ClearAndMarkComputed(); } private async ValueTask TryUpdateItemsAsync( @@ -193,7 +183,7 @@ private async ValueTask TryUpdateItemsAsync( return false; var items = await itemProvider.GetItemsAsync(document, cancellationToken).ConfigureAwait(false); - _childCollection.UpdateItems(_rootProvider, documentId, itemProvider, items); + _childCollection.SetItemsAndMarkComputed(_rootProvider, documentId, itemProvider, items); return true; } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs index 64fbd6f97c9bd..e14ff299e302c 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs @@ -61,7 +61,7 @@ public void ResetToUncomputedState() this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HasItems))); } - public void SetItems( + public void SetItemsAndMarkComputed( RootSymbolTreeItemSourceProvider rootProvider, DocumentId documentId, ISolutionExplorerSymbolTreeItemProvider itemProvider, @@ -77,7 +77,7 @@ public void SetItems( MarkComputed(); } - public void Clear() + public void ClearAndMarkComputed() { using (this._symbolTreeItems.GetBulkOperation()) { From 1ae1a9733ca8a1fed124f450f86249acf7039cdc Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 12:52:12 +0200 Subject: [PATCH 055/353] Simplify --- .../SymbolTree/NonRootSymbolTreeItemSourceProvider.cs | 9 ++------- .../SymbolTree/RootSymbolTreeItemSourceProvider.cs | 1 + 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs index 821e6dcbf27d3..02a62e1fb44f4 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs @@ -4,8 +4,6 @@ using System.ComponentModel.Composition; using System.Diagnostics.CodeAnalysis; -using Microsoft.CodeAnalysis.Editor.Shared.Utilities; -using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.Internal.VisualStudio.PlatformUI; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Utilities; @@ -18,11 +16,8 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore [AppliesToProject("CSharp | VB")] [method: SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] [method: ImportingConstructor] -internal sealed class NonRootSymbolTreeItemSourceProvider( - IThreadingContext threadingContext, - VisualStudioWorkspace workspace, - IAsynchronousOperationListenerProvider listenerProvider) - : AbstractSymbolTreeItemSourceProvider(threadingContext, workspace, listenerProvider) +internal sealed class NonRootSymbolTreeItemSourceProvider() + : AttachedCollectionSourceProvider { protected override IAttachedCollectionSource? CreateCollectionSource(SymbolTreeItem item, string relationshipName) { diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index 2d635c62bce58..61b05270b472d 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -9,6 +9,7 @@ using System.ComponentModel; using System.ComponentModel.Composition; using System.Diagnostics.CodeAnalysis; + using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; From 16e6f35e3eb08f3b93ab3555eb6519d1b5dfb76d Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 12:56:20 +0200 Subject: [PATCH 056/353] Simplify --- .../AbstractSymbolTreeItemSourceProvider.cs | 45 -------------- .../RootSymbolTreeItemSourceProvider.cs | 61 ++++++++++++------- 2 files changed, 40 insertions(+), 66 deletions(-) delete mode 100644 src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs deleted file mode 100644 index 4ff4c2eb15c98..0000000000000 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/AbstractSymbolTreeItemSourceProvider.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Editor.Shared.Utilities; -using Microsoft.CodeAnalysis.ErrorReporting; -using Microsoft.CodeAnalysis.Shared.TestHooks; -using Microsoft.CodeAnalysis.Threading; -using Microsoft.Internal.VisualStudio.PlatformUI; -using Microsoft.CodeAnalysis.Navigation; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; - -internal abstract class AbstractSymbolTreeItemSourceProvider( - IThreadingContext threadingContext, - VisualStudioWorkspace workspace, - IAsynchronousOperationListenerProvider listenerProvider) : AttachedCollectionSourceProvider -{ - public readonly IThreadingContext ThreadingContext = threadingContext; - protected readonly Workspace Workspace = workspace; - - public readonly IAsynchronousOperationListener Listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); - - private static readonly CancellationSeries s_navigationCancellationSeries = new(); - - public void NavigateTo(SymbolTreeItem item, bool preview) - { - // Cancel any in flight navigation and kick off a new one. - var cancellationToken = s_navigationCancellationSeries.CreateNext(this.ThreadingContext.DisposalToken); - var navigationService = Workspace.Services.GetRequiredService(); - - var token = Listener.BeginAsyncOperation(nameof(NavigateTo)); - navigationService.TryNavigateToPositionAsync( - ThreadingContext, - Workspace, - item.DocumentId, - item.ItemSyntax.NavigationToken.SpanStart, - virtualSpace: 0, - // May be calling this on stale data. Allow the position to be invalid - allowInvalidPosition: true, - new NavigationOptions(PreferProvisionalTab: preview), - cancellationToken).ReportNonFatalErrorUnlessCancelledAsync(cancellationToken).CompletesAsyncOperation(token); - } -} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index 61b05270b472d..3934a7253986f 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -9,7 +9,6 @@ using System.ComponentModel; using System.ComponentModel.Composition; using System.Diagnostics.CodeAnalysis; - using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; @@ -17,6 +16,7 @@ using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Navigation; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.Shared.Utilities; @@ -33,11 +33,16 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore [Name(nameof(RootSymbolTreeItemSourceProvider))] [Order(Before = HierarchyItemsProviderNames.Contains)] [AppliesToProject("CSharp | VB")] -internal sealed class RootSymbolTreeItemSourceProvider : AbstractSymbolTreeItemSourceProvider +internal sealed class RootSymbolTreeItemSourceProvider : AttachedCollectionSourceProvider { private readonly ConcurrentSet> _weakCollectionSources = []; private readonly AsyncBatchingWorkQueue _updateSourcesQueue; + private readonly Workspace _workspace; + private readonly CancellationSeries _navigationCancellationSeries = new(); + + public readonly IThreadingContext ThreadingContext; + public readonly IAsynchronousOperationListener Listener; [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] [ImportingConstructor] @@ -45,8 +50,11 @@ public RootSymbolTreeItemSourceProvider( IThreadingContext threadingContext, VisualStudioWorkspace workspace, IAsynchronousOperationListenerProvider listenerProvider) - : base(threadingContext, workspace, listenerProvider) { + ThreadingContext = threadingContext; + _workspace = workspace; + Listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); + _updateSourcesQueue = new AsyncBatchingWorkQueue( DelayTimeSpan.Medium, UpdateCollectionSourcesAsync, @@ -54,7 +62,7 @@ public RootSymbolTreeItemSourceProvider( this.Listener, this.ThreadingContext.DisposalToken); - this.Workspace.RegisterWorkspaceChangedHandler( + this._workspace.RegisterWorkspaceChangedHandler( e => { if (e is { Kind: WorkspaceChangeKind.DocumentChanged or WorkspaceChangeKind.DocumentAdded, DocumentId: not null }) @@ -63,6 +71,25 @@ public RootSymbolTreeItemSourceProvider( options: new WorkspaceEventOptions(RequiresMainThread: false)); } + public void NavigateTo(SymbolTreeItem item, bool preview) + { + // Cancel any in flight navigation and kick off a new one. + var cancellationToken = _navigationCancellationSeries.CreateNext(this.ThreadingContext.DisposalToken); + var navigationService = _workspace.Services.GetRequiredService(); + + var token = Listener.BeginAsyncOperation(nameof(NavigateTo)); + navigationService.TryNavigateToPositionAsync( + ThreadingContext, + _workspace, + item.DocumentId, + item.ItemSyntax.NavigationToken.SpanStart, + virtualSpace: 0, + // May be calling this on stale data. Allow the position to be invalid + allowInvalidPosition: true, + new NavigationOptions(PreferProvisionalTab: preview), + cancellationToken).ReportNonFatalErrorUnlessCancelledAsync(cancellationToken).CompletesAsyncOperation(token); + } + private async ValueTask UpdateCollectionSourcesAsync( ImmutableSegmentedList documentIds, CancellationToken cancellationToken) { @@ -128,26 +155,18 @@ await RoslynParallel.ForEachAsync( return source; } - private sealed class RootSymbolTreeItemCollectionSource : IAttachedCollectionSource, INotifyPropertyChanged + private sealed class RootSymbolTreeItemCollectionSource( + RootSymbolTreeItemSourceProvider rootProvider, + IVsHierarchyItem hierarchyItem) : IAttachedCollectionSource, INotifyPropertyChanged { - private readonly RootSymbolTreeItemSourceProvider _rootProvider; - private readonly IVsHierarchyItem _hierarchyItem; + private readonly RootSymbolTreeItemSourceProvider _rootProvider = rootProvider; + private readonly IVsHierarchyItem _hierarchyItem = hierarchyItem; - private readonly SymbolTreeChildCollection _childCollection; + // Mark hasItems as null as we don't know up front if we have items, and instead have to compute it on demand. + private readonly SymbolTreeChildCollection _childCollection = new(hierarchyItem, hasItems: null); private DocumentId? _documentId; - public RootSymbolTreeItemCollectionSource( - RootSymbolTreeItemSourceProvider rootProvider, - IVsHierarchyItem hierarchyItem) - { - _rootProvider = rootProvider; - _hierarchyItem = hierarchyItem; - - // Mark hasItems as null as we don't know up front if we have items, and instead have to compute it on demand. - _childCollection = new(hierarchyItem, hasItems: null); - } - internal async Task UpdateIfAffectedAsync( HashSet updateSet, CancellationToken cancellationToken) { @@ -172,7 +191,7 @@ private async ValueTask TryUpdateItemsAsync( return true; } - var solution = _rootProvider.Workspace.CurrentSolution; + var solution = _rootProvider._workspace.CurrentSolution; var document = solution.GetDocument(documentId); // If we can't find this document anymore, clear everything out. @@ -192,7 +211,7 @@ private async ValueTask TryUpdateItemsAsync( { if (_documentId == null) { - var idMap = _rootProvider.Workspace.Services.GetService(); + var idMap = _rootProvider._workspace.Services.GetService(); idMap?.TryGetDocumentId(_hierarchyItem, targetFrameworkMoniker: null, out _documentId); } From 03408e4aed4b32c5ded6bbe94d888519531e03a1 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 13:01:59 +0200 Subject: [PATCH 057/353] Update c# --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 65 +++++++++++-------- .../SourceGeneratedFileItemSource.cs | 2 +- .../SymbolTree/SymbolTreeItem.cs | 2 +- 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index 2afb604965c8e..e2cdd5913540d 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -28,19 +28,19 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.SolutionExplorer; [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] internal sealed class CSharpSolutionExplorerSymbolTreeItemProvider() : ISolutionExplorerSymbolTreeItemProvider { - public async Task> GetItemsAsync( + public async Task> GetItemsAsync( Document document, CancellationToken cancellationToken) { var root = (CompilationUnitSyntax)await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - using var _ = ArrayBuilder.GetInstance(out var items); + using var _ = ArrayBuilder.GetInstance(out var items); AddTopLevelTypes(root, items, cancellationToken); return items.ToImmutableAndClear(); } - private static void AddTopLevelTypes(CompilationUnitSyntax root, ArrayBuilder items, CancellationToken cancellationToken) + private static void AddTopLevelTypes(CompilationUnitSyntax root, ArrayBuilder items, CancellationToken cancellationToken) { foreach (var member in root.Members) { @@ -53,7 +53,7 @@ private static void AddTopLevelTypes(CompilationUnitSyntax root, ArrayBuilder items, CancellationToken cancellationToken) + private static void AddTopLevelTypes(BaseNamespaceDeclarationSyntax baseNamespace, ArrayBuilder items, CancellationToken cancellationToken) { foreach (var member in baseNamespace.Members) { @@ -66,7 +66,7 @@ private static void AddTopLevelTypes(BaseNamespaceDeclarationSyntax baseNamespac } } - private static bool TryAddType(MemberDeclarationSyntax member, ArrayBuilder items, CancellationToken cancellationToken) + private static bool TryAddType(MemberDeclarationSyntax member, ArrayBuilder items, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); switch (member) @@ -91,11 +91,11 @@ private static bool TryAddType(MemberDeclarationSyntax member, ArrayBuilder GetItems(SymbolTreeItem item, CancellationToken cancellationToken) + public ImmutableArray GetItems(SyntaxNode node, CancellationToken cancellationToken) { - using var _ = ArrayBuilder.GetInstance(out var items); + using var _ = ArrayBuilder.GetInstance(out var items); - var memberDeclaration = (MemberDeclarationSyntax)item.SyntaxNode; + var memberDeclaration = (MemberDeclarationSyntax)node; switch (memberDeclaration) { case EnumDeclarationSyntax enumDeclaration: @@ -110,7 +110,7 @@ public ImmutableArray GetItems(SymbolTreeItem item, Cancellation return items.ToImmutableAndClear(); } - private static void AddTypeDeclarationMembers(TypeDeclarationSyntax typeDeclaration, ArrayBuilder items, CancellationToken cancellationToken) + private static void AddTypeDeclarationMembers(TypeDeclarationSyntax typeDeclaration, ArrayBuilder items, CancellationToken cancellationToken) { foreach (var member in typeDeclaration.Members) { @@ -124,7 +124,7 @@ private static void AddTypeDeclarationMembers(TypeDeclarationSyntax typeDeclarat } private static void AddMemberDeclaration( - MemberDeclarationSyntax member, ArrayBuilder items) + MemberDeclarationSyntax member, ArrayBuilder items) { switch (member) { @@ -146,7 +146,7 @@ private static void AddMemberDeclaration( } } - private static void AddConversionOperatorDeclaration(ConversionOperatorDeclarationSyntax operatorDeclaration, ArrayBuilder items) + private static void AddConversionOperatorDeclaration(ConversionOperatorDeclarationSyntax operatorDeclaration, ArrayBuilder items) { using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); @@ -162,12 +162,13 @@ private static void AddConversionOperatorDeclaration(ConversionOperatorDeclarati items.Add(new( nameBuilder.ToString(), glyph, + hasItems: false, operatorDeclaration, - hasItems: false)); + operatorDeclaration.Type.GetFirstToken())); } private static void AddOperatorDeclaration( - OperatorDeclarationSyntax operatorDeclaration, ArrayBuilder items) + OperatorDeclarationSyntax operatorDeclaration, ArrayBuilder items) { using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); @@ -183,12 +184,13 @@ private static void AddOperatorDeclaration( items.Add(new( nameBuilder.ToString(), glyph, + hasItems: false, operatorDeclaration, - hasItems: false)); + operatorDeclaration.OperatorToken)); } private static void AddMethodDeclaration( - MethodDeclarationSyntax methodDeclaration, ArrayBuilder items) + MethodDeclarationSyntax methodDeclaration, ArrayBuilder items) { using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); @@ -204,12 +206,13 @@ private static void AddMethodDeclaration( items.Add(new( nameBuilder.ToString(), glyph, + hasItems: false, methodDeclaration, - hasItems: false)); + methodDeclaration.Identifier)); } private static void AddFieldDeclaration( - BaseFieldDeclarationSyntax fieldDeclaration, ArrayBuilder items) + BaseFieldDeclarationSyntax fieldDeclaration, ArrayBuilder items) { using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); @@ -229,12 +232,13 @@ private static void AddFieldDeclaration( items.Add(new( nameBuilder.ToString(), GlyphExtensions.GetGlyph(kind, accessibility), + hasItems: false, variable, - hasItems: false)); + variable.Identifier)); } } - private static void AddEnumDeclarationMembers(EnumDeclarationSyntax enumDeclaration, ArrayBuilder items, CancellationToken cancellationToken) + private static void AddEnumDeclarationMembers(EnumDeclarationSyntax enumDeclaration, ArrayBuilder items, CancellationToken cancellationToken) { foreach (var member in enumDeclaration.Members) { @@ -242,12 +246,13 @@ private static void AddEnumDeclarationMembers(EnumDeclarationSyntax enumDeclarat items.Add(new( member.Identifier.ValueText, Glyph.EnumMemberPublic, + hasItems: false, member, - hasItems: false)); + member.Identifier)); } } - private static void AddEnumDeclaration(EnumDeclarationSyntax enumDeclaration, ArrayBuilder items) + private static void AddEnumDeclaration(EnumDeclarationSyntax enumDeclaration, ArrayBuilder items) { var glyph = GlyphExtensions.GetGlyph( DeclaredSymbolInfoKind.Enum, GetAccessibility(enumDeclaration, enumDeclaration.Modifiers)); @@ -255,13 +260,14 @@ private static void AddEnumDeclaration(EnumDeclarationSyntax enumDeclaration, Ar items.Add(new( enumDeclaration.Identifier.ValueText, glyph, + hasItems: enumDeclaration.Members.Count > 0, enumDeclaration, - hasItems: enumDeclaration.Members.Count > 0)); + enumDeclaration.Identifier)); } private static void AddExtensionBlock( ExtensionBlockDeclarationSyntax extensionBlock, - ArrayBuilder items) + ArrayBuilder items) { using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); @@ -272,13 +278,14 @@ private static void AddExtensionBlock( items.Add(new( nameBuilder.ToString(), Glyph.ClassPublic, + hasItems: extensionBlock.Members.Count > 0, extensionBlock, - hasItems: extensionBlock.Members.Count > 0)); + extensionBlock.Keyword)); } private static void AddDelegateDeclaration( DelegateDeclarationSyntax delegateDeclaration, - ArrayBuilder items) + ArrayBuilder items) { using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); @@ -295,13 +302,14 @@ private static void AddDelegateDeclaration( items.Add(new( nameBuilder.ToString(), glyph, + hasItems: false, delegateDeclaration, - hasItems: false)); + delegateDeclaration.Identifier)); } private static void AddTypeDeclaration( TypeDeclarationSyntax typeDeclaration, - ArrayBuilder items) + ArrayBuilder items) { using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); @@ -314,8 +322,9 @@ private static void AddTypeDeclaration( items.Add(new( nameBuilder.ToString(), glyph, + hasItems: typeDeclaration.Members.Count > 0, typeDeclaration, - hasItems: typeDeclaration.Members.Count > 0)); + typeDeclaration.Identifier)); } private static void AppendCommaSeparatedList( diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/SourceGeneratedFileItemSource.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/SourceGeneratedFileItemSource.cs index 9aefa417d935d..545236d70563a 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/SourceGeneratedFileItemSource.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/SourceGeneratedFileItemSource.cs @@ -135,7 +135,7 @@ private async Task UpdateSourceGeneratedFileItemsAsync(Solution solution, Cancel finally { _items.EndBulkOperation(); - _items.MarkAsInitialized(); + _items.IsInitialized = true; } } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index ed425dcbee431..e139d642169a4 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -125,7 +125,7 @@ private void UpdateChildren() // down further. var items = this.ItemProvider.GetItems( _itemSyntax.DeclarationNode, this.RootProvider.ThreadingContext.DisposalToken); - _childCollection.SetItems(this.RootProvider, this.DocumentId, this.ItemProvider, items); + _childCollection.SetItemsAndMarkComputed(this.RootProvider, this.DocumentId, this.ItemProvider, items); } else { From d1d4140b9010b91f655442e02a27ac4cacdc78e3 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 13:06:48 +0200 Subject: [PATCH 058/353] in progress --- .../CSharpSolutionExplorerSymbolTreeItemProvider.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index e2cdd5913540d..dfc8b84d121a8 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -143,6 +143,10 @@ private static void AddMemberDeclaration( case ConversionOperatorDeclarationSyntax conversionOperatorDeclaration: AddConversionOperatorDeclaration(conversionOperatorDeclaration, items); return; + + case ConstructorDeclarationSyntax constructorDeclaration: + AddConstructorDeclaration(constructorDeclaration, items); + return; } } From ccaec06fbdf1669070e246bbf00e1251f6ebaa07 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 13:30:13 +0200 Subject: [PATCH 059/353] Add constructors --- .../Core/Portable/Common/GlyphExtensions.cs | 6 +----- ...rpSolutionExplorerSymbolTreeItemProvider.cs | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/Features/Core/Portable/Common/GlyphExtensions.cs b/src/Features/Core/Portable/Common/GlyphExtensions.cs index 817fd307c2eb6..413947c8e76d3 100644 --- a/src/Features/Core/Portable/Common/GlyphExtensions.cs +++ b/src/Features/Core/Portable/Common/GlyphExtensions.cs @@ -256,10 +256,6 @@ public static Glyph GetGlyph(DeclaredSymbolInfoKind kind, Accessibility accessib var rawGlyph = GetPublicGlyph(kind); - // No accessibility supported for operators yet. - if (rawGlyph == Glyph.Operator) - return rawGlyph; - switch (accessibility) { case Accessibility.Private: @@ -294,7 +290,7 @@ private static Glyph GetPublicGlyph(DeclaredSymbolInfoKind kind) DeclaredSymbolInfoKind.Interface => Glyph.InterfacePublic, DeclaredSymbolInfoKind.Method => Glyph.MethodPublic, DeclaredSymbolInfoKind.Module => Glyph.ModulePublic, - DeclaredSymbolInfoKind.Operator => Glyph.Operator, + DeclaredSymbolInfoKind.Operator => Glyph.OperatorPublic, DeclaredSymbolInfoKind.Property => Glyph.PropertyPublic, DeclaredSymbolInfoKind.Struct => Glyph.StructurePublic, DeclaredSymbolInfoKind.RecordStruct => Glyph.StructurePublic, diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index dfc8b84d121a8..624e198a00528 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -150,6 +150,24 @@ private static void AddMemberDeclaration( } } + private static void AddConstructorDeclaration(ConstructorDeclarationSyntax constructorDeclaration, ArrayBuilder items) + { + using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); + + nameBuilder.Append(constructorDeclaration.Identifier.ValueText); + AppendParameterList(nameBuilder, constructorDeclaration.ParameterList); + + var accessibility = GetAccessibility(constructorDeclaration, constructorDeclaration.Modifiers); + var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Constructor, accessibility); + + items.Add(new( + nameBuilder.ToString(), + glyph, + hasItems: false, + constructorDeclaration, + constructorDeclaration.Identifier)); + } + private static void AddConversionOperatorDeclaration(ConversionOperatorDeclarationSyntax operatorDeclaration, ArrayBuilder items) { using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); From 4a1e284f904e565c350beb5a01a1b87bdd832335 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 13:32:10 +0200 Subject: [PATCH 060/353] Add destructor --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index 624e198a00528..cd4c013202153 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -147,9 +147,32 @@ private static void AddMemberDeclaration( case ConstructorDeclarationSyntax constructorDeclaration: AddConstructorDeclaration(constructorDeclaration, items); return; + + case DestructorDeclarationSyntax destructorDeclaration: + AddDestructorDeclaration(destructorDeclaration, items); + return; } } + private static void AddDestructorDeclaration(DestructorDeclarationSyntax destructorDeclaration, ArrayBuilder items) + { + using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); + + nameBuilder.Append('~'); + nameBuilder.Append(destructorDeclaration.Identifier.ValueText); + AppendParameterList(nameBuilder, destructorDeclaration.ParameterList); + + var accessibility = GetAccessibility(destructorDeclaration, destructorDeclaration.Modifiers); + var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Constructor, accessibility); + + items.Add(new( + nameBuilder.ToString(), + glyph, + hasItems: false, + destructorDeclaration, + destructorDeclaration.Identifier)); + } + private static void AddConstructorDeclaration(ConstructorDeclarationSyntax constructorDeclaration, ArrayBuilder items) { using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); From 492103ec339b4a98bbdb4f6476b1b10720d699ff Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 13:33:34 +0200 Subject: [PATCH 061/353] share --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 39 +++++++------------ 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index cd4c013202153..cd9ede8f33476 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -145,50 +145,37 @@ private static void AddMemberDeclaration( return; case ConstructorDeclarationSyntax constructorDeclaration: - AddConstructorDeclaration(constructorDeclaration, items); + AddConstructorOrDestructorDeclaration(constructorDeclaration, constructorDeclaration.Identifier, items); return; case DestructorDeclarationSyntax destructorDeclaration: - AddDestructorDeclaration(destructorDeclaration, items); + AddConstructorOrDestructorDeclaration(destructorDeclaration, destructorDeclaration.Identifier, items); return; } } - private static void AddDestructorDeclaration(DestructorDeclarationSyntax destructorDeclaration, ArrayBuilder items) + private static void AddConstructorOrDestructorDeclaration( + BaseMethodDeclarationSyntax declaration, + SyntaxToken identifier, + ArrayBuilder items) { using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); - nameBuilder.Append('~'); - nameBuilder.Append(destructorDeclaration.Identifier.ValueText); - AppendParameterList(nameBuilder, destructorDeclaration.ParameterList); - - var accessibility = GetAccessibility(destructorDeclaration, destructorDeclaration.Modifiers); - var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Constructor, accessibility); - - items.Add(new( - nameBuilder.ToString(), - glyph, - hasItems: false, - destructorDeclaration, - destructorDeclaration.Identifier)); - } - - private static void AddConstructorDeclaration(ConstructorDeclarationSyntax constructorDeclaration, ArrayBuilder items) - { - using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); + if (declaration.Kind() == SyntaxKind.DestructorDeclaration) + nameBuilder.Append('~'); - nameBuilder.Append(constructorDeclaration.Identifier.ValueText); - AppendParameterList(nameBuilder, constructorDeclaration.ParameterList); + nameBuilder.Append(identifier.ValueText); + AppendParameterList(nameBuilder, declaration.ParameterList); - var accessibility = GetAccessibility(constructorDeclaration, constructorDeclaration.Modifiers); + var accessibility = GetAccessibility(declaration, declaration.Modifiers); var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Constructor, accessibility); items.Add(new( nameBuilder.ToString(), glyph, hasItems: false, - constructorDeclaration, - constructorDeclaration.Identifier)); + declaration, + identifier)); } private static void AddConversionOperatorDeclaration(ConversionOperatorDeclarationSyntax operatorDeclaration, ArrayBuilder items) From 451e36010528f16c83f56c02e6c92393a5f07540 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 13:42:24 +0200 Subject: [PATCH 062/353] single name builder --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 144 +++++++++++------- .../Extensions/StringBuilderExtensions.cs | 7 + 2 files changed, 92 insertions(+), 59 deletions(-) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index cd9ede8f33476..e860ee8e8a101 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -33,50 +33,54 @@ public async Task> GetItemsAsync( { var root = (CompilationUnitSyntax)await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - using var _ = ArrayBuilder.GetInstance(out var items); + using var _1 = ArrayBuilder.GetInstance(out var items); + using var _2 = PooledStringBuilder.GetInstance(out var nameBuilder); - AddTopLevelTypes(root, items, cancellationToken); + AddTopLevelTypes(root, items, nameBuilder, cancellationToken); return items.ToImmutableAndClear(); } - private static void AddTopLevelTypes(CompilationUnitSyntax root, ArrayBuilder items, CancellationToken cancellationToken) + private static void AddTopLevelTypes( + CompilationUnitSyntax root, ArrayBuilder items, StringBuilder nameBuilder, CancellationToken cancellationToken) { foreach (var member in root.Members) { cancellationToken.ThrowIfCancellationRequested(); if (member is BaseNamespaceDeclarationSyntax baseNamespace) - AddTopLevelTypes(baseNamespace, items, cancellationToken); + AddTopLevelTypes(baseNamespace, items, nameBuilder, cancellationToken); else - TryAddType(member, items, cancellationToken); + TryAddType(member, items, nameBuilder, cancellationToken); } } - private static void AddTopLevelTypes(BaseNamespaceDeclarationSyntax baseNamespace, ArrayBuilder items, CancellationToken cancellationToken) + private static void AddTopLevelTypes( + BaseNamespaceDeclarationSyntax baseNamespace, ArrayBuilder items, StringBuilder nameBuilder, CancellationToken cancellationToken) { foreach (var member in baseNamespace.Members) { cancellationToken.ThrowIfCancellationRequested(); if (member is BaseNamespaceDeclarationSyntax childNamespace) - AddTopLevelTypes(childNamespace, items, cancellationToken); + AddTopLevelTypes(childNamespace, items, nameBuilder, cancellationToken); else - TryAddType(member, items, cancellationToken); + TryAddType(member, items, nameBuilder, cancellationToken); } } - private static bool TryAddType(MemberDeclarationSyntax member, ArrayBuilder items, CancellationToken cancellationToken) + private static bool TryAddType( + MemberDeclarationSyntax member, ArrayBuilder items, StringBuilder nameBuilder, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); switch (member) { case ExtensionBlockDeclarationSyntax extensionBlock: - AddExtensionBlock(extensionBlock, items); + AddExtensionBlock(extensionBlock, items, nameBuilder); return true; case TypeDeclarationSyntax typeDeclaration: - AddTypeDeclaration(typeDeclaration, items); + AddTypeDeclaration(typeDeclaration, items, nameBuilder); return true; case EnumDeclarationSyntax enumDeclaration: @@ -84,7 +88,7 @@ private static bool TryAddType(MemberDeclarationSyntax member, ArrayBuilder GetItems(SyntaxNode node, CancellationToken cancellationToken) { - using var _ = ArrayBuilder.GetInstance(out var items); + using var _1 = ArrayBuilder.GetInstance(out var items); + using var _2 = PooledStringBuilder.GetInstance(out var nameBuilder); var memberDeclaration = (MemberDeclarationSyntax)node; switch (memberDeclaration) @@ -103,64 +108,86 @@ public ImmutableArray GetItems(SyntaxNode node, Cancellation break; case TypeDeclarationSyntax typeDeclaration: - AddTypeDeclarationMembers(typeDeclaration, items, cancellationToken); + AddTypeDeclarationMembers(typeDeclaration, items, nameBuilder, cancellationToken); break; } return items.ToImmutableAndClear(); } - private static void AddTypeDeclarationMembers(TypeDeclarationSyntax typeDeclaration, ArrayBuilder items, CancellationToken cancellationToken) + private static void AddTypeDeclarationMembers( + TypeDeclarationSyntax typeDeclaration, ArrayBuilder items, StringBuilder nameBuilder, CancellationToken cancellationToken) { foreach (var member in typeDeclaration.Members) { cancellationToken.ThrowIfCancellationRequested(); - if (TryAddType(member, items, cancellationToken)) + if (TryAddType(member, items, nameBuilder, cancellationToken)) continue; - AddMemberDeclaration(member, items); + AddMemberDeclaration(member, items, nameBuilder); } } private static void AddMemberDeclaration( - MemberDeclarationSyntax member, ArrayBuilder items) + MemberDeclarationSyntax member, ArrayBuilder items, StringBuilder nameBuilder) { switch (member) { case BaseFieldDeclarationSyntax fieldDeclaration: - AddFieldDeclaration(fieldDeclaration, items); + AddFieldDeclaration(fieldDeclaration, items, nameBuilder); return; case MethodDeclarationSyntax methodDeclaration: - AddMethodDeclaration(methodDeclaration, items); + AddMethodDeclaration(methodDeclaration, items, nameBuilder); return; case OperatorDeclarationSyntax operatorDeclaration: - AddOperatorDeclaration(operatorDeclaration, items); + AddOperatorDeclaration(operatorDeclaration, items, nameBuilder); return; case ConversionOperatorDeclarationSyntax conversionOperatorDeclaration: - AddConversionOperatorDeclaration(conversionOperatorDeclaration, items); + AddConversionOperatorDeclaration(conversionOperatorDeclaration, items, nameBuilder); return; case ConstructorDeclarationSyntax constructorDeclaration: - AddConstructorOrDestructorDeclaration(constructorDeclaration, constructorDeclaration.Identifier, items); + AddConstructorOrDestructorDeclaration(constructorDeclaration, constructorDeclaration.Identifier, items, nameBuilder); return; case DestructorDeclarationSyntax destructorDeclaration: - AddConstructorOrDestructorDeclaration(destructorDeclaration, destructorDeclaration.Identifier, items); + AddConstructorOrDestructorDeclaration(destructorDeclaration, destructorDeclaration.Identifier, items, nameBuilder); + return; + + case PropertyDeclarationSyntax propertyDeclaration: + AddPropertyDeclaration(propertyDeclaration, items, nameBuilder); return; } } + private static void AddPropertyDeclaration( + PropertyDeclarationSyntax propertyDeclaration, ArrayBuilder items, StringBuilder nameBuilder) + { + nameBuilder.Append(propertyDeclaration.Identifier.ValueText); + nameBuilder.Append(" : "); + AppendType(propertyDeclaration.Type, nameBuilder); + + var accessibility = GetAccessibility(propertyDeclaration, propertyDeclaration.Modifiers); + var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Property, accessibility); + + items.Add(new( + nameBuilder.ToStringAndClear(), + glyph, + hasItems: false, + propertyDeclaration, + propertyDeclaration.Identifier)); + } + private static void AddConstructorOrDestructorDeclaration( BaseMethodDeclarationSyntax declaration, SyntaxToken identifier, - ArrayBuilder items) + ArrayBuilder items, + StringBuilder nameBuilder) { - using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); - if (declaration.Kind() == SyntaxKind.DestructorDeclaration) nameBuilder.Append('~'); @@ -171,17 +198,18 @@ private static void AddConstructorOrDestructorDeclaration( var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Constructor, accessibility); items.Add(new( - nameBuilder.ToString(), + nameBuilder.ToStringAndClear(), glyph, hasItems: false, declaration, identifier)); } - private static void AddConversionOperatorDeclaration(ConversionOperatorDeclarationSyntax operatorDeclaration, ArrayBuilder items) + private static void AddConversionOperatorDeclaration( + ConversionOperatorDeclarationSyntax operatorDeclaration, + ArrayBuilder items, + StringBuilder nameBuilder) { - using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); - nameBuilder.Append(operatorDeclaration.ImplicitOrExplicitKeyword.Kind() == SyntaxKind.ImplicitKeyword ? "implicit operator " : "explicit operator "); @@ -192,7 +220,7 @@ private static void AddConversionOperatorDeclaration(ConversionOperatorDeclarati var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Operator, accessibility); items.Add(new( - nameBuilder.ToString(), + nameBuilder.ToStringAndClear(), glyph, hasItems: false, operatorDeclaration, @@ -200,10 +228,10 @@ private static void AddConversionOperatorDeclaration(ConversionOperatorDeclarati } private static void AddOperatorDeclaration( - OperatorDeclarationSyntax operatorDeclaration, ArrayBuilder items) + OperatorDeclarationSyntax operatorDeclaration, + ArrayBuilder items, + StringBuilder nameBuilder) { - using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); - nameBuilder.Append("operator "); nameBuilder.Append(operatorDeclaration.OperatorToken.ToString()); AppendParameterList(nameBuilder, operatorDeclaration.ParameterList); @@ -214,7 +242,7 @@ private static void AddOperatorDeclaration( var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Operator, accessibility); items.Add(new( - nameBuilder.ToString(), + nameBuilder.ToStringAndClear(), glyph, hasItems: false, operatorDeclaration, @@ -222,10 +250,10 @@ private static void AddOperatorDeclaration( } private static void AddMethodDeclaration( - MethodDeclarationSyntax methodDeclaration, ArrayBuilder items) + MethodDeclarationSyntax methodDeclaration, + ArrayBuilder items, + StringBuilder nameBuilder) { - using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); - nameBuilder.Append(methodDeclaration.Identifier.ValueText); AppendTypeParameterList(nameBuilder, methodDeclaration.TypeParameterList); AppendParameterList(nameBuilder, methodDeclaration.ParameterList); @@ -236,7 +264,7 @@ private static void AddMethodDeclaration( var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Method, accessibility); items.Add(new( - nameBuilder.ToString(), + nameBuilder.ToStringAndClear(), glyph, hasItems: false, methodDeclaration, @@ -244,14 +272,12 @@ private static void AddMethodDeclaration( } private static void AddFieldDeclaration( - BaseFieldDeclarationSyntax fieldDeclaration, ArrayBuilder items) + BaseFieldDeclarationSyntax fieldDeclaration, + ArrayBuilder items, + StringBuilder nameBuilder) { - using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); - foreach (var variable in fieldDeclaration.Declaration.Variables) { - nameBuilder.Clear(); - nameBuilder.Append(variable.Identifier.ValueText); nameBuilder.Append(" : "); AppendType(fieldDeclaration.Declaration.Type, nameBuilder); @@ -262,7 +288,7 @@ private static void AddFieldDeclaration( : DeclaredSymbolInfoKind.Field; items.Add(new( - nameBuilder.ToString(), + nameBuilder.ToStringAndClear(), GlyphExtensions.GetGlyph(kind, accessibility), hasItems: false, variable, @@ -270,7 +296,10 @@ private static void AddFieldDeclaration( } } - private static void AddEnumDeclarationMembers(EnumDeclarationSyntax enumDeclaration, ArrayBuilder items, CancellationToken cancellationToken) + private static void AddEnumDeclarationMembers( + EnumDeclarationSyntax enumDeclaration, + ArrayBuilder items, + CancellationToken cancellationToken) { foreach (var member in enumDeclaration.Members) { @@ -299,16 +328,15 @@ private static void AddEnumDeclaration(EnumDeclarationSyntax enumDeclaration, Ar private static void AddExtensionBlock( ExtensionBlockDeclarationSyntax extensionBlock, - ArrayBuilder items) + ArrayBuilder items, + StringBuilder nameBuilder) { - using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); - nameBuilder.Append("extension"); AppendTypeParameterList(nameBuilder, extensionBlock.TypeParameterList); AppendParameterList(nameBuilder, extensionBlock.ParameterList); items.Add(new( - nameBuilder.ToString(), + nameBuilder.ToStringAndClear(), Glyph.ClassPublic, hasItems: extensionBlock.Members.Count > 0, extensionBlock, @@ -317,10 +345,9 @@ private static void AddExtensionBlock( private static void AddDelegateDeclaration( DelegateDeclarationSyntax delegateDeclaration, - ArrayBuilder items) + ArrayBuilder items, + StringBuilder nameBuilder) { - using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); - nameBuilder.Append(delegateDeclaration.Identifier.ValueText); AppendTypeParameterList(nameBuilder, delegateDeclaration.TypeParameterList); AppendParameterList(nameBuilder, delegateDeclaration.ParameterList); @@ -332,7 +359,7 @@ private static void AddDelegateDeclaration( DeclaredSymbolInfoKind.Delegate, GetAccessibility(delegateDeclaration, delegateDeclaration.Modifiers)); items.Add(new( - nameBuilder.ToString(), + nameBuilder.ToStringAndClear(), glyph, hasItems: false, delegateDeclaration, @@ -341,10 +368,9 @@ private static void AddDelegateDeclaration( private static void AddTypeDeclaration( TypeDeclarationSyntax typeDeclaration, - ArrayBuilder items) + ArrayBuilder items, + StringBuilder nameBuilder) { - using var _ = PooledStringBuilder.GetInstance(out var nameBuilder); - nameBuilder.Append(typeDeclaration.Identifier.ValueText); AppendTypeParameterList(nameBuilder, typeDeclaration.TypeParameterList); @@ -352,7 +378,7 @@ private static void AddTypeDeclaration( GetDeclaredSymbolInfoKind(typeDeclaration), GetAccessibility(typeDeclaration, typeDeclaration.Modifiers)); items.Add(new( - nameBuilder.ToString(), + nameBuilder.ToStringAndClear(), glyph, hasItems: typeDeclaration.Members.Count > 0, typeDeclaration, diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/StringBuilderExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/StringBuilderExtensions.cs index 052ebabcda671..64fc5186351a5 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/StringBuilderExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/StringBuilderExtensions.cs @@ -11,6 +11,13 @@ namespace Microsoft.CodeAnalysis.Shared.Extensions; internal static class StringBuilderExtensions { + public static string ToStringAndClear(this StringBuilder builder) + { + var result = builder.ToString(); + builder.Clear(); + return result; + } + public static StringBuilder AppendJoinedValues(this StringBuilder builder, string separator, IEnumerable values, Action append) { var first = true; From 5d71f18037c4f4ffa05b8ae7ed67044de2691409 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 13:43:50 +0200 Subject: [PATCH 063/353] Add events --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index e860ee8e8a101..514c679f6d40e 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -161,9 +161,33 @@ private static void AddMemberDeclaration( case PropertyDeclarationSyntax propertyDeclaration: AddPropertyDeclaration(propertyDeclaration, items, nameBuilder); return; + + case EventDeclarationSyntax eventDeclaration: + AddEventDeclaration(eventDeclaration, items, nameBuilder); + return; } } + private static void AddEventDeclaration( + EventDeclarationSyntax eventDeclaration, + ArrayBuilder items, + StringBuilder nameBuilder) + { + nameBuilder.Append(eventDeclaration.Identifier.ValueText); + nameBuilder.Append(" : "); + AppendType(eventDeclaration.Type, nameBuilder); + + var accessibility = GetAccessibility(eventDeclaration, eventDeclaration.Modifiers); + var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Event, accessibility); + + items.Add(new( + nameBuilder.ToStringAndClear(), + glyph, + hasItems: false, + eventDeclaration, + eventDeclaration.Identifier)); + } + private static void AddPropertyDeclaration( PropertyDeclarationSyntax propertyDeclaration, ArrayBuilder items, StringBuilder nameBuilder) { From 83631ca960444964c92bf72c4df40589b900743e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 13:48:02 +0200 Subject: [PATCH 064/353] All members done --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index 514c679f6d40e..139b267b8aa09 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -165,9 +165,37 @@ private static void AddMemberDeclaration( case EventDeclarationSyntax eventDeclaration: AddEventDeclaration(eventDeclaration, items, nameBuilder); return; + + case IndexerDeclarationSyntax indexerDeclaration: + AddIndexerDeclaration(indexerDeclaration, items, nameBuilder); + return; } } + private static void AddIndexerDeclaration( + IndexerDeclarationSyntax indexerDeclaration, + ArrayBuilder items, + StringBuilder nameBuilder) + { + nameBuilder.Append("this"); + AppendCommaSeparatedList( + nameBuilder, "[", "]", + indexerDeclaration.ParameterList.Parameters, + static (parameter, nameBuilder) => AppendType(parameter.Type, nameBuilder)); + nameBuilder.Append(" : "); + AppendType(indexerDeclaration.Type, nameBuilder); + + var accessibility = GetAccessibility(indexerDeclaration, indexerDeclaration.Modifiers); + var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Indexer, accessibility); + + items.Add(new( + nameBuilder.ToStringAndClear(), + glyph, + hasItems: false, + indexerDeclaration, + indexerDeclaration.ThisKeyword)); + } + private static void AddEventDeclaration( EventDeclarationSyntax eventDeclaration, ArrayBuilder items, From 5783191af1ba89078f6357c220612a46be576be4 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 13:48:27 +0200 Subject: [PATCH 065/353] Simplify --- .../CSharpSolutionExplorerSymbolTreeItemProvider.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index 139b267b8aa09..9f570555c3f63 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -10,7 +10,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; -using ICSharpCode.Decompiler.CSharp.Syntax; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; From 039d8b407b29bbad30bb08cb76170bc308f63434 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 13:53:28 +0200 Subject: [PATCH 066/353] Remove entrypoint --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 78 +++++-------------- ...ISolutionExplorerSymbolTreeItemProvider.cs | 42 +++++++++- .../RootSymbolTreeItemSourceProvider.cs | 3 +- 3 files changed, 60 insertions(+), 63 deletions(-) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index 9f570555c3f63..d8893f2485a08 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -9,7 +9,6 @@ using System.Diagnostics; using System.Text; using System.Threading; -using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -25,17 +24,27 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.SolutionExplorer; [ExportLanguageService(typeof(ISolutionExplorerSymbolTreeItemProvider), LanguageNames.CSharp), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class CSharpSolutionExplorerSymbolTreeItemProvider() : ISolutionExplorerSymbolTreeItemProvider +internal sealed class CSharpSolutionExplorerSymbolTreeItemProvider() : AbstractSolutionExplorerSymbolTreeItemProvider { - public async Task> GetItemsAsync( - Document document, CancellationToken cancellationToken) + public override ImmutableArray GetItems(SyntaxNode node, CancellationToken cancellationToken) { - var root = (CompilationUnitSyntax)await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - using var _1 = ArrayBuilder.GetInstance(out var items); using var _2 = PooledStringBuilder.GetInstance(out var nameBuilder); - AddTopLevelTypes(root, items, nameBuilder, cancellationToken); + switch (node) + { + case CompilationUnitSyntax compilationUnit: + AddTopLevelTypes(compilationUnit, items, nameBuilder, cancellationToken); + break; + + case EnumDeclarationSyntax enumDeclaration: + AddEnumDeclarationMembers(enumDeclaration, items, cancellationToken); + break; + + case TypeDeclarationSyntax typeDeclaration: + AddTypeDeclarationMembers(typeDeclaration, items, nameBuilder, cancellationToken); + break; + } return items.ToImmutableAndClear(); } @@ -94,26 +103,6 @@ private static bool TryAddType( return false; } - public ImmutableArray GetItems(SyntaxNode node, CancellationToken cancellationToken) - { - using var _1 = ArrayBuilder.GetInstance(out var items); - using var _2 = PooledStringBuilder.GetInstance(out var nameBuilder); - - var memberDeclaration = (MemberDeclarationSyntax)node; - switch (memberDeclaration) - { - case EnumDeclarationSyntax enumDeclaration: - AddEnumDeclarationMembers(enumDeclaration, items, cancellationToken); - break; - - case TypeDeclarationSyntax typeDeclaration: - AddTypeDeclarationMembers(typeDeclaration, items, nameBuilder, cancellationToken); - break; - } - - return items.ToImmutableAndClear(); - } - private static void AddTypeDeclarationMembers( TypeDeclarationSyntax typeDeclaration, ArrayBuilder items, StringBuilder nameBuilder, CancellationToken cancellationToken) { @@ -436,37 +425,6 @@ private static void AddTypeDeclaration( typeDeclaration.Identifier)); } - private static void AppendCommaSeparatedList( - StringBuilder builder, - string openBrace, - string closeBrace, - TArgumentList? argumentList, - Func> getArguments, - Action append, - string separator = ", ") - where TArgumentList : SyntaxNode - where TArgument : SyntaxNode - { - if (argumentList is null) - return; - - AppendCommaSeparatedList(builder, openBrace, closeBrace, getArguments(argumentList), append, separator); - } - - private static void AppendCommaSeparatedList( - StringBuilder builder, - string openBrace, - string closeBrace, - IEnumerable arguments, - Action append, - string separator = ", ") - where TArgument : SyntaxNode - { - builder.Append(openBrace); - builder.AppendJoinedValues(separator, arguments, append); - builder.Append(closeBrace); - } - private static void AppendTypeParameterList( StringBuilder builder, TypeParameterListSyntax? typeParameterList) @@ -512,7 +470,7 @@ private static void AppendType(TypeSyntax? type, StringBuilder builder) else if (type is TupleTypeSyntax tupleType) { AppendCommaSeparatedList( - builder, "(", ")", tupleType.Elements, BuildDisplayText); + builder, "(", ")", tupleType.Elements, AppendTupleElement); } else if (type is RefTypeSyntax refType) { @@ -563,7 +521,7 @@ private static void AppendType(TypeSyntax? type, StringBuilder builder) } } - private static void BuildDisplayText(TupleElementSyntax tupleElement, StringBuilder builder) + private static void AppendTupleElement(TupleElementSyntax tupleElement, StringBuilder builder) { AppendType(tupleElement.Type, builder); if (tupleElement.Identifier != default) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs index effebaff332a5..3f865942fd590 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs @@ -2,16 +2,54 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; +using System.Collections.Generic; using System.Collections.Immutable; +using System.Text; using System.Threading; -using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; internal interface ISolutionExplorerSymbolTreeItemProvider : ILanguageService { - Task> GetItemsAsync(Document document, CancellationToken cancellationToken); ImmutableArray GetItems(SyntaxNode declarationNode, CancellationToken cancellationToken); } + +internal abstract class AbstractSolutionExplorerSymbolTreeItemProvider : ISolutionExplorerSymbolTreeItemProvider +{ + public abstract ImmutableArray GetItems(SyntaxNode declarationNode, CancellationToken cancellationToken); + + protected static void AppendCommaSeparatedList( + StringBuilder builder, + string openBrace, + string closeBrace, + TArgumentList? argumentList, + Func> getArguments, + Action append, + string separator = ", ") + where TArgumentList : SyntaxNode + where TArgument : SyntaxNode + { + if (argumentList is null) + return; + + AppendCommaSeparatedList(builder, openBrace, closeBrace, getArguments(argumentList), append, separator); + } + + protected static void AppendCommaSeparatedList( + StringBuilder builder, + string openBrace, + string closeBrace, + IEnumerable arguments, + Action append, + string separator = ", ") + where TArgument : SyntaxNode + { + builder.Append(openBrace); + builder.AppendJoinedValues(separator, arguments, append); + builder.Append(closeBrace); + } +} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index 3934a7253986f..96adc310c3ed1 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -202,7 +202,8 @@ private async ValueTask TryUpdateItemsAsync( if (itemProvider is null) return false; - var items = await itemProvider.GetItemsAsync(document, cancellationToken).ConfigureAwait(false); + var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + var items = itemProvider.GetItems(root, cancellationToken); _childCollection.SetItemsAndMarkComputed(_rootProvider, documentId, itemProvider, items); return true; } From db4fb9125577db92cd8e00d5483bc8c6bb7c9fab Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 14:15:01 +0200 Subject: [PATCH 067/353] in progress --- .../RootSymbolTreeItemSourceProvider.cs | 15 +-- .../SymbolTree/SymbolTreeChildCollection.cs | 97 +++++++++---------- .../SymbolTree/SymbolTreeItem.cs | 11 ++- 3 files changed, 64 insertions(+), 59 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index 96adc310c3ed1..442e61d67a0aa 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -71,7 +71,7 @@ public RootSymbolTreeItemSourceProvider( options: new WorkspaceEventOptions(RequiresMainThread: false)); } - public void NavigateTo(SymbolTreeItem item, bool preview) + public void NavigateTo(DocumentId documentId, int position, bool preview) { // Cancel any in flight navigation and kick off a new one. var cancellationToken = _navigationCancellationSeries.CreateNext(this.ThreadingContext.DisposalToken); @@ -81,8 +81,8 @@ public void NavigateTo(SymbolTreeItem item, bool preview) navigationService.TryNavigateToPositionAsync( ThreadingContext, _workspace, - item.DocumentId, - item.ItemSyntax.NavigationToken.SpanStart, + documentId, + position, virtualSpace: 0, // May be calling this on stale data. Allow the position to be invalid allowInvalidPosition: true, @@ -168,7 +168,8 @@ private sealed class RootSymbolTreeItemCollectionSource( private DocumentId? _documentId; internal async Task UpdateIfAffectedAsync( - HashSet updateSet, CancellationToken cancellationToken) + HashSet updateSet, + CancellationToken cancellationToken) { var documentId = DetermineDocumentId(); @@ -178,7 +179,8 @@ internal async Task UpdateIfAffectedAsync( // If we didn't have a doc id, or we failed for any reason, clear out all our items and set that as our // current state. - _childCollection.ClearAndMarkComputed(); + await _rootProvider.ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); + _childCollection.ClearAndMarkComputed_OnMainThread(_rootProvider); } private async ValueTask TryUpdateItemsAsync( @@ -204,7 +206,8 @@ private async ValueTask TryUpdateItemsAsync( var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var items = itemProvider.GetItems(root, cancellationToken); - _childCollection.SetItemsAndMarkComputed(_rootProvider, documentId, itemProvider, items); + await _childCollection.SetItemsAndMarkComputedAsync( + _rootProvider, documentId, itemProvider, items, cancellationToken).ConfigureAwait(false); return true; } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs index e14ff299e302c..7bdb78ab1a7f1 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs @@ -16,10 +16,12 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore /// If non-null, the known value for . If null, /// then only known once is initialized internal sealed class SymbolTreeChildCollection( + RootSymbolTreeItemSourceProvider rootProvider, object parentItem, bool? hasItems) : IAttachedCollectionSource, INotifyPropertyChanged { private readonly BulkObservableCollectionWithInit _symbolTreeItems = []; + private readonly RootSymbolTreeItemSourceProvider _rootProvider = rootProvider; public object SourceItem { get; } = parentItem; @@ -61,24 +63,62 @@ public void ResetToUncomputedState() this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HasItems))); } - public void SetItemsAndMarkComputed( - RootSymbolTreeItemSourceProvider rootProvider, + public void SetItemsAndMarkComputed_OnMainThread( DocumentId documentId, ISolutionExplorerSymbolTreeItemProvider itemProvider, - ImmutableArray items) + ImmutableArray itemDatas) { + Contract.ThrowIfFalse(_rootProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); + + using var _ = PooledDictionary>.GetInstance(out var keyToItems); + foreach (var item in _symbolTreeItems) + keyToItems.MultiAdd(item.ItemKey, item); + using (this._symbolTreeItems.GetBulkOperation()) { // We got some item datas. Attempt to reuse existing symbol tree items that match up to preserve // identity in the tree between changes. - IncorporateNewItems(rootProvider, documentId, itemProvider, items); + // Clear out the old items we have. Then go through setting the final list of items. + // Attempt to reuse old items if they have the same visible data from before. + _symbolTreeItems.Clear(); + + foreach (var itemData in itemDatas) + { + if (keyToItems.TryGetValue(itemData.ItemKey, out var matchingItems)) + { + // Found a matching item we can use. Remove it from the list of items so we don't reuse it again. + var matchingItem = matchingItems[0]; + matchingItems.RemoveAt(0); + if (matchingItems.Count == 0) + keyToItems.Remove(itemData.ItemKey); + + Contract.ThrowIfFalse(matchingItem.DocumentId == documentId); + Contract.ThrowIfFalse(matchingItem.ItemProvider == itemProvider); + Contract.ThrowIfFalse(matchingItem.ItemKey == itemData.ItemKey); + + // And update it to point to the new syntax information. + matchingItem.ItemSyntax = itemData.ItemSyntax; + _symbolTreeItems.Add(matchingItem); + } + else + { + // If we didn't find an existing item, create a new one. + _symbolTreeItems.Add(new(_rootProvider, documentId, itemProvider, itemData.ItemKey) + { + ItemSyntax = itemData.ItemSyntax + }); + } + } } MarkComputed(); + keyToItems.FreeValues(); } - public void ClearAndMarkComputed() + public void ClearAndMarkComputed_OnMainThread() { + Contract.ThrowIfFalse(_rootProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); + using (this._symbolTreeItems.GetBulkOperation()) { _symbolTreeItems.Clear(); @@ -89,55 +129,12 @@ public void ClearAndMarkComputed() private void MarkComputed() { + Contract.ThrowIfFalse(_rootProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); + // Once we've been initialized once, mark us that way so that we we move out of the 'spinning/computing' state. _symbolTreeItems.IsInitialized = true; // Notify any listenerrs that we may or may not have items now. this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HasItems))); } - - private void IncorporateNewItems( - RootSymbolTreeItemSourceProvider rootProvider, - DocumentId documentId, - ISolutionExplorerSymbolTreeItemProvider itemProvider, - ImmutableArray datas) - { - using var _ = PooledDictionary>.GetInstance(out var keyToItems); - foreach (var item in _symbolTreeItems) - keyToItems.MultiAdd(item.ItemKey, item); - - // Clear out the old items we have. Then go through setting the final list of items. - // Attempt to reuse old items if they have the same visible data from before. - _symbolTreeItems.Clear(); - - foreach (var data in datas) - { - if (keyToItems.TryGetValue(data.ItemKey, out var matchingItems)) - { - // Found a matching item we can use. Remove it from the list of items so we don't reuse it again. - var matchingItem = matchingItems[0]; - matchingItems.RemoveAt(0); - if (matchingItems.Count == 0) - keyToItems.Remove(data.ItemKey); - - Contract.ThrowIfFalse(matchingItem.DocumentId == documentId); - Contract.ThrowIfFalse(matchingItem.ItemProvider == itemProvider); - Contract.ThrowIfFalse(matchingItem.ItemKey == data.ItemKey); - - // And update it to point to the new syntax information. - matchingItem.ItemSyntax = data.ItemSyntax; - _symbolTreeItems.Add(matchingItem); - } - else - { - // If we didn't find an existing item, create a new one. - _symbolTreeItems.Add(new(rootProvider, documentId, itemProvider, data.ItemKey) - { - ItemSyntax = data.ItemSyntax - }); - } - } - - keyToItems.FreeValues(); - } } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index e139d642169a4..252262dd35c1c 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -70,7 +70,7 @@ public SymbolTreeItem( DocumentId = documentId; ItemProvider = itemProvider; ItemKey = itemKey; - _childCollection = new(this, hasItems: ItemKey.HasItems); + _childCollection = new(rootProvider, this, hasItems: ItemKey.HasItems); } public SymbolTreeItemSyntax ItemSyntax @@ -78,6 +78,8 @@ public SymbolTreeItemSyntax ItemSyntax get => _itemSyntax; set { + Contract.ThrowIfFalse(this.RootProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); + // When the syntax node for this item is changed, we want to recompute the children for it // (if this node is expanded). Otherwise, we can just throw away what we have and recompute // the next time when asked. @@ -97,7 +99,7 @@ public bool Invoke(IEnumerable items, InputSource inputSource, bool prev if (items.FirstOrDefault() is not SymbolTreeItem item) return false; - RootProvider.NavigateTo(item, preview); + RootProvider.NavigateTo(item.DocumentId, item.ItemSyntax.NavigationToken.SpanStart, preview); return true; } @@ -117,6 +119,8 @@ public void AfterCollapse() private void UpdateChildren() { + Contract.ThrowIfFalse(RootProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); + if (_expanded) { // When we update the item syntax we can reset ourselves to the initial state (if collapsed). @@ -125,7 +129,8 @@ private void UpdateChildren() // down further. var items = this.ItemProvider.GetItems( _itemSyntax.DeclarationNode, this.RootProvider.ThreadingContext.DisposalToken); - _childCollection.SetItemsAndMarkComputed(this.RootProvider, this.DocumentId, this.ItemProvider, items); + _childCollection.SetItemsAndMarkComputed_OnMainThread( + this.DocumentId, this.ItemProvider, items); } else { From 1f54440d534012f0a6a2d3af7eb1a4048e21824e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 14:19:31 +0200 Subject: [PATCH 068/353] IN progress --- .../RootSymbolTreeItemSourceProvider.cs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index 442e61d67a0aa..a41cdda8943b7 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -115,13 +115,9 @@ await RoslynParallel.ForEachAsync( cancellationToken, async (source, cancellationToken) => { - try - { - await source.UpdateIfAffectedAsync(documentIdSet, cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) when (FatalError.ReportAndCatchUnlessCanceled(ex)) - { - } + await source.UpdateIfAffectedAsync(documentIdSet, cancellationToken) + .ReportNonFatalErrorUnlessCancelledAsync(cancellationToken) + .ConfigureAwait(false); }).ConfigureAwait(false); } @@ -163,7 +159,7 @@ private sealed class RootSymbolTreeItemCollectionSource( private readonly IVsHierarchyItem _hierarchyItem = hierarchyItem; // Mark hasItems as null as we don't know up front if we have items, and instead have to compute it on demand. - private readonly SymbolTreeChildCollection _childCollection = new(hierarchyItem, hasItems: null); + private readonly SymbolTreeChildCollection _childCollection = new(rootProvider, hierarchyItem, hasItems: null); private DocumentId? _documentId; @@ -180,7 +176,7 @@ internal async Task UpdateIfAffectedAsync( // If we didn't have a doc id, or we failed for any reason, clear out all our items and set that as our // current state. await _rootProvider.ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - _childCollection.ClearAndMarkComputed_OnMainThread(_rootProvider); + _childCollection.ClearAndMarkComputed_OnMainThread(); } private async ValueTask TryUpdateItemsAsync( @@ -206,8 +202,9 @@ private async ValueTask TryUpdateItemsAsync( var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var items = itemProvider.GetItems(root, cancellationToken); - await _childCollection.SetItemsAndMarkComputedAsync( - _rootProvider, documentId, itemProvider, items, cancellationToken).ConfigureAwait(false); + + await _rootProvider.ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); + _childCollection.SetItemsAndMarkComputed_OnMainThread(documentId, itemProvider, items); return true; } From d8ff9a112e15796fe34599bac1df0cb203d14ad8 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 20:51:00 +0200 Subject: [PATCH 069/353] Simplify --- .../HierarchyItemToProjectIdMap.cs | 40 +++++++++++-------- .../RootSymbolTreeItemSourceProvider.cs | 38 ++++++++++-------- 2 files changed, 46 insertions(+), 32 deletions(-) diff --git a/src/VisualStudio/Core/Def/Implementation/HierarchyItemToProjectIdMap.cs b/src/VisualStudio/Core/Def/Implementation/HierarchyItemToProjectIdMap.cs index cd6424af66f27..255fd6d2e3d3a 100644 --- a/src/VisualStudio/Core/Def/Implementation/HierarchyItemToProjectIdMap.cs +++ b/src/VisualStudio/Core/Def/Implementation/HierarchyItemToProjectIdMap.cs @@ -8,6 +8,8 @@ using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Shared.Collections; +using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem; using Microsoft.VisualStudio.LanguageServices.Implementation.Venus; using Microsoft.VisualStudio.Shell; @@ -37,7 +39,7 @@ public bool TryGetDocumentId(IVsHierarchyItem hierarchyItem, string? targetFrame return false; var documentIds = solution.GetDocumentIdsWithFilePath(itemName); - documentId = documentIds.FirstOrDefault(d => d.ProjectId == projectId); + documentId = documentIds.FirstOrDefault(static (d, projectId) => d.ProjectId == projectId, projectId); return documentId != null; } @@ -60,27 +62,30 @@ private bool TryGetProjectId( // the "nested" hierarchy from the IVsHierarchyItem. var nestedHierarchy = hierarchyItem.HierarchyIdentity.NestedHierarchy; + using var candidateProjects = TemporaryArray.Empty; + // First filter the projects by matching up properties on the input hierarchy against properties on each // project's hierarchy. - var candidateProjects = solution.Projects - .Where(p => + foreach (var currentId in solution.ProjectIds) + { + var hierarchy = _workspace.GetHierarchy(currentId); + if (hierarchy == nestedHierarchy) { + var project = solution.GetRequiredProject(currentId); + // We're about to access various properties of the IVsHierarchy associated with the project. // The properties supported and the interpretation of their values varies from one project system // to another. This code is designed with C# and VB in mind, so we need to filter out everything // else. - if (p.Language is not LanguageNames.CSharp and not LanguageNames.VisualBasic) - return false; - - var hierarchy = _workspace.GetHierarchy(p.Id); - return hierarchy == nestedHierarchy; - }) - .ToImmutableArray(); + if (project.Language is LanguageNames.CSharp or LanguageNames.VisualBasic) + candidateProjects.Add(currentId); + } + } // If we only have one candidate then no further checks are required. - if (candidateProjects.Length == 1) + if (candidateProjects.Count == 1) { - projectId = candidateProjects[0].Id; + projectId = candidateProjects[0]; return projectId != null; } @@ -88,11 +93,13 @@ private bool TryGetProjectId( // from CPS to see if this matches. if (targetFrameworkMoniker != null) { - var matchingProject = candidateProjects.FirstOrDefault(p => _workspace.TryGetDependencyNodeTargetIdentifier(p.Id) == targetFrameworkMoniker); + var matchingProjectId = candidateProjects.FirstOrDefault( + static (id, tuple) => tuple._workspace.TryGetDependencyNodeTargetIdentifier(id) == tuple.targetFrameworkMoniker, + (_workspace, targetFrameworkMoniker)); - if (matchingProject != null) + if (matchingProjectId != null) { - projectId = matchingProject.Id; + projectId = matchingProjectId; return projectId != null; } } @@ -101,8 +108,9 @@ private bool TryGetProjectId( // there will be one main project plus one project for each open aspx/cshtml/vbhtml file, all with // identical properties on their hierarchies. We can find the main project by taking the first project // without a ContainedDocument. - foreach (var candidateProject in candidateProjects) + foreach (var candidateProjectId in candidateProjects) { + var candidateProject = solution.GetRequiredProject(candidateProjectId); if (!candidateProject.DocumentIds.Any(id => ContainedDocument.TryGetContainedDocument(id) != null)) { projectId = candidateProject.Id; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index a41cdda8943b7..24599e0ca53ca 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -4,6 +4,7 @@ using System; using System.Collections; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel; @@ -11,6 +12,7 @@ using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; +using EnvDTE; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; @@ -26,6 +28,7 @@ using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Utilities; using Roslyn.Utilities; +using static System.Windows.Forms.LinkLabel; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -35,7 +38,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore [AppliesToProject("CSharp | VB")] internal sealed class RootSymbolTreeItemSourceProvider : AttachedCollectionSourceProvider { - private readonly ConcurrentSet> _weakCollectionSources = []; + private readonly ConcurrentDictionary _hierarchyToCollectionSource = []; private readonly AsyncBatchingWorkQueue _updateSourcesQueue; private readonly Workspace _workspace; @@ -97,18 +100,7 @@ private async ValueTask UpdateCollectionSourcesAsync( using var _2 = Microsoft.CodeAnalysis.PooledObjects.ArrayBuilder.GetInstance(out var sources); documentIdSet.AddRange(documentIds); - - foreach (var weakSource in _weakCollectionSources) - { - // If solution explorer has released this collection source, we can drop it as well. - if (!weakSource.TryGetTarget(out var source)) - { - _weakCollectionSources.Remove(weakSource); - continue; - } - - sources.Add(source); - } + sources.AddRange(_hierarchyToCollectionSource.Values); await RoslynParallel.ForEachAsync( sources, @@ -147,8 +139,22 @@ await source.UpdateIfAffectedAsync(documentIdSet, cancellationToken) } var source = new RootSymbolTreeItemCollectionSource(this, item); - _weakCollectionSources.Add(new WeakReference(source)); + _hierarchyToCollectionSource[item] = source; + + item.PropertyChanged += OnItemPropertyChanged; + return source; + + void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e) + { + // We are notified when the IVsHierarchyItem is removed from the tree via its INotifyPropertyChanged + // event for the IsDisposed property. When this fires, we remove the item->sourcce mapping we're holding. + if (e.PropertyName == nameof(ISupportDisposalNotification.IsDisposed) && item.IsDisposed) + { + _hierarchyToCollectionSource.TryRemove(item, out _); + item.PropertyChanged -= OnItemPropertyChanged; + } + } } private sealed class RootSymbolTreeItemCollectionSource( @@ -212,8 +218,8 @@ private async ValueTask TryUpdateItemsAsync( { if (_documentId == null) { - var idMap = _rootProvider._workspace.Services.GetService(); - idMap?.TryGetDocumentId(_hierarchyItem, targetFrameworkMoniker: null, out _documentId); + var idMap = _rootProvider._workspace.Services.GetRequiredService(); + idMap.TryGetDocumentId(_hierarchyItem, targetFrameworkMoniker: null, out _documentId); } return _documentId; From 9863d9d42eef60b01eab27c40bf1d69ce78fd7fb Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 20:56:24 +0200 Subject: [PATCH 070/353] in progress --- .../RootSymbolTreeItemSourceProvider.cs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index 24599e0ca53ca..caec3ced848d6 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; @@ -10,9 +9,9 @@ using System.ComponentModel; using System.ComponentModel.Composition; using System.Diagnostics.CodeAnalysis; +using System.IO; using System.Threading; using System.Threading.Tasks; -using EnvDTE; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; @@ -24,11 +23,10 @@ using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Threading; using Microsoft.Internal.VisualStudio.PlatformUI; +using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Utilities; -using Roslyn.Utilities; -using static System.Windows.Forms.LinkLabel; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -138,6 +136,15 @@ await source.UpdateIfAffectedAsync(documentIdSet, cancellationToken) return null; } + if (!hierarchy.TryGetCanonicalName(itemId, out var itemName)) + return null; + + // We only support C# and VB files for now. This ensures we don't create source providers for + // other types of files we'll never have results for. + var extension = Path.GetExtension(itemName); + if (extension is not ".cs" and not ".vb") + return null; + var source = new RootSymbolTreeItemCollectionSource(this, item); _hierarchyToCollectionSource[item] = source; @@ -202,7 +209,7 @@ private async ValueTask TryUpdateItemsAsync( if (document is null) return false; - var itemProvider = document.Project.GetLanguageService(); + var itemProvider = document.GetLanguageService(); if (itemProvider is null) return false; From 63dd9cfea3d140224ed4613a9ca97a0ffaa98de2 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 21:33:34 +0200 Subject: [PATCH 071/353] Cleanup --- .../NonRootSymbolTreeItemSourceProvider.cs | 8 +- .../RootSymbolTreeItemCollectionSource.cs | 119 ++++++++++++++++++ .../RootSymbolTreeItemSourceProvider.cs | 92 +------------- .../SymbolTree/SymbolTreeItem.cs | 11 +- 4 files changed, 135 insertions(+), 95 deletions(-) create mode 100644 src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemCollectionSource.cs diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs index 02a62e1fb44f4..c0c0f665da605 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs @@ -2,8 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.ComponentModel.Composition; -using System.Diagnostics.CodeAnalysis; +using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.Internal.VisualStudio.PlatformUI; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Utilities; @@ -14,10 +15,9 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore [Name(nameof(NonRootSymbolTreeItemSourceProvider))] [Order(Before = HierarchyItemsProviderNames.Contains)] [AppliesToProject("CSharp | VB")] -[method: SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] [method: ImportingConstructor] -internal sealed class NonRootSymbolTreeItemSourceProvider() - : AttachedCollectionSourceProvider +[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] +internal sealed class NonRootSymbolTreeItemSourceProvider() : AttachedCollectionSourceProvider { protected override IAttachedCollectionSource? CreateCollectionSource(SymbolTreeItem item, string relationshipName) { diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemCollectionSource.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemCollectionSource.cs new file mode 100644 index 0000000000000..8b5806557a3db --- /dev/null +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemCollectionSource.cs @@ -0,0 +1,119 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.ErrorReporting; +using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Shared.TestHooks; +using Microsoft.VisualStudio.Shell; + +namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; + +internal sealed partial class RootSymbolTreeItemSourceProvider +{ + private sealed class RootSymbolTreeItemCollectionSource( + RootSymbolTreeItemSourceProvider rootProvider, + IVsHierarchyItem hierarchyItem) : IAttachedCollectionSource, INotifyPropertyChanged + { + private readonly RootSymbolTreeItemSourceProvider _rootProvider = rootProvider; + private readonly IVsHierarchyItem _hierarchyItem = hierarchyItem; + + // Mark hasItems as null as we don't know up front if we have items, and instead have to compute it on demand. + private readonly SymbolTreeChildCollection _childCollection = new(rootProvider, hierarchyItem, hasItems: null); + + /// + /// Whether or not this root solution explorer node has been expanded or not. Until it is first expanded, + /// we do no work so as to avoid CPU time and rooting things like syntax nodes. + /// + private volatile int _initialized; + private DocumentId? _documentId; + + internal async Task UpdateIfAffectedAsync( + HashSet? updateSet, + CancellationToken cancellationToken) + { + // If we haven't been initialized yet, then we don't have to do anything. We will get called again + // in the future as documents are mutated, and we'll ignore until the point that the user has at + // least expanded this node once. + if (_initialized == 0) + return; + + var documentId = DetermineDocumentId(); + + if (documentId != null && updateSet != null && !updateSet.Contains(documentId)) + { + // Note: we intentionally return 'true' here. There was no failure here. We just got a notification + // to update a different document than our own. So we can just ignore this. + return; + } + + var solution = _rootProvider._workspace.CurrentSolution; + + var document = solution.GetDocument(documentId); + var itemProvider = document?.GetLanguageService(); + + if (document != null && itemProvider != null) + { + // Compute the items on the BG. + var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + var items = itemProvider.GetItems(root, cancellationToken); + + // Then switch to the UI thread to actually update the collection. + await _rootProvider.ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); + _childCollection.SetItemsAndMarkComputed_OnMainThread(document.Id, itemProvider, items); + } + else + { + // If we can't find this document anymore, clear everything out. + await _rootProvider.ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); + _childCollection.ClearAndMarkComputed_OnMainThread(); + } + } + + private DocumentId? DetermineDocumentId() + { + if (_documentId == null) + { + var idMap = _rootProvider._workspace.Services.GetRequiredService(); + idMap.TryGetDocumentId(_hierarchyItem, targetFrameworkMoniker: null, out _documentId); + } + + return _documentId; + } + + object IAttachedCollectionSource.SourceItem => _childCollection.SourceItem; + + bool IAttachedCollectionSource.HasItems => _childCollection.HasItems; + + IEnumerable IAttachedCollectionSource.Items + { + get + { + if (Interlocked.CompareExchange(ref _initialized, 1, 0) == 0) + { + // This was the first time this node was expanded. Kick off the initial work to + // compute the items for it. + var token = _rootProvider.Listener.BeginAsyncOperation(nameof(IAttachedCollectionSource.Items)); + UpdateIfAffectedAsync(updateSet: null, _rootProvider.ThreadingContext.DisposalToken) + .ReportNonFatalErrorAsync() + .CompletesAsyncOperation(token); + } + + return _childCollection.Items; + } + } + + event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged + { + add => _childCollection.PropertyChanged += value; + remove => _childCollection.PropertyChanged -= value; + } + } +} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index caec3ced848d6..a1a9d004d9f6b 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Collections; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; @@ -16,9 +16,8 @@ using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.ErrorReporting; -using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Navigation; -using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Threading; @@ -34,7 +33,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore [Name(nameof(RootSymbolTreeItemSourceProvider))] [Order(Before = HierarchyItemsProviderNames.Contains)] [AppliesToProject("CSharp | VB")] -internal sealed class RootSymbolTreeItemSourceProvider : AttachedCollectionSourceProvider +internal sealed partial class RootSymbolTreeItemSourceProvider : AttachedCollectionSourceProvider { private readonly ConcurrentDictionary _hierarchyToCollectionSource = []; @@ -45,8 +44,8 @@ internal sealed class RootSymbolTreeItemSourceProvider : AttachedCollectionSourc public readonly IThreadingContext ThreadingContext; public readonly IAsynchronousOperationListener Listener; - [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] public RootSymbolTreeItemSourceProvider( IThreadingContext threadingContext, VisualStudioWorkspace workspace, @@ -66,7 +65,7 @@ public RootSymbolTreeItemSourceProvider( this._workspace.RegisterWorkspaceChangedHandler( e => { - if (e is { Kind: WorkspaceChangeKind.DocumentChanged or WorkspaceChangeKind.DocumentAdded, DocumentId: not null }) + if (e.DocumentId != null) _updateSourcesQueue.AddWork(e.DocumentId); }, options: new WorkspaceEventOptions(RequiresMainThread: false)); @@ -163,85 +162,4 @@ void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e) } } } - - private sealed class RootSymbolTreeItemCollectionSource( - RootSymbolTreeItemSourceProvider rootProvider, - IVsHierarchyItem hierarchyItem) : IAttachedCollectionSource, INotifyPropertyChanged - { - private readonly RootSymbolTreeItemSourceProvider _rootProvider = rootProvider; - private readonly IVsHierarchyItem _hierarchyItem = hierarchyItem; - - // Mark hasItems as null as we don't know up front if we have items, and instead have to compute it on demand. - private readonly SymbolTreeChildCollection _childCollection = new(rootProvider, hierarchyItem, hasItems: null); - - private DocumentId? _documentId; - - internal async Task UpdateIfAffectedAsync( - HashSet updateSet, - CancellationToken cancellationToken) - { - var documentId = DetermineDocumentId(); - - // If we successfully handle this request, we're done. - if (documentId != null && await TryUpdateItemsAsync(updateSet, documentId, cancellationToken).ConfigureAwait(false)) - return; - - // If we didn't have a doc id, or we failed for any reason, clear out all our items and set that as our - // current state. - await _rootProvider.ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - _childCollection.ClearAndMarkComputed_OnMainThread(); - } - - private async ValueTask TryUpdateItemsAsync( - HashSet updateSet, DocumentId documentId, CancellationToken cancellationToken) - { - if (!updateSet.Contains(documentId)) - { - // Note: we intentionally return 'true' here. There was no failure here. We just got a notification - // to update a different document than our own. So we can just ignore this. - return true; - } - - var solution = _rootProvider._workspace.CurrentSolution; - var document = solution.GetDocument(documentId); - - // If we can't find this document anymore, clear everything out. - if (document is null) - return false; - - var itemProvider = document.GetLanguageService(); - if (itemProvider is null) - return false; - - var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var items = itemProvider.GetItems(root, cancellationToken); - - await _rootProvider.ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - _childCollection.SetItemsAndMarkComputed_OnMainThread(documentId, itemProvider, items); - return true; - } - - private DocumentId? DetermineDocumentId() - { - if (_documentId == null) - { - var idMap = _rootProvider._workspace.Services.GetRequiredService(); - idMap.TryGetDocumentId(_hierarchyItem, targetFrameworkMoniker: null, out _documentId); - } - - return _documentId; - } - - object IAttachedCollectionSource.SourceItem => _childCollection.SourceItem; - - bool IAttachedCollectionSource.HasItems => _childCollection.HasItems; - - IEnumerable IAttachedCollectionSource.Items => _childCollection.Items; - - event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged - { - add => _childCollection.PropertyChanged += value; - remove => _childCollection.PropertyChanged -= value; - } - } } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index 252262dd35c1c..881a5d090d17d 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -73,12 +73,15 @@ public SymbolTreeItem( _childCollection = new(rootProvider, this, hasItems: ItemKey.HasItems); } + private void ThrowIfNotOnMainThread() + => Contract.ThrowIfFalse(this.RootProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); + public SymbolTreeItemSyntax ItemSyntax { get => _itemSyntax; set { - Contract.ThrowIfFalse(this.RootProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); + ThrowIfNotOnMainThread(); // When the syntax node for this item is changed, we want to recompute the children for it // (if this node is expanded). Otherwise, we can just throw away what we have and recompute @@ -105,21 +108,21 @@ public bool Invoke(IEnumerable items, InputSource inputSource, bool prev public void BeforeExpand() { - Contract.ThrowIfFalse(RootProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); + ThrowIfNotOnMainThread(); _expanded = true; UpdateChildren(); } public void AfterCollapse() { - Contract.ThrowIfFalse(RootProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); + ThrowIfNotOnMainThread(); _expanded = false; UpdateChildren(); } private void UpdateChildren() { - Contract.ThrowIfFalse(RootProvider.ThreadingContext.JoinableTaskContext.IsOnMainThread); + ThrowIfNotOnMainThread(); if (_expanded) { From 218d9298d924ac5b50c42c29382fa704635992ea Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 21:49:25 +0200 Subject: [PATCH 072/353] delete files --- .../GraphFormattedLabelExtension.cs | 47 ---------- .../Core/Def/Progression/GraphNodeCreation.cs | 79 ---------------- .../IProgressionLanguageService.cs | 17 ---- .../Def/Progression/RoslynGraphCategories.cs | 23 ----- .../Core/Def/Progression/SymbolContainment.cs | 91 ------------------- .../SymbolTree/SymbolTreeChildCollection.cs | 2 + 6 files changed, 2 insertions(+), 257 deletions(-) delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphFormattedLabelExtension.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/IProgressionLanguageService.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/RoslynGraphCategories.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/SymbolContainment.cs diff --git a/src/VisualStudio/Core/Def/Progression/GraphFormattedLabelExtension.cs b/src/VisualStudio/Core/Def/Progression/GraphFormattedLabelExtension.cs deleted file mode 100644 index 030813a85ef32..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphFormattedLabelExtension.cs +++ /dev/null @@ -1,47 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//#nullable disable - -//using Microsoft.VisualStudio.GraphModel; - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//internal sealed class GraphFormattedLabelExtension : IGraphFormattedLabel -//{ -// public string Description(GraphObject graphObject, string graphCommandDefinitionIdentifier) -// { -// return GetStringPropertyForGraphObject( -// graphObject, -// graphCommandDefinitionIdentifier, -// RoslynGraphProperties.Description, -// RoslynGraphProperties.DescriptionWithContainingSymbol); -// } - -// public string Label(GraphObject graphObject, string graphCommandDefinitionIdentifier) -// { -// return GetStringPropertyForGraphObject( -// graphObject, -// graphCommandDefinitionIdentifier, -// RoslynGraphProperties.FormattedLabelWithoutContainingSymbol, -// RoslynGraphProperties.FormattedLabelWithContainingSymbol); -// } - -// private static string GetStringPropertyForGraphObject(GraphObject graphObject, string graphCommandDefinitionIdentifier, GraphProperty propertyWithoutContainingSymbol, GraphProperty propertyWithContainingSymbol) -// { -// if (graphObject is GraphNode graphNode) -// { -// if (graphCommandDefinitionIdentifier != GraphCommandDefinition.Contains.Id) -// { -// return graphNode.GetValue(propertyWithContainingSymbol); -// } -// else -// { -// return graphNode.GetValue(propertyWithoutContainingSymbol); -// } -// } - -// return null; -// } -//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs b/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs deleted file mode 100644 index 1ce605e787370..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs +++ /dev/null @@ -1,79 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//using System; -//using System.Threading; -//using System.Threading.Tasks; -//using Microsoft.CodeAnalysis; -//using Microsoft.VisualStudio.GraphModel; -//using Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//namespace Microsoft.VisualStudio.LanguageServices.Progression; - -///// -///// A helper class that implements the creation of s. -///// -//public static class GraphNodeCreation -//{ -// public static async Task CreateNodeIdAsync(ISymbol symbol, Solution solution, CancellationToken cancellationToken) -// { -// if (symbol == null) -// { -// throw new ArgumentNullException(nameof(symbol)); -// } - -// if (solution == null) -// { -// throw new ArgumentNullException(nameof(solution)); -// } - -// switch (symbol.Kind) -// { -// case SymbolKind.Assembly: -// return await GraphNodeIdCreation.GetIdForAssemblyAsync((IAssemblySymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - -// case SymbolKind.Namespace: -// return await GraphNodeIdCreation.GetIdForNamespaceAsync((INamespaceSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - -// case SymbolKind.NamedType: -// return await GraphNodeIdCreation.GetIdForTypeAsync((ITypeSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - -// case SymbolKind.Method: -// case SymbolKind.Field: -// case SymbolKind.Property: -// case SymbolKind.Event: -// return await GraphNodeIdCreation.GetIdForMemberAsync(symbol, solution, cancellationToken).ConfigureAwait(false); - -// case SymbolKind.Parameter: -// return await GraphNodeIdCreation.GetIdForParameterAsync((IParameterSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - -// case SymbolKind.Local: -// case SymbolKind.RangeVariable: -// return await GraphNodeIdCreation.GetIdForLocalVariableAsync(symbol, solution, cancellationToken).ConfigureAwait(false); - -// default: -// throw new ArgumentException(string.Format(ServicesVSResources.Can_t_create_a_node_id_for_this_symbol_kind_colon_0, symbol)); -// } -// } - -// //public static async Task CreateNodeAsync(this Graph graph, ISymbol symbol, Solution solution, CancellationToken cancellationToken) -// //{ -// // if (graph == null) -// // { -// // throw new ArgumentNullException(nameof(graph)); -// // } - -// // if (symbol == null) -// // { -// // throw new ArgumentNullException(nameof(symbol)); -// // } - -// // if (solution == null) -// // { -// // throw new ArgumentNullException(nameof(solution)); -// // } - -// // return await GraphBuilder.GetOrCreateNodeAsync(graph, symbol, solution, cancellationToken).ConfigureAwait(false); -// //} -//} diff --git a/src/VisualStudio/Core/Def/Progression/IProgressionLanguageService.cs b/src/VisualStudio/Core/Def/Progression/IProgressionLanguageService.cs deleted file mode 100644 index f00bc3076a077..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/IProgressionLanguageService.cs +++ /dev/null @@ -1,17 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//using System.Collections.Generic; -//using System.Threading; -//using Microsoft.CodeAnalysis; -//using Microsoft.CodeAnalysis.Host; - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//internal interface IProgressionLanguageService : ILanguageService -//{ -// IEnumerable GetTopLevelNodesFromDocument(SyntaxNode root, CancellationToken cancellationToken); -// string GetDescriptionForSymbol(ISymbol symbol, bool includeContainingSymbol); -// string GetLabelForSymbol(ISymbol symbol, bool includeContainingSymbol); -//} diff --git a/src/VisualStudio/Core/Def/Progression/RoslynGraphCategories.cs b/src/VisualStudio/Core/Def/Progression/RoslynGraphCategories.cs deleted file mode 100644 index f4ab130359f01..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/RoslynGraphCategories.cs +++ /dev/null @@ -1,23 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//using Microsoft.VisualStudio.GraphModel; - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//internal static class RoslynGraphCategories -//{ -// public static readonly GraphSchema Schema; - -// public static readonly GraphCategory Overrides; - -// static RoslynGraphCategories() -// { -// Schema = RoslynGraphProperties.Schema; - -// Overrides = Schema.Categories.AddNewCategory( -// "Overrides", -// () => new GraphMetadata(GraphMetadataOptions.Sharable)); -// } -//} diff --git a/src/VisualStudio/Core/Def/Progression/SymbolContainment.cs b/src/VisualStudio/Core/Def/Progression/SymbolContainment.cs deleted file mode 100644 index 6b8be85ffff74..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/SymbolContainment.cs +++ /dev/null @@ -1,91 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//#nullable disable - -//using System.Collections.Generic; -//using System.Collections.Immutable; -//using System.Threading; -//using System.Threading.Tasks; -//using Microsoft.CodeAnalysis; -//using Microsoft.CodeAnalysis.PooledObjects; -//using Microsoft.CodeAnalysis.Shared.Extensions; - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//internal static class SymbolContainment -//{ -// public static async Task> GetContainedSyntaxNodesAsync(Document document, CancellationToken cancellationToken) -// { -// var progressionLanguageService = document.GetLanguageService(); -// if (progressionLanguageService == null) -// return []; - -// var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); -// var root = await syntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); -// return progressionLanguageService.GetTopLevelNodesFromDocument(root, cancellationToken); -// } - -// public static async Task> GetContainedSymbolsAsync(Document document, CancellationToken cancellationToken) -// { -// var syntaxNodes = await GetContainedSyntaxNodesAsync(document, cancellationToken).ConfigureAwait(false); -// var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); -// using var _ = ArrayBuilder.GetInstance(out var symbols); - -// foreach (var syntaxNode in syntaxNodes) -// { -// cancellationToken.ThrowIfCancellationRequested(); - -// var symbol = semanticModel.GetDeclaredSymbol(syntaxNode, cancellationToken); -// if (symbol != null && -// !string.IsNullOrEmpty(symbol.Name) && -// IsTopLevelSymbol(symbol)) -// { -// symbols.Add(symbol); -// } -// } - -// return symbols.ToImmutableAndClear(); -// } - -// private static bool IsTopLevelSymbol(ISymbol symbol) -// { -// switch (symbol.Kind) -// { -// case SymbolKind.NamedType: -// case SymbolKind.Method: -// case SymbolKind.Field: -// case SymbolKind.Property: -// case SymbolKind.Event: -// return true; - -// default: -// return false; -// } -// } - -// public static IEnumerable GetContainedSymbols(ISymbol symbol) -// { -// if (symbol is INamedTypeSymbol namedType) -// { -// foreach (var member in namedType.GetMembers()) -// { -// if (member.IsImplicitlyDeclared) -// { -// continue; -// } - -// if (member is IMethodSymbol method && method.AssociatedSymbol != null) -// { -// continue; -// } - -// if (!string.IsNullOrEmpty(member.Name)) -// { -// yield return member; -// } -// } -// } -// } -//} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs index 7bdb78ab1a7f1..361053754c61f 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs @@ -7,6 +7,7 @@ using System.ComponentModel; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.Internal.VisualStudio.PlatformUI; using Microsoft.VisualStudio.LanguageServices.Extensions; using Microsoft.VisualStudio.Shell; using Roslyn.Utilities; @@ -102,6 +103,7 @@ public void SetItemsAndMarkComputed_OnMainThread( } else { + ISearchProvider // If we didn't find an existing item, create a new one. _symbolTreeItems.Add(new(_rootProvider, documentId, itemProvider, itemData.ItemKey) { From 7b1286b707216cd0ac4d6bca9ec3af74d0d9af84 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 27 May 2025 21:59:16 +0200 Subject: [PATCH 073/353] REmove code --- .../Core/Def/Progression/GraphBuilder.cs | 655 +----------------- .../Progression/GraphNavigatorExtension.cs | 6 +- .../Def/Progression/GraphNodeIdCreation.cs | 534 -------------- .../Core/Def/Progression/GraphProvider.cs | 43 -- .../Core/Def/Progression/GraphQueryManager.cs | 49 +- .../Def/Progression/RoslynGraphProperties.cs | 46 -- 6 files changed, 3 insertions(+), 1330 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs b/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs index 89f943433beb7..9ea4218df8980 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs @@ -6,19 +6,14 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.IO; -using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.ErrorReporting; -using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.NavigateTo; -using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.GraphModel; using Microsoft.VisualStudio.GraphModel.CodeSchema; using Microsoft.VisualStudio.GraphModel.Schemas; -using Microsoft.VisualStudio.Progression.CodeSchema; using Roslyn.Utilities; namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; @@ -31,652 +26,12 @@ internal sealed partial class GraphBuilder #pragma warning restore RS0030 // Do not use banned APIs private readonly ISet _createdNodes = new HashSet(); - // private readonly IList> _deferredPropertySets = []; - // private readonly Dictionary _nodeToContextProjectMap = []; - // private readonly Dictionary _nodeToContextDocumentMap = []; - // private readonly Dictionary _nodeToSymbolMap = []; - - /// - /// The input solution. Never null. - /// - // private readonly Solution _solution; - - public GraphBuilder(Solution solution) + public GraphBuilder() { // _solution = solution; } - //public static async Task CreateForInputNodesAsync( - // Solution solution, IEnumerable inputNodes, CancellationToken cancellationToken) - //{ - // var builder = new GraphBuilder(solution); - - // foreach (var inputNode in inputNodes) - // { - // if (inputNode.HasCategory(CodeNodeCategories.File)) - // { - // // builder.PopulateMapsForFileInputNode(inputNode, cancellationToken); - // } - // else if (!inputNode.HasCategory(CodeNodeCategories.SourceLocation)) - // { - // await builder.PopulateMapsForSymbolInputNodeAsync(inputNode, cancellationToken).ConfigureAwait(false); - // } - // } - - // return builder; - //} - - //private void PopulateMapsForFileInputNode(GraphNode inputNode, CancellationToken cancellationToken) - //{ - // using (_gate.DisposableWait(cancellationToken)) - // { - // var projectPath = inputNode.Id.GetNestedValueByName(CodeGraphNodeIdName.Assembly); - // var filePath = inputNode.Id.GetNestedValueByName(CodeGraphNodeIdName.File); - - // if (projectPath == null || filePath == null) - // { - // return; - // } - - // var docIdsWithPath = _solution.GetDocumentIdsWithFilePath(filePath.OriginalString); - // Document? document = null; - // Project? project = null; - - // foreach (var docIdWithPath in docIdsWithPath) - // { - // var projectState = _solution.GetProjectState(docIdWithPath.ProjectId); - // if (projectState == null) - // { - // FatalError.ReportAndCatch(new Exception("GetDocumentIdsWithFilePath returned a document in a project that does not exist.")); - // continue; - // } - - // if (string.Equals(projectState.FilePath, projectPath.OriginalString)) - // { - // project = _solution.GetRequiredProject(projectState.Id); - // document = project.GetDocument(docIdWithPath); - // break; - // } - // } - - // if (document == null || project == null) - // { - // return; - // } - - // _nodeToContextProjectMap.Add(inputNode, project); - // // _nodeToContextDocumentMap.Add(inputNode, document); - // } - //} - - //private async Task PopulateMapsForSymbolInputNodeAsync(GraphNode inputNode, CancellationToken cancellationToken) - //{ - // using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) - // { - // var projectId = (ProjectId)inputNode[RoslynGraphProperties.ContextProjectId]; - // if (projectId == null) - // { - // return; - // } - - // var project = _solution.GetProject(projectId); - // if (project == null) - // { - // return; - // } - - // // _nodeToContextProjectMap.Add(inputNode, project); - - // //var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); - // //var symbolId = (SymbolKey?)inputNode[RoslynGraphProperties.SymbolId]; - // //var symbol = symbolId.Value.Resolve(compilation, cancellationToken: cancellationToken).Symbol; - // //if (symbol != null) - // //{ - // // _nodeToSymbolMap.Add(inputNode, symbol); - // //} - - // var documentId = (DocumentId)inputNode[RoslynGraphProperties.ContextDocumentId]; - // if (documentId != null) - // { - // var document = project.GetDocument(documentId); - // if (document != null) - // { - // // _nodeToContextDocumentMap.Add(inputNode, document); - // } - // } - // } - //} - - //public Project GetContextProject(GraphNode node, CancellationToken cancellationToken) - //{ - // using (_gate.DisposableWait(cancellationToken)) - // { - // _nodeToContextProjectMap.TryGetValue(node, out var project); - // return project; - // } - //} - - //public ProjectId GetContextProjectId(Project project, ISymbol symbol) - //{ - // var thisProject = project.Solution.GetProject(symbol.ContainingAssembly) ?? project; - // return thisProject.Id; - //} - - //public Document GetContextDocument(GraphNode node, CancellationToken cancellationToken) - //{ - // using (_gate.DisposableWait(cancellationToken)) - // { - // _nodeToContextDocumentMap.TryGetValue(node, out var document); - // return document; - // } - //} - - //public ISymbol GetSymbol(GraphNode node, CancellationToken cancellationToken) - //{ - // using (_gate.DisposableWait(cancellationToken)) - // { - // _nodeToSymbolMap.TryGetValue(node, out var symbol); - // return symbol; - // } - //} - - //public Task AddNodeAsync(ISymbol symbol, GraphNode relatedNode, CancellationToken cancellationToken) - //{ - // // The lack of a lock here is acceptable, since each of the functions lock, and GetContextProject/GetContextDocument - // // never change for the same input. - // return AddNodeAsync( - // symbol, - // GetContextProject(relatedNode, cancellationToken), - // GetContextDocument(relatedNode, cancellationToken), - // cancellationToken); - //} - - //public async Task AddNodeAsync( - // ISymbol symbol, Project contextProject, Document contextDocument, CancellationToken cancellationToken) - //{ - // // Figure out what the location for this node should be. We'll arbitrarily pick the - // // first one, unless we have a contextDocument to restrict it - // var preferredLocation = symbol.Locations.FirstOrDefault(l => l.SourceTree != null); - - // if (contextDocument != null) - // { - // var syntaxTree = await contextDocument.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); - - // // If we have one in that tree, use it - // preferredLocation = symbol.Locations.FirstOrDefault(l => l.SourceTree == syntaxTree) ?? preferredLocation; - // } - - // // We may need to look up source code within this solution - // if (preferredLocation == null && symbol.Locations.Any(static loc => loc.IsInMetadata)) - // { - // var newSymbol = await SymbolFinder.FindSourceDefinitionAsync(symbol, contextProject.Solution, cancellationToken).ConfigureAwait(false); - // if (newSymbol != null) - // preferredLocation = newSymbol.Locations.Where(loc => loc.IsInSource).FirstOrDefault(); - // } - - // using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) - // { - // var node = await GetOrCreateNodeAsync(Graph, symbol, _solution, cancellationToken).ConfigureAwait(false); - - // node[RoslynGraphProperties.SymbolId] = (SymbolKey?)symbol.GetSymbolKey(cancellationToken); - // node[RoslynGraphProperties.ContextProjectId] = GetContextProjectId(contextProject, symbol); - // node[RoslynGraphProperties.ExplicitInterfaceImplementations] = symbol.ExplicitInterfaceImplementations().Select(s => s.GetSymbolKey()).ToList(); - // node[RoslynGraphProperties.DeclaredAccessibility] = symbol.DeclaredAccessibility; - // node[RoslynGraphProperties.SymbolModifiers] = symbol.GetSymbolModifiers(); - // node[RoslynGraphProperties.SymbolKind] = symbol.Kind; - - // if (contextDocument != null) - // node[RoslynGraphProperties.ContextDocumentId] = contextDocument.Id; - - // if (preferredLocation?.SourceTree != null) - // { - // var lineSpan = preferredLocation.GetLineSpan(); - // var sourceLocation = TryCreateSourceLocation( - // preferredLocation.SourceTree.FilePath, - // lineSpan.Span); - // if (sourceLocation != null) - // node[CodeNodeProperties.SourceLocation] = sourceLocation.Value; - // } - - // // Keep track of this as a node we have added. Note this is a HashSet, so if the node was already added - // // we won't double-count. - // _createdNodes.Add(node); - - // _nodeToSymbolMap[node] = symbol; - // _nodeToContextProjectMap[node] = contextProject; - - // if (contextDocument != null) - // _nodeToContextDocumentMap[node] = contextDocument; - - // return node; - // } - //} - - //internal static async Task GetOrCreateNodeAsync(Graph graph, ISymbol symbol, Solution solution, CancellationToken cancellationToken) - //{ - // GraphNode node; - - // switch (symbol.Kind) - // { - // case SymbolKind.Assembly: - // node = await GetOrCreateNodeAssemblyAsync(graph, (IAssemblySymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - // break; - - // case SymbolKind.Namespace: - // node = await GetOrCreateNodeForNamespaceAsync(graph, (INamespaceSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - // break; - - // case SymbolKind.NamedType: - // case SymbolKind.ErrorType: - // node = await GetOrCreateNodeForNamedTypeAsync(graph, (INamedTypeSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - // break; - - // case SymbolKind.Method: - // node = await GetOrCreateNodeForMethodAsync(graph, (IMethodSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - // break; - - // case SymbolKind.Field: - // node = await GetOrCreateNodeForFieldAsync(graph, (IFieldSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - // break; - - // case SymbolKind.Property: - // node = await GetOrCreateNodeForPropertyAsync(graph, (IPropertySymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - // break; - - // case SymbolKind.Event: - // node = await GetOrCreateNodeForEventAsync(graph, (IEventSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - // break; - - // case SymbolKind.Parameter: - // node = await GetOrCreateNodeForParameterAsync(graph, (IParameterSymbol)symbol, solution, cancellationToken).ConfigureAwait(false); - // break; - - // case SymbolKind.Local: - // case SymbolKind.RangeVariable: - // node = await GetOrCreateNodeForLocalVariableAsync(graph, symbol, solution, cancellationToken).ConfigureAwait(false); - // break; - - // default: - // throw new ArgumentException("symbol"); - // } - - // UpdatePropertiesForNode(symbol, node); - // UpdateLabelsForNode(symbol, solution, node); - - // return node; - //} - - //private static async Task GetOrCreateNodeForParameterAsync(Graph graph, IParameterSymbol parameterSymbol, Solution solution, CancellationToken cancellationToken) - //{ - // var id = await GraphNodeIdCreation.GetIdForParameterAsync(parameterSymbol, solution, cancellationToken).ConfigureAwait(false); - // var node = graph.Nodes.GetOrCreate(id); - // node.AddCategory(CodeNodeCategories.Parameter); - - // node.SetValue(Properties.IsByReference, parameterSymbol.RefKind == RefKind.Ref); - // node.SetValue(Properties.IsOut, parameterSymbol.RefKind == RefKind.Out); - // node.SetValue(Properties.IsParameterArray, parameterSymbol.IsParams); - - // return node; - //} - - //private static async Task GetOrCreateNodeForLocalVariableAsync(Graph graph, ISymbol localSymbol, Solution solution, CancellationToken cancellationToken) - //{ - // var id = await GraphNodeIdCreation.GetIdForLocalVariableAsync(localSymbol, solution, cancellationToken).ConfigureAwait(false); - // var node = graph.Nodes.GetOrCreate(id); - // node.AddCategory(NodeCategories.LocalExpression); - - // return node; - //} - - //private static async Task GetOrCreateNodeAssemblyAsync(Graph graph, IAssemblySymbol assemblySymbol, Solution solution, CancellationToken cancellationToken) - //{ - // var id = await GraphNodeIdCreation.GetIdForAssemblyAsync(assemblySymbol, solution, cancellationToken).ConfigureAwait(false); - // var node = graph.Nodes.GetOrCreate(id); - // node.AddCategory(CodeNodeCategories.Assembly); - - // return node; - //} - - //private static void UpdateLabelsForNode(ISymbol symbol, Solution solution, GraphNode node) - //{ - // var progressionLanguageService = solution.Services.GetLanguageServices(symbol.Language).GetService(); - - // // A call from unittest may not have a proper language service. - // if (progressionLanguageService != null) - // { - // node[RoslynGraphProperties.Description] = progressionLanguageService.GetDescriptionForSymbol(symbol, includeContainingSymbol: false); - // node[RoslynGraphProperties.DescriptionWithContainingSymbol] = progressionLanguageService.GetDescriptionForSymbol(symbol, includeContainingSymbol: true); - - // node[RoslynGraphProperties.FormattedLabelWithoutContainingSymbol] = progressionLanguageService.GetLabelForSymbol(symbol, includeContainingSymbol: false); - // node[RoslynGraphProperties.FormattedLabelWithContainingSymbol] = progressionLanguageService.GetLabelForSymbol(symbol, includeContainingSymbol: true); - // } - - // switch (symbol.Kind) - // { - // case SymbolKind.NamedType: - // var typeSymbol = (INamedTypeSymbol)symbol; - // if (typeSymbol.IsGenericType) - // { - // // Symbol.name does not contain type params for generic types, so we populate them here for some requiring cases like VS properties panel. - // node.Label = (string)node[RoslynGraphProperties.FormattedLabelWithoutContainingSymbol]; - - // // Some consumers like CodeMap want to show types in an unified way for both C# and VB. - // // Therefore, populate a common label property using only name and its type parameters. - // // For example, VB's "Goo(Of T)" or C#'s "Goo(): T" will be shown as "Goo". - // // This property will be used for drag-and-drop case. - // var commonLabel = new System.Text.StringBuilder(); - // commonLabel.Append(typeSymbol.Name); - // commonLabel.Append('<'); - // commonLabel.Append(string.Join(", ", typeSymbol.TypeParameters.Select(t => t.Name))); - // commonLabel.Append('>'); - // node[Microsoft.VisualStudio.ArchitectureTools.ProgressiveReveal.ProgressiveRevealSchema.CommonLabel] = commonLabel.ToString(); - - // return; - // } - // else - // { - // node.Label = symbol.Name; - // } - - // break; - - // case SymbolKind.Method: - // var methodSymbol = (IMethodSymbol)symbol; - // if (methodSymbol.MethodKind == MethodKind.Constructor) - // { - // node.Label = CodeQualifiedIdentifierBuilder.SpecialNames.GetConstructorLabel(methodSymbol.ContainingSymbol.Name); - // } - // else if (methodSymbol.MethodKind == MethodKind.StaticConstructor) - // { - // node.Label = CodeQualifiedIdentifierBuilder.SpecialNames.GetStaticConstructorLabel(methodSymbol.ContainingSymbol.Name); - // } - // else if (methodSymbol.MethodKind == MethodKind.Destructor) - // { - // node.Label = CodeQualifiedIdentifierBuilder.SpecialNames.GetFinalizerLabel(methodSymbol.ContainingSymbol.Name); - // } - // else - // { - // node.Label = methodSymbol.Name; - // } - - // break; - - // case SymbolKind.Property: - // node.Label = symbol.MetadataName; - - // var propertySymbol = (IPropertySymbol)symbol; - // if (propertySymbol.IsIndexer && LanguageNames.CSharp == propertySymbol.Language) - // { - // // For C# indexer, we will strip off the "[]" - // node.Label = symbol.Name.Replace("[]", string.Empty); - // } - - // break; - - // case SymbolKind.Namespace: - // // Use a name with its parents (e.g., A.B.C) - // node.Label = symbol.ToDisplayString(); - // break; - - // default: - // node.Label = symbol.Name; - // break; - // } - - // // When a node is dragged and dropped from SE to CodeMap, its label could be reset during copying to clipboard. - // // So, we try to keep its label that we computed above in a common label property, which CodeMap can access later. - // node[Microsoft.VisualStudio.ArchitectureTools.ProgressiveReveal.ProgressiveRevealSchema.CommonLabel] = node.Label; - //} - - //private static void UpdatePropertiesForNode(ISymbol symbol, GraphNode node) - //{ - // // Set accessibility properties - // switch (symbol.DeclaredAccessibility) - // { - // case Accessibility.Public: - // node[Properties.IsPublic] = true; - // break; - - // case Accessibility.Internal: - // node[Properties.IsInternal] = true; - // break; - - // case Accessibility.Protected: - // node[Properties.IsProtected] = true; - // break; - - // case Accessibility.Private: - // node[Properties.IsPrivate] = true; - // break; - - // case Accessibility.ProtectedOrInternal: - // node[Properties.IsProtectedOrInternal] = true; - // break; - - // case Accessibility.ProtectedAndInternal: - // node[Properties.IsProtected] = true; - // node[Properties.IsInternal] = true; - // break; - - // case Accessibility.NotApplicable: - // break; - // } - - // // Set common properties - // if (symbol.IsAbstract) - // { - // node[Properties.IsAbstract] = true; - // } - - // if (symbol.IsSealed) - // { - // // For VB module, do not set IsFinal since it's not inheritable. - // if (!symbol.IsModuleType()) - // { - // node[Properties.IsFinal] = true; - // } - // } - - // if (symbol.IsStatic) - // { - // node[Properties.IsStatic] = true; - // } - - // if (symbol.IsVirtual) - // { - // node[Properties.IsVirtual] = true; - // } - - // if (symbol.IsOverride) - // { - // // The property name is a misnomer, but this is what the previous providers do. - // node[Microsoft.VisualStudio.Progression.DgmlProperties.IsOverloaded] = true; - // } - - // // Set type-specific properties - // if (symbol is ITypeSymbol typeSymbol && typeSymbol.IsAnonymousType) - // { - // node[Properties.IsAnonymous] = true; - // } - // else if (symbol is IMethodSymbol methodSymbol) - // { - // UpdateMethodPropertiesForNode(methodSymbol, node); - // } - //} - - //private static void UpdateMethodPropertiesForNode(IMethodSymbol symbol, GraphNode node) - //{ - // if (symbol.HidesBaseMethodsByName) - // { - // node[Properties.IsHideBySignature] = true; - // } - - // if (symbol.IsExtensionMethod) - // { - // node[Properties.IsExtension] = true; - // } - - // switch (symbol.MethodKind) - // { - // case MethodKind.AnonymousFunction: - // node[Properties.IsAnonymous] = true; - // break; - - // case MethodKind.BuiltinOperator: - // case MethodKind.UserDefinedOperator: - // node[Properties.IsOperator] = true; - // break; - - // case MethodKind.Constructor: - // case MethodKind.StaticConstructor: - // node[Properties.IsConstructor] = true; - // break; - - // case MethodKind.Conversion: - // // Operator implicit/explicit - // node[Properties.IsOperator] = true; - // break; - - // case MethodKind.Destructor: - // node[Properties.IsFinalizer] = true; - // break; - - // case MethodKind.PropertyGet: - // node[Properties.IsPropertyGet] = true; - // break; - - // case MethodKind.PropertySet: - // node[Properties.IsPropertySet] = true; - // break; - // } - //} - - //private static async Task GetOrCreateNodeForNamespaceAsync(Graph graph, INamespaceSymbol symbol, Solution solution, CancellationToken cancellationToken) - //{ - // var id = await GraphNodeIdCreation.GetIdForNamespaceAsync(symbol, solution, cancellationToken).ConfigureAwait(false); - // var node = graph.Nodes.GetOrCreate(id); - // node.AddCategory(CodeNodeCategories.Namespace); - - // return node; - //} - - //private static async Task GetOrCreateNodeForNamedTypeAsync(Graph graph, INamedTypeSymbol namedType, Solution solution, CancellationToken cancellationToken) - //{ - // var id = await GraphNodeIdCreation.GetIdForTypeAsync(namedType, solution, cancellationToken).ConfigureAwait(false); - // var node = graph.Nodes.GetOrCreate(id); - // string iconGroupName; - - // switch (namedType.TypeKind) - // { - // case TypeKind.Class: - // node.AddCategory(CodeNodeCategories.Class); - // iconGroupName = "Class"; - // break; - - // case TypeKind.Delegate: - // node.AddCategory(CodeNodeCategories.Delegate); - // iconGroupName = "Delegate"; - // break; - - // case TypeKind.Enum: - // node.AddCategory(CodeNodeCategories.Enum); - // iconGroupName = "Enum"; - // break; - - // case TypeKind.Interface: - // node.AddCategory(CodeNodeCategories.Interface); - // iconGroupName = "Interface"; - // break; - - // case TypeKind.Module: - // node.AddCategory(CodeNodeCategories.Module); - // iconGroupName = "Module"; - // break; - - // case TypeKind.Struct: - // node.AddCategory(CodeNodeCategories.Struct); - // iconGroupName = "Struct"; - // break; - - // case TypeKind.Error: - // node.AddCategory(CodeNodeCategories.Type); - // iconGroupName = "Error"; - // break; - - // default: - // throw ExceptionUtilities.UnexpectedValue(namedType.TypeKind); - // } - - // node[DgmlNodeProperties.Icon] = IconHelper.GetIconName(iconGroupName, namedType.DeclaredAccessibility); - // node[RoslynGraphProperties.TypeKind] = namedType.TypeKind; - - // return node; - //} - - //private static async Task GetOrCreateNodeForMethodAsync(Graph graph, IMethodSymbol method, Solution solution, CancellationToken cancellationToken) - //{ - // var id = await GraphNodeIdCreation.GetIdForMemberAsync(method, solution, cancellationToken).ConfigureAwait(false); - // var node = graph.Nodes.GetOrCreate(id); - - // node.AddCategory(CodeNodeCategories.Method); - - // var isOperator = method.MethodKind is MethodKind.UserDefinedOperator or MethodKind.Conversion; - // node[DgmlNodeProperties.Icon] = isOperator - // ? IconHelper.GetIconName("Operator", method.DeclaredAccessibility) - // : IconHelper.GetIconName("Method", method.DeclaredAccessibility); - - // node[RoslynGraphProperties.TypeKind] = method.ContainingType.TypeKind; - // node[RoslynGraphProperties.MethodKind] = method.MethodKind; - - // return node; - //} - - //private static async Task GetOrCreateNodeForFieldAsync(Graph graph, IFieldSymbol field, Solution solution, CancellationToken cancellationToken) - //{ - // var id = await GraphNodeIdCreation.GetIdForMemberAsync(field, solution, cancellationToken).ConfigureAwait(false); - // var node = graph.Nodes.GetOrCreate(id); - - // node.AddCategory(CodeNodeCategories.Field); - - // if (field.ContainingType.TypeKind == TypeKind.Enum) - // { - // node[DgmlNodeProperties.Icon] = IconHelper.GetIconName("EnumMember", field.DeclaredAccessibility); - // } - // else - // { - // node[DgmlNodeProperties.Icon] = IconHelper.GetIconName("Field", field.DeclaredAccessibility); - // } - - // return node; - //} - - //private static async Task GetOrCreateNodeForPropertyAsync(Graph graph, IPropertySymbol property, Solution solution, CancellationToken cancellationToken) - //{ - // var id = await GraphNodeIdCreation.GetIdForMemberAsync(property, solution, cancellationToken).ConfigureAwait(false); - // var node = graph.Nodes.GetOrCreate(id); - - // node.AddCategory(CodeNodeCategories.Property); - - // node[DgmlNodeProperties.Icon] = IconHelper.GetIconName("Property", property.DeclaredAccessibility); - // node[RoslynGraphProperties.TypeKind] = property.ContainingType.TypeKind; - - // return node; - //} - - //private static async Task GetOrCreateNodeForEventAsync(Graph graph, IEventSymbol eventSymbol, Solution solution, CancellationToken cancellationToken) - //{ - // var id = await GraphNodeIdCreation.GetIdForMemberAsync(eventSymbol, solution, cancellationToken).ConfigureAwait(false); - // var node = graph.Nodes.GetOrCreate(id); - - // node.AddCategory(CodeNodeCategories.Event); - - // node[DgmlNodeProperties.Icon] = IconHelper.GetIconName("Event", eventSymbol.DeclaredAccessibility); - // node[RoslynGraphProperties.TypeKind] = eventSymbol.ContainingType.TypeKind; - - // return node; - //} - public void AddLink(GraphNode from, GraphCategory category, GraphNode to, CancellationToken cancellationToken) { using (_gate.DisposableWait(cancellationToken)) @@ -835,14 +190,6 @@ public void ApplyToGraph(Graph graph, CancellationToken cancellationToken) } } - //public void AddDeferredPropertySet(GraphNode node, GraphProperty property, object value, CancellationToken cancellationToken) - //{ - // using (_gate.DisposableWait(cancellationToken)) - // { - // _deferredPropertySets.Add(Tuple.Create(node, property, value)); - // } - //} - public Graph Graph { get; } = new(); public ImmutableArray GetCreatedNodes(CancellationToken cancellationToken) diff --git a/src/VisualStudio/Core/Def/Progression/GraphNavigatorExtension.cs b/src/VisualStudio/Core/Def/Progression/GraphNavigatorExtension.cs index ed3ccb34086fd..27f81077dff70 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphNavigatorExtension.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphNavigatorExtension.cs @@ -7,9 +7,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; -using Microsoft.CodeAnalysis.GoToDefinition; using Microsoft.CodeAnalysis.Navigation; using Microsoft.VisualStudio.GraphModel; using Microsoft.VisualStudio.GraphModel.CodeSchema; @@ -21,12 +19,10 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; internal sealed class GraphNavigatorExtension( IThreadingContext threadingContext, - Workspace workspace, - Lazy streamingPresenter) : IGraphNavigateToItem + Workspace workspace) : IGraphNavigateToItem { private readonly IThreadingContext _threadingContext = threadingContext; private readonly Workspace _workspace = workspace; - // private readonly Lazy _streamingPresenter = streamingPresenter; public void NavigateTo(GraphObject graphObject) { diff --git a/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs b/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs index 04c77ad78c2cf..eb52039b84d2c 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs @@ -5,17 +5,9 @@ #nullable disable using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.VisualStudio.GraphModel; -using Microsoft.VisualStudio.GraphModel.CodeSchema; using Microsoft.VisualStudio.GraphModel.Schemas; -using Microsoft.VisualStudio.Progression.CodeSchema; -using Roslyn.Utilities; namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; @@ -32,530 +24,4 @@ public static GraphNodeId GetIdForDocument(Document document) GraphNodeId.GetPartial(CodeGraphNodeIdName.Assembly, new Uri(document.Project.FilePath, UriKind.RelativeOrAbsolute)), GraphNodeId.GetPartial(CodeGraphNodeIdName.File, new Uri(document.FilePath, UriKind.RelativeOrAbsolute))); } - - //internal static async Task GetIdForNamespaceAsync(INamespaceSymbol symbol, Solution solution, CancellationToken cancellationToken) - //{ - // var builder = new CodeQualifiedIdentifierBuilder(); - - // var assembly = await GetAssemblyFullPathAsync(symbol, solution, cancellationToken).ConfigureAwait(false); - // if (assembly != null) - // { - // builder.Assembly = assembly; - // } - - // builder.Namespace = symbol.ToDisplayString(); - - // return builder.ToQualifiedIdentifier(); - //} - - //internal static async Task GetIdForTypeAsync(ITypeSymbol symbol, Solution solution, CancellationToken cancellationToken) - //{ - // var nodes = await GetPartialsForNamespaceAndTypeAsync(symbol, true, solution, cancellationToken).ConfigureAwait(false); - // var partials = nodes.ToArray(); - - // if (partials.Length == 1) - // { - // return partials[0]; - // } - // else - // { - // return GraphNodeId.GetNested(partials); - // } - //} - - //private static async Task> GetPartialsForNamespaceAndTypeAsync(ITypeSymbol symbol, bool includeNamespace, Solution solution, CancellationToken cancellationToken, bool isInGenericArguments = false) - //{ - // var items = new List(); - - // Uri assembly = null; - // if (includeNamespace) - // { - // assembly = await GetAssemblyFullPathAsync(symbol, solution, cancellationToken).ConfigureAwait(false); - // } - - // var underlyingType = ChaseToUnderlyingType(symbol); - - // if (symbol.TypeKind == TypeKind.TypeParameter) - // { - // var typeParameter = (ITypeParameterSymbol)symbol; - - // if (typeParameter.TypeParameterKind == TypeParameterKind.Type) - // { - // if (includeNamespace && !typeParameter.ContainingNamespace.IsGlobalNamespace) - // { - // if (assembly != null) - // { - // items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Assembly, assembly)); - // } - - // items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Namespace, typeParameter.ContainingNamespace.ToDisplayString())); - // } - - // items.Add(await GetPartialForTypeAsync(symbol.ContainingType, CodeGraphNodeIdName.Type, solution, cancellationToken).ConfigureAwait(false)); - // } - - // items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Parameter, ((ITypeParameterSymbol)symbol).Ordinal.ToString())); - // } - // else - // { - // if (assembly != null) - // { - // items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Assembly, assembly)); - // } - - // if (underlyingType.TypeKind == TypeKind.Dynamic) - // { - // items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Namespace, "System")); - // } - // else if (underlyingType.ContainingNamespace != null && !underlyingType.ContainingNamespace.IsGlobalNamespace) - // { - // items.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Namespace, underlyingType.ContainingNamespace.ToDisplayString())); - // } - - // items.Add(await GetPartialForTypeAsync(symbol, CodeGraphNodeIdName.Type, solution, cancellationToken, isInGenericArguments).ConfigureAwait(false)); - // } - - // return items; - //} - - //private static async Task GetPartialForTypeAsync(ITypeSymbol symbol, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken, bool isInGenericArguments = false) - //{ - // if (symbol is IArrayTypeSymbol arrayType) - // { - // return await GetPartialForArrayTypeAsync(arrayType, nodeName, solution, cancellationToken).ConfigureAwait(false); - // } - // else if (symbol is INamedTypeSymbol namedType) - // { - // return await GetPartialForNamedTypeAsync(namedType, nodeName, solution, cancellationToken, isInGenericArguments).ConfigureAwait(false); - // } - // else if (symbol is IPointerTypeSymbol pointerType) - // { - // return await GetPartialForPointerTypeAsync(pointerType, nodeName, solution, cancellationToken).ConfigureAwait(false); - // } - // else if (symbol is ITypeParameterSymbol typeParameter) - // { - // return await GetPartialForTypeParameterSymbolAsync(typeParameter, nodeName, solution, cancellationToken).ConfigureAwait(false); - // } - // else if (symbol is IDynamicTypeSymbol) - // { - // return GetPartialForDynamicType(nodeName); - // } - - // throw ExceptionUtilities.Unreachable(); - //} - - //private static GraphNodeId GetPartialForDynamicType(GraphNodeIdName nodeName) - //{ - // // We always consider this to be the "Object" type since Progression takes a very metadata-ish view of the type - // return GraphNodeId.GetPartial(nodeName, "Object"); - //} - - //private static async Task GetPartialForNamedTypeAsync(INamedTypeSymbol namedType, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken, bool isInGenericArguments = false) - //{ - // // If this is a simple type, then we don't have much to do - // if (namedType.ContainingType == null && Equals(namedType.ConstructedFrom, namedType) && namedType.Arity == 0) - // { - // return GraphNodeId.GetPartial(nodeName, namedType.Name); - // } - // else - // { - // // For a generic type, we need to populate "type" property with the following form: - // // - // // Type = (Name =...GenericParameterCount = GenericArguments =...ParentType =...) - // // - // // where "Name" contains a symbol name - // // and "GenericParameterCount" contains the number of type parameters, - // // and "GenericArguments" contains its type parameters' node information. - // // and "ParentType" contains its containing type's node information. - - // var partials = new List - // { - // GraphNodeId.GetPartial(CodeQualifiedName.Name, namedType.Name) - // }; - - // if (namedType.Arity > 0) - // { - // partials.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.GenericParameterCountIdentifier, namedType.Arity.ToString())); - // } - - // // For the property "GenericArguments", we only populate them - // // when type parameters are constructed using instance types (i.e., namedType.ConstructedFrom != namedType). - // // However, there is a case where we need to populate "GenericArguments" even though arguments are not marked as "constructed" - // // because a symbol is not marked as "constructed" when a type is constructed using its own type parameters. - // // To distinguish this case, we use "isInGenericArguments" flag which we pass either to populate arguments recursively or to populate "ParentType". - - // var hasGenericArguments = (!Equals(namedType.ConstructedFrom, namedType) || isInGenericArguments) && namedType.TypeArguments != null && namedType.TypeArguments.Any(); - - // if (hasGenericArguments) - // { - // var genericArguments = new List(); - // foreach (var arg in namedType.TypeArguments) - // { - // var nodes = await GetPartialsForNamespaceAndTypeAsync(arg, includeNamespace: true, solution: solution, cancellationToken: cancellationToken, isInGenericArguments: true).ConfigureAwait(false); - // genericArguments.Add(GraphNodeId.GetNested([.. nodes])); - // } - - // partials.Add(GraphNodeId.GetArray( - // CodeGraphNodeIdName.GenericArgumentsIdentifier, - // [.. genericArguments])); - // } - - // if (namedType.ContainingType != null) - // { - // partials.Add(await GetPartialForTypeAsync(namedType.ContainingType, CodeGraphNodeIdName.ParentType, solution, cancellationToken, hasGenericArguments).ConfigureAwait(false)); - // } - - // return GraphNodeId.GetPartial(nodeName, MakeCollectionIfNecessary([.. partials])); - // } - //} - - //private static async Task GetPartialForPointerTypeAsync(IPointerTypeSymbol pointerType, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken) - //{ - // var indirection = 1; - - // while (pointerType.PointedAtType.TypeKind == TypeKind.Pointer) - // { - // indirection++; - // pointerType = (IPointerTypeSymbol)pointerType.PointedAtType; - // } - - // var partials = new List - // { - // GraphNodeId.GetPartial(CodeQualifiedName.Name, pointerType.PointedAtType.Name), - // GraphNodeId.GetPartial(CodeQualifiedName.Indirection, indirection.ToString()) - // }; - - // if (pointerType.PointedAtType.ContainingType != null) - // { - // partials.Add(await GetPartialForTypeAsync(pointerType.PointedAtType.ContainingType, CodeGraphNodeIdName.ParentType, solution, cancellationToken).ConfigureAwait(false)); - // } - - // return GraphNodeId.GetPartial(nodeName, MakeCollectionIfNecessary([.. partials])); - //} - - //private static async Task GetPartialForArrayTypeAsync(IArrayTypeSymbol arrayType, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken) - //{ - // var partials = new List(); - - // var underlyingType = ChaseToUnderlyingType(arrayType); - - // if (underlyingType.TypeKind == TypeKind.Dynamic) - // { - // partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.Name, "Object")); - // } - // else if (underlyingType.TypeKind != TypeKind.TypeParameter) - // { - // partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.Name, underlyingType.Name)); - // } - - // partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.ArrayRank, arrayType.Rank.ToString())); - // partials.Add(await GetPartialForTypeAsync(arrayType.ElementType, CodeGraphNodeIdName.ParentType, solution, cancellationToken).ConfigureAwait(false)); - - // return GraphNodeId.GetPartial(nodeName, MakeCollectionIfNecessary([.. partials])); - //} - - //private static async Task GetPartialForTypeParameterSymbolAsync(ITypeParameterSymbol typeParameterSymbol, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken) - //{ - // if (typeParameterSymbol.TypeParameterKind == TypeParameterKind.Method) - // { - // return GraphNodeId.GetPartial(nodeName, - // new GraphNodeIdCollection(false, - // GraphNodeId.GetPartial(CodeGraphNodeIdName.Parameter, typeParameterSymbol.Ordinal.ToString()))); - // } - // else - // { - // var nodes = await GetPartialsForNamespaceAndTypeAsync(typeParameterSymbol, false, solution, cancellationToken).ConfigureAwait(false); - // return GraphNodeId.GetPartial(nodeName, - // new GraphNodeIdCollection(false, [.. nodes])); - // } - //} - - //private static ITypeSymbol ChaseToUnderlyingType(ITypeSymbol symbol) - //{ - // while (symbol.TypeKind == TypeKind.Array) - // { - // symbol = ((IArrayTypeSymbol)symbol).ElementType; - // } - - // while (symbol.TypeKind == TypeKind.Pointer) - // { - // symbol = ((IPointerTypeSymbol)symbol).PointedAtType; - // } - - // return symbol; - //} - - //public static async Task GetIdForMemberAsync(ISymbol member, Solution solution, CancellationToken cancellationToken) - //{ - // var partials = new List(); - - // partials.AddRange(await GetPartialsForNamespaceAndTypeAsync(member.ContainingType, true, solution, cancellationToken).ConfigureAwait(false)); - - // var parameters = member.GetParameters(); - // if (parameters.Any() || member.GetArity() > 0) - // { - // var memberPartials = new List - // { - // GraphNodeId.GetPartial(CodeQualifiedName.Name, member.MetadataName) - // }; - - // if (member.GetArity() > 0) - // { - // memberPartials.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.GenericParameterCountIdentifier, member.GetArity().ToString())); - // } - - // if (parameters.Any()) - // { - // var parameterTypeIds = new List(); - // foreach (var p in parameters) - // { - // var parameterIds = await GetPartialsForNamespaceAndTypeAsync(p.Type, true, solution, cancellationToken).ConfigureAwait(false); - // var nodes = parameterIds.ToList(); - // if (p.IsRefOrOut()) - // { - // nodes.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.ParamKind, ParamKind.Ref)); - // } - - // parameterTypeIds.Add(GraphNodeId.GetNested([.. nodes])); - // } - - // if (member is IMethodSymbol methodSymbol && methodSymbol.MethodKind == MethodKind.Conversion) - // { - // // For explicit/implicit conversion operators, we need to include the return type in the method Id, - // // because there can be several conversion operators with same parameters and only differ by return type. - // // For example, - // // - // // public class Class1 - // // { - // // public static explicit (explicit) operator int(Class1 c) { ... } - // // public static explicit (explicit) operator double(Class1 c) { ... } - // // } - - // var nodes = await GetPartialsForNamespaceAndTypeAsync(methodSymbol.ReturnType, true, solution, cancellationToken).ConfigureAwait(false); - // var returnTypePartial = nodes.ToList(); - // returnTypePartial.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.ParamKind, Microsoft.VisualStudio.GraphModel.CodeSchema.ParamKind.Return)); - - // var returnCollection = GraphNodeId.GetNested([.. returnTypePartial]); - // parameterTypeIds.Add(returnCollection); - // } - - // memberPartials.Add(GraphNodeId.GetArray( - // CodeGraphNodeIdName.OverloadingParameters, - // [.. parameterTypeIds])); - // } - - // partials.Add(GraphNodeId.GetPartial( - // CodeGraphNodeIdName.Member, - // MakeCollectionIfNecessary([.. memberPartials]))); - // } - // else - // { - // partials.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.Member, member.MetadataName)); - // } - - // return GraphNodeId.GetNested([.. partials]); - //} - - //private static object MakeCollectionIfNecessary(GraphNodeId[] array) - //{ - // // Place the array of GraphNodeId's into the collection if necessary, so to make them appear in VS Properties Panel - // if (array.Length > 1) - // { - // return new GraphNodeIdCollection(false, array); - // } - - // return GraphNodeId.GetNested(array); - //} - - //private static IAssemblySymbol GetContainingAssembly(ISymbol symbol) - //{ - // if (symbol.ContainingAssembly != null) - // { - // return symbol.ContainingAssembly; - // } - - // if (symbol is not ITypeSymbol typeSymbol) - // { - // return null; - // } - - // var underlyingType = ChaseToUnderlyingType(typeSymbol); - // if (Equals(typeSymbol, underlyingType)) - // { - // // when symbol is for dynamic type - // return null; - // } - - // return GetContainingAssembly(underlyingType); - //} - - //private static async Task GetAssemblyFullPathAsync(ISymbol symbol, Solution solution, CancellationToken cancellationToken) - //{ - // var containingAssembly = GetContainingAssembly(symbol); - // return await GetAssemblyFullPathAsync(containingAssembly, solution, cancellationToken).ConfigureAwait(false); - //} - - //private static async Task GetAssemblyFullPathAsync(IAssemblySymbol containingAssembly, Solution solution, CancellationToken cancellationToken) - //{ - // if (containingAssembly == null) - // { - // return null; - // } - - // var foundProject = solution.GetProject(containingAssembly, cancellationToken); - // if (foundProject != null) - // { - // if (solution.Workspace is VisualStudioWorkspace) - // { - // // TODO: audit the OutputFilePath and whether this is bin or obj - // if (!string.IsNullOrWhiteSpace(foundProject.OutputFilePath)) - // { - // return new Uri(foundProject.OutputFilePath, UriKind.RelativeOrAbsolute); - // } - - // return null; - // } - // } - // else - // { - // // This symbol is not present in the source code, we need to resolve it from the references! - // // If a MetadataReference returned by Compilation.GetMetadataReference(AssemblySymbol) has a path, we could use it. - // foreach (var project in solution.Projects) - // { - // var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); - // if (compilation != null) - // { - // if (compilation.GetMetadataReference(containingAssembly) is PortableExecutableReference reference && !string.IsNullOrEmpty(reference.FilePath)) - // { - // return new Uri(reference.FilePath, UriKind.RelativeOrAbsolute); - // } - // } - // } - // } - - // // If we are not in VS, return project.OutputFilePath as a reasonable fallback. - // // For an example, it could be AdhocWorkspace for unit tests. - // if (foundProject != null && !string.IsNullOrEmpty(foundProject.OutputFilePath)) - // { - // return new Uri(foundProject.OutputFilePath, UriKind.Absolute); - // } - - // return null; - //} - - //internal static async Task GetIdForAssemblyAsync(IAssemblySymbol assemblySymbol, Solution solution, CancellationToken cancellationToken) - //{ - // var assembly = await GetAssemblyFullPathAsync(assemblySymbol, solution, cancellationToken).ConfigureAwait(false); - // if (assembly != null) - // { - // var builder = new CodeQualifiedIdentifierBuilder(); - // builder.Assembly = assembly; - // return builder.ToQualifiedIdentifier(); - // } - - // return null; - //} - - //internal static async Task GetIdForParameterAsync(IParameterSymbol symbol, Solution solution, CancellationToken cancellationToken) - //{ - // if (symbol.ContainingSymbol == null || - // (symbol.ContainingSymbol.Kind != SymbolKind.Method && symbol.ContainingSymbol.Kind != SymbolKind.Property)) - // { - // // We are only support parameters inside methods or properties. - // throw new ArgumentException("symbol"); - // } - - // var containingSymbol = symbol.ContainingSymbol; - // if (containingSymbol is IMethodSymbol method && method.AssociatedSymbol != null && method.AssociatedSymbol.Kind == SymbolKind.Property) - // { - // var property = (IPropertySymbol)method.AssociatedSymbol; - // if (property.Parameters.Any(static (p, symbol) => p.Name == symbol.Name, symbol)) - // { - // containingSymbol = property; - // } - // } - - // var memberId = await GetIdForMemberAsync(containingSymbol, solution, cancellationToken).ConfigureAwait(false); - // if (memberId != null) - // { - // return memberId + GraphNodeId.GetPartial(CodeGraphNodeIdName.Parameter, symbol.Name); - // } - - // return null; - //} - - //internal static async Task GetIdForLocalVariableAsync(ISymbol symbol, Solution solution, CancellationToken cancellationToken) - //{ - // if (symbol.ContainingSymbol == null || - // (symbol.ContainingSymbol.Kind != SymbolKind.Method && symbol.ContainingSymbol.Kind != SymbolKind.Property)) - // { - // // We are only support local variables inside methods or properties. - // throw new ArgumentException("symbol"); - // } - - // var memberId = await GetIdForMemberAsync(symbol.ContainingSymbol, solution, cancellationToken).ConfigureAwait(false); - // if (memberId != null) - // { - // var builder = new CodeQualifiedIdentifierBuilder(memberId); - // builder.LocalVariable = symbol.Name; - // builder.LocalVariableIndex = await GetLocalVariableIndexAsync(symbol, solution, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); - - // return builder.ToQualifiedIdentifier(); - // } - - // return null; - //} - - ///// - ///// Get the position of where a given local variable is defined considering there could be multiple variables with the same name in method body. - ///// For example, in "int M() { { int goo = 0; ...} { int goo = 1; ...} }", - ///// the return value for the first "goo" would be 0 while the value for the second one would be 1. - ///// It will be used to create a node with LocalVariableIndex for a non-zero value. - ///// In the above example, hence, a node id for the first "goo" would look like (... Member=M LocalVariable=bar) - ///// but an id for the second "goo" would be (... Member=M LocalVariable=bar LocalVariableIndex=1) - ///// - //private static async Task GetLocalVariableIndexAsync(ISymbol symbol, Solution solution, CancellationToken cancellationToken) - //{ - // var pos = 0; - - // foreach (var reference in symbol.ContainingSymbol.DeclaringSyntaxReferences) - // { - // var currentNode = await reference.GetSyntaxAsync(cancellationToken).ConfigureAwait(false); - - // // For VB, we have to ask its parent to get local variables within this method body - // // since DeclaringSyntaxReferences return statement rather than enclosing block. - // if (currentNode != null && symbol.Language == LanguageNames.VisualBasic) - // { - // currentNode = currentNode.Parent; - // } - - // if (currentNode != null) - // { - // var document = solution.GetDocument(currentNode.SyntaxTree); - // if (document == null) - // { - // continue; - // } - - // var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); - // foreach (var node in currentNode.DescendantNodes()) - // { - // var current = semanticModel.GetDeclaredSymbol(node, cancellationToken); - // if (current is { Kind: SymbolKind.Local or SymbolKind.RangeVariable } && current.Name == symbol.Name) - // { - // if (!current.Equals(symbol)) - // { - // pos++; - // } - // else - // { - // return pos; - // } - // } - // } - // } - // } - - // throw ExceptionUtilities.Unreachable(); - //} } diff --git a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs index d87f28129f0b9..3c65da844d31f 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs @@ -6,9 +6,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel.Composition; -using System.Linq; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Host.Mef; @@ -21,7 +19,6 @@ using Microsoft.VisualStudio.Language.Intellisense; using Microsoft.VisualStudio.Progression; using Microsoft.VisualStudio.Shell; -using Roslyn.Utilities; namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; @@ -317,46 +314,6 @@ public IEnumerable GetCommands(IEnumerable nodes) //} } - //private static bool IsOverridable(GraphNode node) - //{ - // var modifiers = GetModifiers(node); - // return (modifiers.IsVirtual || modifiers.IsAbstract || modifiers.IsOverride) && - // !modifiers.IsSealed; - //} - - //private static DeclarationModifiers GetModifiers(GraphNode node) - // => (DeclarationModifiers)node[RoslynGraphProperties.SymbolModifiers]; - - //private static bool CheckAccessibility(GraphNode node, Accessibility accessibility) - // => node[RoslynGraphProperties.DeclaredAccessibility].Equals(accessibility); - - //private static bool HasExplicitInterfaces(GraphNode node) - // => ((IList)node[RoslynGraphProperties.ExplicitInterfaceImplementations]).Count > 0; - - //private static bool IsRoslynNode(GraphNode node) - //{ - // return node[RoslynGraphProperties.SymbolKind] != null - // && node[RoslynGraphProperties.TypeKind] != null; - //} - - //private static bool IsAnySymbolKind(GraphNode node, params SymbolKind[] symbolKinds) - // => symbolKinds.Any(k => k.Equals(node[RoslynGraphProperties.SymbolKind])); - - //private static bool IsAnyTypeKind(GraphNode node, params TypeKind[] typeKinds) - // => typeKinds.Any(k => node[RoslynGraphProperties.TypeKind].Equals(k)); - - //private static readonly GraphCommandDefinition s_overridesCommandDefinition = - // new("Overrides", EditorFeaturesResources.Overrides_, GraphContextDirection.Target, 700); - - //private static readonly GraphCommandDefinition s_overriddenByCommandDefinition = - // new("OverriddenBy", EditorFeaturesResources.Overridden_By, GraphContextDirection.Source, 700); - - //private static readonly GraphCommandDefinition s_implementsCommandDefinition = - // new("Implements", EditorFeaturesResources.Implements_, GraphContextDirection.Target, 600); - - //private static readonly GraphCommandDefinition s_implementedByCommandDefinition = - // new("ImplementedBy", EditorFeaturesResources.Implemented_By, GraphContextDirection.Source, 600); - public T? GetExtension(GraphObject graphObject, T previous) where T : class { if (graphObject is GraphNode graphNode) diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueryManager.cs b/src/VisualStudio/Core/Def/Progression/GraphQueryManager.cs index e1ac7aee5dc91..9da3eb327c5fb 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphQueryManager.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphQueryManager.cs @@ -8,10 +8,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.ErrorReporting; -using Microsoft.CodeAnalysis.Shared.TestHooks; -using Microsoft.CodeAnalysis.Threading; using Microsoft.VisualStudio.GraphModel; using Roslyn.Utilities; @@ -29,28 +26,10 @@ internal sealed class GraphQueryManager private readonly object _gate = new(); private ImmutableArray<(WeakReference context, ImmutableArray queries)> _trackedQueries = []; - // private readonly AsyncBatchingWorkQueue _updateQueue; - internal GraphQueryManager( - Workspace workspace, - IThreadingContext threadingContext, - IAsynchronousOperationListener asyncListener) + Workspace workspace) { _workspace = workspace; - - //// Update any existing live/tracking queries 1.5 seconds after every workspace changes. - //_updateQueue = new AsyncBatchingWorkQueue( - // DelayTimeSpan.Idle, - // UpdateExistingQueriesAsync, - // asyncListener, - // threadingContext.DisposalToken); - - // Note: this ends up always listening for workspace events, even if we have no active 'live' queries that - // need updating. But this should basically be practically no cost. The queue just holds a single item - // indicating a change happened. And when UpdateExistingQueriesAsync fires, it will just see that there are - // no live queries and immediately return. So it's just simple to do things this way instead of trying to - // have state management where we try to decide if we should listen or not. - //_ = _workspace.RegisterWorkspaceChangedHandler((_) => _updateQueue.AddWork()); } public async Task AddQueriesAsync(IGraphContext context, ImmutableArray graphQueries, CancellationToken disposalToken) @@ -79,32 +58,6 @@ public async Task AddQueriesAsync(IGraphContext context, ImmutableArray queries)> liveQueries; - // lock (_gate) - // { - // // First, grab the set of contexts that are still live. We'll update them below. - // liveQueries = _trackedQueries - // .SelectAsArray(t => (context: t.context.GetTarget(), t.queries)) - // .WhereAsArray(t => t.context != null)!; - - // // Next, clear out any context that are now no longer alive (or have been canceled). We no longer care - // // about these. - // _trackedQueries = _trackedQueries.RemoveAll(t => - // { - // var target = t.context.GetTarget(); - // return target is null || target.CancelToken.IsCancellationRequested; - // }); - // } - - // var solution = _workspace.CurrentSolution; - - // // Update all the live queries in parallel. - // var tasks = liveQueries.Select(t => PopulateContextGraphAsync(solution, t.context, t.queries, disposalToken)).ToArray(); - // await Task.WhenAll(tasks).ConfigureAwait(false); - //} - /// /// Populate the graph of the context with the values for the given Solution. /// diff --git a/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs b/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs index 9e5b8a19625da..0f1b0e92bdfbd 100644 --- a/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs +++ b/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs @@ -2,9 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Collections.Generic; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Editing; using Microsoft.VisualStudio.GraphModel; namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; @@ -13,11 +11,6 @@ internal static class RoslynGraphProperties { public static readonly GraphSchema Schema; - ///// - ///// A graph property that holds the SymbolId of the symbol. - ///// - //public static readonly GraphProperty SymbolId; - /// /// A graph property that holds the ProjectId where you can find the symbol. Note this is /// not strictly the project that defines the symbol in the case the symbol is from metadata. @@ -25,45 +18,6 @@ internal static class RoslynGraphProperties /// public static readonly GraphProperty ContextProjectId; - ///// - ///// A graph property that holds the DocumentId where you can find the symbol. This is used - ///// to distinguish between multiple locations for partial types. This will only exist - ///// for symbols in source that have partial implementations. - ///// - //public static readonly GraphProperty ContextDocumentId; - - /// - /// A graph property to hold the label we have generated for the node. - /// - // public static readonly GraphProperty Label; - - ///// - ///// A graph property to hold the formatted label we have generated for the node. - ///// - //public static readonly GraphProperty FormattedLabelWithoutContainingSymbol; - - ///// - ///// A graph property to hold the formatted label that has the containing symbol name. - ///// - //public static readonly GraphProperty FormattedLabelWithContainingSymbol; - - ///// - ///// A graph property to hold the description we have generated for the node. - ///// - //public static readonly GraphProperty Description; - - ///// - ///// A graph property to hold the description that has the containing symbol name. - ///// - //public static readonly GraphProperty DescriptionWithContainingSymbol; - - //public static readonly GraphProperty SymbolKind; - //public static readonly GraphProperty TypeKind; - //public static readonly GraphProperty MethodKind; - //public static readonly GraphProperty DeclaredAccessibility; - //public static readonly GraphProperty SymbolModifiers; - //public static readonly GraphProperty ExplicitInterfaceImplementations; - static RoslynGraphProperties() { Schema = new GraphSchema("Roslyn"); From 0631e7c862bd7368c312f21f7e55bd8e0ef1bb6f Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 09:01:15 +0200 Subject: [PATCH 074/353] REmove code --- src/VisualStudio/Core/Def/Progression/GraphProvider.cs | 8 ++++---- .../Core/Def/Progression/GraphQueries/SearchGraphQuery.cs | 2 +- .../SymbolTree/SymbolTreeChildCollection.cs | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs index 3c65da844d31f..6efa77eaae90f 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs @@ -51,7 +51,7 @@ public RoslynGraphProvider( _asyncListener = listenerProvider.GetListener(FeatureAttribute.GraphProvider); _workspace = workspace; _streamingPresenter = streamingPresenter; - _graphQueryManager = new GraphQueryManager(workspace, threadingContext, _asyncListener); + _graphQueryManager = new GraphQueryManager(workspace); } private void EnsureInitialized() @@ -147,8 +147,8 @@ public static ImmutableArray GetGraphQueries(IGraphContext context) // Create two queries. One to find results in normal docs, and one to find results in generated // docs. That way if the generated docs take a long time we can still report the regular doc // results immediately. - graphQueries.Add(new SearchGraphQuery(searchParameters.SearchQuery.SearchString, NavigateToDocumentSupport.RegularDocuments)); - graphQueries.Add(new SearchGraphQuery(searchParameters.SearchQuery.SearchString, NavigateToDocumentSupport.GeneratedDocuments)); + //graphQueries.Add(new SearchGraphQuery(searchParameters.SearchQuery.SearchString, NavigateToDocumentSupport.RegularDocuments)); + //graphQueries.Add(new SearchGraphQuery(searchParameters.SearchQuery.SearchString, NavigateToDocumentSupport.GeneratedDocuments)); } } @@ -330,7 +330,7 @@ public IEnumerable GetCommands(IEnumerable nodes) } if (typeof(T) == typeof(IGraphNavigateToItem)) - return new GraphNavigatorExtension(_threadingContext, _workspace, _streamingPresenter) as T; + return new GraphNavigatorExtension(_threadingContext, _workspace) as T; //if (typeof(T) == typeof(IGraphFormattedLabel)) // return new GraphFormattedLabelExtension() as T; diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/SearchGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/SearchGraphQuery.cs index f9d40e4b7498f..ef8969a0bb3fe 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/SearchGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphQueries/SearchGraphQuery.cs @@ -21,7 +21,7 @@ public async Task GetGraphAsync(Solution solution, IGraphContext c { using var _ = Logger.LogBlock(FunctionId.GraphQuery_Search, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); - var graphBuilder = new GraphBuilder(solution); // await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); + var graphBuilder = new GraphBuilder(); // await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); var callback = new ProgressionNavigateToSearchCallback(solution, context, graphBuilder); // We have a specialized host for progression vs normal nav-to. Progression itself will tell the client if diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs index 361053754c61f..399b829e1032f 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs @@ -103,7 +103,6 @@ public void SetItemsAndMarkComputed_OnMainThread( } else { - ISearchProvider // If we didn't find an existing item, create a new one. _symbolTreeItems.Add(new(_rootProvider, documentId, itemProvider, itemData.ItemKey) { From d4f852f2e623156060f9c7aa09777ad7a34ed923 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 09:04:28 +0200 Subject: [PATCH 075/353] REmove code --- src/VisualStudio/Core/Def/Progression/GraphProvider.cs | 3 --- .../Core/Test/Progression/ProgressionTestHelpers.vb | 5 ----- .../Core/Test/Progression/ProgressionTestState.vb | 2 +- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs index 6efa77eaae90f..972b3acd562cc 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs @@ -30,7 +30,6 @@ internal sealed class RoslynGraphProvider : IGraphProvider private readonly IServiceProvider _serviceProvider; private readonly IAsynchronousOperationListener _asyncListener; private readonly Workspace _workspace; - private readonly Lazy _streamingPresenter; private readonly GraphQueryManager _graphQueryManager; private bool _initialized = false; @@ -42,7 +41,6 @@ public RoslynGraphProvider( IGlyphService glyphService, SVsServiceProvider serviceProvider, VisualStudioWorkspace workspace, - Lazy streamingPresenter, IAsynchronousOperationListenerProvider listenerProvider) { _threadingContext = threadingContext; @@ -50,7 +48,6 @@ public RoslynGraphProvider( _serviceProvider = serviceProvider; _asyncListener = listenerProvider.GetListener(FeatureAttribute.GraphProvider); _workspace = workspace; - _streamingPresenter = streamingPresenter; _graphQueryManager = new GraphQueryManager(workspace); } diff --git a/src/VisualStudio/Core/Test/Progression/ProgressionTestHelpers.vb b/src/VisualStudio/Core/Test/Progression/ProgressionTestHelpers.vb index 63a1bccc7a9be..12947eb06eacc 100644 --- a/src/VisualStudio/Core/Test/Progression/ProgressionTestHelpers.vb +++ b/src/VisualStudio/Core/Test/Progression/ProgressionTestHelpers.vb @@ -3,12 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports System.Runtime.CompilerServices -Imports Microsoft.CodeAnalysis.Editor.UnitTests -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.Composition Imports Microsoft.VisualStudio.GraphModel -Imports Microsoft.VisualStudio.LanguageServices.CSharp.Progression -Imports Microsoft.VisualStudio.LanguageServices.VisualBasic.Progression Imports Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression diff --git a/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb b/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb index 3c0f2280eede6..83f6e7d46cde8 100644 --- a/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb +++ b/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb @@ -26,7 +26,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression End Function Public Function GetGraphWithDocumentNode(filePath As String) As Graph - Dim graphBuilder As New GraphBuilder(Workspace.CurrentSolution) + Dim graphBuilder As New GraphBuilder() Dim documentId = Workspace.Documents.Single(Function(d) d.FilePath = filePath).Id Assert.NotNull(graphBuilder.TryAddNodeForDocument(Workspace.CurrentSolution.GetDocument(documentId), CancellationToken.None)) Return graphBuilder.Graph From c0deb7ebd39193251729824cb0d560f83bf54ef5 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 10:13:59 +0200 Subject: [PATCH 076/353] In progress --- .../RoslynSolutionExplorerSearchProvider.cs | 26 +++++++++++++++++++ .../RootSymbolTreeItemSourceProvider.cs | 1 - 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs new file mode 100644 index 0000000000000..8065f5d91a65b --- /dev/null +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Internal.VisualStudio.PlatformUI; +using Microsoft.VisualStudio.Utilities; + +namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; + +[AppliesToProject("CSharp | VB")] +[Export(typeof(ISearchProvider))] +[Name("DependenciesTreeSearchProvider")] +[VisualStudio.Utilities.Order(Before = "GraphSearchProvider")] +internal sealed class RoslynSolutionExplorerSearchProvider : ISearchProvider +{ + public void Search(IRelationshipSearchParameters parameters, Action resultAccumulator) + { + throw new NotImplementedException(); + } +} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index a1a9d004d9f6b..fd1db5aab16bb 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -8,7 +8,6 @@ using System.Collections.Immutable; using System.ComponentModel; using System.ComponentModel.Composition; -using System.Diagnostics.CodeAnalysis; using System.IO; using System.Threading; using System.Threading.Tasks; From 4aa7b796c9001454f440904ea514d0e0626a9ae9 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 11:28:31 +0200 Subject: [PATCH 077/353] Initial search support --- Roslyn.sln | 7 +- .../RoslynSolutionExplorerSearchProvider.cs | 145 +++++++++++++++++- .../RootSymbolTreeItemSourceProvider.cs | 22 +-- .../SymbolTree/SymbolTreeItem.cs | 2 +- .../SymbolTreeNavigationUtilities.cs | 40 +++++ 5 files changed, 192 insertions(+), 24 deletions(-) create mode 100644 src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeNavigationUtilities.cs diff --git a/Roslyn.sln b/Roslyn.sln index 6fca77405900e..980009f1a1d57 100644 --- a/Roslyn.sln +++ b/Roslyn.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31319.15 +# Visual Studio Version 18 +VisualStudioVersion = 18.0.10623.112 main MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RoslynDeployment", "src\Deployment\RoslynDeployment.csproj", "{600AF682-E097-407B-AD85-EE3CED37E680}" EndProject @@ -2207,8 +2207,11 @@ Global src\Workspaces\SharedUtilitiesAndExtensions\Workspace\VisualBasic\VisualBasicWorkspaceExtensions.projitems*{57ca988d-f010-4bf2-9a2e-07d6dcd2ff2c}*SharedItemsImports = 5 src\Analyzers\CSharp\Tests\CSharpAnalyzers.UnitTests.projitems*{58969243-7f59-4236-93d0-c93b81f569b3}*SharedItemsImports = 13 src\Dependencies\Collections\Microsoft.CodeAnalysis.Collections.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 + src\Dependencies\Contracts\Microsoft.CodeAnalysis.Contracts.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 src\Dependencies\PooledObjects\Microsoft.CodeAnalysis.PooledObjects.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 + src\Dependencies\Threading\Microsoft.CodeAnalysis.Threading.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 src\Workspaces\SharedUtilitiesAndExtensions\Compiler\Core\CompilerExtensions.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 + src\Workspaces\SharedUtilitiesAndExtensions\Compiler\Extensions\Microsoft.CodeAnalysis.Extensions.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 src\Workspaces\SharedUtilitiesAndExtensions\Workspace\Core\WorkspaceExtensions.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 src\Analyzers\Core\CodeFixes\CodeFixes.projitems*{5ff1e493-69cc-4d0b-83f2-039f469a04e1}*SharedItemsImports = 5 src\Workspaces\SharedUtilitiesAndExtensions\Workspace\Core\WorkspaceExtensions.projitems*{5ff1e493-69cc-4d0b-83f2-039f469a04e1}*SharedItemsImports = 5 diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs index 8065f5d91a65b..29193c47e22f3 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs @@ -7,9 +7,23 @@ using System.ComponentModel.Composition; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; +using EnvDTE; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.NavigateTo; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.Internal.VisualStudio.PlatformUI; +using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Utilities; +using Microsoft.CodeAnalysis.ErrorReporting; +using System.Collections.Immutable; +using Microsoft.VisualStudio.Imaging.Interop; +using Microsoft.CodeAnalysis.Editor.Wpf; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -19,8 +33,137 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore [VisualStudio.Utilities.Order(Before = "GraphSearchProvider")] internal sealed class RoslynSolutionExplorerSearchProvider : ISearchProvider { + private readonly VisualStudioWorkspace _workspace; + private readonly IVsHierarchyItemManager _hierarchyItemManager; + private readonly IAsynchronousOperationListener _listener; + private readonly SymbolTreeNavigationSupport _navigationSupport; + + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public RoslynSolutionExplorerSearchProvider( + VisualStudioWorkspace workspace, + IVsHierarchyItemManager hierarchyItemManager, + IAsynchronousOperationListenerProvider listenerProvider, + IThreadingContext threadingContext) + { + _workspace = workspace; + _hierarchyItemManager = hierarchyItemManager; + _listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); + _navigationSupport = new(workspace, threadingContext, _listener); + } + public void Search(IRelationshipSearchParameters parameters, Action resultAccumulator) { - throw new NotImplementedException(); + var cancellationToken = parameters.CancellationToken; + + var solution = _workspace.CurrentSolution; + var searcher = NavigateToSearcher.Create( + solution, + new SolutionExplorerNavigateToSearchCallback(this, resultAccumulator), + parameters.SearchQuery.SearchString.Trim(), + NavigateToUtilities.GetKindsProvided(solution), + new SolutionExplorerNavigateToSearcherHost(_workspace)); + + var token = _listener.BeginAsyncOperation(nameof(Search)); + searcher + .SearchAsync(NavigateToSearchScope.Solution, cancellationToken) + .ReportNonFatalErrorUnlessCancelledAsync(cancellationToken) + .CompletesAsyncOperation(token); + } + + private sealed class SolutionExplorerNavigateToSearchCallback( + RoslynSolutionExplorerSearchProvider provider, + Action resultAccumulator) : INavigateToSearchCallback + { + public void Done(bool isFullyLoaded) { } + public void ReportIncomplete() { } + public void ReportProgress(int current, int maximum) { } + + public Task AddResultsAsync( + ImmutableArray results, + CancellationToken cancellationToken) + { + foreach (var result in results) + resultAccumulator(new SolutionExplorerSearchResult(provider, result)); + + return Task.CompletedTask; + } + } + + private sealed class SolutionExplorerSearchResult( + RoslynSolutionExplorerSearchProvider provider, + INavigateToSearchResult result) : ISearchResult + { + public object GetDisplayItem() + { + var name = result.NavigableItem.DisplayTaggedParts.JoinText(); + return new SolutionExplorerSearchDisplayItem( + provider, name, result); + } + } + + private sealed class SolutionExplorerSearchDisplayItem( + RoslynSolutionExplorerSearchProvider provider, + string name, + INavigateToSearchResult result) + : BaseItem, + IInvocationController + { + private readonly INavigateToSearchResult _result = result; + + public override string Name { get; } = name; + public override ImageMoniker IconMoniker => _result.NavigableItem.Glyph.GetImageMoniker(); + + public override IInvocationController? InvocationController => this; + + public bool Invoke(IEnumerable items, InputSource inputSource, bool preview) + { + if (items.FirstOrDefault() is not SolutionExplorerSearchDisplayItem displayItem) + return false; + + provider._navigationSupport.NavigateTo( + displayItem._result.NavigableItem.Document.Id, + displayItem._result.NavigableItem.SourceSpan.Start, + preview: true); + return true; + } + } + + private sealed class SolutionExplorerNavigateToSearcherHost(Workspace workspace) : INavigateToSearcherHost + { + public INavigateToSearchService? GetNavigateToSearchService(Microsoft.CodeAnalysis.Project project) + => project.GetLanguageService(); + + public async ValueTask IsFullyLoadedAsync(CancellationToken cancellationToken) + { + var statusService = workspace.Services.GetRequiredService(); + var isFullyLoaded = await statusService.IsFullyLoadedAsync(cancellationToken).ConfigureAwait(false); + return isFullyLoaded; + } + } + +#if false + var callback = new ProgressionNavigateToSearchCallback(solution, context, graphBuilder); + + // We have a specialized host for progression vs normal nav-to. Progression itself will tell the client if + // the project is fully loaded or not. But after that point, the client will be considered fully loaded and + // results should reflect that. So we create a host here that will always give complete results once the + // solution is loaded and not give cached/incomplete results at that point. + var statusService = solution.Services.GetRequiredService(); + var isFullyLoaded = await statusService.IsFullyLoadedAsync(cancellationToken).ConfigureAwait(false); + var host = new SearchGraphQueryNavigateToSearchHost(isFullyLoaded); + + var searcher = NavigateToSearcher.Create( + solution, + callback, + searchPattern, + NavigateToUtilities.GetKindsProvided(solution), + host); + + await searcher.SearchAsync(NavigateToSearchScope.Solution, searchScope, cancellationToken).ConfigureAwait(false); + + return graphBuilder; } + +#endif } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index fd1db5aab16bb..58fcdcd303b6f 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -38,7 +38,7 @@ internal sealed partial class RootSymbolTreeItemSourceProvider : AttachedCollect private readonly AsyncBatchingWorkQueue _updateSourcesQueue; private readonly Workspace _workspace; - private readonly CancellationSeries _navigationCancellationSeries = new(); + public readonly SymbolTreeNavigationSupport NavigationSupport; public readonly IThreadingContext ThreadingContext; public readonly IAsynchronousOperationListener Listener; @@ -53,6 +53,7 @@ public RootSymbolTreeItemSourceProvider( ThreadingContext = threadingContext; _workspace = workspace; Listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); + NavigationSupport = new(workspace, threadingContext, Listener); _updateSourcesQueue = new AsyncBatchingWorkQueue( DelayTimeSpan.Medium, @@ -70,25 +71,6 @@ public RootSymbolTreeItemSourceProvider( options: new WorkspaceEventOptions(RequiresMainThread: false)); } - public void NavigateTo(DocumentId documentId, int position, bool preview) - { - // Cancel any in flight navigation and kick off a new one. - var cancellationToken = _navigationCancellationSeries.CreateNext(this.ThreadingContext.DisposalToken); - var navigationService = _workspace.Services.GetRequiredService(); - - var token = Listener.BeginAsyncOperation(nameof(NavigateTo)); - navigationService.TryNavigateToPositionAsync( - ThreadingContext, - _workspace, - documentId, - position, - virtualSpace: 0, - // May be calling this on stale data. Allow the position to be invalid - allowInvalidPosition: true, - new NavigationOptions(PreferProvisionalTab: preview), - cancellationToken).ReportNonFatalErrorUnlessCancelledAsync(cancellationToken).CompletesAsyncOperation(token); - } - private async ValueTask UpdateCollectionSourcesAsync( ImmutableSegmentedList documentIds, CancellationToken cancellationToken) { diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index 881a5d090d17d..8f1c1c1416b26 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -102,7 +102,7 @@ public bool Invoke(IEnumerable items, InputSource inputSource, bool prev if (items.FirstOrDefault() is not SymbolTreeItem item) return false; - RootProvider.NavigateTo(item.DocumentId, item.ItemSyntax.NavigationToken.SpanStart, preview); + RootProvider.NavigationSupport.NavigateTo(item.DocumentId, item.ItemSyntax.NavigationToken.SpanStart, preview); return true; } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeNavigationUtilities.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeNavigationUtilities.cs new file mode 100644 index 0000000000000..add72c0e9f514 --- /dev/null +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeNavigationUtilities.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.ErrorReporting; +using Microsoft.CodeAnalysis.Navigation; +using Microsoft.CodeAnalysis.Shared.TestHooks; +using Microsoft.CodeAnalysis.Threading; + +namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; + +internal sealed class SymbolTreeNavigationSupport( + Workspace workspace, + IThreadingContext threadingContext, + IAsynchronousOperationListener listener) +{ + private readonly CancellationSeries _cancellationSeries = new(threadingContext.DisposalToken); + + public void NavigateTo( + DocumentId documentId, int position, bool preview) + { + // Cancel any in flight navigation and kick off a new one. + var cancellationToken = _cancellationSeries.CreateNext(); + var navigationService = workspace.Services.GetRequiredService(); + + var token = listener.BeginAsyncOperation(nameof(NavigateTo)); + navigationService.TryNavigateToPositionAsync( + threadingContext, + workspace, + documentId, + position, + virtualSpace: 0, + // May be calling this on stale data. Allow the position to be invalid + allowInvalidPosition: true, + new NavigationOptions(PreferProvisionalTab: preview), + cancellationToken).ReportNonFatalErrorUnlessCancelledAsync(cancellationToken).CompletesAsyncOperation(token); + } +} From 2fae084b306dfc375c86f25bdd8ef0e684156521 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 11:44:32 +0200 Subject: [PATCH 078/353] Cleanup --- .../RoslynSolutionExplorerSearchProvider.cs | 82 +++---------------- .../SolutionExplorerSearchDisplayItem.cs | 40 +++++++++ ...ExplorerSearchDisplayItemSourceProvider.cs | 59 +++++++++++++ ...s => SolutionExplorerNavigationSupport.cs} | 2 +- 4 files changed, 113 insertions(+), 70 deletions(-) create mode 100644 src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItem.cs create mode 100644 src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItemSourceProvider.cs rename src/VisualStudio/Core/Impl/SolutionExplorer/{SymbolTree/SymbolTreeNavigationUtilities.cs => SolutionExplorerNavigationSupport.cs} (96%) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs index 29193c47e22f3..15697ec01fb14 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs @@ -3,57 +3,53 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; +using System.Collections.Immutable; using System.ComponentModel.Composition; -using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; -using EnvDTE; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.NavigateTo; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.Internal.VisualStudio.PlatformUI; -using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Utilities; -using Microsoft.CodeAnalysis.ErrorReporting; -using System.Collections.Immutable; -using Microsoft.VisualStudio.Imaging.Interop; -using Microsoft.CodeAnalysis.Editor.Wpf; -using Microsoft.CodeAnalysis.Editor.Shared.Utilities; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; +/// +/// Entrypoint that exposes roslyn search capabilities from solution explorer. +/// [AppliesToProject("CSharp | VB")] [Export(typeof(ISearchProvider))] -[Name("DependenciesTreeSearchProvider")] -[VisualStudio.Utilities.Order(Before = "GraphSearchProvider")] +[Name(nameof(RoslynSolutionExplorerSearchProvider))] +[Order(Before = "GraphSearchProvider")] internal sealed class RoslynSolutionExplorerSearchProvider : ISearchProvider { private readonly VisualStudioWorkspace _workspace; - private readonly IVsHierarchyItemManager _hierarchyItemManager; private readonly IAsynchronousOperationListener _listener; - private readonly SymbolTreeNavigationSupport _navigationSupport; + public readonly SymbolTreeNavigationSupport NavigationSupport; [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] public RoslynSolutionExplorerSearchProvider( VisualStudioWorkspace workspace, - IVsHierarchyItemManager hierarchyItemManager, IAsynchronousOperationListenerProvider listenerProvider, IThreadingContext threadingContext) { _workspace = workspace; - _hierarchyItemManager = hierarchyItemManager; _listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); - _navigationSupport = new(workspace, threadingContext, _listener); + NavigationSupport = new(workspace, threadingContext, _listener); } public void Search(IRelationshipSearchParameters parameters, Action resultAccumulator) { + if (!parameters.Options.SearchFileContents) + return; + var cancellationToken = parameters.CancellationToken; var solution = _workspace.CurrentSolution; @@ -102,33 +98,6 @@ public object GetDisplayItem() } } - private sealed class SolutionExplorerSearchDisplayItem( - RoslynSolutionExplorerSearchProvider provider, - string name, - INavigateToSearchResult result) - : BaseItem, - IInvocationController - { - private readonly INavigateToSearchResult _result = result; - - public override string Name { get; } = name; - public override ImageMoniker IconMoniker => _result.NavigableItem.Glyph.GetImageMoniker(); - - public override IInvocationController? InvocationController => this; - - public bool Invoke(IEnumerable items, InputSource inputSource, bool preview) - { - if (items.FirstOrDefault() is not SolutionExplorerSearchDisplayItem displayItem) - return false; - - provider._navigationSupport.NavigateTo( - displayItem._result.NavigableItem.Document.Id, - displayItem._result.NavigableItem.SourceSpan.Start, - preview: true); - return true; - } - } - private sealed class SolutionExplorerNavigateToSearcherHost(Workspace workspace) : INavigateToSearcherHost { public INavigateToSearchService? GetNavigateToSearchService(Microsoft.CodeAnalysis.Project project) @@ -141,29 +110,4 @@ public async ValueTask IsFullyLoadedAsync(CancellationToken cancellationTo return isFullyLoaded; } } - -#if false - var callback = new ProgressionNavigateToSearchCallback(solution, context, graphBuilder); - - // We have a specialized host for progression vs normal nav-to. Progression itself will tell the client if - // the project is fully loaded or not. But after that point, the client will be considered fully loaded and - // results should reflect that. So we create a host here that will always give complete results once the - // solution is loaded and not give cached/incomplete results at that point. - var statusService = solution.Services.GetRequiredService(); - var isFullyLoaded = await statusService.IsFullyLoadedAsync(cancellationToken).ConfigureAwait(false); - var host = new SearchGraphQueryNavigateToSearchHost(isFullyLoaded); - - var searcher = NavigateToSearcher.Create( - solution, - callback, - searchPattern, - NavigateToUtilities.GetKindsProvided(solution), - host); - - await searcher.SearchAsync(NavigateToSearchScope.Solution, searchScope, cancellationToken).ConfigureAwait(false); - - return graphBuilder; - } - -#endif } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItem.cs new file mode 100644 index 0000000000000..64edd21741d93 --- /dev/null +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItem.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.NavigateTo; +using Microsoft.Internal.VisualStudio.PlatformUI; +using Microsoft.VisualStudio.Imaging.Interop; +using Microsoft.CodeAnalysis.Editor.Wpf; + +namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; + +internal sealed class SolutionExplorerSearchDisplayItem( + RoslynSolutionExplorerSearchProvider provider, + string name, + INavigateToSearchResult result) + : BaseItem, + IInvocationController +{ + public readonly INavigateToSearchResult Result = result; + + public override string Name { get; } = name; + public override ImageMoniker IconMoniker => Result.NavigableItem.Glyph.GetImageMoniker(); + + public override IInvocationController? InvocationController => this; + + public bool Invoke(IEnumerable items, InputSource inputSource, bool preview) + { + if (items.FirstOrDefault() is not SolutionExplorerSearchDisplayItem displayItem) + return false; + + provider.NavigationSupport.NavigateTo( + displayItem.Result.NavigableItem.Document.Id, + displayItem.Result.NavigableItem.SourceSpan.Start, + preview: true); + return true; + } +} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItemSourceProvider.cs new file mode 100644 index 0000000000000..c5a19afc307da --- /dev/null +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItemSourceProvider.cs @@ -0,0 +1,59 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections; +using System.Collections.Immutable; +using System.ComponentModel.Composition; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.Internal.VisualStudio.PlatformUI; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Utilities; + +namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; + +/// +/// Responsible for taking search result items and parenting them with their corresponding real document +/// (i.e. an IVhHierarchy + itemid) in the solution explorer window. In other words, this source provider +/// providers the "contained by" relation, mapping to +/// . +/// +[Export(typeof(IAttachedCollectionSourceProvider))] +[Name(nameof(RootSymbolTreeItemSourceProvider))] +[Order(Before = HierarchyItemsProviderNames.ContainedBy)] +[AppliesToProject("CSharp | VB")] +[method: ImportingConstructor] +[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] +internal sealed partial class SolutionExplorerSearchDisplayItemSourceProvider( + VisualStudioWorkspace workspace, + IVsHierarchyItemManager hierarchyItemManager) + : AttachedCollectionSourceProvider +{ + protected override IAttachedCollectionSource? CreateCollectionSource( + SolutionExplorerSearchDisplayItem item, string relationshipName) + { + if (relationshipName != KnownRelationships.ContainedBy) + return null; + + var document = workspace.CurrentSolution.GetDocument(item.Result.NavigableItem.Document.Id); + if (document is null) + return null; + + if (!VisualStudioWorkspaceUtilities.TryGetVsHierarchyItem( + hierarchyItemManager, document, out var hierarchyItem)) + { + return null; + } + + return new SolutionExplorerSearchDisplayItemCollectionSource(item, hierarchyItem); + } + + private sealed class SolutionExplorerSearchDisplayItemCollectionSource( + SolutionExplorerSearchDisplayItem item, IVsHierarchyItem hierarchyItem) : IAttachedCollectionSource + { + public object SourceItem => item; + public bool HasItems => true; + public IEnumerable Items => ImmutableArray.Create(hierarchyItem); + } +} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeNavigationUtilities.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SolutionExplorerNavigationSupport.cs similarity index 96% rename from src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeNavigationUtilities.cs rename to src/VisualStudio/Core/Impl/SolutionExplorer/SolutionExplorerNavigationSupport.cs index add72c0e9f514..c65f30c18afb5 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeNavigationUtilities.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SolutionExplorerNavigationSupport.cs @@ -11,7 +11,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; -internal sealed class SymbolTreeNavigationSupport( +internal sealed class SolutionExplorerNavigationSupport( Workspace workspace, IThreadingContext threadingContext, IAsynchronousOperationListener listener) From 43ca6e743cbd5164b05d2fadb82862ebc3a1ba9c Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 11:46:35 +0200 Subject: [PATCH 079/353] rename type --- .../Search/RoslynSolutionExplorerSearchProvider.cs | 2 +- .../SymbolTree/RootSymbolTreeItemSourceProvider.cs | 2 +- .../SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs index 15697ec01fb14..2745e8054a7b7 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs @@ -31,7 +31,7 @@ internal sealed class RoslynSolutionExplorerSearchProvider : ISearchProvider { private readonly VisualStudioWorkspace _workspace; private readonly IAsynchronousOperationListener _listener; - public readonly SymbolTreeNavigationSupport NavigationSupport; + public readonly SolutionExplorerNavigationSupport NavigationSupport; [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index 58fcdcd303b6f..846e0223701ce 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -38,7 +38,7 @@ internal sealed partial class RootSymbolTreeItemSourceProvider : AttachedCollect private readonly AsyncBatchingWorkQueue _updateSourcesQueue; private readonly Workspace _workspace; - public readonly SymbolTreeNavigationSupport NavigationSupport; + public readonly SolutionExplorerNavigationSupport NavigationSupport; public readonly IThreadingContext ThreadingContext; public readonly IAsynchronousOperationListener Listener; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs index 399b829e1032f..7bdb78ab1a7f1 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeChildCollection.cs @@ -7,7 +7,6 @@ using System.ComponentModel; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.PooledObjects; -using Microsoft.Internal.VisualStudio.PlatformUI; using Microsoft.VisualStudio.LanguageServices.Extensions; using Microsoft.VisualStudio.Shell; using Roslyn.Utilities; From c9cdb51fc539e717234856f3cf42db435f2c71eb Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 11:51:18 +0200 Subject: [PATCH 080/353] Cleanup --- .../RoslynSolutionExplorerSearchProvider.cs | 25 +++++++------------ .../SolutionExplorerNavigationSupport.cs | 8 +++--- .../RootSymbolTreeItemSourceProvider.cs | 2 +- 3 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs index 2745e8054a7b7..96aca2a338f0b 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs @@ -27,23 +27,16 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore [Export(typeof(ISearchProvider))] [Name(nameof(RoslynSolutionExplorerSearchProvider))] [Order(Before = "GraphSearchProvider")] -internal sealed class RoslynSolutionExplorerSearchProvider : ISearchProvider +[method: ImportingConstructor] +[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] +internal sealed class RoslynSolutionExplorerSearchProvider( + VisualStudioWorkspace workspace, + IAsynchronousOperationListenerProvider listenerProvider, + IThreadingContext threadingContext) : ISearchProvider { - private readonly VisualStudioWorkspace _workspace; - private readonly IAsynchronousOperationListener _listener; - public readonly SolutionExplorerNavigationSupport NavigationSupport; - - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public RoslynSolutionExplorerSearchProvider( - VisualStudioWorkspace workspace, - IAsynchronousOperationListenerProvider listenerProvider, - IThreadingContext threadingContext) - { - _workspace = workspace; - _listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); - NavigationSupport = new(workspace, threadingContext, _listener); - } + private readonly VisualStudioWorkspace _workspace = workspace; + private readonly IAsynchronousOperationListener _listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); + public readonly SolutionExplorerNavigationSupport NavigationSupport = new(workspace, threadingContext, listenerProvider); public void Search(IRelationshipSearchParameters parameters, Action resultAccumulator) { diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SolutionExplorerNavigationSupport.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SolutionExplorerNavigationSupport.cs index c65f30c18afb5..ece58b44157e1 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SolutionExplorerNavigationSupport.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SolutionExplorerNavigationSupport.cs @@ -14,18 +14,18 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore internal sealed class SolutionExplorerNavigationSupport( Workspace workspace, IThreadingContext threadingContext, - IAsynchronousOperationListener listener) + IAsynchronousOperationListenerProvider listenerProvider) { private readonly CancellationSeries _cancellationSeries = new(threadingContext.DisposalToken); + private readonly IAsynchronousOperationListener _listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); - public void NavigateTo( - DocumentId documentId, int position, bool preview) + public void NavigateTo(DocumentId documentId, int position, bool preview) { // Cancel any in flight navigation and kick off a new one. var cancellationToken = _cancellationSeries.CreateNext(); var navigationService = workspace.Services.GetRequiredService(); - var token = listener.BeginAsyncOperation(nameof(NavigateTo)); + var token = _listener.BeginAsyncOperation(nameof(NavigateTo)); navigationService.TryNavigateToPositionAsync( threadingContext, workspace, diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index 846e0223701ce..7cf4f1ca88449 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -53,7 +53,7 @@ public RootSymbolTreeItemSourceProvider( ThreadingContext = threadingContext; _workspace = workspace; Listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); - NavigationSupport = new(workspace, threadingContext, Listener); + NavigationSupport = new(workspace, threadingContext, listenerProvider); _updateSourcesQueue = new AsyncBatchingWorkQueue( DelayTimeSpan.Medium, From 704c6f7c8682480281b6a96eba038b014e215ab4 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 12:20:08 +0200 Subject: [PATCH 081/353] Working search --- .../RoslynSolutionExplorerSearchProvider.cs | 49 +++++++++---------- .../SolutionExplorerSearchDisplayItem.cs | 2 +- ...ExplorerSearchDisplayItemSourceProvider.cs | 30 +++++++++++- .../Search/SolutionExplorerSearchResult.cs | 21 ++++++++ .../RootSymbolTreeItemSourceProvider.cs | 1 - 5 files changed, 74 insertions(+), 29 deletions(-) create mode 100644 src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchResult.cs diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs index 96aca2a338f0b..029c7ccb6e638 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs @@ -35,6 +35,7 @@ internal sealed class RoslynSolutionExplorerSearchProvider( IThreadingContext threadingContext) : ISearchProvider { private readonly VisualStudioWorkspace _workspace = workspace; + private readonly IThreadingContext _threadingContext = threadingContext; private readonly IAsynchronousOperationListener _listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); public readonly SolutionExplorerNavigationSupport NavigationSupport = new(workspace, threadingContext, listenerProvider); @@ -43,21 +44,31 @@ public void Search(IRelationshipSearchParameters parameters, Action KnownRelationships.Contains; + public string DisplayName => KnownRelationships.Contains; + } + + private sealed class ContainedByAttachedRelationship : IAttachedRelationship + { + public string Name => KnownRelationships.ContainedBy; + public string DisplayName => KnownRelationships.ContainedBy; + } +} + /// /// Responsible for taking search result items and parenting them with their corresponding real document /// (i.e. an IVhHierarchy + itemid) in the solution explorer window. In other words, this source provider @@ -20,8 +40,8 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore /// . /// [Export(typeof(IAttachedCollectionSourceProvider))] -[Name(nameof(RootSymbolTreeItemSourceProvider))] -[Order(Before = HierarchyItemsProviderNames.ContainedBy)] +[Name(nameof(SolutionExplorerSearchDisplayItemSourceProvider))] +[Order(Before = HierarchyItemsProviderNames.Contains)] [AppliesToProject("CSharp | VB")] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] @@ -30,6 +50,12 @@ internal sealed partial class SolutionExplorerSearchDisplayItemSourceProvider( IVsHierarchyItemManager hierarchyItemManager) : AttachedCollectionSourceProvider { + protected override IEnumerable GetRelationships(SolutionExplorerSearchDisplayItem item) + { + yield return Relationships.Contains; + yield return Relationships.ContainedBy; + } + protected override IAttachedCollectionSource? CreateCollectionSource( SolutionExplorerSearchDisplayItem item, string relationshipName) { diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchResult.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchResult.cs new file mode 100644 index 0000000000000..10a8d0eed7af7 --- /dev/null +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchResult.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.NavigateTo; +using Microsoft.Internal.VisualStudio.PlatformUI; + +namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; + +internal sealed class SolutionExplorerSearchResult( + RoslynSolutionExplorerSearchProvider provider, + INavigateToSearchResult result) : ISearchResult +{ + public object GetDisplayItem() + { + var name = result.NavigableItem.DisplayTaggedParts.JoinText(); + return new SolutionExplorerSearchDisplayItem( + provider, name, result); + } +} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index 7cf4f1ca88449..0d850940c6e21 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -16,7 +16,6 @@ using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.Navigation; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Threading; From b1b5905e0a0007721c8611c88d36acd72bbbcd80 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 12:24:39 +0200 Subject: [PATCH 082/353] Working search --- .../Search/RoslynSolutionExplorerSearchProvider.cs | 8 +++++++- .../Search/SolutionExplorerSearchDisplayItem.cs | 5 +++-- .../Search/SolutionExplorerSearchResult.cs | 12 +++++------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs index 029c7ccb6e638..55b08948d85ea 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.Editor.Wpf; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host.Mef; @@ -84,7 +85,12 @@ public Task AddResultsAsync( CancellationToken cancellationToken) { foreach (var result in results) - resultAccumulator(new SolutionExplorerSearchResult(provider, result)); + { + // Compute the name on the BG to avoid UI work. + var name = result.NavigableItem.DisplayTaggedParts.JoinText(); + var imageMoniker = result.NavigableItem.Glyph.GetImageMoniker(); + resultAccumulator(new SolutionExplorerSearchResult(provider, result, name, imageMoniker)); + } return Task.CompletedTask; } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItem.cs index b7f833a37e4ec..e399518257f46 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItem.cs @@ -14,15 +14,16 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore internal sealed class SolutionExplorerSearchDisplayItem( RoslynSolutionExplorerSearchProvider provider, + INavigateToSearchResult result, string name, - INavigateToSearchResult result) + ImageMoniker imageMoniker) : BaseItem(canPreview: true), IInvocationController { public readonly INavigateToSearchResult Result = result; public override string Name { get; } = name; - public override ImageMoniker IconMoniker => Result.NavigableItem.Glyph.GetImageMoniker(); + public override ImageMoniker IconMoniker { get; } = imageMoniker; public override IInvocationController? InvocationController => this; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchResult.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchResult.cs index 10a8d0eed7af7..ea181e55530b2 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchResult.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchResult.cs @@ -2,20 +2,18 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.NavigateTo; using Microsoft.Internal.VisualStudio.PlatformUI; +using Microsoft.VisualStudio.Imaging.Interop; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; internal sealed class SolutionExplorerSearchResult( RoslynSolutionExplorerSearchProvider provider, - INavigateToSearchResult result) : ISearchResult + INavigateToSearchResult result, + string name, + ImageMoniker imageMoniker) : ISearchResult { public object GetDisplayItem() - { - var name = result.NavigableItem.DisplayTaggedParts.JoinText(); - return new SolutionExplorerSearchDisplayItem( - provider, name, result); - } + => new SolutionExplorerSearchDisplayItem(provider, result, name, imageMoniker); } From 2c0b1c74d3a4388e3ded62d78f8e53ebb38c02af Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 12:26:50 +0200 Subject: [PATCH 083/353] Make nested type --- .../RoslynSolutionExplorerSearchProvider.cs | 14 +++++++++++++- .../Search/SolutionExplorerSearchResult.cs | 19 ------------------- 2 files changed, 13 insertions(+), 20 deletions(-) delete mode 100644 src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchResult.cs diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs index 55b08948d85ea..ed117f76f6e27 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/RoslynSolutionExplorerSearchProvider.cs @@ -17,6 +17,7 @@ using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.Internal.VisualStudio.PlatformUI; +using Microsoft.VisualStudio.Imaging.Interop; using Microsoft.VisualStudio.Utilities; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -37,7 +38,6 @@ internal sealed class RoslynSolutionExplorerSearchProvider( { private readonly VisualStudioWorkspace _workspace = workspace; private readonly IThreadingContext _threadingContext = threadingContext; - private readonly IAsynchronousOperationListener _listener = listenerProvider.GetListener(FeatureAttribute.SolutionExplorer); public readonly SolutionExplorerNavigationSupport NavigationSupport = new(workspace, threadingContext, listenerProvider); public void Search(IRelationshipSearchParameters parameters, Action resultAccumulator) @@ -45,6 +45,8 @@ public void Search(IRelationshipSearchParameters parameters, Action new SolutionExplorerSearchDisplayItem(provider, result, name, imageMoniker); + } + private sealed class SolutionExplorerNavigateToSearcherHost(Workspace workspace) : INavigateToSearcherHost { public INavigateToSearchService? GetNavigateToSearchService(Microsoft.CodeAnalysis.Project project) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchResult.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchResult.cs deleted file mode 100644 index ea181e55530b2..0000000000000 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchResult.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.CodeAnalysis.NavigateTo; -using Microsoft.Internal.VisualStudio.PlatformUI; -using Microsoft.VisualStudio.Imaging.Interop; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; - -internal sealed class SolutionExplorerSearchResult( - RoslynSolutionExplorerSearchProvider provider, - INavigateToSearchResult result, - string name, - ImageMoniker imageMoniker) : ISearchResult -{ - public object GetDisplayItem() - => new SolutionExplorerSearchDisplayItem(provider, result, name, imageMoniker); -} From a74bb6ed409bb3dace222cdcf2c7a82acfe1299e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 12:39:00 +0200 Subject: [PATCH 084/353] remove code --- ...ExplorerSearchDisplayItemSourceProvider.cs | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItemSourceProvider.cs index 8020088df60d4..72b05a8e00f2f 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItemSourceProvider.cs @@ -4,7 +4,6 @@ using System; using System.Collections; -using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel.Composition; using Microsoft.CodeAnalysis.Host.Mef; @@ -14,25 +13,6 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; -internal static class Relationships -{ - public static IAttachedRelationship Contains { get; } = new ContainsAttachedRelationship(); - - public static IAttachedRelationship ContainedBy { get; } = new ContainedByAttachedRelationship(); - - private sealed class ContainsAttachedRelationship : IAttachedRelationship - { - public string Name => KnownRelationships.Contains; - public string DisplayName => KnownRelationships.Contains; - } - - private sealed class ContainedByAttachedRelationship : IAttachedRelationship - { - public string Name => KnownRelationships.ContainedBy; - public string DisplayName => KnownRelationships.ContainedBy; - } -} - /// /// Responsible for taking search result items and parenting them with their corresponding real document /// (i.e. an IVhHierarchy + itemid) in the solution explorer window. In other words, this source provider @@ -50,12 +30,6 @@ internal sealed partial class SolutionExplorerSearchDisplayItemSourceProvider( IVsHierarchyItemManager hierarchyItemManager) : AttachedCollectionSourceProvider { - protected override IEnumerable GetRelationships(SolutionExplorerSearchDisplayItem item) - { - yield return Relationships.Contains; - yield return Relationships.ContainedBy; - } - protected override IAttachedCollectionSource? CreateCollectionSource( SolutionExplorerSearchDisplayItem item, string relationshipName) { From 1105ccc187c36577dac1f7ee4902a1716470a98d Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 12:54:09 +0200 Subject: [PATCH 085/353] Remove files --- .../Core/Def/Progression/GraphBuilder.cs | 202 ----- .../Progression/GraphNavigatorExtension.cs | 224 ++--- .../Def/Progression/GraphNodeIdCreation.cs | 46 +- .../Core/Def/Progression/GraphProvider.cs | 686 +++++++-------- .../ProgressionNavigateToSearchCallback.cs | 56 -- .../GraphQueries/SearchGraphQuery.cs | 55 -- .../Core/Def/Progression/GraphQueryManager.cs | 122 --- .../SearchGraphQueryTests_NavigateTo.vb | 818 +++++++++--------- 8 files changed, 887 insertions(+), 1322 deletions(-) delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphBuilder.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphQueries/ProgressionNavigateToSearchCallback.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphQueries/SearchGraphQuery.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphQueryManager.cs diff --git a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs b/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs deleted file mode 100644 index 9ea4218df8980..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphBuilder.cs +++ /dev/null @@ -1,202 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.IO; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.NavigateTo; -using Microsoft.CodeAnalysis.Text; -using Microsoft.VisualStudio.GraphModel; -using Microsoft.VisualStudio.GraphModel.CodeSchema; -using Microsoft.VisualStudio.GraphModel.Schemas; -using Roslyn.Utilities; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -internal sealed partial class GraphBuilder -{ - // Our usage of SemaphoreSlim is fine. We don't perform blocking waits for it on the UI thread. -#pragma warning disable RS0030 // Do not use banned APIs - private readonly SemaphoreSlim _gate = new(initialCount: 1); -#pragma warning restore RS0030 // Do not use banned APIs - - private readonly ISet _createdNodes = new HashSet(); - - public GraphBuilder() - { - // _solution = solution; - } - - public void AddLink(GraphNode from, GraphCategory category, GraphNode to, CancellationToken cancellationToken) - { - using (_gate.DisposableWait(cancellationToken)) - { - Graph.Links.GetOrCreate(from, to).AddCategory(category); - } - } - - public GraphNode? TryAddNodeForDocument(Document document, CancellationToken cancellationToken) - { - // Under the covers, progression will attempt to convert a label into a URI. Ensure that we - // can do this safely. before proceeding. - // - // The corresponding code on the progression side does: new Uri(text, UriKind.RelativeOrAbsolute) - // so we check that same kind here. - var fileName = Path.GetFileName(document.FilePath); - if (!Uri.TryCreate(fileName, UriKind.RelativeOrAbsolute, out _)) - return null; - - using (_gate.DisposableWait(cancellationToken)) - { - var id = GraphNodeIdCreation.GetIdForDocument(document); - - var node = Graph.Nodes.GetOrCreate(id, fileName, CodeNodeCategories.ProjectItem); - - // _nodeToContextDocumentMap[node] = document; - // _nodeToContextProjectMap[node] = document.Project; - - _createdNodes.Add(node); - - return node; - } - } - - public async Task CreateNodeAsync(Solution solution, INavigateToSearchResult result, CancellationToken cancellationToken) - { - var document = await result.NavigableItem.Document.GetRequiredDocumentAsync(solution, cancellationToken).ConfigureAwait(false); - var project = document.Project; - - // If it doesn't belong to a document or project we can navigate to, then ignore entirely. - if (document.FilePath == null || project.FilePath == null) - return null; - - var category = result.Kind switch - { - NavigateToItemKind.Class => CodeNodeCategories.Class, - NavigateToItemKind.Delegate => CodeNodeCategories.Delegate, - NavigateToItemKind.Enum => CodeNodeCategories.Enum, - NavigateToItemKind.Interface => CodeNodeCategories.Interface, - NavigateToItemKind.Module => CodeNodeCategories.Module, - NavigateToItemKind.Structure => CodeNodeCategories.Struct, - NavigateToItemKind.Method => CodeNodeCategories.Method, - NavigateToItemKind.Property => CodeNodeCategories.Property, - NavigateToItemKind.Event => CodeNodeCategories.Event, - NavigateToItemKind.Constant or - NavigateToItemKind.EnumItem or - NavigateToItemKind.Field => CodeNodeCategories.Field, - _ => null, - }; - - // If it's not a category that progression understands, then ignore. - if (category == null) - return null; - - // Get or make a node for this symbol's containing document that will act as the parent node in the UI. - var documentNode = this.TryAddNodeForDocument(document, cancellationToken); - if (documentNode == null) - return null; - - // For purposes of keying this node, just use the display text we will show. In practice, outside of error - // scenarios this will be unique and suitable as an ID (esp. as these names are joined with their parent - // document name to form the full ID). - var label = result.NavigableItem.DisplayTaggedParts.JoinText(); - var id = documentNode.Id.Add(GraphNodeId.GetLiteral(label)); - - // If we already have a node that matches this (say there are multiple identical sibling symbols in an error - // situation). We just ignore the second match. - var existing = Graph.Nodes.Get(id); - if (existing != null) - return null; - - var text = await document.GetValueTextAsync(cancellationToken).ConfigureAwait(false); - var span = text.Lines.GetLinePositionSpan(NavigateToUtilities.GetBoundedSpan(result.NavigableItem, text)); - var sourceLocation = TryCreateSourceLocation(document.FilePath, span); - if (sourceLocation == null) - return null; - - var symbolNode = Graph.Nodes.GetOrCreate(id); - - symbolNode.Label = label; - symbolNode.AddCategory(category); - symbolNode[DgmlNodeProperties.Icon] = GetIconString(result.NavigableItem.Glyph); - // symbolNode[RoslynGraphProperties.ContextDocumentId] = document.Id; - symbolNode[RoslynGraphProperties.ContextProjectId] = document.Project.Id; - - symbolNode[CodeNodeProperties.SourceLocation] = sourceLocation.Value; - - this.AddLink(documentNode, GraphCommonSchema.Contains, symbolNode, cancellationToken); - - return symbolNode; - } - - public static SourceLocation? TryCreateSourceLocation(string path, LinePositionSpan span) - { - // SourceLocation's constructor attempts to create an absolute uri. So if we can't do that - // bail out immediately. - if (!Uri.TryCreate(path, UriKind.Absolute, out var uri)) - return null; - - return new SourceLocation( - uri, - new Position(span.Start.Line, span.Start.Character), - new Position(span.End.Line, span.End.Character)); - } - - private static string? GetIconString(Glyph glyph) - { - var groupName = glyph switch - { - Glyph.ClassPublic or Glyph.ClassProtected or Glyph.ClassPrivate or Glyph.ClassInternal => "Class", - Glyph.ConstantPublic or Glyph.ConstantProtected or Glyph.ConstantPrivate or Glyph.ConstantInternal => "Field", - Glyph.DelegatePublic or Glyph.DelegateProtected or Glyph.DelegatePrivate or Glyph.DelegateInternal => "Delegate", - Glyph.EnumPublic or Glyph.EnumProtected or Glyph.EnumPrivate or Glyph.EnumInternal => "Enum", - Glyph.EnumMemberPublic or Glyph.EnumMemberProtected or Glyph.EnumMemberPrivate or Glyph.EnumMemberInternal => "EnumMember", - Glyph.ExtensionMethodPublic or Glyph.ExtensionMethodProtected or Glyph.ExtensionMethodPrivate or Glyph.ExtensionMethodInternal => "Method", - Glyph.EventPublic or Glyph.EventProtected or Glyph.EventPrivate or Glyph.EventInternal => "Event", - Glyph.FieldPublic or Glyph.FieldProtected or Glyph.FieldPrivate or Glyph.FieldInternal => "Field", - Glyph.InterfacePublic or Glyph.InterfaceProtected or Glyph.InterfacePrivate or Glyph.InterfaceInternal => "Interface", - Glyph.MethodPublic or Glyph.MethodProtected or Glyph.MethodPrivate or Glyph.MethodInternal => "Method", - Glyph.ModulePublic or Glyph.ModuleProtected or Glyph.ModulePrivate or Glyph.ModuleInternal => "Module", - Glyph.PropertyPublic or Glyph.PropertyProtected or Glyph.PropertyPrivate or Glyph.PropertyInternal => "Property", - Glyph.StructurePublic or Glyph.StructureProtected or Glyph.StructurePrivate or Glyph.StructureInternal => "Structure", - _ => null, - }; - - if (groupName == null) - return null; - - return IconHelper.GetIconName(groupName, GlyphExtensions.GetAccessibility(GlyphTags.GetTags(glyph))); - } - - public void ApplyToGraph(Graph graph, CancellationToken cancellationToken) - { - using (_gate.DisposableWait(cancellationToken)) - { - using var graphTransaction = new GraphTransactionScope(); - graph.Merge(this.Graph); - - //foreach (var deferredProperty in _deferredPropertySets) - //{ - // var nodeToSet = graph.Nodes.Get(deferredProperty.Item1.Id); - // nodeToSet.SetValue(deferredProperty.Item2, deferredProperty.Item3); - //} - - graphTransaction.Complete(); - } - } - - public Graph Graph { get; } = new(); - - public ImmutableArray GetCreatedNodes(CancellationToken cancellationToken) - { - using (_gate.DisposableWait(cancellationToken)) - { - return [.. _createdNodes]; - } - } -} diff --git a/src/VisualStudio/Core/Def/Progression/GraphNavigatorExtension.cs b/src/VisualStudio/Core/Def/Progression/GraphNavigatorExtension.cs index 27f81077dff70..7f0cc45d0691b 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphNavigatorExtension.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphNavigatorExtension.cs @@ -1,112 +1,112 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Editor.Shared.Utilities; -using Microsoft.CodeAnalysis.Navigation; -using Microsoft.VisualStudio.GraphModel; -using Microsoft.VisualStudio.GraphModel.CodeSchema; -using Microsoft.VisualStudio.GraphModel.Schemas; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -using Workspace = Microsoft.CodeAnalysis.Workspace; - -internal sealed class GraphNavigatorExtension( - IThreadingContext threadingContext, - Workspace workspace) : IGraphNavigateToItem -{ - private readonly IThreadingContext _threadingContext = threadingContext; - private readonly Workspace _workspace = workspace; - - public void NavigateTo(GraphObject graphObject) - { - if (graphObject is not GraphNode graphNode) - return; - - _threadingContext.JoinableTaskFactory.Run(() => NavigateToAsync(graphNode, CancellationToken.None)); - } - - private async Task NavigateToAsync(GraphNode graphNode, CancellationToken cancellationToken) - { - var projectId = graphNode.GetValue(RoslynGraphProperties.ContextProjectId); - - if (projectId is null) - return; - - var solution = _workspace.CurrentSolution; - var project = solution.GetProject(projectId); - if (project is null) - return; - - // Go through the mainline symbol id path if we have it. That way we notify third parties, and we can navigate - // to metadata. - //var symbolId = graphNode.GetValue(RoslynGraphProperties.SymbolId); - //if (symbolId is not null) - //{ - // var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); - // if (compilation is not null) - // { - // var symbol = symbolId.Value.Resolve(compilation, cancellationToken: cancellationToken).GetAnySymbol(); - // if (symbol is not null) - // { - // await GoToDefinitionHelpers.TryNavigateToLocationAsync( - // symbol, project.Solution, _threadingContext, _streamingPresenter.Value, cancellationToken).ConfigureAwait(false); - // return; - // } - // } - //} - - // If we didn't have a symbol id, attempt to navigate to the source location directly if the node includes one. - var sourceLocation = graphNode.GetValue(CodeNodeProperties.SourceLocation); - if (sourceLocation.FileName is null || !sourceLocation.IsValid) - return; - - var document = project.Documents.FirstOrDefault( - d => string.Equals( - d.FilePath, - sourceLocation.FileName.LocalPath, - StringComparison.OrdinalIgnoreCase)); - - if (document == null) - return; - - // We must find the right document in this project. This may not be the - // ContextDocumentId if you have a partial member that is shown under one - // document, but only exists in the other - - var editorWorkspace = document.Project.Solution.Workspace; - var navigationService = editorWorkspace.Services.GetRequiredService(); - - // TODO: Get the platform to use and pass us an operation context, or create one ourselves. - await navigationService.TryNavigateToLineAndOffsetAsync( - _threadingContext, - editorWorkspace, - document.Id, - sourceLocation.StartPosition.Line, - sourceLocation.StartPosition.Character, - NavigationOptions.Default, - cancellationToken).ConfigureAwait(false); - } - - public int GetRank(GraphObject graphObject) - { - if (graphObject is GraphNode graphNode) - { - var sourceLocation = graphNode.GetValue(CodeNodeProperties.SourceLocation); - var projectId = graphNode.GetValue(RoslynGraphProperties.ContextProjectId); - - if (sourceLocation.IsValid && projectId != null) - { - return GraphNavigateToItemRanks.OwnItem; - } - } - - return GraphNavigateToItemRanks.CanNavigateToItem; - } -} +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. + +//using System; +//using System.Linq; +//using System.Threading; +//using System.Threading.Tasks; +//using Microsoft.CodeAnalysis; +//using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +//using Microsoft.CodeAnalysis.Navigation; +//using Microsoft.VisualStudio.GraphModel; +//using Microsoft.VisualStudio.GraphModel.CodeSchema; +//using Microsoft.VisualStudio.GraphModel.Schemas; + +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; + +//using Workspace = Microsoft.CodeAnalysis.Workspace; + +//internal sealed class GraphNavigatorExtension( +// IThreadingContext threadingContext, +// Workspace workspace) : IGraphNavigateToItem +//{ +// private readonly IThreadingContext _threadingContext = threadingContext; +// private readonly Workspace _workspace = workspace; + +// public void NavigateTo(GraphObject graphObject) +// { +// if (graphObject is not GraphNode graphNode) +// return; + +// _threadingContext.JoinableTaskFactory.Run(() => NavigateToAsync(graphNode, CancellationToken.None)); +// } + +// private async Task NavigateToAsync(GraphNode graphNode, CancellationToken cancellationToken) +// { +// var projectId = graphNode.GetValue(RoslynGraphProperties.ContextProjectId); + +// if (projectId is null) +// return; + +// var solution = _workspace.CurrentSolution; +// var project = solution.GetProject(projectId); +// if (project is null) +// return; + +// // Go through the mainline symbol id path if we have it. That way we notify third parties, and we can navigate +// // to metadata. +// //var symbolId = graphNode.GetValue(RoslynGraphProperties.SymbolId); +// //if (symbolId is not null) +// //{ +// // var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); +// // if (compilation is not null) +// // { +// // var symbol = symbolId.Value.Resolve(compilation, cancellationToken: cancellationToken).GetAnySymbol(); +// // if (symbol is not null) +// // { +// // await GoToDefinitionHelpers.TryNavigateToLocationAsync( +// // symbol, project.Solution, _threadingContext, _streamingPresenter.Value, cancellationToken).ConfigureAwait(false); +// // return; +// // } +// // } +// //} + +// // If we didn't have a symbol id, attempt to navigate to the source location directly if the node includes one. +// var sourceLocation = graphNode.GetValue(CodeNodeProperties.SourceLocation); +// if (sourceLocation.FileName is null || !sourceLocation.IsValid) +// return; + +// var document = project.Documents.FirstOrDefault( +// d => string.Equals( +// d.FilePath, +// sourceLocation.FileName.LocalPath, +// StringComparison.OrdinalIgnoreCase)); + +// if (document == null) +// return; + +// // We must find the right document in this project. This may not be the +// // ContextDocumentId if you have a partial member that is shown under one +// // document, but only exists in the other + +// var editorWorkspace = document.Project.Solution.Workspace; +// var navigationService = editorWorkspace.Services.GetRequiredService(); + +// // TODO: Get the platform to use and pass us an operation context, or create one ourselves. +// await navigationService.TryNavigateToLineAndOffsetAsync( +// _threadingContext, +// editorWorkspace, +// document.Id, +// sourceLocation.StartPosition.Line, +// sourceLocation.StartPosition.Character, +// NavigationOptions.Default, +// cancellationToken).ConfigureAwait(false); +// } + +// public int GetRank(GraphObject graphObject) +// { +// if (graphObject is GraphNode graphNode) +// { +// var sourceLocation = graphNode.GetValue(CodeNodeProperties.SourceLocation); +// var projectId = graphNode.GetValue(RoslynGraphProperties.ContextProjectId); + +// if (sourceLocation.IsValid && projectId != null) +// { +// return GraphNavigateToItemRanks.OwnItem; +// } +// } + +// return GraphNavigateToItemRanks.CanNavigateToItem; +// } +//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs b/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs index eb52039b84d2c..f5b35eea0e3c5 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs @@ -1,27 +1,27 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. -#nullable disable +//#nullable disable -using System; -using Microsoft.CodeAnalysis; -using Microsoft.VisualStudio.GraphModel; -using Microsoft.VisualStudio.GraphModel.Schemas; +//using System; +//using Microsoft.CodeAnalysis; +//using Microsoft.VisualStudio.GraphModel; +//using Microsoft.VisualStudio.GraphModel.Schemas; -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; -/// -/// A helper class that implements the creation of GraphNodeIds that matches the .dgml creation -/// by the metadata progression provider. -/// -internal static class GraphNodeIdCreation -{ - public static GraphNodeId GetIdForDocument(Document document) - { - return - GraphNodeId.GetNested( - GraphNodeId.GetPartial(CodeGraphNodeIdName.Assembly, new Uri(document.Project.FilePath, UriKind.RelativeOrAbsolute)), - GraphNodeId.GetPartial(CodeGraphNodeIdName.File, new Uri(document.FilePath, UriKind.RelativeOrAbsolute))); - } -} +///// +///// A helper class that implements the creation of GraphNodeIds that matches the .dgml creation +///// by the metadata progression provider. +///// +//internal static class GraphNodeIdCreation +//{ +// public static GraphNodeId GetIdForDocument(Document document) +// { +// return +// GraphNodeId.GetNested( +// GraphNodeId.GetPartial(CodeGraphNodeIdName.Assembly, new Uri(document.Project.FilePath, UriKind.RelativeOrAbsolute)), +// GraphNodeId.GetPartial(CodeGraphNodeIdName.File, new Uri(document.FilePath, UriKind.RelativeOrAbsolute))); +// } +//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs index 972b3acd562cc..08ceddf53d309 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs @@ -1,343 +1,343 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.ComponentModel.Composition; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Editor.Host; -using Microsoft.CodeAnalysis.Editor.Shared.Utilities; -using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.NavigateTo; -using Microsoft.CodeAnalysis.PooledObjects; -using Microsoft.CodeAnalysis.Shared.TestHooks; -using Microsoft.VisualStudio.GraphModel; -using Microsoft.VisualStudio.GraphModel.CodeSchema; -using Microsoft.VisualStudio.GraphModel.Schemas; -using Microsoft.VisualStudio.Language.Intellisense; -using Microsoft.VisualStudio.Progression; -using Microsoft.VisualStudio.Shell; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -[GraphProvider(Name = nameof(RoslynGraphProvider), ProjectCapability = "(CSharp | VB)")] -internal sealed class RoslynGraphProvider : IGraphProvider -{ - private readonly IThreadingContext _threadingContext; - private readonly IGlyphService _glyphService; - private readonly IServiceProvider _serviceProvider; - private readonly IAsynchronousOperationListener _asyncListener; - private readonly Workspace _workspace; - private readonly GraphQueryManager _graphQueryManager; - - private bool _initialized = false; - - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public RoslynGraphProvider( - IThreadingContext threadingContext, - IGlyphService glyphService, - SVsServiceProvider serviceProvider, - VisualStudioWorkspace workspace, - IAsynchronousOperationListenerProvider listenerProvider) - { - _threadingContext = threadingContext; - _glyphService = glyphService; - _serviceProvider = serviceProvider; - _asyncListener = listenerProvider.GetListener(FeatureAttribute.GraphProvider); - _workspace = workspace; - _graphQueryManager = new GraphQueryManager(workspace); - } - - private void EnsureInitialized() - { - if (_initialized) - { - return; - } - - var iconService = (IIconService)_serviceProvider.GetService(typeof(IIconService)); - IconHelper.Initialize(_glyphService, iconService); - _initialized = true; - } - - public static ImmutableArray GetGraphQueries(IGraphContext context) - { - using var _ = ArrayBuilder.GetInstance(out var graphQueries); - - //if (context.Direction == GraphContextDirection.Self && context.RequestedProperties.Contains(DgmlNodeProperties.ContainsChildren)) - //{ - // graphQueries.Add(new ContainsChildrenGraphQuery()); - //} - - //if (context.Direction == GraphContextDirection.Contains || - // (context.Direction == GraphContextDirection.Target && context.LinkCategories.Contains(CodeLinkCategories.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(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. - // - // Create two queries. One to find results in normal docs, and one to find results in generated - // docs. That way if the generated docs take a long time we can still report the regular doc - // results immediately. - //graphQueries.Add(new SearchGraphQuery(searchParameters.SearchQuery.SearchString, NavigateToDocumentSupport.RegularDocuments)); - //graphQueries.Add(new SearchGraphQuery(searchParameters.SearchQuery.SearchString, NavigateToDocumentSupport.GeneratedDocuments)); - } - } - - return graphQueries.ToImmutableAndClear(); - } - - public void BeginGetGraphData(IGraphContext context) - { - EnsureInitialized(); - - var graphQueries = GetGraphQueries(context); - - // Perform the queries asynchronously in a fire-and-forget fashion. This helper will be responsible - // for always completing the context. AddQueriesAsync is `async`, so it always returns a task and will never - // bubble out an exception synchronously (so CompletesAsyncOperation is safe). - var asyncToken = _asyncListener.BeginAsyncOperation(nameof(BeginGetGraphData)); - _ = _graphQueryManager - .AddQueriesAsync(context, graphQueries, _threadingContext.DisposalToken) - .CompletesAsyncOperation(asyncToken); - } - - public IEnumerable GetCommands(IEnumerable nodes) - { - yield break; - - //EnsureInitialized(); - - //// Only nodes that explicitly state that they contain children (e.g., source files) and named types should - //// be expandable. - //if (nodes.Any(n => n.Properties.Any(p => p.Key == DgmlNodeProperties.ContainsChildren)) || - // nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType))) - //{ - // yield return new GraphCommand( - // GraphCommandDefinition.Contains, - // targetCategories: null, - // linkCategories: [GraphCommonSchema.Contains], - // trackChanges: true); - //} - - //// All graph commands below this point apply only to Roslyn-owned nodes. - //if (!nodes.All(n => IsRoslynNode(n))) - //{ - // yield break; - //} - - //// Only show 'Base Types' and 'Derived Types' on a class or interface. - //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && - // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Interface, TypeKind.Struct, TypeKind.Enum, TypeKind.Delegate))) - //{ - // yield return new GraphCommand( - // GraphCommandDefinition.BaseTypes, - // targetCategories: null, - // linkCategories: [CodeLinkCategories.InheritsFrom], - // trackChanges: true); - - // yield return new GraphCommand( - // GraphCommandDefinition.DerivedTypes, - // targetCategories: null, - // linkCategories: [CodeLinkCategories.InheritsFrom], - // trackChanges: true); - //} - - //// Only show 'Calls' on an applicable member in a class or struct - //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property, SymbolKind.Field))) - //{ - // yield return new GraphCommand( - // GraphCommandDefinition.Calls, - // targetCategories: null, - // linkCategories: [CodeLinkCategories.Calls], - // trackChanges: true); - //} - - //// Only show 'Is Called By' on an applicable member in a class or struct - //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && - // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct))) - //{ - // yield return new GraphCommand( - // GraphCommandDefinition.IsCalledBy, - // targetCategories: null, - // linkCategories: [CodeLinkCategories.Calls], - // trackChanges: true); - //} - - //// Show 'Is Used By' - //yield return new GraphCommand( - // GraphCommandDefinition.IsUsedBy, - // targetCategories: [CodeNodeCategories.SourceLocation], - // linkCategories: [CodeLinkCategories.SourceReferences], - // trackChanges: true); - - //// Show 'Implements' on a class or struct, or an applicable member in a class or struct. - //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && - // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct))) - //{ - // yield return new GraphCommand( - // s_implementsCommandDefinition, - // targetCategories: null, - // linkCategories: [CodeLinkCategories.Implements], - // trackChanges: true); - //} - - //// Show 'Implements' on public, non-static members of a class or struct. Note: we should - //// also show it on explicit interface impls in C#. - //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && - // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && - // !GetModifiers(n).IsStatic)) - //{ - // if (nodes.Any(n => CheckAccessibility(n, Accessibility.Public) || - // HasExplicitInterfaces(n))) - // { - // yield return new GraphCommand( - // s_implementsCommandDefinition, - // targetCategories: null, - // linkCategories: [CodeLinkCategories.Implements], - // trackChanges: true); - // } - //} - - //// Show 'Implemented By' on an interface. - //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && - // IsAnyTypeKind(n, TypeKind.Interface))) - //{ - // yield return new GraphCommand( - // s_implementedByCommandDefinition, - // targetCategories: null, - // linkCategories: [CodeLinkCategories.Implements], - // trackChanges: true); - //} - - //// Show 'Implemented By' on any member of an interface. - //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && - // IsAnyTypeKind(n, TypeKind.Interface))) - //{ - // yield return new GraphCommand( - // s_implementedByCommandDefinition, - // targetCategories: null, - // linkCategories: [CodeLinkCategories.Implements], - // trackChanges: true); - //} - - //// Show 'Overrides' on any applicable member of a class or struct - //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && - // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && - // GetModifiers(n).IsOverride)) - //{ - // yield return new GraphCommand( - // s_overridesCommandDefinition, - // targetCategories: null, - // linkCategories: [RoslynGraphCategories.Overrides], - // trackChanges: true); - //} - - //// Show 'Overridden By' on any applicable member of a class or struct - //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && - // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && - // IsOverridable(n))) - //{ - // yield return new GraphCommand( - // s_overriddenByCommandDefinition, - // targetCategories: null, - // linkCategories: [RoslynGraphCategories.Overrides], - // trackChanges: true); - //} - } - - public T? GetExtension(GraphObject graphObject, T previous) where T : class - { - if (graphObject is GraphNode graphNode) - { - // If this is not a Roslyn node, bail out. - if (graphNode.GetValue(RoslynGraphProperties.ContextProjectId) == null) - return null; - - // Has to have at least a symbolid, or source location to navigate to. - if (// graphNode.GetValue(RoslynGraphProperties.SymbolId) == null && - graphNode.GetValue(CodeNodeProperties.SourceLocation).FileName == null) - { - return null; - } - - if (typeof(T) == typeof(IGraphNavigateToItem)) - return new GraphNavigatorExtension(_threadingContext, _workspace) as T; - - //if (typeof(T) == typeof(IGraphFormattedLabel)) - // return new GraphFormattedLabelExtension() as T; - } - - return null; - } - - public Graph? Schema - { - get { return null; } - } -} +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. + +//using System; +//using System.Collections.Generic; +//using System.Collections.Immutable; +//using System.ComponentModel.Composition; +//using Microsoft.CodeAnalysis; +//using Microsoft.CodeAnalysis.Editor.Host; +//using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +//using Microsoft.CodeAnalysis.Host.Mef; +//using Microsoft.CodeAnalysis.NavigateTo; +//using Microsoft.CodeAnalysis.PooledObjects; +//using Microsoft.CodeAnalysis.Shared.TestHooks; +//using Microsoft.VisualStudio.GraphModel; +//using Microsoft.VisualStudio.GraphModel.CodeSchema; +//using Microsoft.VisualStudio.GraphModel.Schemas; +//using Microsoft.VisualStudio.Language.Intellisense; +//using Microsoft.VisualStudio.Progression; +//using Microsoft.VisualStudio.Shell; + +//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; + +//[GraphProvider(Name = nameof(RoslynGraphProvider), ProjectCapability = "(CSharp | VB)")] +//internal sealed class RoslynGraphProvider : IGraphProvider +//{ +// private readonly IThreadingContext _threadingContext; +// private readonly IGlyphService _glyphService; +// private readonly IServiceProvider _serviceProvider; +// private readonly IAsynchronousOperationListener _asyncListener; +// private readonly Workspace _workspace; +// private readonly GraphQueryManager _graphQueryManager; + +// private bool _initialized = false; + +// [ImportingConstructor] +// [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] +// public RoslynGraphProvider( +// IThreadingContext threadingContext, +// IGlyphService glyphService, +// SVsServiceProvider serviceProvider, +// VisualStudioWorkspace workspace, +// IAsynchronousOperationListenerProvider listenerProvider) +// { +// _threadingContext = threadingContext; +// _glyphService = glyphService; +// _serviceProvider = serviceProvider; +// _asyncListener = listenerProvider.GetListener(FeatureAttribute.GraphProvider); +// _workspace = workspace; +// _graphQueryManager = new GraphQueryManager(workspace); +// } + +// private void EnsureInitialized() +// { +// if (_initialized) +// { +// return; +// } + +// var iconService = (IIconService)_serviceProvider.GetService(typeof(IIconService)); +// IconHelper.Initialize(_glyphService, iconService); +// _initialized = true; +// } + +// public static ImmutableArray GetGraphQueries(IGraphContext context) +// { +// using var _ = ArrayBuilder.GetInstance(out var graphQueries); + +// //if (context.Direction == GraphContextDirection.Self && context.RequestedProperties.Contains(DgmlNodeProperties.ContainsChildren)) +// //{ +// // graphQueries.Add(new ContainsChildrenGraphQuery()); +// //} + +// //if (context.Direction == GraphContextDirection.Contains || +// // (context.Direction == GraphContextDirection.Target && context.LinkCategories.Contains(CodeLinkCategories.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(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. +// // +// // Create two queries. One to find results in normal docs, and one to find results in generated +// // docs. That way if the generated docs take a long time we can still report the regular doc +// // results immediately. +// //graphQueries.Add(new SearchGraphQuery(searchParameters.SearchQuery.SearchString, NavigateToDocumentSupport.RegularDocuments)); +// //graphQueries.Add(new SearchGraphQuery(searchParameters.SearchQuery.SearchString, NavigateToDocumentSupport.GeneratedDocuments)); +// } +// } + +// return graphQueries.ToImmutableAndClear(); +// } + +// public void BeginGetGraphData(IGraphContext context) +// { +// EnsureInitialized(); + +// var graphQueries = GetGraphQueries(context); + +// // Perform the queries asynchronously in a fire-and-forget fashion. This helper will be responsible +// // for always completing the context. AddQueriesAsync is `async`, so it always returns a task and will never +// // bubble out an exception synchronously (so CompletesAsyncOperation is safe). +// var asyncToken = _asyncListener.BeginAsyncOperation(nameof(BeginGetGraphData)); +// _ = _graphQueryManager +// .AddQueriesAsync(context, graphQueries, _threadingContext.DisposalToken) +// .CompletesAsyncOperation(asyncToken); +// } + +// public IEnumerable GetCommands(IEnumerable nodes) +// { +// yield break; + +// //EnsureInitialized(); + +// //// Only nodes that explicitly state that they contain children (e.g., source files) and named types should +// //// be expandable. +// //if (nodes.Any(n => n.Properties.Any(p => p.Key == DgmlNodeProperties.ContainsChildren)) || +// // nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType))) +// //{ +// // yield return new GraphCommand( +// // GraphCommandDefinition.Contains, +// // targetCategories: null, +// // linkCategories: [GraphCommonSchema.Contains], +// // trackChanges: true); +// //} + +// //// All graph commands below this point apply only to Roslyn-owned nodes. +// //if (!nodes.All(n => IsRoslynNode(n))) +// //{ +// // yield break; +// //} + +// //// Only show 'Base Types' and 'Derived Types' on a class or interface. +// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && +// // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Interface, TypeKind.Struct, TypeKind.Enum, TypeKind.Delegate))) +// //{ +// // yield return new GraphCommand( +// // GraphCommandDefinition.BaseTypes, +// // targetCategories: null, +// // linkCategories: [CodeLinkCategories.InheritsFrom], +// // trackChanges: true); + +// // yield return new GraphCommand( +// // GraphCommandDefinition.DerivedTypes, +// // targetCategories: null, +// // linkCategories: [CodeLinkCategories.InheritsFrom], +// // trackChanges: true); +// //} + +// //// Only show 'Calls' on an applicable member in a class or struct +// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property, SymbolKind.Field))) +// //{ +// // yield return new GraphCommand( +// // GraphCommandDefinition.Calls, +// // targetCategories: null, +// // linkCategories: [CodeLinkCategories.Calls], +// // trackChanges: true); +// //} + +// //// Only show 'Is Called By' on an applicable member in a class or struct +// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && +// // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct))) +// //{ +// // yield return new GraphCommand( +// // GraphCommandDefinition.IsCalledBy, +// // targetCategories: null, +// // linkCategories: [CodeLinkCategories.Calls], +// // trackChanges: true); +// //} + +// //// Show 'Is Used By' +// //yield return new GraphCommand( +// // GraphCommandDefinition.IsUsedBy, +// // targetCategories: [CodeNodeCategories.SourceLocation], +// // linkCategories: [CodeLinkCategories.SourceReferences], +// // trackChanges: true); + +// //// Show 'Implements' on a class or struct, or an applicable member in a class or struct. +// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && +// // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct))) +// //{ +// // yield return new GraphCommand( +// // s_implementsCommandDefinition, +// // targetCategories: null, +// // linkCategories: [CodeLinkCategories.Implements], +// // trackChanges: true); +// //} + +// //// Show 'Implements' on public, non-static members of a class or struct. Note: we should +// //// also show it on explicit interface impls in C#. +// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && +// // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && +// // !GetModifiers(n).IsStatic)) +// //{ +// // if (nodes.Any(n => CheckAccessibility(n, Accessibility.Public) || +// // HasExplicitInterfaces(n))) +// // { +// // yield return new GraphCommand( +// // s_implementsCommandDefinition, +// // targetCategories: null, +// // linkCategories: [CodeLinkCategories.Implements], +// // trackChanges: true); +// // } +// //} + +// //// Show 'Implemented By' on an interface. +// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && +// // IsAnyTypeKind(n, TypeKind.Interface))) +// //{ +// // yield return new GraphCommand( +// // s_implementedByCommandDefinition, +// // targetCategories: null, +// // linkCategories: [CodeLinkCategories.Implements], +// // trackChanges: true); +// //} + +// //// Show 'Implemented By' on any member of an interface. +// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && +// // IsAnyTypeKind(n, TypeKind.Interface))) +// //{ +// // yield return new GraphCommand( +// // s_implementedByCommandDefinition, +// // targetCategories: null, +// // linkCategories: [CodeLinkCategories.Implements], +// // trackChanges: true); +// //} + +// //// Show 'Overrides' on any applicable member of a class or struct +// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && +// // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && +// // GetModifiers(n).IsOverride)) +// //{ +// // yield return new GraphCommand( +// // s_overridesCommandDefinition, +// // targetCategories: null, +// // linkCategories: [RoslynGraphCategories.Overrides], +// // trackChanges: true); +// //} + +// //// Show 'Overridden By' on any applicable member of a class or struct +// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && +// // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && +// // IsOverridable(n))) +// //{ +// // yield return new GraphCommand( +// // s_overriddenByCommandDefinition, +// // targetCategories: null, +// // linkCategories: [RoslynGraphCategories.Overrides], +// // trackChanges: true); +// //} +// } + +// public T? GetExtension(GraphObject graphObject, T previous) where T : class +// { +// if (graphObject is GraphNode graphNode) +// { +// // If this is not a Roslyn node, bail out. +// if (graphNode.GetValue(RoslynGraphProperties.ContextProjectId) == null) +// return null; + +// // Has to have at least a symbolid, or source location to navigate to. +// if (// graphNode.GetValue(RoslynGraphProperties.SymbolId) == null && +// graphNode.GetValue(CodeNodeProperties.SourceLocation).FileName == null) +// { +// return null; +// } + +// if (typeof(T) == typeof(IGraphNavigateToItem)) +// return new GraphNavigatorExtension(_threadingContext, _workspace) as T; + +// //if (typeof(T) == typeof(IGraphFormattedLabel)) +// // return new GraphFormattedLabelExtension() as T; +// } + +// return null; +// } + +// public Graph? Schema +// { +// get { return null; } +// } +//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/ProgressionNavigateToSearchCallback.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/ProgressionNavigateToSearchCallback.cs deleted file mode 100644 index 41fee3a23b167..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/ProgressionNavigateToSearchCallback.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.VisualStudio.GraphModel; -using Microsoft.CodeAnalysis.NavigateTo; -using System.Collections.Immutable; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -internal sealed partial class SearchGraphQuery -{ - private sealed class ProgressionNavigateToSearchCallback : INavigateToSearchCallback - { - private readonly Solution _solution; - private readonly IGraphContext _context; - private readonly GraphBuilder _graphBuilder; - - public ProgressionNavigateToSearchCallback(Solution solution, IGraphContext context, GraphBuilder graphBuilder) - { - _solution = solution; - _context = context; - _graphBuilder = graphBuilder; - } - - public void Done(bool isFullyLoaded) - { - // Do nothing here. Even though the navigate to search completed, we still haven't passed any - // information along to progression. That will happen in GraphQueryManager.PopulateContextGraphAsync - } - - public void ReportProgress(int current, int maximum) - => _context.ReportProgress(current, maximum, message: null); - - public void ReportIncomplete() - { - } - - public async Task AddResultsAsync(ImmutableArray results, CancellationToken cancellationToken) - { - foreach (var result in results) - { - var node = await _graphBuilder.CreateNodeAsync(_solution, result, cancellationToken).ConfigureAwait(false); - if (node != null) - { - // _context.OutputNodes is not threadsafe. So ensure only one navto callback can mutate it at a time. - lock (this) - _context.OutputNodes.Add(node); - } - } - } - } -} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/SearchGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/SearchGraphQuery.cs deleted file mode 100644 index ef8969a0bb3fe..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/SearchGraphQuery.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Host; -using Microsoft.CodeAnalysis.Internal.Log; -using Microsoft.CodeAnalysis.NavigateTo; -using Microsoft.CodeAnalysis.Shared.Extensions; -using Microsoft.VisualStudio.GraphModel; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -internal sealed partial class SearchGraphQuery( - string searchPattern, - NavigateToDocumentSupport searchScope) : IGraphQuery -{ - public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) - { - using var _ = Logger.LogBlock(FunctionId.GraphQuery_Search, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); - - var graphBuilder = new GraphBuilder(); // await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - var callback = new ProgressionNavigateToSearchCallback(solution, context, graphBuilder); - - // We have a specialized host for progression vs normal nav-to. Progression itself will tell the client if - // the project is fully loaded or not. But after that point, the client will be considered fully loaded and - // results should reflect that. So we create a host here that will always give complete results once the - // solution is loaded and not give cached/incomplete results at that point. - var statusService = solution.Services.GetRequiredService(); - var isFullyLoaded = await statusService.IsFullyLoadedAsync(cancellationToken).ConfigureAwait(false); - var host = new SearchGraphQueryNavigateToSearchHost(isFullyLoaded); - - var searcher = NavigateToSearcher.Create( - solution, - callback, - searchPattern, - NavigateToUtilities.GetKindsProvided(solution), - host); - - await searcher.SearchAsync(NavigateToSearchScope.Solution, searchScope, cancellationToken).ConfigureAwait(false); - - return graphBuilder; - } - - private sealed class SearchGraphQueryNavigateToSearchHost(bool isFullyLoaded) : INavigateToSearcherHost - { - public INavigateToSearchService? GetNavigateToSearchService(Project project) - => project.GetLanguageService(); - - public ValueTask IsFullyLoadedAsync(CancellationToken cancellationToken) - => new(isFullyLoaded); - } -} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueryManager.cs b/src/VisualStudio/Core/Def/Progression/GraphQueryManager.cs deleted file mode 100644 index 9da3eb327c5fb..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphQueryManager.cs +++ /dev/null @@ -1,122 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Immutable; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.ErrorReporting; -using Microsoft.VisualStudio.GraphModel; -using Roslyn.Utilities; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -using Workspace = Microsoft.CodeAnalysis.Workspace; - -internal sealed class GraphQueryManager -{ - private readonly Workspace _workspace; - - /// - /// This gate locks manipulation of . - /// - private readonly object _gate = new(); - private ImmutableArray<(WeakReference context, ImmutableArray queries)> _trackedQueries = []; - - internal GraphQueryManager( - Workspace workspace) - { - _workspace = workspace; - } - - public async Task AddQueriesAsync(IGraphContext context, ImmutableArray graphQueries, CancellationToken disposalToken) - { - try - { - var solution = _workspace.CurrentSolution; - - // Perform the actual graph query first. - await PopulateContextGraphAsync(solution, context, graphQueries, disposalToken).ConfigureAwait(false); - - // If this context would like to be continuously updated with live changes to this query, then add the - // tracked query to our tracking list, keeping it alive as long as those is keeping the context alive. - if (context.TrackChanges) - { - lock (_gate) - { - _trackedQueries = _trackedQueries.Add((new WeakReference(context), graphQueries)); - } - } - } - finally - { - // We want to ensure that no matter what happens, this initial context is completed - context.OnCompleted(); - } - } - - /// - /// Populate the graph of the context with the values for the given Solution. - /// - private static async Task PopulateContextGraphAsync( - Solution solution, - IGraphContext context, - ImmutableArray graphQueries, - CancellationToken disposalToken) - { - try - { - // Compute all queries in parallel. Then as each finishes, update the graph. - - // Cancel the work if either the context wants us to cancel, or our host is getting disposed. - using var source = CancellationTokenSource.CreateLinkedTokenSource(context.CancelToken, disposalToken); - var cancellationToken = source.Token; - - var tasks = graphQueries.Select(q => Task.Run(() => q.GetGraphAsync(solution, context, cancellationToken), cancellationToken)).ToHashSet(); - - var first = true; - while (tasks.Count > 0) - { - cancellationToken.ThrowIfCancellationRequested(); - - var completedTask = await Task.WhenAny(tasks).ConfigureAwait(false); - tasks.Remove(completedTask); - - // if this is the first task finished, clear out the existing results and add all the new - // results as a single transaction. Doing this as a single transaction is vital for - // solution-explorer as that is how it can map the prior elements to the new ones, preserving the - // view-state (like ensuring the same nodes stay collapsed/expanded). - // - // As additional queries finish, add those results in after without clearing the results of the - // prior queries. - - var graphBuilder = await completedTask.ConfigureAwait(false); - using var transaction = new GraphTransactionScope(); - - if (first) - { - first = false; - context.Graph.Links.Clear(); - } - - graphBuilder.ApplyToGraph(context.Graph, cancellationToken); - context.OutputNodes.AddAll(graphBuilder.GetCreatedNodes(cancellationToken)); - - transaction.Complete(); - } - } - catch (OperationCanceledException) - { - // Don't bubble this cancellation outwards. The queue's cancellation token is mixed with the context's - // token to make a final token that controls the work we do above. We don't want any of the wrong - // cancellations leaking outwards. - } - catch (Exception ex) when (FatalError.ReportAndPropagateUnlessCanceled(ex, ErrorSeverity.Diagnostic)) - { - throw ExceptionUtilities.Unreachable(); - } - } -} diff --git a/src/VisualStudio/Core/Test/Progression/SearchGraphQueryTests_NavigateTo.vb b/src/VisualStudio/Core/Test/Progression/SearchGraphQueryTests_NavigateTo.vb index 7b2bca02f1228..3cdb232a37c9c 100644 --- a/src/VisualStudio/Core/Test/Progression/SearchGraphQueryTests_NavigateTo.vb +++ b/src/VisualStudio/Core/Test/Progression/SearchGraphQueryTests_NavigateTo.vb @@ -1,409 +1,409 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. - -Imports System.Threading.Tasks -Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities -Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces -Imports Microsoft.CodeAnalysis.NavigateTo -Imports Microsoft.CodeAnalysis.Shared.TestHooks -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -Imports Roslyn.Test.Utilities - -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - - Public Class SearchGraphQueryTests_NavigateTo - - Public Async Function SearchForType() As Task - Using testState = ProgressionTestState.Create( - - - - class C { } - - - ) - - Dim outputContext = Await testState.GetGraphContextAfterQuery( - New Graph(), New SearchGraphQuery("C", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function SearchForNestedType() As Task - Using testState = ProgressionTestState.Create( - - - - class C { class F { } } - - - ) - - Dim outputContext = Await testState.GetGraphContextAfterQuery( - New Graph(), New SearchGraphQuery("F", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function SearchForMember() As Task - Using testState = ProgressionTestState.Create( - - - - class C { void M(); } - - - ) - - Dim outputContext = Await testState.GetGraphContextAfterQuery( - New Graph(), New SearchGraphQuery("M", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function SearchForPartialType() As Task - Using testState = ProgressionTestState.Create( - - - -Namespace N - Partial Class C - Sub Goo() - End Sub - End Class -End Namespace - - -Namespace N - Partial Class C - Sub Bar() - End Sub - End Class -End Namespace - - - ) - - Dim outputContext = Await testState.GetGraphContextAfterQuery( - New Graph(), New SearchGraphQuery("C", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function SearchForMethodInPartialType() As Task - Using testState = ProgressionTestState.Create( - - - -Namespace N - Partial Class C - Sub Goo() - End Sub - End Class -End Namespace - - -Namespace N - Partial Class C - Sub Bar() - End Sub - End Class -End Namespace - - - ) - - Dim outputContext = Await testState.GetGraphContextAfterQuery( - New Graph(), New SearchGraphQuery("Goo", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function SearchWithResultsAcrossMultipleTypeParts() As Task - Using testState = ProgressionTestState.Create( - - - -Namespace N - Partial Class C - Sub ZGoo() - End Sub - End Class -End Namespace - - -Namespace N - Partial Class C - Sub ZBar() - End Sub - End Class -End Namespace - - - ) - - Dim outputContext = Await testState.GetGraphContextAfterQuery( - New Graph(), New SearchGraphQuery("Z", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function SearchForDottedName1() As Task - Using testState = ProgressionTestState.Create( - - - - class Dog { void Bark() { } } - - - ) - - Dim outputContext = Await testState.GetGraphContextAfterQuery( - New Graph(), New SearchGraphQuery("D.B", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function SearchForDottedName2() As Task - Using testState = ProgressionTestState.Create( - - - - class Dog { void Bark() { } } - - - ) - - Dim outputContext = Await testState.GetGraphContextAfterQuery( - New Graph(), New SearchGraphQuery("C.B", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - ) - End Using - End Function - - - Public Async Function SearchForDottedName3() As Task - Using testState = ProgressionTestState.Create( - - - - namespace Animal { class Dog<X> { void Bark() { } } } - - - ) - - Dim outputContext = Await testState.GetGraphContextAfterQuery( - New Graph(), New SearchGraphQuery("D.B", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function SearchForDottedName4() As Task - Using testState = ProgressionTestState.Create( - - - - namespace Animal { class Dog<X> { void Bark() { } } } - - - ) - - Dim outputContext = Await testState.GetGraphContextAfterQuery( - New Graph(), New SearchGraphQuery("A.D.B", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - - - - - - - - - - ) - End Using - End Function - - - Public Async Function SearchWithNullFilePathsOnProject() As Task - Using testState = ProgressionTestState.Create( - - > - - namespace Animal { class Dog<X> { void Bark() { } } } - - - ) - - Dim outputContext = Await testState.GetGraphContextAfterQuery( - New Graph(), New SearchGraphQuery("A.D.B", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - - ' When searching, don't descend into projects with a null FilePath because they are artifacts and not - ' representable in the Solution Explorer, e.g., Venus projects create sub-projects with a null file - ' path for each .aspx file. Documents, on the other hand, are never allowed to have a null file path - ' and as such are not tested here. The project/document structure for these scenarios would look - ' similar to this: - ' - ' Project: SomeVenusProject, FilePath=C:\path\to\project.csproj - ' + Document: SomeVenusDocument.aspx, FilePath=C:\path\to\SomeVenusDocument.aspx - ' + Project: 1_SomeNamespace_SomeVenusDocument.aspx, FilePath=null <- the problem is here - ' + Document: SomeVenusDocument.aspx.cs - AssertSimplifiedGraphIs( - outputContext.Graph, - - - - ) - End Using - End Function - End Class -End Namespace +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. + +'Imports System.Threading.Tasks +'Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities +'Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces +'Imports Microsoft.CodeAnalysis.NavigateTo +'Imports Microsoft.CodeAnalysis.Shared.TestHooks +'Imports Microsoft.CodeAnalysis.Test.Utilities +'Imports Microsoft.VisualStudio.GraphModel +'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression +'Imports Roslyn.Test.Utilities + +'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression +' +' Public Class SearchGraphQueryTests_NavigateTo +' +' Public Async Function SearchForType() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class C { } +' +' +' ) + +' Dim outputContext = Await testState.GetGraphContextAfterQuery( +' New Graph(), New SearchGraphQuery("C", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function SearchForNestedType() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class C { class F { } } +' +' +' ) + +' Dim outputContext = Await testState.GetGraphContextAfterQuery( +' New Graph(), New SearchGraphQuery("F", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function SearchForMember() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class C { void M(); } +' +' +' ) + +' Dim outputContext = Await testState.GetGraphContextAfterQuery( +' New Graph(), New SearchGraphQuery("M", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function SearchForPartialType() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +'Namespace N +' Partial Class C +' Sub Goo() +' End Sub +' End Class +'End Namespace +' +' +'Namespace N +' Partial Class C +' Sub Bar() +' End Sub +' End Class +'End Namespace +' +' +' ) + +' Dim outputContext = Await testState.GetGraphContextAfterQuery( +' New Graph(), New SearchGraphQuery("C", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function SearchForMethodInPartialType() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +'Namespace N +' Partial Class C +' Sub Goo() +' End Sub +' End Class +'End Namespace +' +' +'Namespace N +' Partial Class C +' Sub Bar() +' End Sub +' End Class +'End Namespace +' +' +' ) + +' Dim outputContext = Await testState.GetGraphContextAfterQuery( +' New Graph(), New SearchGraphQuery("Goo", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function SearchWithResultsAcrossMultipleTypeParts() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +'Namespace N +' Partial Class C +' Sub ZGoo() +' End Sub +' End Class +'End Namespace +' +' +'Namespace N +' Partial Class C +' Sub ZBar() +' End Sub +' End Class +'End Namespace +' +' +' ) + +' Dim outputContext = Await testState.GetGraphContextAfterQuery( +' New Graph(), New SearchGraphQuery("Z", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function SearchForDottedName1() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class Dog { void Bark() { } } +' +' +' ) + +' Dim outputContext = Await testState.GetGraphContextAfterQuery( +' New Graph(), New SearchGraphQuery("D.B", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function SearchForDottedName2() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' class Dog { void Bark() { } } +' +' +' ) + +' Dim outputContext = Await testState.GetGraphContextAfterQuery( +' New Graph(), New SearchGraphQuery("C.B", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function SearchForDottedName3() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' namespace Animal { class Dog<X> { void Bark() { } } } +' +' +' ) + +' Dim outputContext = Await testState.GetGraphContextAfterQuery( +' New Graph(), New SearchGraphQuery("D.B", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function SearchForDottedName4() As Task +' Using testState = ProgressionTestState.Create( +' +' +' +' namespace Animal { class Dog<X> { void Bark() { } } } +' +' +' ) + +' Dim outputContext = Await testState.GetGraphContextAfterQuery( +' New Graph(), New SearchGraphQuery("A.D.B", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) + +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' +' +' +' +' +' +' +' +' +' ) +' End Using +' End Function + +' +' Public Async Function SearchWithNullFilePathsOnProject() As Task +' Using testState = ProgressionTestState.Create( +' +' > +' +' namespace Animal { class Dog<X> { void Bark() { } } } +' +' +' ) + +' Dim outputContext = Await testState.GetGraphContextAfterQuery( +' New Graph(), New SearchGraphQuery("A.D.B", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) + +' ' When searching, don't descend into projects with a null FilePath because they are artifacts and not +' ' representable in the Solution Explorer, e.g., Venus projects create sub-projects with a null file +' ' path for each .aspx file. Documents, on the other hand, are never allowed to have a null file path +' ' and as such are not tested here. The project/document structure for these scenarios would look +' ' similar to this: +' ' +' ' Project: SomeVenusProject, FilePath=C:\path\to\project.csproj +' ' + Document: SomeVenusDocument.aspx, FilePath=C:\path\to\SomeVenusDocument.aspx +' ' + Project: 1_SomeNamespace_SomeVenusDocument.aspx, FilePath=null <- the problem is here +' ' + Document: SomeVenusDocument.aspx.cs +' AssertSimplifiedGraphIs( +' outputContext.Graph, +' +' +' +' ) +' End Using +' End Function +' End Class +'End Namespace From 0924c9d2950b5e37dddbdcf19f12e182680603dd Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 12:54:37 +0200 Subject: [PATCH 086/353] Remove files --- .../Progression/GraphNavigatorExtension.cs | 112 ------------------ .../Def/Progression/GraphNodeIdCreation.cs | 27 ----- 2 files changed, 139 deletions(-) delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphNavigatorExtension.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs diff --git a/src/VisualStudio/Core/Def/Progression/GraphNavigatorExtension.cs b/src/VisualStudio/Core/Def/Progression/GraphNavigatorExtension.cs deleted file mode 100644 index 7f0cc45d0691b..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphNavigatorExtension.cs +++ /dev/null @@ -1,112 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//using System; -//using System.Linq; -//using System.Threading; -//using System.Threading.Tasks; -//using Microsoft.CodeAnalysis; -//using Microsoft.CodeAnalysis.Editor.Shared.Utilities; -//using Microsoft.CodeAnalysis.Navigation; -//using Microsoft.VisualStudio.GraphModel; -//using Microsoft.VisualStudio.GraphModel.CodeSchema; -//using Microsoft.VisualStudio.GraphModel.Schemas; - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//using Workspace = Microsoft.CodeAnalysis.Workspace; - -//internal sealed class GraphNavigatorExtension( -// IThreadingContext threadingContext, -// Workspace workspace) : IGraphNavigateToItem -//{ -// private readonly IThreadingContext _threadingContext = threadingContext; -// private readonly Workspace _workspace = workspace; - -// public void NavigateTo(GraphObject graphObject) -// { -// if (graphObject is not GraphNode graphNode) -// return; - -// _threadingContext.JoinableTaskFactory.Run(() => NavigateToAsync(graphNode, CancellationToken.None)); -// } - -// private async Task NavigateToAsync(GraphNode graphNode, CancellationToken cancellationToken) -// { -// var projectId = graphNode.GetValue(RoslynGraphProperties.ContextProjectId); - -// if (projectId is null) -// return; - -// var solution = _workspace.CurrentSolution; -// var project = solution.GetProject(projectId); -// if (project is null) -// return; - -// // Go through the mainline symbol id path if we have it. That way we notify third parties, and we can navigate -// // to metadata. -// //var symbolId = graphNode.GetValue(RoslynGraphProperties.SymbolId); -// //if (symbolId is not null) -// //{ -// // var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); -// // if (compilation is not null) -// // { -// // var symbol = symbolId.Value.Resolve(compilation, cancellationToken: cancellationToken).GetAnySymbol(); -// // if (symbol is not null) -// // { -// // await GoToDefinitionHelpers.TryNavigateToLocationAsync( -// // symbol, project.Solution, _threadingContext, _streamingPresenter.Value, cancellationToken).ConfigureAwait(false); -// // return; -// // } -// // } -// //} - -// // If we didn't have a symbol id, attempt to navigate to the source location directly if the node includes one. -// var sourceLocation = graphNode.GetValue(CodeNodeProperties.SourceLocation); -// if (sourceLocation.FileName is null || !sourceLocation.IsValid) -// return; - -// var document = project.Documents.FirstOrDefault( -// d => string.Equals( -// d.FilePath, -// sourceLocation.FileName.LocalPath, -// StringComparison.OrdinalIgnoreCase)); - -// if (document == null) -// return; - -// // We must find the right document in this project. This may not be the -// // ContextDocumentId if you have a partial member that is shown under one -// // document, but only exists in the other - -// var editorWorkspace = document.Project.Solution.Workspace; -// var navigationService = editorWorkspace.Services.GetRequiredService(); - -// // TODO: Get the platform to use and pass us an operation context, or create one ourselves. -// await navigationService.TryNavigateToLineAndOffsetAsync( -// _threadingContext, -// editorWorkspace, -// document.Id, -// sourceLocation.StartPosition.Line, -// sourceLocation.StartPosition.Character, -// NavigationOptions.Default, -// cancellationToken).ConfigureAwait(false); -// } - -// public int GetRank(GraphObject graphObject) -// { -// if (graphObject is GraphNode graphNode) -// { -// var sourceLocation = graphNode.GetValue(CodeNodeProperties.SourceLocation); -// var projectId = graphNode.GetValue(RoslynGraphProperties.ContextProjectId); - -// if (sourceLocation.IsValid && projectId != null) -// { -// return GraphNavigateToItemRanks.OwnItem; -// } -// } - -// return GraphNavigateToItemRanks.CanNavigateToItem; -// } -//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs b/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs deleted file mode 100644 index f5b35eea0e3c5..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphNodeIdCreation.cs +++ /dev/null @@ -1,27 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//#nullable disable - -//using System; -//using Microsoft.CodeAnalysis; -//using Microsoft.VisualStudio.GraphModel; -//using Microsoft.VisualStudio.GraphModel.Schemas; - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -///// -///// A helper class that implements the creation of GraphNodeIds that matches the .dgml creation -///// by the metadata progression provider. -///// -//internal static class GraphNodeIdCreation -//{ -// public static GraphNodeId GetIdForDocument(Document document) -// { -// return -// GraphNodeId.GetNested( -// GraphNodeId.GetPartial(CodeGraphNodeIdName.Assembly, new Uri(document.Project.FilePath, UriKind.RelativeOrAbsolute)), -// GraphNodeId.GetPartial(CodeGraphNodeIdName.File, new Uri(document.FilePath, UriKind.RelativeOrAbsolute))); -// } -//} From 3be518a4d8deb188c75a540b176d5b414694f9e6 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 12:56:05 +0200 Subject: [PATCH 087/353] Remove files --- .../Core/Def/Progression/GraphProvider.cs | 483 +++++++----------- .../Core/Def/Progression/IGraphQuery.cs | 15 - .../Core/Def/Progression/IconHelper.cs | 87 ---- .../Def/Progression/RoslynGraphProperties.cs | 95 ---- 4 files changed, 174 insertions(+), 506 deletions(-) delete mode 100644 src/VisualStudio/Core/Def/Progression/IGraphQuery.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/IconHelper.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs diff --git a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs index 08ceddf53d309..613e9cc47df2c 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs @@ -1,343 +1,208 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. -//using System; -//using System.Collections.Generic; -//using System.Collections.Immutable; -//using System.ComponentModel.Composition; -//using Microsoft.CodeAnalysis; -//using Microsoft.CodeAnalysis.Editor.Host; -//using Microsoft.CodeAnalysis.Editor.Shared.Utilities; -//using Microsoft.CodeAnalysis.Host.Mef; -//using Microsoft.CodeAnalysis.NavigateTo; -//using Microsoft.CodeAnalysis.PooledObjects; -//using Microsoft.CodeAnalysis.Shared.TestHooks; -//using Microsoft.VisualStudio.GraphModel; -//using Microsoft.VisualStudio.GraphModel.CodeSchema; -//using Microsoft.VisualStudio.GraphModel.Schemas; -//using Microsoft.VisualStudio.Language.Intellisense; -//using Microsoft.VisualStudio.Progression; -//using Microsoft.VisualStudio.Shell; +//if (context.Direction == GraphContextDirection.Self && context.RequestedProperties.Contains(DgmlNodeProperties.ContainsChildren)) +//{ +// graphQueries.Add(new ContainsChildrenGraphQuery()); +//} -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; +//if (context.Direction == GraphContextDirection.Contains || +// (context.Direction == GraphContextDirection.Target && context.LinkCategories.Contains(CodeLinkCategories.Contains))) +//{ +// graphQueries.Add(new ContainsGraphQuery()); +//} -//[GraphProvider(Name = nameof(RoslynGraphProvider), ProjectCapability = "(CSharp | VB)")] -//internal sealed class RoslynGraphProvider : IGraphProvider +//if (context.LinkCategories.Contains(CodeLinkCategories.InheritsFrom)) //{ -// private readonly IThreadingContext _threadingContext; -// private readonly IGlyphService _glyphService; -// private readonly IServiceProvider _serviceProvider; -// private readonly IAsynchronousOperationListener _asyncListener; -// private readonly Workspace _workspace; -// private readonly GraphQueryManager _graphQueryManager; +// if (context.Direction == GraphContextDirection.Target) +// { +// graphQueries.Add(new InheritsGraphQuery()); +// } +// else if (context.Direction == GraphContextDirection.Source) +// { +// graphQueries.Add(new InheritedByGraphQuery()); +// } +//} -// private bool _initialized = false; +//if (context.LinkCategories.Contains(CodeLinkCategories.SourceReferences)) +//{ +// graphQueries.Add(new IsUsedByGraphQuery()); +//} -// [ImportingConstructor] -// [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -// public RoslynGraphProvider( -// IThreadingContext threadingContext, -// IGlyphService glyphService, -// SVsServiceProvider serviceProvider, -// VisualStudioWorkspace workspace, -// IAsynchronousOperationListenerProvider listenerProvider) +//if (context.LinkCategories.Contains(CodeLinkCategories.Calls)) +//{ +// if (context.Direction == GraphContextDirection.Target) // { -// _threadingContext = threadingContext; -// _glyphService = glyphService; -// _serviceProvider = serviceProvider; -// _asyncListener = listenerProvider.GetListener(FeatureAttribute.GraphProvider); -// _workspace = workspace; -// _graphQueryManager = new GraphQueryManager(workspace); +// graphQueries.Add(new CallsGraphQuery()); // } - -// private void EnsureInitialized() +// else if (context.Direction == GraphContextDirection.Source) // { -// if (_initialized) -// { -// return; -// } - -// var iconService = (IIconService)_serviceProvider.GetService(typeof(IIconService)); -// IconHelper.Initialize(_glyphService, iconService); -// _initialized = true; +// graphQueries.Add(new IsCalledByGraphQuery()); // } +//} -// public static ImmutableArray GetGraphQueries(IGraphContext context) +//if (context.LinkCategories.Contains(CodeLinkCategories.Implements)) +//{ +// if (context.Direction == GraphContextDirection.Target) // { -// using var _ = ArrayBuilder.GetInstance(out var graphQueries); - -// //if (context.Direction == GraphContextDirection.Self && context.RequestedProperties.Contains(DgmlNodeProperties.ContainsChildren)) -// //{ -// // graphQueries.Add(new ContainsChildrenGraphQuery()); -// //} - -// //if (context.Direction == GraphContextDirection.Contains || -// // (context.Direction == GraphContextDirection.Target && context.LinkCategories.Contains(CodeLinkCategories.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(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. -// // -// // Create two queries. One to find results in normal docs, and one to find results in generated -// // docs. That way if the generated docs take a long time we can still report the regular doc -// // results immediately. -// //graphQueries.Add(new SearchGraphQuery(searchParameters.SearchQuery.SearchString, NavigateToDocumentSupport.RegularDocuments)); -// //graphQueries.Add(new SearchGraphQuery(searchParameters.SearchQuery.SearchString, NavigateToDocumentSupport.GeneratedDocuments)); -// } -// } - -// return graphQueries.ToImmutableAndClear(); +// graphQueries.Add(new ImplementsGraphQuery()); // } - -// public void BeginGetGraphData(IGraphContext context) +// else if (context.Direction == GraphContextDirection.Source) // { -// EnsureInitialized(); - -// var graphQueries = GetGraphQueries(context); - -// // Perform the queries asynchronously in a fire-and-forget fashion. This helper will be responsible -// // for always completing the context. AddQueriesAsync is `async`, so it always returns a task and will never -// // bubble out an exception synchronously (so CompletesAsyncOperation is safe). -// var asyncToken = _asyncListener.BeginAsyncOperation(nameof(BeginGetGraphData)); -// _ = _graphQueryManager -// .AddQueriesAsync(context, graphQueries, _threadingContext.DisposalToken) -// .CompletesAsyncOperation(asyncToken); +// graphQueries.Add(new ImplementedByGraphQuery()); // } +//} -// public IEnumerable GetCommands(IEnumerable nodes) +//if (context.LinkCategories.Contains(RoslynGraphCategories.Overrides)) +//{ +// if (context.Direction == GraphContextDirection.Source) // { -// yield break; - -// //EnsureInitialized(); - -// //// Only nodes that explicitly state that they contain children (e.g., source files) and named types should -// //// be expandable. -// //if (nodes.Any(n => n.Properties.Any(p => p.Key == DgmlNodeProperties.ContainsChildren)) || -// // nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType))) -// //{ -// // yield return new GraphCommand( -// // GraphCommandDefinition.Contains, -// // targetCategories: null, -// // linkCategories: [GraphCommonSchema.Contains], -// // trackChanges: true); -// //} - -// //// All graph commands below this point apply only to Roslyn-owned nodes. -// //if (!nodes.All(n => IsRoslynNode(n))) -// //{ -// // yield break; -// //} - -// //// Only show 'Base Types' and 'Derived Types' on a class or interface. -// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && -// // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Interface, TypeKind.Struct, TypeKind.Enum, TypeKind.Delegate))) -// //{ -// // yield return new GraphCommand( -// // GraphCommandDefinition.BaseTypes, -// // targetCategories: null, -// // linkCategories: [CodeLinkCategories.InheritsFrom], -// // trackChanges: true); +// graphQueries.Add(new OverridesGraphQuery()); +// } +// else if (context.Direction == GraphContextDirection.Target) +// { +// graphQueries.Add(new OverriddenByGraphQuery()); +// } +//} -// // yield return new GraphCommand( -// // GraphCommandDefinition.DerivedTypes, -// // targetCategories: null, -// // linkCategories: [CodeLinkCategories.InheritsFrom], -// // trackChanges: true); -// //} -// //// Only show 'Calls' on an applicable member in a class or struct -// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property, SymbolKind.Field))) -// //{ -// // yield return new GraphCommand( -// // GraphCommandDefinition.Calls, -// // targetCategories: null, -// // linkCategories: [CodeLinkCategories.Calls], -// // trackChanges: true); -// //} -// //// Only show 'Is Called By' on an applicable member in a class or struct -// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && -// // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct))) -// //{ -// // yield return new GraphCommand( -// // GraphCommandDefinition.IsCalledBy, -// // targetCategories: null, -// // linkCategories: [CodeLinkCategories.Calls], -// // trackChanges: true); -// //} +//EnsureInitialized(); -// //// Show 'Is Used By' -// //yield return new GraphCommand( -// // GraphCommandDefinition.IsUsedBy, -// // targetCategories: [CodeNodeCategories.SourceLocation], -// // linkCategories: [CodeLinkCategories.SourceReferences], -// // trackChanges: true); +//// Only nodes that explicitly state that they contain children (e.g., source files) and named types should +//// be expandable. +//if (nodes.Any(n => n.Properties.Any(p => p.Key == DgmlNodeProperties.ContainsChildren)) || +// nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType))) +//{ +// yield return new GraphCommand( +// GraphCommandDefinition.Contains, +// targetCategories: null, +// linkCategories: [GraphCommonSchema.Contains], +// trackChanges: true); +//} -// //// Show 'Implements' on a class or struct, or an applicable member in a class or struct. -// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && -// // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct))) -// //{ -// // yield return new GraphCommand( -// // s_implementsCommandDefinition, -// // targetCategories: null, -// // linkCategories: [CodeLinkCategories.Implements], -// // trackChanges: true); -// //} +//// All graph commands below this point apply only to Roslyn-owned nodes. +//if (!nodes.All(n => IsRoslynNode(n))) +//{ +// yield break; +//} -// //// Show 'Implements' on public, non-static members of a class or struct. Note: we should -// //// also show it on explicit interface impls in C#. -// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && -// // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && -// // !GetModifiers(n).IsStatic)) -// //{ -// // if (nodes.Any(n => CheckAccessibility(n, Accessibility.Public) || -// // HasExplicitInterfaces(n))) -// // { -// // yield return new GraphCommand( -// // s_implementsCommandDefinition, -// // targetCategories: null, -// // linkCategories: [CodeLinkCategories.Implements], -// // trackChanges: true); -// // } -// //} +//// Only show 'Base Types' and 'Derived Types' on a class or interface. +//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && +// IsAnyTypeKind(n, TypeKind.Class, TypeKind.Interface, TypeKind.Struct, TypeKind.Enum, TypeKind.Delegate))) +//{ +// yield return new GraphCommand( +// GraphCommandDefinition.BaseTypes, +// targetCategories: null, +// linkCategories: [CodeLinkCategories.InheritsFrom], +// trackChanges: true); + +// yield return new GraphCommand( +// GraphCommandDefinition.DerivedTypes, +// targetCategories: null, +// linkCategories: [CodeLinkCategories.InheritsFrom], +// trackChanges: true); +//} -// //// Show 'Implemented By' on an interface. -// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && -// // IsAnyTypeKind(n, TypeKind.Interface))) -// //{ -// // yield return new GraphCommand( -// // s_implementedByCommandDefinition, -// // targetCategories: null, -// // linkCategories: [CodeLinkCategories.Implements], -// // trackChanges: true); -// //} +//// Only show 'Calls' on an applicable member in a class or struct +//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property, SymbolKind.Field))) +//{ +// yield return new GraphCommand( +// GraphCommandDefinition.Calls, +// targetCategories: null, +// linkCategories: [CodeLinkCategories.Calls], +// trackChanges: true); +//} -// //// Show 'Implemented By' on any member of an interface. -// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && -// // IsAnyTypeKind(n, TypeKind.Interface))) -// //{ -// // yield return new GraphCommand( -// // s_implementedByCommandDefinition, -// // targetCategories: null, -// // linkCategories: [CodeLinkCategories.Implements], -// // trackChanges: true); -// //} +//// Only show 'Is Called By' on an applicable member in a class or struct +//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && +// IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct))) +//{ +// yield return new GraphCommand( +// GraphCommandDefinition.IsCalledBy, +// targetCategories: null, +// linkCategories: [CodeLinkCategories.Calls], +// trackChanges: true); +//} -// //// Show 'Overrides' on any applicable member of a class or struct -// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && -// // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && -// // GetModifiers(n).IsOverride)) -// //{ -// // yield return new GraphCommand( -// // s_overridesCommandDefinition, -// // targetCategories: null, -// // linkCategories: [RoslynGraphCategories.Overrides], -// // trackChanges: true); -// //} +//// Show 'Is Used By' +//yield return new GraphCommand( +// GraphCommandDefinition.IsUsedBy, +// targetCategories: [CodeNodeCategories.SourceLocation], +// linkCategories: [CodeLinkCategories.SourceReferences], +// trackChanges: true); -// //// Show 'Overridden By' on any applicable member of a class or struct -// //if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && -// // IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && -// // IsOverridable(n))) -// //{ -// // yield return new GraphCommand( -// // s_overriddenByCommandDefinition, -// // targetCategories: null, -// // linkCategories: [RoslynGraphCategories.Overrides], -// // trackChanges: true); -// //} -// } +//// Show 'Implements' on a class or struct, or an applicable member in a class or struct. +//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && +// IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct))) +//{ +// yield return new GraphCommand( +// s_implementsCommandDefinition, +// targetCategories: null, +// linkCategories: [CodeLinkCategories.Implements], +// trackChanges: true); +//} -// public T? GetExtension(GraphObject graphObject, T previous) where T : class +//// Show 'Implements' on public, non-static members of a class or struct. Note: we should +//// also show it on explicit interface impls in C#. +//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && +// IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && +// !GetModifiers(n).IsStatic)) +//{ +// if (nodes.Any(n => CheckAccessibility(n, Accessibility.Public) || +// HasExplicitInterfaces(n))) // { -// if (graphObject is GraphNode graphNode) -// { -// // If this is not a Roslyn node, bail out. -// if (graphNode.GetValue(RoslynGraphProperties.ContextProjectId) == null) -// return null; - -// // Has to have at least a symbolid, or source location to navigate to. -// if (// graphNode.GetValue(RoslynGraphProperties.SymbolId) == null && -// graphNode.GetValue(CodeNodeProperties.SourceLocation).FileName == null) -// { -// return null; -// } +// yield return new GraphCommand( +// s_implementsCommandDefinition, +// targetCategories: null, +// linkCategories: [CodeLinkCategories.Implements], +// trackChanges: true); +// } +//} -// if (typeof(T) == typeof(IGraphNavigateToItem)) -// return new GraphNavigatorExtension(_threadingContext, _workspace) as T; +//// Show 'Implemented By' on an interface. +//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && +// IsAnyTypeKind(n, TypeKind.Interface))) +//{ +// yield return new GraphCommand( +// s_implementedByCommandDefinition, +// targetCategories: null, +// linkCategories: [CodeLinkCategories.Implements], +// trackChanges: true); +//} -// //if (typeof(T) == typeof(IGraphFormattedLabel)) -// // return new GraphFormattedLabelExtension() as T; -// } +//// Show 'Implemented By' on any member of an interface. +//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && +// IsAnyTypeKind(n, TypeKind.Interface))) +//{ +// yield return new GraphCommand( +// s_implementedByCommandDefinition, +// targetCategories: null, +// linkCategories: [CodeLinkCategories.Implements], +// trackChanges: true); +//} -// return null; -// } +//// Show 'Overrides' on any applicable member of a class or struct +//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && +// IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && +// GetModifiers(n).IsOverride)) +//{ +// yield return new GraphCommand( +// s_overridesCommandDefinition, +// targetCategories: null, +// linkCategories: [RoslynGraphCategories.Overrides], +// trackChanges: true); +//} -// public Graph? Schema -// { -// get { return null; } -// } +//// Show 'Overridden By' on any applicable member of a class or struct +//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && +// IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && +// IsOverridable(n))) +//{ +// yield return new GraphCommand( +// s_overriddenByCommandDefinition, +// targetCategories: null, +// linkCategories: [RoslynGraphCategories.Overrides], +// trackChanges: true); //} diff --git a/src/VisualStudio/Core/Def/Progression/IGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/IGraphQuery.cs deleted file mode 100644 index c5a9cf73b70d6..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/IGraphQuery.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.VisualStudio.GraphModel; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -internal interface IGraphQuery -{ - Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken); -} diff --git a/src/VisualStudio/Core/Def/Progression/IconHelper.cs b/src/VisualStudio/Core/Def/Progression/IconHelper.cs deleted file mode 100644 index 102705aa3875a..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/IconHelper.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using Microsoft.CodeAnalysis; -using Microsoft.VisualStudio.Language.Intellisense; -using Microsoft.VisualStudio.Progression; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -internal static class IconHelper -{ - private static string GetIconName(string groupName, string itemName) - => string.Format("Microsoft.VisualStudio.{0}.{1}", groupName, itemName); - - public static string GetIconName(string groupName, Accessibility symbolAccessibility) - { - switch (symbolAccessibility) - { - case Accessibility.Private: - return GetIconName(groupName, "Private"); - - case Accessibility.Protected: - case Accessibility.ProtectedAndInternal: - case Accessibility.ProtectedOrInternal: - return GetIconName(groupName, "Protected"); - - case Accessibility.Internal: - return GetIconName(groupName, "Internal"); - - case Accessibility.Public: - case Accessibility.NotApplicable: - return GetIconName(groupName, "Public"); - - default: - throw new ArgumentException(); - } - } - - public static void Initialize(IGlyphService glyphService, IIconService iconService) - { - var supportedGlyphGroups = new Dictionary - { - { StandardGlyphGroup.GlyphGroupError, "Error" }, - { StandardGlyphGroup.GlyphGroupDelegate, "Delegate" }, - { StandardGlyphGroup.GlyphGroupEnum, "Enum" }, - { StandardGlyphGroup.GlyphGroupStruct, "Struct" }, - { StandardGlyphGroup.GlyphGroupClass, "Class" }, - { StandardGlyphGroup.GlyphGroupInterface, "Interface" }, - { StandardGlyphGroup.GlyphGroupModule, "Module" }, - { StandardGlyphGroup.GlyphGroupConstant, "Constant" }, - { StandardGlyphGroup.GlyphGroupEnumMember, "EnumMember" }, - { StandardGlyphGroup.GlyphGroupEvent, "Event" }, - { StandardGlyphGroup.GlyphExtensionMethodPrivate, "ExtensionMethodPrivate" }, - { StandardGlyphGroup.GlyphExtensionMethodProtected, "ExtensionMethodProtected" }, - { StandardGlyphGroup.GlyphExtensionMethodInternal, "ExtensionMethodInternal" }, - { StandardGlyphGroup.GlyphExtensionMethod, "ExtensionMethod" }, - { StandardGlyphGroup.GlyphGroupMethod, "Method" }, - { StandardGlyphGroup.GlyphGroupProperty, "Property" }, - { StandardGlyphGroup.GlyphGroupField, "Field" }, - { StandardGlyphGroup.GlyphGroupOperator, "Operator" }, - { StandardGlyphGroup.GlyphReference, "Reference" } - }; - - var supportedGlyphItems = new Dictionary - { - { StandardGlyphItem.GlyphItemPrivate, "Private" }, - { StandardGlyphItem.GlyphItemProtected, "Protected" }, - { StandardGlyphItem.GlyphItemInternal, "Internal" }, - { StandardGlyphItem.GlyphItemPublic, "Public" }, - { StandardGlyphItem.GlyphItemFriend, "Friend" } - }; - - foreach (var groupKvp in supportedGlyphGroups) - { - foreach (var itemKvp in supportedGlyphItems) - { - var iconName = GetIconName(groupKvp.Value, itemKvp.Value); - var localGroup = groupKvp.Key; - var localItem = itemKvp.Key; - iconService.AddIcon(iconName, iconName, () => glyphService.GetGlyph(localGroup, localItem)); - } - } - } -} diff --git a/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs b/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs deleted file mode 100644 index 0f1b0e92bdfbd..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/RoslynGraphProperties.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.CodeAnalysis; -using Microsoft.VisualStudio.GraphModel; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -internal static class RoslynGraphProperties -{ - public static readonly GraphSchema Schema; - - /// - /// A graph property that holds the ProjectId where you can find the symbol. Note this is - /// not strictly the project that defines the symbol in the case the symbol is from metadata. - /// It's simply a project that has a compilation which you can use to get to the symbol. - /// - public static readonly GraphProperty ContextProjectId; - - static RoslynGraphProperties() - { - Schema = new GraphSchema("Roslyn"); - - //SymbolKind = Schema.Properties.AddNewProperty( - // id: "SymbolKind", - // dataType: typeof(SymbolKind), - // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - //TypeKind = Schema.Properties.AddNewProperty( - // id: "TypeKind", - // dataType: typeof(TypeKind), - // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - //MethodKind = Schema.Properties.AddNewProperty( - // id: "MethodKind", - // dataType: typeof(MethodKind), - // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - //DeclaredAccessibility = Schema.Properties.AddNewProperty( - // id: "DeclaredAccessibility", - // dataType: typeof(Accessibility), - // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - //SymbolModifiers = Schema.Properties.AddNewProperty( - // id: "SymbolModifiers", - // dataType: typeof(DeclarationModifiers), - // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - //ExplicitInterfaceImplementations = Schema.Properties.AddNewProperty( - // id: "ExplicitInterfaceImplementations", - // dataType: typeof(IList), - // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - //SymbolId = Schema.Properties.AddNewProperty( - // id: "SymbolId", - // dataType: typeof(SymbolKey?), - // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - ContextProjectId = Schema.Properties.AddNewProperty( - id: "ContextProjectId", - dataType: typeof(ProjectId), - callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - //ContextDocumentId = Schema.Properties.AddNewProperty( - // id: "ContextDocumentId", - // dataType: typeof(DocumentId), - // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - //Label = Schema.Properties.AddNewProperty( - // id: "Label", - // dataType: typeof(string), - // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - //FormattedLabelWithoutContainingSymbol = Schema.Properties.AddNewProperty( - // id: "FormattedLabelWithoutContainingSymbol", - // dataType: typeof(string), - // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - //FormattedLabelWithContainingSymbol = Schema.Properties.AddNewProperty( - // id: "FormattedLabelWithContainingSymbol", - // dataType: typeof(string), - // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - //Description = Schema.Properties.AddNewProperty( - // id: "Description", - // dataType: typeof(string), - // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - - //DescriptionWithContainingSymbol = Schema.Properties.AddNewProperty( - // id: "DescriptionWithContainingSymbol", - // dataType: typeof(string), - // callback: () => new GraphMetadata(options: GraphMetadataOptions.Sharable | GraphMetadataOptions.Removable)); - } -} From 2da09f536c6f8ccdd16cf85ef0d851b8518dc0e6 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 13:41:50 +0200 Subject: [PATCH 088/353] Add base type --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 82 ++++------------- ...ISolutionExplorerSymbolTreeItemProvider.cs | 88 ++++++++++++++++++- ...Studio.LanguageServices.VisualBasic.vbproj | 2 +- ...cSolutionExplorerSymbolTreeItemProvider.vb | 72 +++++++++++++++ 4 files changed, 174 insertions(+), 70 deletions(-) create mode 100644 src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index d8893f2485a08..3dfb3770d0dae 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -24,60 +24,24 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.SolutionExplorer; [ExportLanguageService(typeof(ISolutionExplorerSymbolTreeItemProvider), LanguageNames.CSharp), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class CSharpSolutionExplorerSymbolTreeItemProvider() : AbstractSolutionExplorerSymbolTreeItemProvider +internal sealed class CSharpSolutionExplorerSymbolTreeItemProvider() + : AbstractSolutionExplorerSymbolTreeItemProvider< + CompilationUnitSyntax, + MemberDeclarationSyntax, + BaseNamespaceDeclarationSyntax, + EnumDeclarationSyntax, + TypeDeclarationSyntax> { - public override ImmutableArray GetItems(SyntaxNode node, CancellationToken cancellationToken) - { - using var _1 = ArrayBuilder.GetInstance(out var items); - using var _2 = PooledStringBuilder.GetInstance(out var nameBuilder); - - switch (node) - { - case CompilationUnitSyntax compilationUnit: - AddTopLevelTypes(compilationUnit, items, nameBuilder, cancellationToken); - break; - - case EnumDeclarationSyntax enumDeclaration: - AddEnumDeclarationMembers(enumDeclaration, items, cancellationToken); - break; - - case TypeDeclarationSyntax typeDeclaration: - AddTypeDeclarationMembers(typeDeclaration, items, nameBuilder, cancellationToken); - break; - } - - return items.ToImmutableAndClear(); - } - - private static void AddTopLevelTypes( - CompilationUnitSyntax root, ArrayBuilder items, StringBuilder nameBuilder, CancellationToken cancellationToken) - { - foreach (var member in root.Members) - { - cancellationToken.ThrowIfCancellationRequested(); - - if (member is BaseNamespaceDeclarationSyntax baseNamespace) - AddTopLevelTypes(baseNamespace, items, nameBuilder, cancellationToken); - else - TryAddType(member, items, nameBuilder, cancellationToken); - } - } + protected override SyntaxList GetMembers(CompilationUnitSyntax root) + => root.Members; - private static void AddTopLevelTypes( - BaseNamespaceDeclarationSyntax baseNamespace, ArrayBuilder items, StringBuilder nameBuilder, CancellationToken cancellationToken) - { - foreach (var member in baseNamespace.Members) - { - cancellationToken.ThrowIfCancellationRequested(); + protected override SyntaxList GetMembers(BaseNamespaceDeclarationSyntax baseNamespace) + => baseNamespace.Members; - if (member is BaseNamespaceDeclarationSyntax childNamespace) - AddTopLevelTypes(childNamespace, items, nameBuilder, cancellationToken); - else - TryAddType(member, items, nameBuilder, cancellationToken); - } - } + protected override SyntaxList GetMembers(TypeDeclarationSyntax typeDeclaration) + => typeDeclaration.Members; - private static bool TryAddType( + protected override bool TryAddType( MemberDeclarationSyntax member, ArrayBuilder items, StringBuilder nameBuilder, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -103,21 +67,7 @@ private static bool TryAddType( return false; } - private static void AddTypeDeclarationMembers( - TypeDeclarationSyntax typeDeclaration, ArrayBuilder items, StringBuilder nameBuilder, CancellationToken cancellationToken) - { - foreach (var member in typeDeclaration.Members) - { - cancellationToken.ThrowIfCancellationRequested(); - - if (TryAddType(member, items, nameBuilder, cancellationToken)) - continue; - - AddMemberDeclaration(member, items, nameBuilder); - } - } - - private static void AddMemberDeclaration( + protected override void AddMemberDeclaration( MemberDeclarationSyntax member, ArrayBuilder items, StringBuilder nameBuilder) { switch (member) @@ -336,7 +286,7 @@ private static void AddFieldDeclaration( } } - private static void AddEnumDeclarationMembers( + protected override void AddEnumDeclarationMembers( EnumDeclarationSyntax enumDeclaration, ArrayBuilder items, CancellationToken cancellationToken) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs index 3f865942fd590..e59e56342db3e 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs @@ -9,6 +9,7 @@ using System.Threading; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -18,10 +19,18 @@ internal interface ISolutionExplorerSymbolTreeItemProvider : ILanguageService ImmutableArray GetItems(SyntaxNode declarationNode, CancellationToken cancellationToken); } -internal abstract class AbstractSolutionExplorerSymbolTreeItemProvider : ISolutionExplorerSymbolTreeItemProvider +internal abstract class AbstractSolutionExplorerSymbolTreeItemProvider< + TCompilationUnitSyntax, + TMemberDeclarationSyntax, + TNamespaceDeclarationSyntax, + TEnumDeclarationSyntax, + TTypeDeclarationSyntax> + : ISolutionExplorerSymbolTreeItemProvider + where TCompilationUnitSyntax : SyntaxNode + where TMemberDeclarationSyntax : SyntaxNode + where TNamespaceDeclarationSyntax : TMemberDeclarationSyntax + where TEnumDeclarationSyntax : TMemberDeclarationSyntax { - public abstract ImmutableArray GetItems(SyntaxNode declarationNode, CancellationToken cancellationToken); - protected static void AppendCommaSeparatedList( StringBuilder builder, string openBrace, @@ -52,4 +61,77 @@ protected static void AppendCommaSeparatedList( builder.AppendJoinedValues(separator, arguments, append); builder.Append(closeBrace); } + + protected abstract SyntaxList GetMembers(TCompilationUnitSyntax root); + protected abstract SyntaxList GetMembers(TNamespaceDeclarationSyntax baseNamespace); + protected abstract SyntaxList GetMembers(TTypeDeclarationSyntax typeDeclaration); + + protected abstract bool TryAddType(TMemberDeclarationSyntax member, ArrayBuilder items, StringBuilder nameBuilder, CancellationToken cancellationToken); + protected abstract void AddMemberDeclaration(TMemberDeclarationSyntax member, ArrayBuilder items, StringBuilder nameBuilder); + protected abstract void AddEnumDeclarationMembers(TEnumDeclarationSyntax enumDeclaration, ArrayBuilder items, CancellationToken cancellationToken); + + public ImmutableArray GetItems(SyntaxNode node, CancellationToken cancellationToken) + { + using var _1 = ArrayBuilder.GetInstance(out var items); + using var _2 = PooledStringBuilder.GetInstance(out var nameBuilder); + + switch (node) + { + case TCompilationUnitSyntax compilationUnit: + AddTopLevelTypes(compilationUnit, items, nameBuilder, cancellationToken); + break; + + case TEnumDeclarationSyntax enumDeclaration: + AddEnumDeclarationMembers(enumDeclaration, items, cancellationToken); + break; + + case TTypeDeclarationSyntax typeDeclaration: + AddTypeDeclarationMembers(typeDeclaration, items, nameBuilder, cancellationToken); + break; + } + + return items.ToImmutableAndClear(); + } + + private void AddTopLevelTypes( + TCompilationUnitSyntax root, ArrayBuilder items, StringBuilder nameBuilder, CancellationToken cancellationToken) + { + foreach (var member in GetMembers(root)) + { + cancellationToken.ThrowIfCancellationRequested(); + + if (member is TNamespaceDeclarationSyntax baseNamespace) + AddTopLevelTypes(baseNamespace, items, nameBuilder, cancellationToken); + else + TryAddType(member, items, nameBuilder, cancellationToken); + } + } + + private void AddTopLevelTypes( + TNamespaceDeclarationSyntax baseNamespace, ArrayBuilder items, StringBuilder nameBuilder, CancellationToken cancellationToken) + { + foreach (var member in GetMembers(baseNamespace)) + { + cancellationToken.ThrowIfCancellationRequested(); + + if (member is TNamespaceDeclarationSyntax childNamespace) + AddTopLevelTypes(childNamespace, items, nameBuilder, cancellationToken); + else + TryAddType(member, items, nameBuilder, cancellationToken); + } + } + + private void AddTypeDeclarationMembers( + TTypeDeclarationSyntax typeDeclaration, ArrayBuilder items, StringBuilder nameBuilder, CancellationToken cancellationToken) + { + foreach (var member in GetMembers(typeDeclaration)) + { + cancellationToken.ThrowIfCancellationRequested(); + + if (TryAddType(member, items, nameBuilder, cancellationToken)) + continue; + + AddMemberDeclaration(member, items, nameBuilder); + } + } } diff --git a/src/VisualStudio/VisualBasic/Impl/Microsoft.VisualStudio.LanguageServices.VisualBasic.vbproj b/src/VisualStudio/VisualBasic/Impl/Microsoft.VisualStudio.LanguageServices.VisualBasic.vbproj index 491f2a1e80c77..3dd19da145884 100644 --- a/src/VisualStudio/VisualBasic/Impl/Microsoft.VisualStudio.LanguageServices.VisualBasic.vbproj +++ b/src/VisualStudio/VisualBasic/Impl/Microsoft.VisualStudio.LanguageServices.VisualBasic.vbproj @@ -56,7 +56,7 @@ - + true VSPackage Designer diff --git a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb new file mode 100644 index 0000000000000..00937ba7ef224 --- /dev/null +++ b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb @@ -0,0 +1,72 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. +' See the LICENSE file in the project root for more information. + +Imports System.Collections.Immutable +Imports System.Composition +Imports System.Threading +Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Host.Mef +Imports Microsoft.CodeAnalysis.PooledObjects +Imports Microsoft.CodeAnalysis.VisualBasic.Syntax +Imports Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer + +Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer + + Friend Class VisualBasicSolutionExplorerSymbolTreeItemProvider + Inherits AbstractSolutionExplorerSymbolTreeItemProvider + + + + Public Sub New() + End Sub + + Public Overrides Function GetItems(declarationNode As SyntaxNode, cancellationToken As CancellationToken) As ImmutableArray(Of SymbolTreeItemData) + Dim items = ArrayBuilder(Of SymbolTreeItemData).GetInstance() + Dim nameBuilder = PooledStringBuilder.GetInstance() + + Dim compilationUnit = TryCast(declarationNode, CompilationUnitSyntax) + If compilationUnit IsNot Nothing Then + AddTopLevelTypes(compilationUnit, items, nameBuilder, cancellationToken) + End If + + Dim typeBlock = TryCast(declarationNode, TypeBlockSyntax) + If typeBlock IsNot Nothing Then + AddTypeBlockMembers(typeBlock, items, nameBuilder, cancellationToken) + End If + + nameBuilder.Free() + Return items.ToImmutableAndFree() + End Function + + Private Sub AddTopLevelTypes(compilationUnit As CompilationUnitSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As PooledStringBuilder, cancellationToken As CancellationToken) + For Each member In compilationUnit.Members + cancellationToken.ThrowIfCancellationRequested() + + Dim namespaceBlock = TryCast(member, NamespaceBlockSyntax) + If namespaceBlock IsNot Nothing Then + AddTopLevelTypes(namespaceBlock, items, nameBuilder, cancellationToken) + Else + TryAddType(member, items, nameBuilder, cancellationToken) + End If + Next + End Sub + + Private Sub AddTopLevelTypes(namespaceBlock As NamespaceBlockSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As PooledStringBuilder, cancellationToken As CancellationToken) + For Each member In namespaceBlock.Members + cancellationToken.ThrowIfCancellationRequested() + + Dim childNamespaceBlock = TryCast(member, NamespaceBlockSyntax) + If childNamespaceBlock IsNot Nothing Then + AddTopLevelTypes(childNamespaceBlock, items, nameBuilder, cancellationToken) + Else + TryAddType(member, items, nameBuilder, cancellationToken) + End If + Next + End Sub + + Private Sub TryAddType(member As DeclarationStatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As PooledStringBuilder, cancellationToken As CancellationToken) + Throw New NotImplementedException() + End Sub + End Class +End Namespace From 43aff2011904fe1471b83c40448815bcb1decdbc Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 13:46:43 +0200 Subject: [PATCH 089/353] VB stubs --- ...cSolutionExplorerSymbolTreeItemProvider.vb | 66 ++++++++----------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb index 00937ba7ef224..3e2c741b06569 100644 --- a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb +++ b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb @@ -4,6 +4,7 @@ Imports System.Collections.Immutable Imports System.Composition +Imports System.Text Imports System.Threading Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Host.Mef @@ -14,58 +15,47 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer Friend Class VisualBasicSolutionExplorerSymbolTreeItemProvider - Inherits AbstractSolutionExplorerSymbolTreeItemProvider + Inherits AbstractSolutionExplorerSymbolTreeItemProvider(Of + CompilationUnitSyntax, + StatementSyntax, + NamespaceBlockSyntax, + EnumBlockSyntax, + TypeBlockSyntax) Public Sub New() End Sub - Public Overrides Function GetItems(declarationNode As SyntaxNode, cancellationToken As CancellationToken) As ImmutableArray(Of SymbolTreeItemData) - Dim items = ArrayBuilder(Of SymbolTreeItemData).GetInstance() - Dim nameBuilder = PooledStringBuilder.GetInstance() - - Dim compilationUnit = TryCast(declarationNode, CompilationUnitSyntax) - If compilationUnit IsNot Nothing Then - AddTopLevelTypes(compilationUnit, items, nameBuilder, cancellationToken) - End If - - Dim typeBlock = TryCast(declarationNode, TypeBlockSyntax) - If typeBlock IsNot Nothing Then - AddTypeBlockMembers(typeBlock, items, nameBuilder, cancellationToken) - End If - - nameBuilder.Free() - Return items.ToImmutableAndFree() + Protected Overrides Function GetMembers(root As CompilationUnitSyntax) As SyntaxList(Of StatementSyntax) + Return root.Members End Function - Private Sub AddTopLevelTypes(compilationUnit As CompilationUnitSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As PooledStringBuilder, cancellationToken As CancellationToken) - For Each member In compilationUnit.Members - cancellationToken.ThrowIfCancellationRequested() + Protected Overrides Function GetMembers(baseNamespace As NamespaceBlockSyntax) As SyntaxList(Of StatementSyntax) + Return baseNamespace.Members + End Function - Dim namespaceBlock = TryCast(member, NamespaceBlockSyntax) - If namespaceBlock IsNot Nothing Then - AddTopLevelTypes(namespaceBlock, items, nameBuilder, cancellationToken) - Else - TryAddType(member, items, nameBuilder, cancellationToken) - End If - Next - End Sub + Protected Overrides Function GetMembers(typeDeclaration As TypeBlockSyntax) As SyntaxList(Of StatementSyntax) + Return typeDeclaration.Members + End Function - Private Sub AddTopLevelTypes(namespaceBlock As NamespaceBlockSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As PooledStringBuilder, cancellationToken As CancellationToken) - For Each member In namespaceBlock.Members - cancellationToken.ThrowIfCancellationRequested() + Protected Overrides Function TryAddType(member As StatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder, cancellationToken As CancellationToken) As Boolean + Throw New NotImplementedException() + End Function - Dim childNamespaceBlock = TryCast(member, NamespaceBlockSyntax) - If childNamespaceBlock IsNot Nothing Then - AddTopLevelTypes(childNamespaceBlock, items, nameBuilder, cancellationToken) - Else - TryAddType(member, items, nameBuilder, cancellationToken) - End If + Protected Overrides Sub AddEnumDeclarationMembers(enumDeclaration As EnumBlockSyntax, items As ArrayBuilder(Of SymbolTreeItemData), cancellationToken As CancellationToken) + For Each member In enumDeclaration.Members + Dim enumMember = TryCast(member, EnumMemberDeclarationSyntax) + items.Add(New SymbolTreeItemData( + enumMember.Identifier.ValueText, + Glyph.EnumMemberPublic, + hasItems:=False, + enumMember, + enumMember.Identifier)) Next End Sub - Private Sub TryAddType(member As DeclarationStatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As PooledStringBuilder, cancellationToken As CancellationToken) + Protected Overrides Sub AddMemberDeclaration(member As StatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) Throw New NotImplementedException() End Sub End Class From d93cc11e82cff18b77dd9db8fd366a5bc8a3e018 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 14:05:55 +0200 Subject: [PATCH 090/353] Add delegate support --- ...cSolutionExplorerSymbolTreeItemProvider.vb | 78 +++++++++++++++++-- .../FindSymbols/FindSymbolsUtilities.vb | 51 ++++++++++++ ...alBasicDeclaredSymbolInfoFactoryService.vb | 44 +---------- 3 files changed, 124 insertions(+), 49 deletions(-) create mode 100644 src/Workspaces/VisualBasic/Portable/FindSymbols/FindSymbolsUtilities.vb diff --git a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb index 3e2c741b06569..23370b64ea94b 100644 --- a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb +++ b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb @@ -11,6 +11,8 @@ Imports Microsoft.CodeAnalysis.Host.Mef Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer +Imports Microsoft.CodeAnalysis.Shared.Extensions +Imports Microsoft.CodeAnalysis.FindSymbols Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer @@ -40,23 +42,87 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer End Function Protected Overrides Function TryAddType(member As StatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder, cancellationToken As CancellationToken) As Boolean - Throw New NotImplementedException() + Dim typeBlock = TryCast(member, TypeBlockSyntax) + If typeBlock IsNot Nothing Then + AddTypeBlock(typeBlock, items, nameBuilder, cancellationToken) + Return True + End If + + Dim enumBlock = TryCast(member, EnumBlockSyntax) + If enumBlock IsNot Nothing Then + AddEnumBlock(enumBlock, items, nameBuilder, cancellationToken) + Return True + End If + + Dim delegateStatement = TryCast(member, DelegateStatementSyntax) + If delegateStatement IsNot Nothing Then + AddDelegateStatement(delegateStatement, items, nameBuilder, cancellationToken) + Return True + End If + + Return False End Function + Private Shared Sub AddDelegateStatement(delegateStatement As DelegateStatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder, cancellationToken As CancellationToken) + nameBuilder.Append(delegateStatement.Identifier.ValueText) + AppendTypeParameterList(nameBuilder, delegateStatement.TypeParameterList) + AppendParameterList(nameBuilder, delegateStatement.ParameterList) + AppendAsClause(nameBuilder, delegateStatement.AsClause) + + Dim accessibility = GetAccessibility(delegateStatement.Parent, delegateStatement, delegateStatement.Modifiers) + items.Add(New SymbolTreeItemData( + nameBuilder.ToStringAndClear(), + GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Delegate, accessibility), + hasItems:=False, + delegateStatement, + delegateStatement.Identifier)) + End Sub + Protected Overrides Sub AddEnumDeclarationMembers(enumDeclaration As EnumBlockSyntax, items As ArrayBuilder(Of SymbolTreeItemData), cancellationToken As CancellationToken) For Each member In enumDeclaration.Members Dim enumMember = TryCast(member, EnumMemberDeclarationSyntax) items.Add(New SymbolTreeItemData( - enumMember.Identifier.ValueText, - Glyph.EnumMemberPublic, - hasItems:=False, - enumMember, - enumMember.Identifier)) + enumMember.Identifier.ValueText, + Glyph.EnumMemberPublic, + hasItems:=False, + enumMember, + enumMember.Identifier)) Next End Sub Protected Overrides Sub AddMemberDeclaration(member As StatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) Throw New NotImplementedException() End Sub + + Private Shared Sub AppendTypeParameterList( + builder As StringBuilder, + typeParameterList As TypeParameterListSyntax) + + AppendCommaSeparatedList( + builder, "(Of ", ")", typeParameterList, + Function(list) list.Parameters, + Sub(parameter, innherBuilder) innherBuilder.Append(parameter.Identifier.ValueText)) + End Sub + + Private Shared Sub AppendParameterList( + builder As StringBuilder, + parameterList As ParameterListSyntax) + + AppendCommaSeparatedList( + builder, "(", ")", parameterList, + Function(list) list.Parameters, + Sub(parameter, innerBuilder) AppendType(parameter?.AsClause?.Type, builder)) + End Sub + + Private Shared Sub AppendAsClause(nameBuilder As StringBuilder, asClause As SimpleAsClauseSyntax) + If asClause IsNot Nothing Then + nameBuilder.Append(" As ") + AppendType(asClause.Type, nameBuilder) + End If + End Sub + + Private Shared Sub AppendType(typeSyntax As TypeSyntax, builder As StringBuilder) + Throw New NotImplementedException() + End Sub End Class End Namespace diff --git a/src/Workspaces/VisualBasic/Portable/FindSymbols/FindSymbolsUtilities.vb b/src/Workspaces/VisualBasic/Portable/FindSymbols/FindSymbolsUtilities.vb new file mode 100644 index 0000000000000..e2a10127d79d8 --- /dev/null +++ b/src/Workspaces/VisualBasic/Portable/FindSymbols/FindSymbolsUtilities.vb @@ -0,0 +1,51 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. +' See the LICENSE file in the project root for more information. + +Imports Microsoft.CodeAnalysis.VisualBasic.Syntax + +Namespace Microsoft.CodeAnalysis.FindSymbols + Friend Module FindSymbolsUtilities + Public Function GetAccessibility(container As SyntaxNode, node As StatementSyntax, modifiers As SyntaxTokenList) As Accessibility + Dim sawFriend = False + + For Each modifier In modifiers + Select Case modifier.Kind() + Case SyntaxKind.PublicKeyword : Return Accessibility.Public + Case SyntaxKind.PrivateKeyword : Return Accessibility.Private + Case SyntaxKind.ProtectedKeyword : Return Accessibility.Protected + Case SyntaxKind.FriendKeyword + sawFriend = True + Continue For + End Select + Next + + If sawFriend Then + Return Accessibility.Internal + End If + + ' No accessibility modifiers + Select Case container.Kind() + Case SyntaxKind.ClassBlock + ' In a class, fields and shared-constructors are private by default, + ' everything Else Is Public + If node.Kind() = SyntaxKind.FieldDeclaration Then + Return Accessibility.Private + End If + + If node.Kind() = SyntaxKind.SubNewStatement AndAlso + DirectCast(node, SubNewStatementSyntax).Modifiers.Any(SyntaxKind.SharedKeyword) Then + Return Accessibility.Private + End If + + Return Accessibility.Public + Case SyntaxKind.StructureBlock, SyntaxKind.InterfaceBlock, SyntaxKind.ModuleBlock + ' Everything in a struct/interface/module is public + Return Accessibility.Public + End Select + + ' Otherwise, it's internal + Return Accessibility.Internal + End Function + End Module +End Namespace diff --git a/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicDeclaredSymbolInfoFactoryService.vb b/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicDeclaredSymbolInfoFactoryService.vb index 053dcb4224475..85f32ad9e2af2 100644 --- a/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicDeclaredSymbolInfoFactoryService.vb +++ b/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicDeclaredSymbolInfoFactoryService.vb @@ -150,7 +150,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.FindSymbols ' namespaces. If blockStatement.Modifiers.Any(SyntaxKind.PartialKeyword) AndAlso typeDeclaration.Members.Any() AndAlso -typeDeclaration.Members.All(Function(m) TypeOf m Is TypeBlockSyntax) Then + typeDeclaration.Members.All(Function(m) TypeOf m Is TypeBlockSyntax) Then Return Nothing End If @@ -402,48 +402,6 @@ typeDeclaration.Members.All(Function(m) TypeOf m Is TypeBlockSyntax) Then Return TypeOf node.Parent Is TypeBlockSyntax End Function - Private Shared Function GetAccessibility(container As SyntaxNode, node As StatementSyntax, modifiers As SyntaxTokenList) As Accessibility - Dim sawFriend = False - - For Each modifier In modifiers - Select Case modifier.Kind() - Case SyntaxKind.PublicKeyword : Return Accessibility.Public - Case SyntaxKind.PrivateKeyword : Return Accessibility.Private - Case SyntaxKind.ProtectedKeyword : Return Accessibility.Protected - Case SyntaxKind.FriendKeyword - sawFriend = True - Continue For - End Select - Next - - If sawFriend Then - Return Accessibility.Internal - End If - - ' No accessibility modifiers - Select Case container.Kind() - Case SyntaxKind.ClassBlock - ' In a class, fields and shared-constructors are private by default, - ' everything Else Is Public - If node.Kind() = SyntaxKind.FieldDeclaration Then - Return Accessibility.Private - End If - - If node.Kind() = SyntaxKind.SubNewStatement AndAlso - DirectCast(node, SubNewStatementSyntax).Modifiers.Any(SyntaxKind.SharedKeyword) Then - Return Accessibility.Private - End If - - Return Accessibility.Public - Case SyntaxKind.StructureBlock, SyntaxKind.InterfaceBlock, SyntaxKind.ModuleBlock - ' Everything in a struct/interface/module is public - Return Accessibility.Public - End Select - - ' Otherwise, it's internal - Return Accessibility.Internal - End Function - Private Shared Function GetMethodSuffix(method As MethodStatementSyntax) As String Return GetTypeParameterSuffix(method.TypeParameterList) & GetSuffix(method.ParameterList) End Function From 9ce51478ce909fb6e181102e8a8e2d4a1e61ad68 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 14:07:34 +0200 Subject: [PATCH 091/353] Add enum support --- ...ualBasicSolutionExplorerSymbolTreeItemProvider.vb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb index 23370b64ea94b..903ccf2673f03 100644 --- a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb +++ b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb @@ -63,6 +63,18 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer Return False End Function + Private Shared Sub AddEnumBlock(enumBlock As EnumBlockSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder, cancellationToken As CancellationToken) + nameBuilder.Append(enumBlock.EnumStatement.Identifier.ValueText) + + Dim accessibility = GetAccessibility(enumBlock.Parent, enumBlock.EnumStatement, enumBlock.EnumStatement.Modifiers) + items.Add(New SymbolTreeItemData( + nameBuilder.ToStringAndClear(), + GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Enum, accessibility), + hasItems:=False, + enumBlock, + enumBlock.EnumStatement.Identifier)) + End Sub + Private Shared Sub AddDelegateStatement(delegateStatement As DelegateStatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder, cancellationToken As CancellationToken) nameBuilder.Append(delegateStatement.Identifier.ValueText) AppendTypeParameterList(nameBuilder, delegateStatement.TypeParameterList) From 05de6e4cf9a740c2f405292bdfdebaca51621515 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 14:18:06 +0200 Subject: [PATCH 092/353] Add type support --- ...cSolutionExplorerSymbolTreeItemProvider.vb | 73 ++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb index 903ccf2673f03..db0faa9e96553 100644 --- a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb +++ b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb @@ -13,6 +13,7 @@ Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer Imports Microsoft.CodeAnalysis.Shared.Extensions Imports Microsoft.CodeAnalysis.FindSymbols +Imports Microsoft.Build.Framework Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer @@ -134,7 +135,77 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer End Sub Private Shared Sub AppendType(typeSyntax As TypeSyntax, builder As StringBuilder) - Throw New NotImplementedException() + If typeSyntax Is Nothing Then + Return + End If + + Dim tupleType = TryCast(typeSyntax, TupleTypeSyntax) + If tupleType IsNot Nothing Then + AppendCommaSeparatedList( + builder, "(", ")", tupleType.Elements, + Sub(element, innerBuilder) AppendTupleElement(element, innerBuilder)) + Return + End If + + Dim arrayType = TryCast(typeSyntax, ArrayTypeSyntax) + If arrayType IsNot Nothing Then + AppendType(arrayType.ElementType, builder) + builder.Append("()") + Return + End If + + Dim nullableType = TryCast(typeSyntax, NullableTypeSyntax) + If nullableType IsNot Nothing Then + AppendType(nullableType.ElementType, builder) + builder.Append('?') + Return + End If + + Dim predefinedType = TryCast(typeSyntax, PredefinedTypeSyntax) + If predefinedType IsNot Nothing Then + builder.Append(predefinedType.ToString()) + Return + End If + + Dim identifierName = TryCast(typeSyntax, IdentifierNameSyntax) + If identifierName IsNot Nothing Then + builder.Append(identifierName.Identifier.ValueText) + Return + End If + + Dim genericName = TryCast(typeSyntax, GenericNameSyntax) + If genericName IsNot Nothing Then + builder.Append(genericName.Identifier.ValueText) + AppendCommaSeparatedList( + builder, "(Of ", ")", genericName.TypeArgumentList.Arguments, + Sub(typeArgument, innerBuilder) AppendType(typeArgument, innerBuilder)) + Return + End If + + Dim qualifiedName = TryCast(typeSyntax, QualifiedNameSyntax) + If qualifiedName IsNot Nothing Then + AppendType(qualifiedName.Right, builder) + Return + End If + + Debug.Fail("Unhandled type: " + typeSyntax.GetType().FullName) + End Sub + + Private Shared Sub AppendTupleElement(element As TupleElementSyntax, builder As StringBuilder) + Dim typedTupleElement = TryCast(element, TypedTupleElementSyntax) + If typedTupleElement IsNot Nothing Then + AppendType(typedTupleElement.Type, builder) + Return + End If + + Dim namedTupleElement = TryCast(element, NamedTupleElementSyntax) + If namedTupleElement IsNot Nothing Then + AppendType(namedTupleElement.AsClause?.Type, builder) + Return + End If + + Debug.Fail("Unhandled type: " + element.GetType().FullName) + End Sub End Class End Namespace From c52562471820aa73ba72d253dd1452ab546c0bcd Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 14:25:48 +0200 Subject: [PATCH 093/353] add typeblock support --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 3 +- ...ISolutionExplorerSymbolTreeItemProvider.cs | 8 ++-- ...cSolutionExplorerSymbolTreeItemProvider.vb | 39 ++++++++++++------- .../FindSymbols/FindSymbolsUtilities.vb | 13 +++++++ ...alBasicDeclaredSymbolInfoFactoryService.vb | 4 +- .../FindSymbols/VisualBasicReferenceFinder.vb | 1 + 6 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index 3dfb3770d0dae..4aec8a7f9f14c 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -42,9 +42,8 @@ protected override SyntaxList GetMembers(TypeDeclaratio => typeDeclaration.Members; protected override bool TryAddType( - MemberDeclarationSyntax member, ArrayBuilder items, StringBuilder nameBuilder, CancellationToken cancellationToken) + MemberDeclarationSyntax member, ArrayBuilder items, StringBuilder nameBuilder) { - cancellationToken.ThrowIfCancellationRequested(); switch (member) { case ExtensionBlockDeclarationSyntax extensionBlock: diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs index e59e56342db3e..a0cf80e800a75 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs @@ -66,7 +66,7 @@ protected static void AppendCommaSeparatedList( protected abstract SyntaxList GetMembers(TNamespaceDeclarationSyntax baseNamespace); protected abstract SyntaxList GetMembers(TTypeDeclarationSyntax typeDeclaration); - protected abstract bool TryAddType(TMemberDeclarationSyntax member, ArrayBuilder items, StringBuilder nameBuilder, CancellationToken cancellationToken); + protected abstract bool TryAddType(TMemberDeclarationSyntax member, ArrayBuilder items, StringBuilder nameBuilder); protected abstract void AddMemberDeclaration(TMemberDeclarationSyntax member, ArrayBuilder items, StringBuilder nameBuilder); protected abstract void AddEnumDeclarationMembers(TEnumDeclarationSyntax enumDeclaration, ArrayBuilder items, CancellationToken cancellationToken); @@ -103,7 +103,7 @@ private void AddTopLevelTypes( if (member is TNamespaceDeclarationSyntax baseNamespace) AddTopLevelTypes(baseNamespace, items, nameBuilder, cancellationToken); else - TryAddType(member, items, nameBuilder, cancellationToken); + TryAddType(member, items, nameBuilder); } } @@ -117,7 +117,7 @@ private void AddTopLevelTypes( if (member is TNamespaceDeclarationSyntax childNamespace) AddTopLevelTypes(childNamespace, items, nameBuilder, cancellationToken); else - TryAddType(member, items, nameBuilder, cancellationToken); + TryAddType(member, items, nameBuilder); } } @@ -128,7 +128,7 @@ private void AddTypeDeclarationMembers( { cancellationToken.ThrowIfCancellationRequested(); - if (TryAddType(member, items, nameBuilder, cancellationToken)) + if (TryAddType(member, items, nameBuilder)) continue; AddMemberDeclaration(member, items, nameBuilder); diff --git a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb index db0faa9e96553..e8a33ab5ee194 100644 --- a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb +++ b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb @@ -2,18 +2,16 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. -Imports System.Collections.Immutable Imports System.Composition Imports System.Text Imports System.Threading Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.FindSymbols Imports Microsoft.CodeAnalysis.Host.Mef Imports Microsoft.CodeAnalysis.PooledObjects +Imports Microsoft.CodeAnalysis.Shared.Extensions Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer -Imports Microsoft.CodeAnalysis.Shared.Extensions -Imports Microsoft.CodeAnalysis.FindSymbols -Imports Microsoft.Build.Framework Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer @@ -42,41 +40,56 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer Return typeDeclaration.Members End Function - Protected Overrides Function TryAddType(member As StatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder, cancellationToken As CancellationToken) As Boolean + Protected Overrides Function TryAddType(member As StatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) As Boolean Dim typeBlock = TryCast(member, TypeBlockSyntax) If typeBlock IsNot Nothing Then - AddTypeBlock(typeBlock, items, nameBuilder, cancellationToken) + AddTypeBlock(typeBlock, items, nameBuilder) Return True End If Dim enumBlock = TryCast(member, EnumBlockSyntax) If enumBlock IsNot Nothing Then - AddEnumBlock(enumBlock, items, nameBuilder, cancellationToken) + AddEnumBlock(enumBlock, items) Return True End If Dim delegateStatement = TryCast(member, DelegateStatementSyntax) If delegateStatement IsNot Nothing Then - AddDelegateStatement(delegateStatement, items, nameBuilder, cancellationToken) + AddDelegateStatement(delegateStatement, items, nameBuilder) Return True End If Return False End Function - Private Shared Sub AddEnumBlock(enumBlock As EnumBlockSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder, cancellationToken As CancellationToken) - nameBuilder.Append(enumBlock.EnumStatement.Identifier.ValueText) + Private Shared Sub AddTypeBlock(typeBlock As TypeBlockSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) + Dim blockStatement As TypeStatementSyntax = typeBlock.BlockStatement + + nameBuilder.Append(blockStatement.Identifier.ValueText) + AppendTypeParameterList(nameBuilder, blockStatement.TypeParameterList) + + Dim kind = GetDeclaredSymbolInfoKind(typeBlock) + Dim accessibility = GetAccessibility(typeBlock.Parent, blockStatement, blockStatement.Modifiers) - Dim accessibility = GetAccessibility(enumBlock.Parent, enumBlock.EnumStatement, enumBlock.EnumStatement.Modifiers) items.Add(New SymbolTreeItemData( nameBuilder.ToStringAndClear(), + GlyphExtensions.GetGlyph(kind, accessibility), + hasItems:=False, + typeBlock, + blockStatement.Identifier)) + End Sub + + Private Shared Sub AddEnumBlock(enumBlock As EnumBlockSyntax, items As ArrayBuilder(Of SymbolTreeItemData)) + Dim accessibility = GetAccessibility(enumBlock.Parent, enumBlock.EnumStatement, enumBlock.EnumStatement.Modifiers) + items.Add(New SymbolTreeItemData( + enumBlock.EnumStatement.Identifier.ValueText, GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Enum, accessibility), hasItems:=False, enumBlock, enumBlock.EnumStatement.Identifier)) End Sub - Private Shared Sub AddDelegateStatement(delegateStatement As DelegateStatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder, cancellationToken As CancellationToken) + Private Shared Sub AddDelegateStatement(delegateStatement As DelegateStatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) nameBuilder.Append(delegateStatement.Identifier.ValueText) AppendTypeParameterList(nameBuilder, delegateStatement.TypeParameterList) AppendParameterList(nameBuilder, delegateStatement.ParameterList) @@ -157,7 +170,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer Dim nullableType = TryCast(typeSyntax, NullableTypeSyntax) If nullableType IsNot Nothing Then AppendType(nullableType.ElementType, builder) - builder.Append('?') + builder.Append("?"c) Return End If diff --git a/src/Workspaces/VisualBasic/Portable/FindSymbols/FindSymbolsUtilities.vb b/src/Workspaces/VisualBasic/Portable/FindSymbols/FindSymbolsUtilities.vb index e2a10127d79d8..c131cdafd3471 100644 --- a/src/Workspaces/VisualBasic/Portable/FindSymbols/FindSymbolsUtilities.vb +++ b/src/Workspaces/VisualBasic/Portable/FindSymbols/FindSymbolsUtilities.vb @@ -6,6 +6,19 @@ Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.FindSymbols Friend Module FindSymbolsUtilities + Public Function GetDeclaredSymbolInfoKind(typeBlock As TypeBlockSyntax) As DeclaredSymbolInfoKind + Select Case typeBlock.Kind() + Case SyntaxKind.CaseBlock + Return DeclaredSymbolInfoKind.Class + Case SyntaxKind.InterfaceBlock + Return DeclaredSymbolInfoKind.Interface + Case SyntaxKind.ModuleBlock + Return DeclaredSymbolInfoKind.Module + Case Else + Return DeclaredSymbolInfoKind.Struct + End Select + End Function + Public Function GetAccessibility(container As SyntaxNode, node As StatementSyntax, modifiers As SyntaxTokenList) As Accessibility Dim sawFriend = False diff --git a/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicDeclaredSymbolInfoFactoryService.vb b/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicDeclaredSymbolInfoFactoryService.vb index 85f32ad9e2af2..1518e95dd4590 100644 --- a/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicDeclaredSymbolInfoFactoryService.vb +++ b/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicDeclaredSymbolInfoFactoryService.vb @@ -163,9 +163,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.FindSymbols fullyQualifiedContainerName, blockStatement.Modifiers.Any(SyntaxKind.PartialKeyword), blockStatement.AttributeLists.Any(), - If(typeDeclaration.Kind() = SyntaxKind.ClassBlock, DeclaredSymbolInfoKind.Class, - If(typeDeclaration.Kind() = SyntaxKind.InterfaceBlock, DeclaredSymbolInfoKind.Interface, - If(typeDeclaration.Kind() = SyntaxKind.ModuleBlock, DeclaredSymbolInfoKind.Module, DeclaredSymbolInfoKind.Struct))), + GetDeclaredSymbolInfoKind(typeDeclaration), GetAccessibility(container, typeDeclaration, blockStatement.Modifiers), blockStatement.Identifier.Span, GetInheritanceNames(stringTable, typeDeclaration), diff --git a/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicReferenceFinder.vb b/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicReferenceFinder.vb index 37bf617330aca..37c62a5da70ef 100644 --- a/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicReferenceFinder.vb +++ b/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicReferenceFinder.vb @@ -7,6 +7,7 @@ Imports System.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.FindSymbols.Finders Imports Microsoft.CodeAnalysis.Host.Mef +Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Microsoft.CodeAnalysis.VisualBasic.Utilities Namespace Microsoft.CodeAnalysis.FindSymbols From 9da2ae6e98e598ed783bcf3a15d382707af6f17a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 14:32:33 +0200 Subject: [PATCH 094/353] Add stubs --- ...cSolutionExplorerSymbolTreeItemProvider.vb | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb index e8a33ab5ee194..6f3ea127acc5f 100644 --- a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb +++ b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb @@ -117,7 +117,41 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer End Sub Protected Overrides Sub AddMemberDeclaration(member As StatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) - Throw New NotImplementedException() + Dim methodStatement = If(TryCast(member, MethodStatementSyntax), TryCast(member, MethodBlockSyntax)?.SubOrFunctionStatement) + If methodStatement IsNot Nothing Then + AddMethodStatement(methodStatement, items, nameBuilder) + Return + End If + + Dim constructorStatement = If(TryCast(member, SubNewStatementSyntax), TryCast(member, ConstructorBlockSyntax)?.SubNewStatement) + If constructorStatement IsNot Nothing Then + AddConstructorStatement(constructorStatement, items, nameBuilder) + Return + End If + + Dim operatorStatement = If(TryCast(member, OperatorStatementSyntax), TryCast(member, OperatorBlockSyntax)?.OperatorStatement) + If operatorStatement IsNot Nothing Then + AddOperatorStatement(operatorStatement, items, nameBuilder) + Return + End If + + Dim propertystatement = If(TryCast(member, PropertyStatementSyntax), TryCast(member, PropertyBlockSyntax)?.PropertyStatement) + If propertystatement IsNot Nothing Then + AddPropertyStatement(propertystatement, items, nameBuilder) + Return + End If + + Dim eventStatement = If(TryCast(member, EventStatementSyntax), TryCast(member, EventBlockSyntax)?.EventStatement) + If eventStatement IsNot Nothing Then + AddEventStatement(eventStatement, items, nameBuilder) + Return + End If + + Dim fieldDeclaration = TryCast(member, FieldDeclarationSyntax) + If fieldDeclaration IsNot Nothing Then + AddFieldDeclaration(fieldDeclaration, items, nameBuilder) + Return + End If End Sub Private Shared Sub AppendTypeParameterList( From 72dae5a9d46058a5c08d7d38f9866f2a1fd1bfc7 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 14:44:23 +0200 Subject: [PATCH 095/353] Add fields --- ...cSolutionExplorerSymbolTreeItemProvider.vb | 53 +++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb index 6f3ea127acc5f..7fc885983b832 100644 --- a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb +++ b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb @@ -10,8 +10,10 @@ Imports Microsoft.CodeAnalysis.FindSymbols Imports Microsoft.CodeAnalysis.Host.Mef Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.Shared.Extensions +Imports Microsoft.CodeAnalysis.VisualBasic.Extensions Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer +Imports Roslyn.LanguageServer.Protocol Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer @@ -154,6 +156,23 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer End If End Sub + Private Shared Sub AddFieldDeclaration(fieldDeclaration As FieldDeclarationSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) + For Each declarator In fieldDeclaration.Declarators + For Each name In declarator.Names + nameBuilder.Append(name.Identifier.ValueText) + AppendAsClause(nameBuilder, declarator.AsClause, fallbackToObject:=True) + + Dim accesibility = GetAccessibility(fieldDeclaration.Parent, fieldDeclaration, fieldDeclaration.Modifiers) + items.Add(New SymbolTreeItemData( + nameBuilder.ToStringAndClear(), + GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Field, accesibility), + hasItems:=False, + fieldDeclaration, + name.Identifier)) + Next + Next + End Sub + Private Shared Sub AppendTypeParameterList( builder As StringBuilder, typeParameterList As TypeParameterListSyntax) @@ -174,10 +193,38 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer Sub(parameter, innerBuilder) AppendType(parameter?.AsClause?.Type, builder)) End Sub - Private Shared Sub AppendAsClause(nameBuilder As StringBuilder, asClause As SimpleAsClauseSyntax) + Private Shared Sub AppendAsClause( + nameBuilder As StringBuilder, + asClause As AsClauseSyntax, + Optional fallbackToObject As Boolean = False) If asClause IsNot Nothing Then - nameBuilder.Append(" As ") - AppendType(asClause.Type, nameBuilder) + + Dim simpleAsClause = TryCast(asClause, SimpleAsClauseSyntax) + If simpleAsClause IsNot Nothing Then + nameBuilder.Append(" As ") + AppendType(simpleAsClause.Type, nameBuilder) + Return + End If + + Dim asNewClause = TryCast(asClause, AsNewClauseSyntax) + If asNewClause IsNot Nothing Then + Dim newObjectCreation = TryCast(asNewClause.NewExpression, ObjectCreationExpressionSyntax) + If newObjectCreation IsNot Nothing Then + nameBuilder.Append(" As ") + AppendType(newObjectCreation.Type, nameBuilder) + Return + End If + + Dim newArrayCreation = TryCast(asNewClause.NewExpression, ArrayCreationExpressionSyntax) + If newArrayCreation IsNot Nothing Then + nameBuilder.Append(" As ") + AppendType(newArrayCreation.Type, nameBuilder) + nameBuilder.Append("()") + Return + End If + End If + ElseIf fallbackToObject Then + nameBuilder.Append(" As Object") End If End Sub From 50ed0bfafcb31235e73b02153e7f847b0121f640 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 14:48:09 +0200 Subject: [PATCH 096/353] Add events --- ...cSolutionExplorerSymbolTreeItemProvider.vb | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb index 7fc885983b832..436365ab4a6ef 100644 --- a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb +++ b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb @@ -10,10 +10,8 @@ Imports Microsoft.CodeAnalysis.FindSymbols Imports Microsoft.CodeAnalysis.Host.Mef Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.Shared.Extensions -Imports Microsoft.CodeAnalysis.VisualBasic.Extensions Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer -Imports Roslyn.LanguageServer.Protocol Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer @@ -76,7 +74,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer items.Add(New SymbolTreeItemData( nameBuilder.ToStringAndClear(), GlyphExtensions.GetGlyph(kind, accessibility), - hasItems:=False, + hasItems:=typeBlock.Members.Count > 0, typeBlock, blockStatement.Identifier)) End Sub @@ -86,7 +84,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer items.Add(New SymbolTreeItemData( enumBlock.EnumStatement.Identifier.ValueText, GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Enum, accessibility), - hasItems:=False, + hasItems:=enumBlock.Members.Count > 0, enumBlock, enumBlock.EnumStatement.Identifier)) End Sub @@ -119,50 +117,68 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer End Sub Protected Overrides Sub AddMemberDeclaration(member As StatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) + Dim container = member.Parent Dim methodStatement = If(TryCast(member, MethodStatementSyntax), TryCast(member, MethodBlockSyntax)?.SubOrFunctionStatement) If methodStatement IsNot Nothing Then - AddMethodStatement(methodStatement, items, nameBuilder) + AddMethodStatement(container, methodStatement, items, nameBuilder) Return End If Dim constructorStatement = If(TryCast(member, SubNewStatementSyntax), TryCast(member, ConstructorBlockSyntax)?.SubNewStatement) If constructorStatement IsNot Nothing Then - AddConstructorStatement(constructorStatement, items, nameBuilder) + AddConstructorStatement(container, constructorStatement, items, nameBuilder) Return End If Dim operatorStatement = If(TryCast(member, OperatorStatementSyntax), TryCast(member, OperatorBlockSyntax)?.OperatorStatement) If operatorStatement IsNot Nothing Then - AddOperatorStatement(operatorStatement, items, nameBuilder) + AddOperatorStatement(container, operatorStatement, items, nameBuilder) Return End If Dim propertystatement = If(TryCast(member, PropertyStatementSyntax), TryCast(member, PropertyBlockSyntax)?.PropertyStatement) If propertystatement IsNot Nothing Then - AddPropertyStatement(propertystatement, items, nameBuilder) + AddPropertyStatement(container, propertystatement, items, nameBuilder) Return End If Dim eventStatement = If(TryCast(member, EventStatementSyntax), TryCast(member, EventBlockSyntax)?.EventStatement) If eventStatement IsNot Nothing Then - AddEventStatement(eventStatement, items, nameBuilder) + AddEventStatement(container, eventStatement, items, nameBuilder) Return End If Dim fieldDeclaration = TryCast(member, FieldDeclarationSyntax) If fieldDeclaration IsNot Nothing Then - AddFieldDeclaration(fieldDeclaration, items, nameBuilder) + AddFieldDeclaration(container, fieldDeclaration, items, nameBuilder) Return End If End Sub - Private Shared Sub AddFieldDeclaration(fieldDeclaration As FieldDeclarationSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) + Private Shared Sub AddEventStatement(container As SyntaxNode, eventStatement As EventStatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) + nameBuilder.Append(eventStatement.Identifier.ValueText) + AppendAsClause(nameBuilder, eventStatement.AsClause) + + Dim accesibility = GetAccessibility(container, eventStatement, eventStatement.Modifiers) + items.Add(New SymbolTreeItemData( + nameBuilder.ToStringAndClear(), + GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Event, accesibility), + hasItems:=False, + eventStatement, + eventStatement.Identifier)) + End Sub + + Private Shared Sub AddFieldDeclaration( + container As SyntaxNode, + fieldDeclaration As FieldDeclarationSyntax, + items As ArrayBuilder(Of SymbolTreeItemData), + nameBuilder As StringBuilder) For Each declarator In fieldDeclaration.Declarators For Each name In declarator.Names nameBuilder.Append(name.Identifier.ValueText) AppendAsClause(nameBuilder, declarator.AsClause, fallbackToObject:=True) - Dim accesibility = GetAccessibility(fieldDeclaration.Parent, fieldDeclaration, fieldDeclaration.Modifiers) + Dim accesibility = GetAccessibility(container, fieldDeclaration, fieldDeclaration.Modifiers) items.Add(New SymbolTreeItemData( nameBuilder.ToStringAndClear(), GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Field, accesibility), From c053fc1cb28af50858989ca837b80830ea9df752 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 14:49:18 +0200 Subject: [PATCH 097/353] Add proeprties --- ...lBasicSolutionExplorerSymbolTreeItemProvider.vb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb index 436365ab4a6ef..71ce4e2e93740 100644 --- a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb +++ b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb @@ -155,6 +155,20 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer End If End Sub + Private Shared Sub AddPropertyStatement(container As SyntaxNode, propertystatement As PropertyStatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) + nameBuilder.Append(propertystatement.Identifier.ValueText) + AppendParameterList(nameBuilder, propertystatement.ParameterList) + AppendAsClause(nameBuilder, propertystatement.AsClause, fallbackToObject:=True) + + Dim accesibility = GetAccessibility(container, propertystatement, propertystatement.Modifiers) + items.Add(New SymbolTreeItemData( + nameBuilder.ToStringAndClear(), + GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Property, accesibility), + hasItems:=False, + propertystatement, + propertystatement.Identifier)) + End Sub + Private Shared Sub AddEventStatement(container As SyntaxNode, eventStatement As EventStatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) nameBuilder.Append(eventStatement.Identifier.ValueText) AppendAsClause(nameBuilder, eventStatement.AsClause) From e9e0bad54dc2e46321993773092bb2a200037903 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 14:55:14 +0200 Subject: [PATCH 098/353] Add operatosr --- ...BasicSolutionExplorerSymbolTreeItemProvider.vb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb index 71ce4e2e93740..afe54179c012a 100644 --- a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb +++ b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb @@ -155,6 +155,21 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer End If End Sub + Private Shared Sub AddOperatorStatement(container As SyntaxNode, operatorStatement As OperatorStatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) + nameBuilder.Append("Operator ") + nameBuilder.Append(operatorStatement.OperatorToken.ToString()) + AppendParameterList(nameBuilder, operatorStatement.ParameterList) + AppendAsClause(nameBuilder, operatorStatement.AsClause, fallbackToObject:=True) + + Dim accesibility = GetAccessibility(container, operatorStatement, operatorStatement.Modifiers) + items.Add(New SymbolTreeItemData( + nameBuilder.ToStringAndClear(), + GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Operator, accesibility), + hasItems:=False, + operatorStatement, + operatorStatement.OperatorToken)) + End Sub + Private Shared Sub AddPropertyStatement(container As SyntaxNode, propertystatement As PropertyStatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) nameBuilder.Append(propertystatement.Identifier.ValueText) AppendParameterList(nameBuilder, propertystatement.ParameterList) From d7c04ffe9ce894f661f1817f0b13afca7a269163 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 14:56:55 +0200 Subject: [PATCH 099/353] Add constructors --- ...alBasicSolutionExplorerSymbolTreeItemProvider.vb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb index afe54179c012a..f1a08dba6208e 100644 --- a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb +++ b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb @@ -155,6 +155,19 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer End If End Sub + Private Shared Sub AddConstructorStatement(container As SyntaxNode, constructorStatement As SubNewStatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) + nameBuilder.Append("New") + AppendParameterList(nameBuilder, constructorStatement.ParameterList) + + Dim accesibility = GetAccessibility(container, constructorStatement, constructorStatement.Modifiers) + items.Add(New SymbolTreeItemData( + nameBuilder.ToStringAndClear(), + GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Operator, accesibility), + hasItems:=False, + constructorStatement, + constructorStatement.NewKeyword)) + End Sub + Private Shared Sub AddOperatorStatement(container As SyntaxNode, operatorStatement As OperatorStatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) nameBuilder.Append("Operator ") nameBuilder.Append(operatorStatement.OperatorToken.ToString()) From 4381b040873f16a905e12b1248a34fc8761d5705 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 14:58:46 +0200 Subject: [PATCH 100/353] Add methods --- ...sicSolutionExplorerSymbolTreeItemProvider.vb | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb index f1a08dba6208e..efd732bb7485e 100644 --- a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb +++ b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb @@ -155,6 +155,21 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer End If End Sub + Private Shared Sub AddMethodStatement(container As SyntaxNode, methodStatement As MethodStatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) + nameBuilder.Append(methodStatement.Identifier.ValueText) + AppendTypeParameterList(nameBuilder, methodStatement.TypeParameterList) + AppendParameterList(nameBuilder, methodStatement.ParameterList) + AppendAsClause(nameBuilder, methodStatement.AsClause) + + Dim accesibility = GetAccessibility(container, methodStatement, methodStatement.Modifiers) + items.Add(New SymbolTreeItemData( + nameBuilder.ToStringAndClear(), + GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Method, accesibility), + hasItems:=False, + methodStatement, + methodStatement.Identifier)) + End Sub + Private Shared Sub AddConstructorStatement(container As SyntaxNode, constructorStatement As SubNewStatementSyntax, items As ArrayBuilder(Of SymbolTreeItemData), nameBuilder As StringBuilder) nameBuilder.Append("New") AppendParameterList(nameBuilder, constructorStatement.ParameterList) @@ -162,7 +177,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer Dim accesibility = GetAccessibility(container, constructorStatement, constructorStatement.Modifiers) items.Add(New SymbolTreeItemData( nameBuilder.ToStringAndClear(), - GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Operator, accesibility), + GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Constructor, accesibility), hasItems:=False, constructorStatement, constructorStatement.NewKeyword)) From 5fc1fe31145691328765a0b2ca17421277357427 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 15:01:06 +0200 Subject: [PATCH 101/353] Seal type --- .../VisualBasicSolutionExplorerSymbolTreeItemProvider.vb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb index efd732bb7485e..d976094ff551c 100644 --- a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb +++ b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb @@ -15,7 +15,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer - Friend Class VisualBasicSolutionExplorerSymbolTreeItemProvider + Friend NotInheritable Class VisualBasicSolutionExplorerSymbolTreeItemProvider Inherits AbstractSolutionExplorerSymbolTreeItemProvider(Of CompilationUnitSyntax, StatementSyntax, From be0b606b561c14c05f4a10b465ff51d60a3bf68d Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 15:11:36 +0200 Subject: [PATCH 102/353] Delete old code --- .../CSharpProgressionLanguageService.cs | 128 ------------- .../Test/Progression/ProgressionTestState.vb | 174 +++++++++--------- 2 files changed, 87 insertions(+), 215 deletions(-) delete mode 100644 src/VisualStudio/CSharp/Impl/Progression/CSharpProgressionLanguageService.cs diff --git a/src/VisualStudio/CSharp/Impl/Progression/CSharpProgressionLanguageService.cs b/src/VisualStudio/CSharp/Impl/Progression/CSharpProgressionLanguageService.cs deleted file mode 100644 index 156fd89c0919e..0000000000000 --- a/src/VisualStudio/CSharp/Impl/Progression/CSharpProgressionLanguageService.cs +++ /dev/null @@ -1,128 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//#nullable disable - -//using System; -//using System.Collections.Generic; -//using System.Composition; -//using System.Threading; -//using Microsoft.CodeAnalysis; -//using Microsoft.CodeAnalysis.CSharp; -//using Microsoft.CodeAnalysis.CSharp.Symbols; -//using Microsoft.CodeAnalysis.Host.Mef; -//using Microsoft.CodeAnalysis.PooledObjects; -//using Microsoft.CodeAnalysis.Shared.Extensions; -//using Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//namespace Microsoft.VisualStudio.LanguageServices.CSharp.Progression; - -//[ExportLanguageService(typeof(IProgressionLanguageService), LanguageNames.CSharp), Shared] -//internal sealed partial class CSharpProgressionLanguageService : IProgressionLanguageService -//{ -// private static readonly SymbolDisplayFormat s_descriptionFormat = new( -// globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.OmittedAsContaining, -// typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces, -// genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters, -// memberOptions: SymbolDisplayMemberOptions.IncludeParameters | -// SymbolDisplayMemberOptions.IncludeContainingType, -// parameterOptions: SymbolDisplayParameterOptions.IncludeType | -// SymbolDisplayParameterOptions.IncludeParamsRefOut | -// SymbolDisplayParameterOptions.IncludeOptionalBrackets, -// miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes); - -// private static readonly SymbolDisplayFormat s_labelFormat = new( -// genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters, -// memberOptions: SymbolDisplayMemberOptions.IncludeParameters | -// SymbolDisplayMemberOptions.IncludeExplicitInterface, -// parameterOptions: SymbolDisplayParameterOptions.IncludeType | -// SymbolDisplayParameterOptions.IncludeParamsRefOut | -// SymbolDisplayParameterOptions.IncludeOptionalBrackets, -// delegateStyle: SymbolDisplayDelegateStyle.NameAndParameters, -// miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes); - -// [ImportingConstructor] -// [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -// public CSharpProgressionLanguageService() -// { -// } - -// public IEnumerable GetTopLevelNodesFromDocument(SyntaxNode root, CancellationToken cancellationToken) -// { -// // We implement this method lazily so we are able to abort as soon as we need to. -// if (!cancellationToken.IsCancellationRequested) -// { -// using var _ = ArrayBuilder.GetInstance(out var nodes); -// nodes.Push(root); - -// while (nodes.TryPop(out var node)) -// { -// if (!cancellationToken.IsCancellationRequested) -// { -// if (node.Kind() is SyntaxKind.ClassDeclaration or -// SyntaxKind.RecordDeclaration or -// SyntaxKind.RecordStructDeclaration or -// SyntaxKind.DelegateDeclaration or -// SyntaxKind.EnumDeclaration or -// SyntaxKind.InterfaceDeclaration or -// SyntaxKind.StructDeclaration or -// SyntaxKind.VariableDeclarator or -// SyntaxKind.MethodDeclaration or -// SyntaxKind.PropertyDeclaration) -// { -// yield return node; -// } -// else -// { -// foreach (var child in node.ChildNodes()) -// { -// nodes.Push(child); -// } -// } -// } -// } -// } -// } - -// public string GetDescriptionForSymbol(ISymbol symbol, bool includeContainingSymbol) -// => GetSymbolText(symbol, includeContainingSymbol, s_descriptionFormat); - -// public string GetLabelForSymbol(ISymbol symbol, bool includeContainingSymbol) -// => GetSymbolText(symbol, includeContainingSymbol, s_labelFormat); - -// private static string GetSymbolText(ISymbol symbol, bool includeContainingSymbol, SymbolDisplayFormat displayFormat) -// { -// var label = symbol.ToDisplayString(displayFormat); - -// var typeToShow = GetType(symbol); - -// if (typeToShow != null) -// { -// label += " : " + typeToShow.ToDisplayString(s_labelFormat); -// } - -// if (includeContainingSymbol && symbol.ContainingSymbol != null) -// { -// label += " (" + symbol.ContainingSymbol.ToDisplayString(s_labelFormat) + ")"; -// } - -// return label; -// } - -// private static ITypeSymbol GetType(ISymbol symbol) -// { -// switch (symbol) -// { -// case IEventSymbol f: return f.Type; -// case IFieldSymbol f: return f.ContainingType.TypeKind == TypeKind.Enum ? null : f.Type; -// case IMethodSymbol m: return IncludeReturnType(m) ? m.ReturnType : null; -// case IPropertySymbol p: return p.Type; -// case INamedTypeSymbol n: return n.IsDelegateType() ? n.DelegateInvokeMethod.ReturnType : null; -// default: return null; -// } -// } - -// private static bool IncludeReturnType(IMethodSymbol f) -// => f.MethodKind is MethodKind.Ordinary or MethodKind.ExplicitInterfaceImplementation; -//} diff --git a/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb b/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb index 83f6e7d46cde8..ee1161238d21c 100644 --- a/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb +++ b/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb @@ -1,87 +1,87 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. - -Imports System.Threading -Imports Microsoft.CodeAnalysis -Imports Microsoft.CodeAnalysis.FindSymbols -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression - -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - Friend Class ProgressionTestState - Implements IDisposable - - Public ReadOnly Workspace As EditorTestWorkspace - - Public Sub New(workspace As EditorTestWorkspace) - Me.Workspace = workspace - End Sub - - Public Shared Function Create(workspaceXml As XElement) As ProgressionTestState - Dim workspace = EditorTestWorkspace.Create(workspaceXml, composition:=VisualStudioTestCompositions.LanguageServices) - - Return New ProgressionTestState(workspace) - End Function - - Public Function GetGraphWithDocumentNode(filePath As String) As Graph - Dim graphBuilder As New GraphBuilder() - Dim documentId = Workspace.Documents.Single(Function(d) d.FilePath = filePath).Id - Assert.NotNull(graphBuilder.TryAddNodeForDocument(Workspace.CurrentSolution.GetDocument(documentId), CancellationToken.None)) - Return graphBuilder.Graph - End Function - - 'Public Async Function GetGraphWithMarkedSymbolNodeAsync(Optional symbolTransform As Func(Of ISymbol, ISymbol) = Nothing) As Task(Of Graph) - ' Dim hostDocument As TestHostDocument = Workspace.Documents.Single(Function(d) d.CursorPosition.HasValue) - ' Dim document = Workspace.CurrentSolution.GetDocument(hostDocument.Id) - ' Dim symbol = Await GetMarkedSymbolAsync() - - ' If symbolTransform IsNot Nothing Then - ' symbol = symbolTransform(symbol) - ' End If - - ' Dim graphBuilder As New GraphBuilder(Workspace.CurrentSolution) - ' Await graphBuilder.AddNodeAsync(symbol, document.Project, document, CancellationToken.None) - ' Return graphBuilder.Graph - 'End Function - - Public Async Function GetGraphContextAfterQuery(graph As Graph, graphQuery As IGraphQuery, direction As GraphContextDirection) As Task(Of IGraphContext) - Dim graphContext As New MockGraphContext(direction, graph.Copy(), graph.Nodes) - Dim graphBuilder = Await graphQuery.GetGraphAsync(Workspace.CurrentSolution, graphContext, CancellationToken.None) - graphBuilder.ApplyToGraph(graphContext.Graph, CancellationToken.None) - - Return graphContext - End Function - - Public Async Function GetGraphContextAfterQueryWithSolution(graph As Graph, solution As Solution, graphQuery As IGraphQuery, direction As GraphContextDirection) As Task(Of IGraphContext) - Dim graphContext As New MockGraphContext(direction, graph.Copy(), graph.Nodes) - Dim graphBuilder = Await graphQuery.GetGraphAsync(solution, graphContext, CancellationToken.None) - graphBuilder.ApplyToGraph(graphContext.Graph, CancellationToken.None) - - Return graphContext - End Function - - Private Sub Dispose() Implements IDisposable.Dispose - Workspace.Dispose() - End Sub - - 'Public Async Function AssertMarkedSymbolLabelIsAsync(graphCommandId As String, label As String, description As String) As Task - ' Dim graphNode = (Await GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() - ' Dim formattedLabelExtension As New GraphFormattedLabelExtension() - - ' Assert.Equal(label, formattedLabelExtension.Label(graphNode, graphCommandId)) - ' Assert.Equal(description, formattedLabelExtension.Description(graphNode, graphCommandId)) - 'End Function - - Public Function GetMarkedSymbolAsync() As Task(Of ISymbol) - Dim hostDocument As TestHostDocument = Workspace.Documents.Single(Function(d) d.CursorPosition.HasValue) - Dim document = Workspace.CurrentSolution.GetDocument(hostDocument.Id) - Return SymbolFinder.FindSymbolAtPositionAsync(document, hostDocument.CursorPosition.Value) - End Function - - Public Function GetSolution() As Solution - Return Workspace.CurrentSolution - End Function - End Class -End Namespace +'' Licensed to the .NET Foundation under one or more agreements. +'' The .NET Foundation licenses this file to you under the MIT license. +'' See the LICENSE file in the project root for more information. + +'Imports System.Threading +'Imports Microsoft.CodeAnalysis +'Imports Microsoft.CodeAnalysis.FindSymbols +'Imports Microsoft.CodeAnalysis.Test.Utilities +'Imports Microsoft.VisualStudio.GraphModel +'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression + +'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression +' Friend Class ProgressionTestState +' Implements IDisposable + +' Public ReadOnly Workspace As EditorTestWorkspace + +' Public Sub New(workspace As EditorTestWorkspace) +' Me.Workspace = workspace +' End Sub + +' Public Shared Function Create(workspaceXml As XElement) As ProgressionTestState +' Dim workspace = EditorTestWorkspace.Create(workspaceXml, composition:=VisualStudioTestCompositions.LanguageServices) + +' Return New ProgressionTestState(workspace) +' End Function + +' Public Function GetGraphWithDocumentNode(filePath As String) As Graph +' Dim graphBuilder As New GraphBuilder() +' Dim documentId = Workspace.Documents.Single(Function(d) d.FilePath = filePath).Id +' Assert.NotNull(graphBuilder.TryAddNodeForDocument(Workspace.CurrentSolution.GetDocument(documentId), CancellationToken.None)) +' Return graphBuilder.Graph +' End Function + +' 'Public Async Function GetGraphWithMarkedSymbolNodeAsync(Optional symbolTransform As Func(Of ISymbol, ISymbol) = Nothing) As Task(Of Graph) +' ' Dim hostDocument As TestHostDocument = Workspace.Documents.Single(Function(d) d.CursorPosition.HasValue) +' ' Dim document = Workspace.CurrentSolution.GetDocument(hostDocument.Id) +' ' Dim symbol = Await GetMarkedSymbolAsync() + +' ' If symbolTransform IsNot Nothing Then +' ' symbol = symbolTransform(symbol) +' ' End If + +' ' Dim graphBuilder As New GraphBuilder(Workspace.CurrentSolution) +' ' Await graphBuilder.AddNodeAsync(symbol, document.Project, document, CancellationToken.None) +' ' Return graphBuilder.Graph +' 'End Function + +' Public Async Function GetGraphContextAfterQuery(graph As Graph, graphQuery As IGraphQuery, direction As GraphContextDirection) As Task(Of IGraphContext) +' Dim graphContext As New MockGraphContext(direction, graph.Copy(), graph.Nodes) +' Dim graphBuilder = Await graphQuery.GetGraphAsync(Workspace.CurrentSolution, graphContext, CancellationToken.None) +' graphBuilder.ApplyToGraph(graphContext.Graph, CancellationToken.None) + +' Return graphContext +' End Function + +' Public Async Function GetGraphContextAfterQueryWithSolution(graph As Graph, solution As Solution, graphQuery As IGraphQuery, direction As GraphContextDirection) As Task(Of IGraphContext) +' Dim graphContext As New MockGraphContext(direction, graph.Copy(), graph.Nodes) +' Dim graphBuilder = Await graphQuery.GetGraphAsync(solution, graphContext, CancellationToken.None) +' graphBuilder.ApplyToGraph(graphContext.Graph, CancellationToken.None) + +' Return graphContext +' End Function + +' Private Sub Dispose() Implements IDisposable.Dispose +' Workspace.Dispose() +' End Sub + +' 'Public Async Function AssertMarkedSymbolLabelIsAsync(graphCommandId As String, label As String, description As String) As Task +' ' Dim graphNode = (Await GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() +' ' Dim formattedLabelExtension As New GraphFormattedLabelExtension() + +' ' Assert.Equal(label, formattedLabelExtension.Label(graphNode, graphCommandId)) +' ' Assert.Equal(description, formattedLabelExtension.Description(graphNode, graphCommandId)) +' 'End Function + +' Public Function GetMarkedSymbolAsync() As Task(Of ISymbol) +' Dim hostDocument As TestHostDocument = Workspace.Documents.Single(Function(d) d.CursorPosition.HasValue) +' Dim document = Workspace.CurrentSolution.GetDocument(hostDocument.Id) +' Return SymbolFinder.FindSymbolAtPositionAsync(document, hostDocument.CursorPosition.Value) +' End Function + +' Public Function GetSolution() As Solution +' Return Workspace.CurrentSolution +' End Function +' End Class +'End Namespace From 1bbde8f245d5c5b86d33c45568f1191c21dc81e1 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 15:14:19 +0200 Subject: [PATCH 103/353] Delete old code --- .../Progression/CSharpSymbolLabelTests.vb | 195 ----- .../Test/Progression/CallsGraphQueryTests.vb | 235 ----- .../ContainsChildrenGraphQueryTests.vb | 162 ---- .../Progression/ContainsGraphQueryTests.vb | 392 --------- .../Progression/GraphNodeCreationTests.vb | 811 ------------------ .../Core/Test/Progression/GraphNodeIdTests.vb | 133 --- .../Test/Progression/GraphProviderTests.vb | 37 - .../ImplementedByGraphQueryTests.vb | 73 -- .../Progression/ImplementsGraphQueryTests.vb | 87 -- .../Progression/InheritedByGraphQueryTests.vb | 238 ----- .../InheritsFromGraphQueryTests.vb | 119 --- .../Progression/IsCalledByGraphQueryTests.vb | 65 -- .../Progression/IsUsedByGraphQueryTests.vb | 59 -- .../Core/Test/Progression/MockGraphContext.vb | 121 --- .../OverriddenByGraphQueryTests.vb | 102 --- .../Progression/OverridesGraphQueryTests.vb | 102 --- .../Progression/ProgressionTestHelpers.vb | 47 - .../Test/Progression/ProgressionTestState.vb | 87 -- .../SearchGraphQueryTests_NavigateTo.vb | 409 --------- .../VisualBasicSymbolLabelTests.vb | 82 -- 20 files changed, 3556 deletions(-) delete mode 100644 src/VisualStudio/Core/Test/Progression/CSharpSymbolLabelTests.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/CallsGraphQueryTests.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/ContainsChildrenGraphQueryTests.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/ContainsGraphQueryTests.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/GraphNodeCreationTests.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/GraphNodeIdTests.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/GraphProviderTests.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/ImplementedByGraphQueryTests.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/ImplementsGraphQueryTests.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/InheritedByGraphQueryTests.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/InheritsFromGraphQueryTests.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/IsCalledByGraphQueryTests.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/IsUsedByGraphQueryTests.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/MockGraphContext.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/OverriddenByGraphQueryTests.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/OverridesGraphQueryTests.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/ProgressionTestHelpers.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/SearchGraphQueryTests_NavigateTo.vb delete mode 100644 src/VisualStudio/Core/Test/Progression/VisualBasicSymbolLabelTests.vb diff --git a/src/VisualStudio/Core/Test/Progression/CSharpSymbolLabelTests.vb b/src/VisualStudio/Core/Test/Progression/CSharpSymbolLabelTests.vb deleted file mode 100644 index d21f121fda6b0..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/CSharpSymbolLabelTests.vb +++ /dev/null @@ -1,195 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports System.Threading.Tasks -'Imports Microsoft.CodeAnalysis.Test.Utilities -'Imports Microsoft.VisualStudio.GraphModel -'Imports Roslyn.Test.Utilities - -'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression -' -' Public Class CSharpSymbolLabelTests -' -' Public Async Function TestNamedType() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class $$C { } -' -' -' ) - -' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "C", "C") -' End Using -' End Function - -' -' Public Async Function TestGenericNamedType() As Task -' Using testState = ProgressionTestState.Create( -' -' -' { } -' ]]> -' -' ) - -' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "C", "C") -' End Using -' End Function - -' -' Public Async Function TestGenericMethod() As Task -' Using testState = ProgressionTestState.Create( -' -' -' () { } } -' ]]> -' -' ) - -' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M() : void", "C.M() : void") -' End Using -' End Function - -' -' Public Async Function TestMethodWithParamsParameter() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class C { void $$M(params string[] goo) { } } -' -' -' ) - -' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M(params string[]) : void", "C.M(params string[]) : void") -' End Using -' End Function - -' -' Public Async Function TestMethodWithOptionalParameter() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class C { void $$M(int i = 0) { } } -' -' -' ) - -' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M([int]) : void", "C.M([int]) : void") -' End Using -' End Function - -' -' Public Async Function TestMethodWithRefAndOutParameters() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class C { void $$M(out string goo, ref string bar) { } } -' -' -' ) - -' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M(out string, ref string) : void", "C.M(out string, ref string) : void") -' End Using -' End Function - -' -' Public Async Function TestEnumMember() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' enum E { $$M } -' -' -' ) - -' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M", "E.M") -' End Using -' End Function - -' -' Public Async Function TestConstructor() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class C { $$C() { } } -' -' -' ) - -' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "C()", "C.C()") -' End Using -' End Function - -' -' Public Async Function TestDestructor() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class C { ~$$C() { } } -' -' -' ) - -' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "~C()", "C.~C()") -' End Using -' End Function - -' -' Public Async Function TestExplicitlyImplementedInterface() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' using System; -' class C : IDisposable { void IDisposable.$$Dispose() { } } -' -' -' ) - -' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "IDisposable.Dispose() : void", "C.Dispose() : void") -' End Using -' End Function - -' -' Public Async Function TestFixedFieldInStruct() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' struct C { fixed int $$f[42]; } -' -' -' ) - -' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "f : int*", "C.f : int*") -' End Using -' End Function - -' -' -' Public Async Function TestDelegateStyle() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' delegate void $$Goo(); -' -' -' ) - -' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "Goo() : void", "Goo : void") -' End Using -' End Function -' End Class -'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/CallsGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/CallsGraphQueryTests.vb deleted file mode 100644 index 05e4fc4e026d9..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/CallsGraphQueryTests.vb +++ /dev/null @@ -1,235 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports Microsoft.CodeAnalysis.Test.Utilities -'Imports Microsoft.VisualStudio.GraphModel -'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -'Imports Roslyn.Test.Utilities - -'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression -' -' Public Class CallsGraphQueryTests -' -' Public Async Function CallsSimpleTests() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class A -' { -' public A() { } -' public void Run() { } -' static void $$Main(string[] args) { new A().Run(); } -' } -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New CallsGraphQuery(), GraphContextDirection.Source) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function CallsLambdaTests() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -'using System; -'using System.Collections.Generic; -'using System.Linq; -'using System.Threading.Tasks; - -'class A -' { -' static void $$Goo(String[] args) -' { -' int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; -' int oddNumbers = numbers.Count(n => n % 2 == 1); -' } -' } -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New CallsGraphQuery(), GraphContextDirection.Source) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function CallsPropertiesTests() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class A -' { -' static public int Get() { return 1; } -' public int $$PropertyA = A.Get(); -' } -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New CallsGraphQuery(), GraphContextDirection.Source) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function CallsDelegatesTests() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -'using System; -'using System.Collections.Generic; -'using System.Linq; -'using System.Threading.Tasks; - -'delegate void MyDelegate1(int x, float y); - -'class C -'{ -' public void DelegatedMethod(int x, float y = 3.0f) { System.Console.WriteLine(y); } -' static void $$Main(string[] args) -' { -' C mc = new C(); -' MyDelegate1 md1 = null; -' md1 += mc.DelegatedMethod; -' md1(1, 5); -' md1 -= mc.DelegatedMethod; -' } -'} -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New CallsGraphQuery(), GraphContextDirection.Source) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function CallsDelegateCreationExpressionTests() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -'using System; -'using System.Collections.Generic; -'using System.Linq; -'using System.Threading.Tasks; - -'delegate void MyEvent(); - -'class Test -'{ -' event MyEvent Clicked; -' void Handler() { } - -' public void $$Run() -' { -' Test t = new Test(); -' t.Clicked += new MyEvent(Handler); -' } -'} -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New CallsGraphQuery(), GraphContextDirection.Source) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function -' End Class -'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/ContainsChildrenGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/ContainsChildrenGraphQueryTests.vb deleted file mode 100644 index a1ec582316309..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/ContainsChildrenGraphQueryTests.vb +++ /dev/null @@ -1,162 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports System.Threading.Tasks -'Imports Microsoft.CodeAnalysis.Test.Utilities -'Imports Microsoft.VisualStudio.GraphModel -'Imports Microsoft.VisualStudio.GraphModel.Schemas -'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -'Imports Roslyn.Test.Utilities - -'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression -' -' Public Class ContainsChildrenGraphQueryTests -' -' Public Async Function ContainsChildrenForDocument() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class C { } -' -' -' ) - -' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsChildrenGraphQuery(), GraphContextDirection.Self) - -' Dim node = outputContext.Graph.Nodes.Single() - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function ContainsChildrenForEmptyDocument() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' -' -' ) - -' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsChildrenGraphQuery(), GraphContextDirection.Self) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' -' Public Async Function ContainsChildrenForFileWithIllegalPath() As Task -' Using testState = ProgressionTestState.Create() -' Dim graph = New Graph -' graph.Nodes.GetOrCreate( -' GraphNodeId.GetNested(GraphNodeId.GetPartial(CodeGraphNodeIdName.File, New Uri("C:\path\to\""some folder\App.config""", UriKind.RelativeOrAbsolute))), -' label:=String.Empty, -' CodeNodeCategories.File) - -' ' Just making sure it doesn't throw. -' Dim outputContext = Await testState.GetGraphContextAfterQuery(graph, New ContainsChildrenGraphQuery(), GraphContextDirection.Self) -' End Using -' End Function - -' -' -' Public Async Function ContainsChildrenForNotYetLoadedSolution() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class C { } -' -' -' ) - -' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") - -' ' To simulate the situation where a solution is not yet loaded and project info is not available, -' ' remove a project from the solution. - -' Dim oldSolution = testState.GetSolution() -' Dim newSolution = oldSolution.RemoveProject(oldSolution.ProjectIds.FirstOrDefault()) -' Dim outputContext = Await testState.GetGraphContextAfterQueryWithSolution(inputGraph, newSolution, New ContainsChildrenGraphQuery(), GraphContextDirection.Self) - -' ' ContainsChildren should be set to false, so following updates will be tractable. - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' ) - -' End Using -' End Function - -' -' Public Async Function ContainsChildrenForNodeWithRelativeUriPath() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' Class C -' End Class -' -' -' ) - -' ' Force creation of a graph node that has a nested relative URI file path. This simulates nodes that -' ' other project types can give us for non-code files. E.g., `favicon.ico` for web projects. -' Dim nodeId = GraphNodeId.GetNested(GraphNodeId.GetPartial(CodeGraphNodeIdName.File, New Uri("/Z:/Project.vb", UriKind.Relative))) -' Dim inputGraph = New Graph() -' Dim node = inputGraph.Nodes.GetOrCreate(nodeId) -' node.AddCategory(CodeNodeCategories.File) - -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsChildrenGraphQuery(), GraphContextDirection.Any) -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function -' End Class -'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/ContainsGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/ContainsGraphQueryTests.vb deleted file mode 100644 index 13d5f9cc96cc3..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/ContainsGraphQueryTests.vb +++ /dev/null @@ -1,392 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports System.Threading.Tasks -'Imports Microsoft.CodeAnalysis.Test.Utilities -'Imports Microsoft.VisualStudio.GraphModel -'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -'Imports Roslyn.Test.Utilities - -'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression -' -' Public Class ContainsGraphQueryTests -' -' Public Async Function TypesContainedInCSharpDocument() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class C { } -' enum E { } -' interface I { } -' struct S { } -' record R1 { } -' record R2; -' record class R3; -' record struct R4 { } -' -' -' ) - -' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TypesContainedInCSharpDocumentInsideNamespace() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' namespace N.M -' { -' class C { } -' enum E { } -' interface I { } -' struct S { } -' } -' -' -' ) - -' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TypesContainedInVisualBasicDocument() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' Class C -' End Class - -' Enum E -' End Enum - -' Interface I -' End Interface - -' Module M -' End Module - -' Structure S -' End Structure -' -' -' ) - -' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.vb") -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function MembersContainedInCSharpScriptDocument() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' -' int F; -' int P { get; set; } -' void M() -' { -' } -' -' -' ) - -' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.csx") -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains).ConfigureAwait(False) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function MembersContainedInClass() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class $$C { void M(); event System.EventHandler E; } -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function NestedTypesContainedInClass() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class C { class $$D { class E { } } } -' -' -' ) - -' Dim inputGraph = await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function EnumMembersInEnum() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' enum $$E { M } -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function NothingInBrokenCode() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' [(delegate static -' -' -' ) - -' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function NothingInBrokenCode2() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' int this[] { get { int x; } } -' -' -' ) - -' Dim inputGraph = testState.GetGraphWithDocumentNode(filePath:="Z:\Project.cs") -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function NothingInBrokenCode3() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' Module $$Module1 -' Public Class -' End Module -' -' -' ) - -' Dim inputGraph = await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ContainsGraphQuery(), GraphContextDirection.Contains) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function -' End Class -'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/GraphNodeCreationTests.vb b/src/VisualStudio/Core/Test/Progression/GraphNodeCreationTests.vb deleted file mode 100644 index c990ed0d20858..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/GraphNodeCreationTests.vb +++ /dev/null @@ -1,811 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports System.Threading -'Imports System.Threading.Tasks -'Imports Microsoft.CodeAnalysis -'Imports Microsoft.CodeAnalysis.Test.Utilities -'Imports Microsoft.VisualStudio.GraphModel -'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -'Imports Microsoft.VisualStudio.LanguageServices.Progression -'Imports Roslyn.Test.Utilities - -'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression -' -' Public Class GraphNodeCreationTests -' Private Shared Async Function AssertCreatedNodeIsAsync(code As String, expectedId As String, xml As XElement, Optional language As String = "C#") As Task -' Using testState = ProgressionTestState.Create( -' -' CommonReferences="true" FilePath="Z:\Project.csproj"> -' -' <%= code %> -' -' -' ) -' Dim symbol = Await testState.GetMarkedSymbolAsync() -' Dim node = GraphNodeCreation.CreateNodeIdAsync(symbol, testState.GetSolution(), CancellationToken.None).Result -' Assert.Equal(expectedId, node.ToString()) - -' Dim graph = New Graph() -' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) -' AssertSimplifiedGraphIs(graph, xml) -' End Using -' End Function - -' -' Public Async Function TestSimpleType() As Task -' Await AssertCreatedNodeIsAsync("namespace N { class $$C { } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C)", -' -' -' -' -' -' -' -' -' ) -' End Function - -' -' Public Async Function TestNamespaceType() As Task -' Await AssertCreatedNodeIsAsync("namespace $$N { class C { } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N)", -' -' -' -' -' -' -' -' -' ) -' End Function - -' -' Public Async Function TestLongNamespaceType() As Task -' Await AssertCreatedNodeIsAsync("namespace N.$$N1.N11 { class C { } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N.N1)", -' -' -' -' -' -' -' -' -' ) -' End Function - -' -' Public Async Function TestSimpleParameterType() As Task -' Await AssertCreatedNodeIsAsync("namespace N { class C { void M(int $$x) { } } }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32)]) ParameterIdentifier=x)", -' -' -' -' -' -' -' -' -' -' ) -' End Function - -' -' Public Async Function TestDelegateType() As Task -' Await AssertCreatedNodeIsAsync("namespace N { delegate void D(string $$m); }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=D Member=(Name=Invoke OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=String)]) ParameterIdentifier=m)", -' -' -' -' -' -' -' -' -' -' ) -' End Function - -' -' Public Async Function TestLambdaParameterType() As Task -' Await AssertCreatedNodeIsAsync("namespace N { class C { void M(Func $$x) { } } }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/bin/CSharpAssembly1.dll Type=(Name=Func GenericParameterCount=2 GenericArguments=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32),(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32)]))]) ParameterIdentifier=x)", -' -' -' -' -' -' -' -' -' -' ) -' End Function - -' -' Public Async Function TestLocalType() As Task -' Await AssertCreatedNodeIsAsync("namespace N { class C { int M() { int $$y = 0; return y; } } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=M LocalVariable=y)", -' -' -' -' -' -' -' -' -' ) -' End Function - -' -' Public Async Function TestFirstLocalWithSameNameType() As Task -' Await AssertCreatedNodeIsAsync("namespace N { class C { int M() { { int $$y = 0; } { int y = 1;} } } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=M LocalVariable=y)", -' -' -' -' -' -' -' -' -' ) -' End Function - -' -' Public Async Function TestSecondLocalWithSameNameType() As Task -' Await AssertCreatedNodeIsAsync("namespace N { class C { int M() { { int y = 0; } { int $$y = 1;} } } }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=M LocalVariable=y LocalVariableIndex=1)", -' -' -' -' -' -' -' -' -' ) -' End Function - -' -' Public Async Function TestErrorType() As Task -' Await AssertCreatedNodeIsAsync( -' "Class $$C : Inherits D : End Class", -' "(Assembly=file:///Z:/bin/VisualBasicAssembly1.dll Type=C)", -' -' -' -' -' -' -' -' -' , -' LanguageNames.VisualBasic) -' End Function - -' -' Public Async Function TestSimpleMethodSymbolTest() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' -' ) - -' Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() -' Dim formattedLabelExtension As New GraphFormattedLabelExtension() -' Assert.Equal("Goo(string[]) : void", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) -' Assert.Equal("Goo", graphNode.Label) -' End Using -' End Function - -' -' Public Async Function TestReferenceParameterSymbolTest() As Task -' Await AssertCreatedNodeIsAsync("namespace N { class C { void $$Goo(ref int i) { i = i + 1; } } }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=Goo OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32 ParamKind=Ref)]))", -' -' -' -' -' -' -' -' -' -' ) -' End Function - -' -' Public Async Function TestReferenceOutParameterSymbolTest() As Task -' Await AssertCreatedNodeIsAsync("namespace N { class C { void $$Goo(out int i) { i = 1; } } }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=Goo OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32 ParamKind=Ref)]))", -' -' -' -' -' -' -' -' -' -' ) -' End Function - -' -' Public Async Function TestSimpleIndexerTest() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' -' ) - -' Dim symbol = Await testState.GetMarkedSymbolAsync() -' Dim graph = New Graph() -' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) -' AssertSimplifiedGraphIs(graph, -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestAttributedIndexerTest() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' -' ) - -' Dim symbol = Await testState.GetMarkedSymbolAsync() -' Dim graph = New Graph() -' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) -' AssertSimplifiedGraphIs(graph, -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestParameterWithConversionOperatorTest() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' -' ) - -' Dim symbol = Await testState.GetMarkedSymbolAsync() -' Dim graph = New Graph() -' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) -' AssertSimplifiedGraphIs(graph, -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestLocalVBVariableType() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' -' ) - -' Dim symbol = Await testState.GetMarkedSymbolAsync() -' Dim graph = New Graph() -' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) -' AssertSimplifiedGraphIs(graph, -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestLocalVBRangeTypeVariable() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' -' ) - -' Dim symbol = Await testState.GetMarkedSymbolAsync() -' Dim graph = New Graph() -' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) -' AssertSimplifiedGraphIs(graph, -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestLocalVBVariableWithinBlockType() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' -' ) - -' Dim symbol = Await testState.GetMarkedSymbolAsync() -' Dim graph = New Graph() -' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) -' AssertSimplifiedGraphIs(graph, -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestLocalVariableIndexTest() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' -' ) - -' Dim symbol = Await testState.GetMarkedSymbolAsync() -' Dim graph = New Graph() -' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) -' AssertSimplifiedGraphIs(graph, -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestGenericArgumentsTest() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' { -' public class MgtpTestInnerClass -' { -' public void MgtpTestMethod( -' T1 p1, -' T2[][,] p2, -' T3 p3, -' T4[][,] p4, -' T5 p5, -' MgtpTestOuterClass> p6) -' { -' } - -' public void MgtpTestMethod2( -' T1 p1, -' T2[][,] p2, -' T3 p3, -' T4[][,] p4, -' T5 p5, -' MgtpTestOuterClass> p6) -' { -' } -' } -' } -' } -' ]]> -' -' ) - -' Dim symbol = Await testState.GetMarkedSymbolAsync() -' Dim graph = New Graph() -' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) -' AssertSimplifiedGraphIs(graph, -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestGenericArgumentsTest2() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' { -' public class MgtpTestInnerClass -' { -' public void MgtpTestMethod( -' T1 p1, -' T2[][,] p2, -' T3 p3, -' T4[][,] p4, -' T5 p5, -' MgtpTestOuterClass> p6) -' { -' } - -' public void MgtpTestMethod2( -' T1 p1, -' T2[][,] p2, -' T3 p3, -' T4[][,] p4, -' T5 p5, -' MgtpTestOuterClass> p6) -' { -' } -' } -' } -' } -' ]]> -' -' ) - -' Dim symbol = Await testState.GetMarkedSymbolAsync() -' Dim graph = New Graph() -' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) -' AssertSimplifiedGraphIs(graph, -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestGenericCSharpMethodSymbolTest() As Task -' Using testState = ProgressionTestState.Create( -' -' -' { -' void $$Goo() {} -' } -' ]]> -' -' ) - -' Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() -' Dim formattedLabelExtension As New GraphFormattedLabelExtension() -' Assert.Equal("Goo() : void", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) -' Assert.Equal("Goo", graphNode.Label) -' End Using -' End Function - -' -' Public Async Function TestGenericCSharpTypeSymbolTest() As Task -' Using testState = ProgressionTestState.Create( -' -' -' { -' } -' ]]> -' -' ) - -' Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() -' Dim formattedLabelExtension As New GraphFormattedLabelExtension() -' Assert.Equal("C", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) -' Assert.Equal("C", graphNode.Label) - -' Dim symbol = Await testState.GetMarkedSymbolAsync() -' Dim graph = New Graph() -' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) -' AssertSimplifiedGraphIs(graph, -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestGenericCSharpMethodTypeSymbolTest() As Task -' Using testState = ProgressionTestState.Create( -' -' -' (T param); -' } -' ]]> -' -' ) - -' Dim symbol = Await testState.GetMarkedSymbolAsync() -' Dim graph = New Graph() -' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) -' AssertSimplifiedGraphIs(graph, -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestGenericVBMethodSymbolTest() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' Module Module1 -' Public Class Goo(Of T) -' Public Sub $$Goo(ByVal x As T) -' End Sub -' End Class -' End Module -' -' -' ) - -' Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() -' Dim formattedLabelExtension As New GraphFormattedLabelExtension() -' Assert.Equal("Goo(T)", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) -' Assert.Equal("Goo", graphNode.Label) -' End Using -' End Function - -' -' Public Async Function TestGenericVBTypeSymbolTest() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' Module Module1 -' Public Class $$Goo(Of T) -' End Class -' End Module -' -' -' ) - -' Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() -' Dim formattedLabelExtension As New GraphFormattedLabelExtension() -' Assert.Equal("Goo(Of T)", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) -' Assert.Equal("Goo(Of T)", graphNode.Label) - -' Dim symbol = Await testState.GetMarkedSymbolAsync() -' Dim graph = New Graph() -' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) -' AssertSimplifiedGraphIs(graph, -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestMultiGenericVBTypeSymbolTest() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' Module Module1 -' Public Class $$Goo(Of T, X) -' End Class -' End Module -' -' -' ) - -' Dim graphNode = (Await testState.GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() -' Dim formattedLabelExtension As New GraphFormattedLabelExtension() -' Assert.Equal("Goo(Of T, X)", formattedLabelExtension.Label(graphNode, GraphCommandDefinition.Contains.Id)) -' Assert.Equal("Goo(Of T, X)", graphNode.Label) - -' Dim symbol = Await testState.GetMarkedSymbolAsync() -' Dim graph = New Graph() -' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) -' AssertSimplifiedGraphIs(graph, -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestFilteringPropertiesTest() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -'Public Class TestEvents -' Public Custom Event CustomEvent As EventHandler(Of Object) -' AddHandler($$value As EventHandler(Of Object)) - -' End AddHandler - -' RemoveHandler(value As EventHandler(Of Object)) - -' End RemoveHandler - -' RaiseEvent(sender As Object, e As Object) - -' End RaiseEvent -' End Event -'End Class -' -' -' ) - -' Dim symbol = Await testState.GetMarkedSymbolAsync() -' Dim graph = New Graph() -' Await graph.CreateNodeAsync(symbol, testState.GetSolution(), CancellationToken.None) -' AssertSimplifiedGraphIs(graph, -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function -' End Class -'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/GraphNodeIdTests.vb b/src/VisualStudio/Core/Test/Progression/GraphNodeIdTests.vb deleted file mode 100644 index 0712a8f2c4747..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/GraphNodeIdTests.vb +++ /dev/null @@ -1,133 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports System.Threading.Tasks -'Imports Microsoft.CodeAnalysis -'Imports Microsoft.CodeAnalysis.Test.Utilities -'Imports Microsoft.VisualStudio.GraphModel -'Imports Roslyn.Test.Utilities - -'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression -' -' Public Class GraphNodeIdTests -' Private Shared Async Function AssertMarkedNodeIdIsAsync(code As String, expectedId As String, Optional language As String = "C#", Optional symbolTransform As Func(Of ISymbol, ISymbol) = Nothing) As Task -' Using testState = ProgressionTestState.Create( -' -' CommonReferences="true" FilePath="Z:\Project.csproj"> -' -' <%= code %> -' -' -' ) - -' Dim graph = await testState.GetGraphWithMarkedSymbolNodeAsync(symbolTransform) -' Dim node = graph.Nodes.Single() -' Assert.Equal(expectedId, node.Id.ToString()) -' End Using -' End Function - -' -' Public Async Function TestSimpleType() As Task -' Await AssertMarkedNodeIdIsAsync("namespace N { class $$C { } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C)") -' End Function - -' -' Public Async Function TestNestedType() As Task -' Await AssertMarkedNodeIdIsAsync("namespace N { class C { class $$E { } } }", "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=E ParentType=C))") -' End Function - -' -' Public Async Function TestMemberWithSimpleArrayType() As Task -' Await AssertMarkedNodeIdIsAsync( -' "namespace N { class C { void $$M(int[] p) { } } }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=(Name=Int32 ArrayRank=1 ParentType=Int32))]))") -' End Function - -' -' Public Async Function TestMemberWithNestedArrayType() As Task -' Await AssertMarkedNodeIdIsAsync( -' "namespace N { class C { void $$M(int[][,] p) { } } }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=(Name=Int32 ArrayRank=1 ParentType=(Name=Int32 ArrayRank=2 ParentType=Int32)))]))") -' End Function - -' -' Public Async Function TestMemberWithPointerType() As Task -' Await AssertMarkedNodeIdIsAsync( -' "namespace N { class C { struct S { } unsafe void $$M(S** p) { } } }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=S Indirection=2 ParentType=C))]))") -' End Function - -' -' Public Async Function TestMemberWithVoidPointerType() As Task -' Await AssertMarkedNodeIdIsAsync( -' "namespace N { class C { unsafe void $$M(void* p) { } } }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=(Name=Void Indirection=1))]))") -' End Function - -' -' Public Async Function TestMemberWithGenericTypeParameters() As Task -' Await AssertMarkedNodeIdIsAsync( -' "namespace N { class C { void $$M(T t, U u) { } } }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=C GenericParameterCount=1) Member=(Name=M GenericParameterCount=1 OverloadingParameters=[(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=C GenericParameterCount=1) ParameterIdentifier=0),(ParameterIdentifier=0)]))") -' End Function - -' -' Public Async Function TestMemberWithParameterTypeConstructedWithMemberTypeParameter() As Task -' Await AssertMarkedNodeIdIsAsync( -' "namespace N { class C { void $$M(T t, System.Func u) { } } }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M GenericParameterCount=1 OverloadingParameters=[(ParameterIdentifier=0),(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=(Name=Func GenericParameterCount=2 GenericArguments=[(ParameterIdentifier=0),(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32)]))]))") -' End Function - -' -' Public Async Function TestMemberWithArraysOfGenericTypeParameters() As Task -' Await AssertMarkedNodeIdIsAsync( -' "namespace N { class C { void $$M(T[] t, U[] u) { } } }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=C GenericParameterCount=1) Member=(Name=M GenericParameterCount=1 OverloadingParameters=[(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(ArrayRank=1 ParentType=(Type=(Name=C GenericParameterCount=1) ParameterIdentifier=0))),(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(ArrayRank=1 ParentType=(ParameterIdentifier=0)))]))") -' End Function - -' -' Public Async Function TestMemberWithArraysOfGenericTypeParameters2() As Task -' Await AssertMarkedNodeIdIsAsync( -' "namespace N { class C { void $$M(T[][,] t, U[][,] u) { } } }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(Name=C GenericParameterCount=1) Member=(Name=M GenericParameterCount=1 OverloadingParameters=[(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(ArrayRank=1 ParentType=(ArrayRank=2 ParentType=(Type=(Name=C GenericParameterCount=1) ParameterIdentifier=0)))),(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=(ArrayRank=1 ParentType=(ArrayRank=2 ParentType=(ParameterIdentifier=0))))]))") -' End Function - -' -' Public Async Function TestMemberWithGenericType() As Task -' Await AssertMarkedNodeIdIsAsync( -' "namespace N { class C { void $$M(System.Collections.Generic.List p) { } } }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System.Collections.Generic Type=(Name=List GenericParameterCount=1 GenericArguments=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System Type=Int32)]))]))") -' End Function - -' -' Public Async Function TestMemberWithDynamicType() As Task -' Await AssertMarkedNodeIdIsAsync( -' "namespace N { class C { void $$M(dynamic d) { } } }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Namespace=System Type=Object)]))") -' End Function - -' -' Public Async Function TestMemberWithGenericTypeOfDynamicType() As Task -' Await AssertMarkedNodeIdIsAsync( -' "namespace N { class C { void $$M(System.Collections.Generic.List p) { } } }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Assembly=file:///Z:/FxReferenceAssembliesUri Namespace=System.Collections.Generic Type=(Name=List GenericParameterCount=1 GenericArguments=[(Namespace=System Type=Object)]))]))") -' End Function - -' -' Public Async Function TestMemberWithArrayOfDynamicType() As Task -' Await AssertMarkedNodeIdIsAsync( -' "namespace N { class C { void $$M(dynamic[] d) { } } }", -' "(Assembly=file:///Z:/bin/CSharpAssembly1.dll Namespace=N Type=C Member=(Name=M OverloadingParameters=[(Namespace=System Type=(Name=Object ArrayRank=1 ParentType=Object))]))") -' End Function - -' -' Public Async Function TestErrorType() As Task -' Await AssertMarkedNodeIdIsAsync( -' "Class $$C : Inherits D : End Class", -' "Type=D", -' LanguageNames.VisualBasic, -' Function(s) DirectCast(s, INamedTypeSymbol).BaseType) -' End Function -' End Class -'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/GraphProviderTests.vb b/src/VisualStudio/Core/Test/Progression/GraphProviderTests.vb deleted file mode 100644 index 5808a9a42f02a..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/GraphProviderTests.vb +++ /dev/null @@ -1,37 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. - -Imports Microsoft.CodeAnalysis.Test.Utilities -Imports Microsoft.VisualStudio.GraphModel -Imports Microsoft.VisualStudio.GraphModel.Schemas -Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -Imports Moq -Imports Roslyn.Test.Utilities - -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - - Public Class GraphProviderTests - ' - 'Public Sub TestGetContainsGraphQueries() - ' Dim context = CreateGraphContext(GraphContextDirection.Contains, Array.Empty(Of GraphCategory)()) - ' Dim queries = RoslynGraphProvider.GetGraphQueries(context) - ' Assert.Equal(queries.Single().GetType(), GetType(ContainsGraphQuery)) - 'End Sub - - ' - 'Public Sub TestGetContainsGraphQueriesWithTarget() - ' Dim context = CreateGraphContext(GraphContextDirection.Target, {CodeLinkCategories.Contains}) - ' Dim queries = RoslynGraphProvider.GetGraphQueries(context) - ' Assert.Equal(queries.Single().GetType(), GetType(ContainsGraphQuery)) - 'End Sub - - Private Shared Function CreateGraphContext(direction As GraphContextDirection, linkCategories As IEnumerable(Of GraphCategory)) As IGraphContext - Dim context = New Mock(Of IGraphContext)(MockBehavior.Strict) - context.Setup(Function(x) x.Direction).Returns(direction) - context.Setup(Function(x) x.LinkCategories).Returns(linkCategories) - Return context.Object - End Function - End Class - -End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/ImplementedByGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/ImplementedByGraphQueryTests.vb deleted file mode 100644 index fed26fa953de4..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/ImplementedByGraphQueryTests.vb +++ /dev/null @@ -1,73 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports System.Threading.Tasks -'Imports Microsoft.CodeAnalysis.Test.Utilities -'Imports Microsoft.VisualStudio.GraphModel -'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -'Imports Roslyn.Test.Utilities - -'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - -' -' Public Class ImplementedByGraphQueryTests -' -' Public Async Function TestImplementedBy1() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -'using System; - -'interface $$IBlah { -'} - -'abstract class Base -'{ -' public abstract int CompareTo(object obj); -'} - -'class Goo : Base, IComparable, IBlah -'{ -' public override int CompareTo(object obj) -' { -' throw new NotImplementedException(); -' } -'} - -'class Goo2 : Base, IBlah -'{ -' public override int CompareTo(object obj) -' { -' throw new NotImplementedException(); -' } -'} -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ImplementedByGraphQuery(), GraphContextDirection.Target) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function -' End Class - -'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/ImplementsGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/ImplementsGraphQueryTests.vb deleted file mode 100644 index 4aa284d5cd6e6..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/ImplementsGraphQueryTests.vb +++ /dev/null @@ -1,87 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports System.Threading.Tasks -'Imports Microsoft.CodeAnalysis.Test.Utilities -'Imports Microsoft.VisualStudio.GraphModel -'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -'Imports Roslyn.Test.Utilities - -'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - -' -' Public Class ImplementsGraphQueryTests -' -' Public Async Function TestClassImplementsInterface1() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class $$C : System.IDisposable { } -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ImplementsGraphQuery(), GraphContextDirection.Target) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestMethodImplementsInterfaceMethod1() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -'using System; - -'class Goo : IComparable -'{ -' public int $$CompareTo(object obj) -' { -' throw new NotImplementedException(); -' } -'} -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New ImplementsGraphQuery(), GraphContextDirection.Target) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function -' End Class -'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/InheritedByGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/InheritedByGraphQueryTests.vb deleted file mode 100644 index 8556a02a0d1e4..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/InheritedByGraphQueryTests.vb +++ /dev/null @@ -1,238 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports System.Threading.Tasks -'Imports Microsoft.CodeAnalysis.Test.Utilities -'Imports Microsoft.VisualStudio.GraphModel -'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -'Imports Roslyn.Test.Utilities - -'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - -' -' Public Class InheritedByGraphQueryTests -' -' Public Async Function TestInheritedByClassesCSharp() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -'using System; - -'interface IBlah { -'} - -'abstract class $$Base -'{ -' public abstract int CompareTo(object obj); -'} - -'class Goo : Base, IComparable, IBlah -'{ -' public override int CompareTo(object obj) -' { -' throw new NotImplementedException(); -' } -'} - -'class Goo2 : Base, IBlah -'{ -' public override int CompareTo(object obj) -' { -' throw new NotImplementedException(); -' } -'} - -'class ReallyDerived : Goo // should not be shown as inherited by Base -'{ -'} -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritedByGraphQuery(), GraphContextDirection.Target) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestInheritedByInterfacesCSharp() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -'using System; - -'public interface $$I { } - -'public class C : I { } // should appear as being derived from (implementing) I - -'public class C2 : C { } // should not appear as being derived from (implementing) I - -'interface I2 : I, IComparable -'{ -' void M(); -'} - -'interface I3 : I2 // should not be shown as inherited by I -'{ -'} -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritedByGraphQuery(), GraphContextDirection.Target) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestInheritedByClassesVisualBasic() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -'Imports System - -'Interface IBlah -'End Interface - -'MustInherit Class $$Base -' Public MustOverride Function CompareTo(obj As Object) As Integer -'End Class - -'Class Goo -' Inherits Base -' Implements IComparable, IBlah -' Public Overrides Function CompareTo(obj As Object) As Integer Implements IComparable.CompareTo -' Throw New NotImplementedException() -' End Function -'End Class - -'Class Goo2 -' Inherits Base -' Implements IBlah -' Public Overrides Function CompareTo(obj As Object) As Integer -' Throw New NotImplementedException() -' End Function -'End Class - -'Class ReallyDerived ' should not be shown as inherited by Base -' Inherits Goo -'End Class -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritedByGraphQuery(), GraphContextDirection.Target) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestInheritedByInterfacesVisualBasic() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -'Imports System - -'Public Interface $$I -'End Interface - -'Public Class C ' should appear as being derived from (implementing) I -' Implements I -'End Class - -'Public Class C2 ' should not appear as being derived from (implementing) I -' Inherits C -'End Class - -'Interface I2 -' Inherits I, IComparable -' Sub M() -'End Interface - -'Interface I3 ' should not be shown as inherited by I -' Inherits I2 -'End Interface -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritedByGraphQuery(), GraphContextDirection.Target) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function -' End Class - -'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/InheritsFromGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/InheritsFromGraphQueryTests.vb deleted file mode 100644 index 23b1a60e10826..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/InheritsFromGraphQueryTests.vb +++ /dev/null @@ -1,119 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports System.IO -'Imports System.Threading.Tasks -'Imports Microsoft.CodeAnalysis.LanguageServer -'Imports Microsoft.CodeAnalysis.Test.Utilities -'Imports Microsoft.VisualStudio.GraphModel -'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -'Imports Roslyn.Test.Utilities - -'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression -' -' Public Class InheritsGraphQueryTests -' -' Public Async Function BaseTypesOfSimpleType() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class $$C : System.IDisposable { } -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritsGraphQuery(), GraphContextDirection.Target) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestErrorBaseType() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class $$C : A { } -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritsGraphQuery(), GraphContextDirection.Target) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestSolutionWithMultipleProjects() As Task -' Using testState = ProgressionTestState.Create( -' -' -' public class A { } -' -' -' ProjectA -' public class B : A { } -' -' -' ProjectB -' public class C : B$$ { } -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New InheritsGraphQuery(), GraphContextDirection.Target) - -' Dim dirUri = ProtocolConversions.GetAbsoluteUriString(Path.Combine(TestWorkspace.RootDirectory, "bin")) & "/" - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' /> -' /> -' -' ) -' End Using -' End Function -' End Class -'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/IsCalledByGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/IsCalledByGraphQueryTests.vb deleted file mode 100644 index 5eeaf4ac6e5f2..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/IsCalledByGraphQueryTests.vb +++ /dev/null @@ -1,65 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports System.Threading.Tasks -'Imports Microsoft.CodeAnalysis.Test.Utilities -'Imports Microsoft.VisualStudio.GraphModel -'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -'Imports Roslyn.Test.Utilities - -'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression -' -' Public Class IsCalledByGraphQueryTests -' -' Public Async Function IsCalledBySimpleTests() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class A -' { -' public $$A() { } -' public virtual void Run() { } -' } - -' class B : A -' { -' public B() { } -' override public void Run() { var x = new A(); x.Run(); } -' } - -' class C -' { -' public C() { } -' public void Goo() -' { -' var x = new B(); -' x.Run(); -' } -' } -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New IsCalledByGraphQuery(), GraphContextDirection.Target) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function -' End Class -'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/IsUsedByGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/IsUsedByGraphQueryTests.vb deleted file mode 100644 index 4c5905393ade4..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/IsUsedByGraphQueryTests.vb +++ /dev/null @@ -1,59 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports System.Threading.Tasks -'Imports Microsoft.CodeAnalysis.Test.Utilities -'Imports Microsoft.VisualStudio.GraphModel -'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -'Imports Roslyn.Test.Utilities - -'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression -' -' Public Class IsUsedByGraphQueryTests -' -' Public Async Function IsUsedByTests() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' public class C { -' public int $$X; -' public int Y = X * X; -' public void M() { -' int x = 10; -' int y = x + X; -' } -' } -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New IsUsedByGraphQuery(), GraphContextDirection.Target) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function -' End Class -'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/MockGraphContext.vb b/src/VisualStudio/Core/Test/Progression/MockGraphContext.vb deleted file mode 100644 index a534cee5a3462..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/MockGraphContext.vb +++ /dev/null @@ -1,121 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. - -Imports System.Threading -Imports Microsoft.VisualStudio.GraphModel - -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - Friend Class MockGraphContext - Implements IGraphContext - - Private ReadOnly _direction As GraphContextDirection - Private ReadOnly _graph As Graph - Private ReadOnly _inputNodes As ISet(Of GraphNode) - Private ReadOnly _outputNodes As New HashSet(Of GraphNode) - - Public Sub New(direction As GraphContextDirection, graph As Graph, inputNodes As IEnumerable(Of GraphNode)) - _direction = direction - _graph = graph - _inputNodes = New HashSet(Of GraphNode)(inputNodes) - End Sub - - Public Event Canceled(sender As Object, e As EventArgs) Implements IGraphContext.Canceled - - Public ReadOnly Property CancelToken As CancellationToken Implements IGraphContext.CancelToken - Get - - End Get - End Property - - Public Event Completed(sender As Object, e As EventArgs) Implements IGraphContext.Completed - - Public ReadOnly Property Direction As GraphContextDirection Implements IGraphContext.Direction - Get - Return _direction - End Get - End Property - - Public ReadOnly Property Errors As IEnumerable(Of Exception) Implements IGraphContext.Errors - Get - Throw New NotImplementedException() - End Get - End Property - - Public Function GetValue(Of T)(name As String) As T Implements IGraphContext.GetValue - Return Nothing - End Function - - Public Property Graph As Graph Implements IGraphContext.Graph - Get - Return _graph - End Get - - Set(value As Graph) - Throw New NotImplementedException() - End Set - End Property - - Public Function HasValue(name As String) As Boolean Implements IGraphContext.HasValue - Return False - End Function - - Public ReadOnly Property InputNodes As ISet(Of GraphNode) Implements IGraphContext.InputNodes - Get - Return _inputNodes - End Get - End Property - - Public ReadOnly Property LinkCategories As IEnumerable(Of GraphCategory) Implements IGraphContext.LinkCategories - Get - Throw New NotImplementedException() - - End Get - End Property - - Public ReadOnly Property LinkDepth As Integer Implements IGraphContext.LinkDepth - Get - Return 1 - End Get - End Property - - Public ReadOnly Property NodeCategories As IEnumerable(Of GraphCategory) Implements IGraphContext.NodeCategories - Get - Throw New NotImplementedException() - End Get - End Property - - Public Sub OnCompleted() Implements IGraphContext.OnCompleted - End Sub - - Public ReadOnly Property OutputNodes As ISet(Of GraphNode) Implements IGraphContext.OutputNodes - Get - Return _outputNodes - End Get - End Property - - Public Sub ReportError(exception As Exception) Implements IGraphContext.ReportError - - End Sub - - Public Sub ReportProgress(current As Integer, maximum As Integer, message As String) Implements IGraphContext.ReportProgress - - End Sub - - Public ReadOnly Property RequestedProperties As IEnumerable(Of GraphProperty) Implements IGraphContext.RequestedProperties - Get - Throw New NotImplementedException() - End Get - End Property - - Public Sub SetValue(Of T)(name As String, value As T) Implements IGraphContext.SetValue - - End Sub - - Public ReadOnly Property TrackChanges As Boolean Implements IGraphContext.TrackChanges - Get - Return False - End Get - End Property - End Class -End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/OverriddenByGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/OverriddenByGraphQueryTests.vb deleted file mode 100644 index 5ea5259793f30..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/OverriddenByGraphQueryTests.vb +++ /dev/null @@ -1,102 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports System.Threading.Tasks -'Imports Microsoft.CodeAnalysis.Test.Utilities -'Imports Microsoft.VisualStudio.GraphModel -'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -'Imports Roslyn.Test.Utilities - -'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - -' -' Public Class OverriddenByGraphQueryTests -' -' Public Async Function TestOverriddenByMethod1() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -'using System; - -'abstract class Base -'{ -' public abstract int $$CompareTo(object obj); -'} - -'class Goo : Base, IComparable -'{ -' public override int CompareTo(object obj) -' { -' throw new NotImplementedException(); -' } -'} -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New OverriddenByGraphQuery(), GraphContextDirection.Target) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestOverriddenByMethod2() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -'using System; - -'abstract class Base -'{ -' public abstract int CompareTo(object obj); -'} - -'class Goo : Base, IComparable -'{ -' public override int $$CompareTo(object obj) -' { -' throw new NotImplementedException(); -' } -'} -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New OverriddenByGraphQuery(), GraphContextDirection.Target) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function -' End Class -'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/OverridesGraphQueryTests.vb b/src/VisualStudio/Core/Test/Progression/OverridesGraphQueryTests.vb deleted file mode 100644 index 2cde2c772d54c..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/OverridesGraphQueryTests.vb +++ /dev/null @@ -1,102 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports System.Threading.Tasks -'Imports Microsoft.CodeAnalysis.Test.Utilities -'Imports Microsoft.VisualStudio.GraphModel -'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -'Imports Roslyn.Test.Utilities - -'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - -' -' Public Class OverridesGraphQueryTests -' -' Public Async Function TestOverridesMethod1() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -'using System; - -'abstract class Base -'{ -' public abstract int $$CompareTo(object obj); -'} - -'class Goo : Base, IComparable -'{ -' public override int CompareTo(object obj) -' { -' throw new NotImplementedException(); -' } -'} -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New OverridesGraphQuery(), GraphContextDirection.Target) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function TestOverridesMethod2() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -'using System; - -'abstract class Base -'{ -' public abstract int CompareTo(object obj); -'} - -'class Goo : Base, IComparable -'{ -' public override int $$CompareTo(object obj) -' { -' throw new NotImplementedException(); -' } -'} -' -' -' ) - -' Dim inputGraph = Await testState.GetGraphWithMarkedSymbolNodeAsync() -' Dim outputContext = Await testState.GetGraphContextAfterQuery(inputGraph, New OverridesGraphQuery(), GraphContextDirection.Target) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function -' End Class -'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/ProgressionTestHelpers.vb b/src/VisualStudio/Core/Test/Progression/ProgressionTestHelpers.vb deleted file mode 100644 index 12947eb06eacc..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/ProgressionTestHelpers.vb +++ /dev/null @@ -1,47 +0,0 @@ -' Licensed to the .NET Foundation under one or more agreements. -' The .NET Foundation licenses this file to you under the MIT license. -' See the LICENSE file in the project root for more information. - -Imports System.Runtime.CompilerServices -Imports Microsoft.VisualStudio.GraphModel -Imports - -Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression - Friend Module ProgressionTestHelpers - - Public Function ToSimplifiedXDocument(graph As Graph) As XDocument - Dim document = XDocument.Parse(graph.ToXml(graphNodeIdAliasThreshold:=1000000)) - - document.Root..Remove() - document.Root..Remove() - document.Root..Remove() - - For Each node In document.Descendants(XName.Get("Node", "http://schemas.microsoft.com/vs/2009/dgml")) - Dim attribute = node.Attribute("SourceLocation") - If attribute IsNot Nothing Then - attribute.Remove() - End If - Next - - Return document - End Function - - Public Sub AssertSimplifiedGraphIs(graph As Graph, xml As XElement) - Dim graphXml = graph.ToSimplifiedXDocument() - If Not XNode.DeepEquals(graphXml.Root, xml) Then - ' They aren't equal, so therefore the text representations definitely aren't equal. - ' We'll Assert.Equal those, so that way xunit will show nice before/after text - 'Assert.Equal(xml.ToString(), graphXml.ToString()) - - ' In an attempt to diagnose some flaky tests, the whole contents of both objects will be output - Throw New Exception($"Graph XML was not equal, check for out-of-order elements. -Expected: -{xml.ToString()} - -Actual: -{graphXml.ToString()} -") - End If - End Sub - End Module -End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb b/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb deleted file mode 100644 index ee1161238d21c..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb +++ /dev/null @@ -1,87 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports System.Threading -'Imports Microsoft.CodeAnalysis -'Imports Microsoft.CodeAnalysis.FindSymbols -'Imports Microsoft.CodeAnalysis.Test.Utilities -'Imports Microsoft.VisualStudio.GraphModel -'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression - -'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression -' Friend Class ProgressionTestState -' Implements IDisposable - -' Public ReadOnly Workspace As EditorTestWorkspace - -' Public Sub New(workspace As EditorTestWorkspace) -' Me.Workspace = workspace -' End Sub - -' Public Shared Function Create(workspaceXml As XElement) As ProgressionTestState -' Dim workspace = EditorTestWorkspace.Create(workspaceXml, composition:=VisualStudioTestCompositions.LanguageServices) - -' Return New ProgressionTestState(workspace) -' End Function - -' Public Function GetGraphWithDocumentNode(filePath As String) As Graph -' Dim graphBuilder As New GraphBuilder() -' Dim documentId = Workspace.Documents.Single(Function(d) d.FilePath = filePath).Id -' Assert.NotNull(graphBuilder.TryAddNodeForDocument(Workspace.CurrentSolution.GetDocument(documentId), CancellationToken.None)) -' Return graphBuilder.Graph -' End Function - -' 'Public Async Function GetGraphWithMarkedSymbolNodeAsync(Optional symbolTransform As Func(Of ISymbol, ISymbol) = Nothing) As Task(Of Graph) -' ' Dim hostDocument As TestHostDocument = Workspace.Documents.Single(Function(d) d.CursorPosition.HasValue) -' ' Dim document = Workspace.CurrentSolution.GetDocument(hostDocument.Id) -' ' Dim symbol = Await GetMarkedSymbolAsync() - -' ' If symbolTransform IsNot Nothing Then -' ' symbol = symbolTransform(symbol) -' ' End If - -' ' Dim graphBuilder As New GraphBuilder(Workspace.CurrentSolution) -' ' Await graphBuilder.AddNodeAsync(symbol, document.Project, document, CancellationToken.None) -' ' Return graphBuilder.Graph -' 'End Function - -' Public Async Function GetGraphContextAfterQuery(graph As Graph, graphQuery As IGraphQuery, direction As GraphContextDirection) As Task(Of IGraphContext) -' Dim graphContext As New MockGraphContext(direction, graph.Copy(), graph.Nodes) -' Dim graphBuilder = Await graphQuery.GetGraphAsync(Workspace.CurrentSolution, graphContext, CancellationToken.None) -' graphBuilder.ApplyToGraph(graphContext.Graph, CancellationToken.None) - -' Return graphContext -' End Function - -' Public Async Function GetGraphContextAfterQueryWithSolution(graph As Graph, solution As Solution, graphQuery As IGraphQuery, direction As GraphContextDirection) As Task(Of IGraphContext) -' Dim graphContext As New MockGraphContext(direction, graph.Copy(), graph.Nodes) -' Dim graphBuilder = Await graphQuery.GetGraphAsync(solution, graphContext, CancellationToken.None) -' graphBuilder.ApplyToGraph(graphContext.Graph, CancellationToken.None) - -' Return graphContext -' End Function - -' Private Sub Dispose() Implements IDisposable.Dispose -' Workspace.Dispose() -' End Sub - -' 'Public Async Function AssertMarkedSymbolLabelIsAsync(graphCommandId As String, label As String, description As String) As Task -' ' Dim graphNode = (Await GetGraphWithMarkedSymbolNodeAsync()).Nodes.Single() -' ' Dim formattedLabelExtension As New GraphFormattedLabelExtension() - -' ' Assert.Equal(label, formattedLabelExtension.Label(graphNode, graphCommandId)) -' ' Assert.Equal(description, formattedLabelExtension.Description(graphNode, graphCommandId)) -' 'End Function - -' Public Function GetMarkedSymbolAsync() As Task(Of ISymbol) -' Dim hostDocument As TestHostDocument = Workspace.Documents.Single(Function(d) d.CursorPosition.HasValue) -' Dim document = Workspace.CurrentSolution.GetDocument(hostDocument.Id) -' Return SymbolFinder.FindSymbolAtPositionAsync(document, hostDocument.CursorPosition.Value) -' End Function - -' Public Function GetSolution() As Solution -' Return Workspace.CurrentSolution -' End Function -' End Class -'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/SearchGraphQueryTests_NavigateTo.vb b/src/VisualStudio/Core/Test/Progression/SearchGraphQueryTests_NavigateTo.vb deleted file mode 100644 index 3cdb232a37c9c..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/SearchGraphQueryTests_NavigateTo.vb +++ /dev/null @@ -1,409 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports System.Threading.Tasks -'Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities -'Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces -'Imports Microsoft.CodeAnalysis.NavigateTo -'Imports Microsoft.CodeAnalysis.Shared.TestHooks -'Imports Microsoft.CodeAnalysis.Test.Utilities -'Imports Microsoft.VisualStudio.GraphModel -'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression -'Imports Roslyn.Test.Utilities - -'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression -' -' Public Class SearchGraphQueryTests_NavigateTo -' -' Public Async Function SearchForType() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class C { } -' -' -' ) - -' Dim outputContext = Await testState.GetGraphContextAfterQuery( -' New Graph(), New SearchGraphQuery("C", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function SearchForNestedType() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class C { class F { } } -' -' -' ) - -' Dim outputContext = Await testState.GetGraphContextAfterQuery( -' New Graph(), New SearchGraphQuery("F", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function SearchForMember() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class C { void M(); } -' -' -' ) - -' Dim outputContext = Await testState.GetGraphContextAfterQuery( -' New Graph(), New SearchGraphQuery("M", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function SearchForPartialType() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -'Namespace N -' Partial Class C -' Sub Goo() -' End Sub -' End Class -'End Namespace -' -' -'Namespace N -' Partial Class C -' Sub Bar() -' End Sub -' End Class -'End Namespace -' -' -' ) - -' Dim outputContext = Await testState.GetGraphContextAfterQuery( -' New Graph(), New SearchGraphQuery("C", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function SearchForMethodInPartialType() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -'Namespace N -' Partial Class C -' Sub Goo() -' End Sub -' End Class -'End Namespace -' -' -'Namespace N -' Partial Class C -' Sub Bar() -' End Sub -' End Class -'End Namespace -' -' -' ) - -' Dim outputContext = Await testState.GetGraphContextAfterQuery( -' New Graph(), New SearchGraphQuery("Goo", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function SearchWithResultsAcrossMultipleTypeParts() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -'Namespace N -' Partial Class C -' Sub ZGoo() -' End Sub -' End Class -'End Namespace -' -' -'Namespace N -' Partial Class C -' Sub ZBar() -' End Sub -' End Class -'End Namespace -' -' -' ) - -' Dim outputContext = Await testState.GetGraphContextAfterQuery( -' New Graph(), New SearchGraphQuery("Z", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function SearchForDottedName1() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class Dog { void Bark() { } } -' -' -' ) - -' Dim outputContext = Await testState.GetGraphContextAfterQuery( -' New Graph(), New SearchGraphQuery("D.B", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function SearchForDottedName2() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' class Dog { void Bark() { } } -' -' -' ) - -' Dim outputContext = Await testState.GetGraphContextAfterQuery( -' New Graph(), New SearchGraphQuery("C.B", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function SearchForDottedName3() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' namespace Animal { class Dog<X> { void Bark() { } } } -' -' -' ) - -' Dim outputContext = Await testState.GetGraphContextAfterQuery( -' New Graph(), New SearchGraphQuery("D.B", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function SearchForDottedName4() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' namespace Animal { class Dog<X> { void Bark() { } } } -' -' -' ) - -' Dim outputContext = Await testState.GetGraphContextAfterQuery( -' New Graph(), New SearchGraphQuery("A.D.B", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' -' -' -' -' -' -' -' -' -' ) -' End Using -' End Function - -' -' Public Async Function SearchWithNullFilePathsOnProject() As Task -' Using testState = ProgressionTestState.Create( -' -' > -' -' namespace Animal { class Dog<X> { void Bark() { } } } -' -' -' ) - -' Dim outputContext = Await testState.GetGraphContextAfterQuery( -' New Graph(), New SearchGraphQuery("A.D.B", NavigateToDocumentSupport.AllDocuments), GraphContextDirection.Custom) - -' ' When searching, don't descend into projects with a null FilePath because they are artifacts and not -' ' representable in the Solution Explorer, e.g., Venus projects create sub-projects with a null file -' ' path for each .aspx file. Documents, on the other hand, are never allowed to have a null file path -' ' and as such are not tested here. The project/document structure for these scenarios would look -' ' similar to this: -' ' -' ' Project: SomeVenusProject, FilePath=C:\path\to\project.csproj -' ' + Document: SomeVenusDocument.aspx, FilePath=C:\path\to\SomeVenusDocument.aspx -' ' + Project: 1_SomeNamespace_SomeVenusDocument.aspx, FilePath=null <- the problem is here -' ' + Document: SomeVenusDocument.aspx.cs -' AssertSimplifiedGraphIs( -' outputContext.Graph, -' -' -' -' ) -' End Using -' End Function -' End Class -'End Namespace diff --git a/src/VisualStudio/Core/Test/Progression/VisualBasicSymbolLabelTests.vb b/src/VisualStudio/Core/Test/Progression/VisualBasicSymbolLabelTests.vb deleted file mode 100644 index cbf5a8af16882..0000000000000 --- a/src/VisualStudio/Core/Test/Progression/VisualBasicSymbolLabelTests.vb +++ /dev/null @@ -1,82 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports System.Threading.Tasks -'Imports Microsoft.CodeAnalysis.Test.Utilities -'Imports Microsoft.VisualStudio.GraphModel -'Imports Roslyn.Test.Utilities - -'Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression -' -' Public Class VisualBasicSymbolLabelTests -' -' Public Async Function TestMethodWithOptionalParameter() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' Class C -' Sub $$S(Optional i As Integer = 42) -' End Sub -' End Class -' -' -' ) - -' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "S([Integer])", "C.S([Integer])") -' End Using -' End Function - -' -' Public Async Function TestMethodWithByRefParameter() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' Class C -' Sub $$S(ByRef i As Integer) -' End Sub -' End Class -' -' -' ) - -' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "S(ByRef Integer)", "C.S(ByRef Integer)") -' End Using -' End Function - -' -' Public Async Function TestEnumMember() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' Enum E -' $$M -' End Enum -' -' -' ) - -' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "M", "E.M") -' End Using -' End Function - -' -' Public Async Function TestGenericType() As Task -' Using testState = ProgressionTestState.Create( -' -' -' -' Class $$C(Of T) -' End Class -' -' -' ) - -' Await testState.AssertMarkedSymbolLabelIsAsync(GraphCommandDefinition.Contains.Id, "C(Of T)", "C(Of T)") -' End Using -' End Function -' End Class -'End Namespace From 8314fe1fc44d4d8ea5f9a2efa4ab52c0be03f87a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 15:14:56 +0200 Subject: [PATCH 104/353] Delete old code --- .../VisualBasicProgressionLanguageService.vb | 95 ------------------- 1 file changed, 95 deletions(-) delete mode 100644 src/VisualStudio/VisualBasic/Impl/Progression/VisualBasicProgressionLanguageService.vb diff --git a/src/VisualStudio/VisualBasic/Impl/Progression/VisualBasicProgressionLanguageService.vb b/src/VisualStudio/VisualBasic/Impl/Progression/VisualBasicProgressionLanguageService.vb deleted file mode 100644 index 0b4391863868f..0000000000000 --- a/src/VisualStudio/VisualBasic/Impl/Progression/VisualBasicProgressionLanguageService.vb +++ /dev/null @@ -1,95 +0,0 @@ -'' Licensed to the .NET Foundation under one or more agreements. -'' The .NET Foundation licenses this file to you under the MIT license. -'' See the LICENSE file in the project root for more information. - -'Imports System.Composition -'Imports System.Threading -'Imports Microsoft.CodeAnalysis -'Imports Microsoft.CodeAnalysis.Host -'Imports Microsoft.CodeAnalysis.Host.Mef -'Imports Microsoft.CodeAnalysis.Shared.Extensions -'Imports Microsoft.CodeAnalysis.VisualBasic -'Imports Microsoft.VisualStudio.LanguageServices.Implementation.Progression - -'Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Progression -' -' Partial Friend Class VisualBasicProgressionLanguageService -' Implements IProgressionLanguageService - -' -' -' Public Sub New() -' End Sub - -' Public Function GetTopLevelNodesFromDocument(root As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of SyntaxNode) Implements IProgressionLanguageService.GetTopLevelNodesFromDocument -' ' TODO: Implement this lazily like in C#? -' Dim nodes = New Stack(Of SyntaxNode)() - -' Dim result = New List(Of SyntaxNode) - -' nodes.Push(root) - -' While nodes.Count > 0 -' cancellationToken.ThrowIfCancellationRequested() - -' Dim node = nodes.Pop() - -' If node.Kind = SyntaxKind.ClassBlock OrElse -' node.Kind = SyntaxKind.DelegateFunctionStatement OrElse -' node.Kind = SyntaxKind.DelegateSubStatement OrElse -' node.Kind = SyntaxKind.EnumBlock OrElse -' node.Kind = SyntaxKind.ModuleBlock OrElse -' node.Kind = SyntaxKind.InterfaceBlock OrElse -' node.Kind = SyntaxKind.StructureBlock OrElse -' node.Kind = SyntaxKind.FieldDeclaration OrElse -' node.Kind = SyntaxKind.SubBlock OrElse -' node.Kind = SyntaxKind.FunctionBlock OrElse -' node.Kind = SyntaxKind.PropertyBlock Then -' result.Add(node) -' Else -' For Each child In node.ChildNodes() -' nodes.Push(child) -' Next -' End If -' End While - -' Return result -' End Function - -' Private Shared ReadOnly s_descriptionFormat As SymbolDisplayFormat = New SymbolDisplayFormat( -' globalNamespaceStyle:=SymbolDisplayGlobalNamespaceStyle.OmittedAsContaining, -' typeQualificationStyle:=SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces, -' genericsOptions:=SymbolDisplayGenericsOptions.IncludeTypeParameters, -' memberOptions:=SymbolDisplayMemberOptions.IncludeParameters Or SymbolDisplayMemberOptions.IncludeContainingType, -' parameterOptions:=SymbolDisplayParameterOptions.IncludeType Or SymbolDisplayParameterOptions.IncludeParamsRefOut Or SymbolDisplayParameterOptions.IncludeOptionalBrackets, -' miscellaneousOptions:=SymbolDisplayMiscellaneousOptions.UseSpecialTypes) - -' Public Function GetDescriptionForSymbol(symbol As ISymbol, includeContainingSymbol As Boolean) As String Implements IProgressionLanguageService.GetDescriptionForSymbol -' Return GetSymbolText(symbol, False, s_descriptionFormat) -' End Function - -' Private Shared ReadOnly s_labelFormat As SymbolDisplayFormat = New SymbolDisplayFormat( -' genericsOptions:=SymbolDisplayGenericsOptions.IncludeTypeParameters, -' memberOptions:=SymbolDisplayMemberOptions.IncludeParameters Or SymbolDisplayMemberOptions.IncludeType, -' parameterOptions:=SymbolDisplayParameterOptions.IncludeType Or SymbolDisplayParameterOptions.IncludeParamsRefOut Or SymbolDisplayParameterOptions.IncludeOptionalBrackets, -' miscellaneousOptions:=SymbolDisplayMiscellaneousOptions.UseSpecialTypes) - -' Public Function GetLabelForSymbol(symbol As ISymbol, includeContainingSymbol As Boolean) As String Implements IProgressionLanguageService.GetLabelForSymbol -' Return GetSymbolText(symbol, includeContainingSymbol, s_labelFormat) -' End Function - -' Private Shared Function GetSymbolText(symbol As ISymbol, includeContainingSymbol As Boolean, displayFormat As SymbolDisplayFormat) As String -' If symbol.Kind = SymbolKind.Field AndAlso symbol.ContainingType.TypeKind = TypeKind.Enum Then -' displayFormat = displayFormat.RemoveMemberOptions(SymbolDisplayMemberOptions.IncludeType) -' End If - -' Dim label As String = symbol.ToDisplayString(displayFormat) - -' If includeContainingSymbol AndAlso symbol.ContainingSymbol IsNot Nothing Then -' label += " (" + symbol.ContainingSymbol.ToDisplayString(displayFormat) + ")" -' End If - -' Return label -' End Function -' End Class -'End Namespace From 5a5dc9cb0928fad101392cb3b7a9ff6a97457803 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 15:15:58 +0200 Subject: [PATCH 105/353] Update persistence version --- .../FindSymbols/Shared/AbstractSyntaxIndex_Persistence.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/Shared/AbstractSyntaxIndex_Persistence.cs b/src/Workspaces/Core/Portable/FindSymbols/Shared/AbstractSyntaxIndex_Persistence.cs index 3d1cbab0dc203..96cdb613307f7 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/Shared/AbstractSyntaxIndex_Persistence.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/Shared/AbstractSyntaxIndex_Persistence.cs @@ -23,7 +23,7 @@ internal abstract partial class AbstractSyntaxIndex /// that we will not try to read previously cached data from a prior version of roslyn with a different format and /// will instead regenerate all the indices with the new format. /// - private static readonly Checksum s_serializationFormatChecksum = CodeAnalysis.Checksum.Create("47"); + private static readonly Checksum s_serializationFormatChecksum = CodeAnalysis.Checksum.Create("49"); /// /// Cache of ParseOptions to a checksum for the contained From 20036bb8e82cc89735019d6966c58eccc6d90a63 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 15:18:13 +0200 Subject: [PATCH 106/353] Avoid boxing --- .../Extensions/StringBuilderExtensions.cs | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/StringBuilderExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/StringBuilderExtensions.cs index 64fc5186351a5..77885c2feee0e 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/StringBuilderExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/StringBuilderExtensions.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; using System.Collections.Immutable; using System.Text; @@ -18,15 +17,32 @@ public static string ToStringAndClear(this StringBuilder builder) return result; } - public static StringBuilder AppendJoinedValues(this StringBuilder builder, string separator, IEnumerable values, Action append) + public static StringBuilder AppendJoinedValues( + this StringBuilder builder, string separator, SyntaxList values, Action append) + where TNode : SyntaxNode + { + var first = true; + foreach (var value in values) + { + if (!first) + builder.Append(separator); + + first = false; + append(value, builder); + } + + return builder; + } + + public static StringBuilder AppendJoinedValues( + this StringBuilder builder, string separator, SeparatedSyntaxList values, Action append) + where TNode : SyntaxNode { var first = true; foreach (var value in values) { if (!first) - { builder.Append(separator); - } first = false; append(value, builder); @@ -41,9 +57,7 @@ public static StringBuilder AppendJoinedValues(this StringBuilder builder, st foreach (var value in values) { if (!first) - { builder.Append(separator); - } first = false; append(value, builder); From b904e2a1ee2b9b71597fe455873795a9985ba772 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 15:22:45 +0200 Subject: [PATCH 107/353] Fix c# arrays --- .../CSharpSolutionExplorerSymbolTreeItemProvider.cs | 11 ++++++++--- .../ISolutionExplorerSymbolTreeItemProvider.cs | 10 +++++----- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index 4aec8a7f9f14c..7a58e0553808f 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -402,9 +402,14 @@ private static void AppendType(TypeSyntax? type, StringBuilder builder) if (type is ArrayTypeSyntax arrayType) { AppendType(arrayType.ElementType, builder); - AppendCommaSeparatedList( - builder, "[", "]", arrayType.RankSpecifiers, - static (_, _) => { }, ","); + foreach (var rankSpecifier in arrayType.RankSpecifiers) + { + builder.Append('['); + AppendCommaSeparatedList( + builder, "", "", rankSpecifier.Sizes, + static (_, _) => { }, ","); + builder.Append(']'); + } } else if (type is PointerTypeSyntax pointerType) { diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs index a0cf80e800a75..317cc0f810cda 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/ISolutionExplorerSymbolTreeItemProvider.cs @@ -36,7 +36,7 @@ protected static void AppendCommaSeparatedList( string openBrace, string closeBrace, TArgumentList? argumentList, - Func> getArguments, + Func> getArguments, Action append, string separator = ", ") where TArgumentList : SyntaxNode @@ -48,14 +48,14 @@ protected static void AppendCommaSeparatedList( AppendCommaSeparatedList(builder, openBrace, closeBrace, getArguments(argumentList), append, separator); } - protected static void AppendCommaSeparatedList( + protected static void AppendCommaSeparatedList( StringBuilder builder, string openBrace, string closeBrace, - IEnumerable arguments, - Action append, + SeparatedSyntaxList arguments, + Action append, string separator = ", ") - where TArgument : SyntaxNode + where TNode : SyntaxNode { builder.Append(openBrace); builder.AppendJoinedValues(separator, arguments, append); From 68eb24bdad0f4f0bff19a4bd6bb7721694a157b3 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 15:24:40 +0200 Subject: [PATCH 108/353] Fix vb arrays --- .../VisualBasicSolutionExplorerSymbolTreeItemProvider.vb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb index d976094ff551c..d011f24009477 100644 --- a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb +++ b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb @@ -317,7 +317,11 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer Dim arrayType = TryCast(typeSyntax, ArrayTypeSyntax) If arrayType IsNot Nothing Then AppendType(arrayType.ElementType, builder) - builder.Append("()") + For Each rankSpecifier In arrayType.RankSpecifiers + builder.Append("("c) + builder.Append(","c, rankSpecifier.CommaTokens.Count) + builder.Append(")"c) + Next Return End If From 411e12c0c5757a60cb29d3e662198a8ea0b2c6b8 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 15:52:14 +0200 Subject: [PATCH 109/353] Add C# tests --- src/Compilers/Test/Core/Traits/Traits.cs | 1 + ...pSolutionExplorerSymbolTreeItemProvider.cs | 2 - ...tionExplorerSymbolTreeItemProviderTests.cs | 164 ++++++++++++++++++ .../SymbolTree/SymbolTreeItem.cs | 3 + 4 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs diff --git a/src/Compilers/Test/Core/Traits/Traits.cs b/src/Compilers/Test/Core/Traits/Traits.cs index b5003cb91f2ed..5df9376001ed4 100644 --- a/src/Compilers/Test/Core/Traits/Traits.cs +++ b/src/Compilers/Test/Core/Traits/Traits.cs @@ -315,6 +315,7 @@ public static class Features public const string SmartIndent = nameof(SmartIndent); public const string SmartTokenFormatting = nameof(SmartTokenFormatting); public const string Snippets = nameof(Snippets); + public const string SolutionExplorer = nameof(SolutionExplorer); public const string SourceGenerators = nameof(SourceGenerators); public const string SplitComment = nameof(SplitComment); public const string SplitStringLiteral = nameof(SplitStringLiteral); diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index 7a58e0553808f..6660be59b7dab 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -3,8 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; -using System.Collections.Immutable; using System.Composition; using System.Diagnostics; using System.Text; diff --git a/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs new file mode 100644 index 0000000000000..e2222ec1c9fcf --- /dev/null +++ b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs @@ -0,0 +1,164 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Test.Utilities; +using Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; +using Microsoft.VisualStudio.LanguageServices.UnitTests; +using Roslyn.Test.Utilities; +using Xunit; + +namespace Roslyn.VisualStudio.CSharp.UnitTests.SolutionExplorer; + +[UseExportProvider, Trait(Traits.Feature, Traits.Features.SolutionExplorer)] +public sealed class CSharpSolutionExplorerSymbolTreeItemProviderTests +{ + private static readonly TestComposition s_testComposition = VisualStudioTestCompositions.LanguageServices; + + private static async Task TestCompilationUnit( + string code, string expected) + { + using var workspace = TestWorkspace.CreateCSharp(code, composition: s_testComposition); + + var testDocument = workspace.Documents.Single(); + var document = workspace.CurrentSolution.Projects.Single().Documents.Single(); + var root = await document.GetRequiredSyntaxRootAsync(CancellationToken.None); + + var service = document.GetRequiredLanguageService(); + var items = service.GetItems(root, CancellationToken.None); + + var actual = string.Join("\r\n", items); + AssertEx.Equal(expected, actual); + + AssertEx.SequenceEqual( + testDocument.SelectedSpans, + items.Select(i => i.ItemSyntax.NavigationToken.Span)); + } + + [Fact] + public async Task TestEmptyFile() + { + await TestCompilationUnit("", ""); + } + + [Fact] + public async Task TestTopLevelClass() + { + await TestCompilationUnit(""" + class [|C|] + { + } + """, """ + Name=C Glyph=ClassPrivate HasItems=False + """); + } + + [Fact] + public async Task TestTwoTopLevelTypes() + { + await TestCompilationUnit(""" + class [|C|] + { + } + + class [|D|] + { + } + """, """ + Name=C Glyph=ClassPrivate HasItems=False + Name=D Glyph=ClassPrivate HasItems=False + """); + } + + [Fact] + public async Task TestDelegatesAndEnums() + { + await TestCompilationUnit(""" + delegate string [|D|](int x); + + enum [|E|] + { + } + """, """ + Name=D(int) : string Glyph=DelegateInternal HasItems=False + Name=E Glyph=EnumInternal HasItems=False + """); + } + + [Fact] + public async Task TestTypesInBlockNamespace() + { + await TestCompilationUnit(""" + namespace N + { + class [|C|] + { + } + + class [|D|] + { + } + } + """, """ + Name=C Glyph=ClassPrivate HasItems=False + Name=D Glyph=ClassPrivate HasItems=False + """); + } + + [Fact] + public async Task TestTypesInFileScopedNamespace() + { + await TestCompilationUnit(""" + namespace N; + + class [|C|] + { + } + + class [|D|] + { + } + """, """ + Name=C Glyph=ClassPrivate HasItems=False + Name=D Glyph=ClassPrivate HasItems=False + """); + } + + [Fact] + public async Task TestTypesAcrossNamespaces() + { + await TestCompilationUnit(""" + class [|C|] + { + } + + namespace N + { + class [|D|] + { + } + } + """, """ + Name=C Glyph=ClassPrivate HasItems=False + Name=D Glyph=ClassPrivate HasItems=False + """); + } + + [Theory, CombinatorialData] + public async Task TestTypePermutations( + [CombinatorialValues("Public", "Private", "Protected", "Internal")] string accessibility, + [CombinatorialValues("Record", "Class", "Interface", "Struct")] string type) + { + await TestCompilationUnit($$""" + {{accessibility.ToLowerInvariant()}} {{type.ToLowerInvariant()}} [|C|] + { + } + """, $$""" + Name=C Glyph={{type switch { "Record" => "Class", "Struct" => "Structure", _ => type }}}{{accessibility}} HasItems=False + """); + } +} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index 8f1c1c1416b26..7cb157b9034bf 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -37,6 +37,9 @@ public SymbolTreeItemData( : this(new(name, glyph, hasItems), new(declarationNode, navigationToken)) { } + + public override string ToString() + => $"Name={ItemKey.Name} Glyph={ItemKey.Glyph} HasItems={ItemKey.HasItems}"; } /// From b5dd97b8c252b44d721c8692077d0e70c18ea96e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 16:01:14 +0200 Subject: [PATCH 110/353] Fix accessibility --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 22 ++++----- ...tionExplorerSymbolTreeItemProviderTests.cs | 47 +++++++++++++++---- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index 6660be59b7dab..e4c628f880557 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -120,7 +120,7 @@ private static void AddIndexerDeclaration( nameBuilder.Append(" : "); AppendType(indexerDeclaration.Type, nameBuilder); - var accessibility = GetAccessibility(indexerDeclaration, indexerDeclaration.Modifiers); + var accessibility = GetAccessibility(indexerDeclaration.GetRequiredParent(), indexerDeclaration.Modifiers); var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Indexer, accessibility); items.Add(new( @@ -140,7 +140,7 @@ private static void AddEventDeclaration( nameBuilder.Append(" : "); AppendType(eventDeclaration.Type, nameBuilder); - var accessibility = GetAccessibility(eventDeclaration, eventDeclaration.Modifiers); + var accessibility = GetAccessibility(eventDeclaration.GetRequiredParent(), eventDeclaration.Modifiers); var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Event, accessibility); items.Add(new( @@ -158,7 +158,7 @@ private static void AddPropertyDeclaration( nameBuilder.Append(" : "); AppendType(propertyDeclaration.Type, nameBuilder); - var accessibility = GetAccessibility(propertyDeclaration, propertyDeclaration.Modifiers); + var accessibility = GetAccessibility(propertyDeclaration.GetRequiredParent(), propertyDeclaration.Modifiers); var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Property, accessibility); items.Add(new( @@ -181,7 +181,7 @@ private static void AddConstructorOrDestructorDeclaration( nameBuilder.Append(identifier.ValueText); AppendParameterList(nameBuilder, declaration.ParameterList); - var accessibility = GetAccessibility(declaration, declaration.Modifiers); + var accessibility = GetAccessibility(declaration.GetRequiredParent(), declaration.Modifiers); var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Constructor, accessibility); items.Add(new( @@ -203,7 +203,7 @@ private static void AddConversionOperatorDeclaration( AppendType(operatorDeclaration.Type, nameBuilder); AppendParameterList(nameBuilder, operatorDeclaration.ParameterList); - var accessibility = GetAccessibility(operatorDeclaration, operatorDeclaration.Modifiers); + var accessibility = GetAccessibility(operatorDeclaration.GetRequiredParent(), operatorDeclaration.Modifiers); var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Operator, accessibility); items.Add(new( @@ -225,7 +225,7 @@ private static void AddOperatorDeclaration( nameBuilder.Append(" : "); AppendType(operatorDeclaration.ReturnType, nameBuilder); - var accessibility = GetAccessibility(operatorDeclaration, operatorDeclaration.Modifiers); + var accessibility = GetAccessibility(operatorDeclaration.GetRequiredParent(), operatorDeclaration.Modifiers); var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Operator, accessibility); items.Add(new( @@ -247,7 +247,7 @@ private static void AddMethodDeclaration( nameBuilder.Append(" : "); AppendType(methodDeclaration.ReturnType, nameBuilder); - var accessibility = GetAccessibility(methodDeclaration, methodDeclaration.Modifiers); + var accessibility = GetAccessibility(methodDeclaration.GetRequiredParent(), methodDeclaration.Modifiers); var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Method, accessibility); items.Add(new( @@ -269,7 +269,7 @@ private static void AddFieldDeclaration( nameBuilder.Append(" : "); AppendType(fieldDeclaration.Declaration.Type, nameBuilder); - var accessibility = GetAccessibility(fieldDeclaration, fieldDeclaration.Modifiers); + var accessibility = GetAccessibility(fieldDeclaration.GetRequiredParent(), fieldDeclaration.Modifiers); var kind = fieldDeclaration is EventFieldDeclarationSyntax ? DeclaredSymbolInfoKind.Event : DeclaredSymbolInfoKind.Field; @@ -303,7 +303,7 @@ protected override void AddEnumDeclarationMembers( private static void AddEnumDeclaration(EnumDeclarationSyntax enumDeclaration, ArrayBuilder items) { var glyph = GlyphExtensions.GetGlyph( - DeclaredSymbolInfoKind.Enum, GetAccessibility(enumDeclaration, enumDeclaration.Modifiers)); + DeclaredSymbolInfoKind.Enum, GetAccessibility(enumDeclaration.GetRequiredParent(), enumDeclaration.Modifiers)); items.Add(new( enumDeclaration.Identifier.ValueText, @@ -343,7 +343,7 @@ private static void AddDelegateDeclaration( AppendType(delegateDeclaration.ReturnType, nameBuilder); var glyph = GlyphExtensions.GetGlyph( - DeclaredSymbolInfoKind.Delegate, GetAccessibility(delegateDeclaration, delegateDeclaration.Modifiers)); + DeclaredSymbolInfoKind.Delegate, GetAccessibility(delegateDeclaration.GetRequiredParent(), delegateDeclaration.Modifiers)); items.Add(new( nameBuilder.ToStringAndClear(), @@ -363,7 +363,7 @@ private static void AddTypeDeclaration( var glyph = GlyphExtensions.GetGlyph( GetDeclaredSymbolInfoKind(typeDeclaration), - GetAccessibility(typeDeclaration, typeDeclaration.Modifiers)); + GetAccessibility(typeDeclaration.GetRequiredParent(), typeDeclaration.Modifiers)); items.Add(new( nameBuilder.ToStringAndClear(), glyph, diff --git a/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs index e2222ec1c9fcf..ff6dbae4fee15 100644 --- a/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs +++ b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs @@ -53,7 +53,7 @@ class [|C|] { } """, """ - Name=C Glyph=ClassPrivate HasItems=False + Name=C Glyph=ClassInternal HasItems=False """); } @@ -69,8 +69,8 @@ class [|D|] { } """, """ - Name=C Glyph=ClassPrivate HasItems=False - Name=D Glyph=ClassPrivate HasItems=False + Name=C Glyph=ClassInternal HasItems=False + Name=D Glyph=ClassInternal HasItems=False """); } @@ -104,8 +104,8 @@ class [|D|] } } """, """ - Name=C Glyph=ClassPrivate HasItems=False - Name=D Glyph=ClassPrivate HasItems=False + Name=C Glyph=ClassInternal HasItems=False + Name=D Glyph=ClassInternal HasItems=False """); } @@ -123,8 +123,8 @@ class [|D|] { } """, """ - Name=C Glyph=ClassPrivate HasItems=False - Name=D Glyph=ClassPrivate HasItems=False + Name=C Glyph=ClassInternal HasItems=False + Name=D Glyph=ClassInternal HasItems=False """); } @@ -143,8 +143,8 @@ class [|D|] } } """, """ - Name=C Glyph=ClassPrivate HasItems=False - Name=D Glyph=ClassPrivate HasItems=False + Name=C Glyph=ClassInternal HasItems=False + Name=D Glyph=ClassInternal HasItems=False """); } @@ -161,4 +161,33 @@ await TestCompilationUnit($$""" Name=C Glyph={{type switch { "Record" => "Class", "Struct" => "Structure", _ => type }}}{{accessibility}} HasItems=False """); } + + [Theory, CombinatorialData] + public async Task TestTypeHasItems( + [CombinatorialValues("Record", "Class", "Interface", "Struct")] string type) + { + await TestCompilationUnit($$""" + {{type.ToLowerInvariant()}} [|C|] + { + int i; + } + """, $$""" + Name=C Glyph={{type switch { "Record" => "Class", "Struct" => "Structure", _ => type }}}Internal HasItems=True + """); + } + + [Fact] + public async Task TestEnumHasItems() + { + await TestCompilationUnit(""" + enum [|E|] + { + A, + B, + C + } + """, """ + Name=E Glyph=EnumInternal HasItems=True + """); + } } From 3882d54945d772841c2580ee44a81bfd8a219f4b Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 16:11:56 +0200 Subject: [PATCH 111/353] Add more tests --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 2 +- ...tionExplorerSymbolTreeItemProviderTests.cs | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index e4c628f880557..df894ad6a9e9c 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -442,7 +442,7 @@ private static void AppendType(TypeSyntax? type, StringBuilder builder) { builder.Append("delegate*"); AppendCommaSeparatedList( - builder, "(", ")", functionPointerType.ParameterList.Parameters, + builder, "<", ">", functionPointerType.ParameterList.Parameters, static (parameter, builder) => AppendType(parameter.Type, builder)); } else if (type is OmittedTypeArgumentSyntax) diff --git a/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs index ff6dbae4fee15..32ed438063d48 100644 --- a/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs +++ b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs @@ -190,4 +190,29 @@ enum [|E|] Name=E Glyph=EnumInternal HasItems=True """); } + + [Theory] + [InlineData("int", "int")] + [InlineData("int[]", "int[]")] + [InlineData("int[][]", "int[][]")] + [InlineData("int[,][,,]", "int[,][,,]")] + [InlineData("int*", "int*")] + [InlineData("int?", "int?")] + [InlineData("(int, string)", "(int, string)")] + [InlineData("(int a, string b)", "(int a, string b)")] + [InlineData("delegate*unmanaged[a]", "delegate*")] + [InlineData("A.B", "B")] + [InlineData("A::B", "B")] + [InlineData("A::B.C", "C")] + [InlineData("A", "A")] + [InlineData("A.B>", "B>")] + public async Task TestTypes( + string parameterType, string resultType) + { + await TestCompilationUnit($$""" + delegate void [|D|]({{parameterType}} x); + """, $$""" + Name=D({{resultType}}) : void Glyph=DelegateInternal HasItems=False + """); + } } From ca65013e71d48147121817ad63560498f93a50ce Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 16:46:57 +0200 Subject: [PATCH 112/353] Add tests --- ...tionExplorerSymbolTreeItemProviderTests.cs | 91 ++++++++++++++++++- 1 file changed, 89 insertions(+), 2 deletions(-) diff --git a/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs index 32ed438063d48..97e849d9ba595 100644 --- a/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs +++ b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs @@ -5,6 +5,8 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -19,8 +21,15 @@ public sealed class CSharpSolutionExplorerSymbolTreeItemProviderTests { private static readonly TestComposition s_testComposition = VisualStudioTestCompositions.LanguageServices; - private static async Task TestCompilationUnit( + + private static Task TestCompilationUnit( string code, string expected) + { + return TestNode(code, expected); + } + + private static async Task TestNode( + string code, string expected) where TNode : SyntaxNode { using var workspace = TestWorkspace.CreateCSharp(code, composition: s_testComposition); @@ -29,7 +38,9 @@ private static async Task TestCompilationUnit( var root = await document.GetRequiredSyntaxRootAsync(CancellationToken.None); var service = document.GetRequiredLanguageService(); - var items = service.GetItems(root, CancellationToken.None); + + var node = root.DescendantNodesAndSelf().OfType().First(); + var items = service.GetItems(node, CancellationToken.None); var actual = string.Join("\r\n", items); AssertEx.Equal(expected, actual); @@ -215,4 +226,80 @@ await TestCompilationUnit($$""" Name=D({{resultType}}) : void Glyph=DelegateInternal HasItems=False """); } + + [Fact] + public async Task TestGenericClass() + { + await TestCompilationUnit(""" + class [|C|] + { + } + """, """ + Name=C Glyph=ClassInternal HasItems=False + """); + } + + [Fact] + public async Task TestGenericDelegate() + { + await TestCompilationUnit(""" + delegate void [|D|]() + """, """ + Name=D() : void Glyph=DelegateInternal HasItems=False + """); + } + + [Fact] + public async Task TestEnumMembers() + { + await TestNode(""" + enum E + { + [|A|], [|B|], [|C|] + } + """, """ + Name=A Glyph=EnumMemberPublic HasItems=False + Name=B Glyph=EnumMemberPublic HasItems=False + Name=C Glyph=EnumMemberPublic HasItems=False + """); + } + + [Fact] + public async Task TestClassMembers() + { + await TestNode(""" + class C + { + private int [|a|], [|b|]; + public P [|Prop|] => default; + internal [|C|]() { } + ~[|C|]() { } + + protected R [|this|][string s] => default; + private event Action [|A|] { } + public event Action [|B|], [|C|]; + + void [|M|](int a) { } + public void IInterface.[|O|]() { } + + public static operator [|+|](C c1, int a) => default; + + internal static implicit operator [|int|](C c1) => default; + } + """, """ + Name=a : int Glyph=FieldPrivate HasItems=False + Name=b : int Glyph=FieldPrivate HasItems=False + Name=Prop : P Glyph=PropertyPublic HasItems=False + Name=C() Glyph=MethodInternal HasItems=False + Name=~C() Glyph=MethodPrivate HasItems=False + Name=this[string] : R Glyph=PropertyProtected HasItems=False + Name=A : Action Glyph=EventPrivate HasItems=False + Name=B : Action Glyph=EventPublic HasItems=False + Name=C : Action Glyph=EventPublic HasItems=False + Name=M(int) : void Glyph=MethodPrivate HasItems=False + Name=O() : void Glyph=MethodPublic HasItems=False + Name=operator +(C, int) : Glyph=OperatorPublic HasItems=False + Name=implicit operator int(C) Glyph=OperatorInternal HasItems=False + """); + } } From 33446805a16e44e175c9e20dbef429f17f94c901 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 16:58:17 +0200 Subject: [PATCH 113/353] .\.devcontainer\ --- ...pSolutionExplorerSymbolTreeItemProvider.cs | 7 +++- ...tionExplorerSymbolTreeItemProviderTests.cs | 39 ++++++++++++++++++- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs index df894ad6a9e9c..755abe6202178 100644 --- a/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs +++ b/src/VisualStudio/CSharp/Impl/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProvider.cs @@ -7,8 +7,10 @@ using System.Diagnostics; using System.Text; using System.Threading; +using ICSharpCode.Decompiler.TypeSystem; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.Host.Mef; @@ -248,7 +250,10 @@ private static void AddMethodDeclaration( AppendType(methodDeclaration.ReturnType, nameBuilder); var accessibility = GetAccessibility(methodDeclaration.GetRequiredParent(), methodDeclaration.Modifiers); - var glyph = GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Method, accessibility); + var isExtension = methodDeclaration.IsParentKind(SyntaxKind.ExtensionBlockDeclaration) || + (methodDeclaration.ParameterList is { Parameters: [var parameter, ..] } && parameter.Modifiers.Any(SyntaxKind.ThisKeyword)); + var glyph = GlyphExtensions.GetGlyph( + isExtension ? DeclaredSymbolInfoKind.ExtensionMethod : DeclaredSymbolInfoKind.Method, accessibility); items.Add(new( nameBuilder.ToStringAndClear(), diff --git a/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs index 97e849d9ba595..c80eced748dc5 100644 --- a/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs +++ b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs @@ -6,6 +6,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; @@ -21,7 +22,6 @@ public sealed class CSharpSolutionExplorerSymbolTreeItemProviderTests { private static readonly TestComposition s_testComposition = VisualStudioTestCompositions.LanguageServices; - private static Task TestCompilationUnit( string code, string expected) { @@ -31,7 +31,8 @@ private static Task TestCompilationUnit( private static async Task TestNode( string code, string expected) where TNode : SyntaxNode { - using var workspace = TestWorkspace.CreateCSharp(code, composition: s_testComposition); + using var workspace = TestWorkspace.CreateCSharp + (code, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview), composition: s_testComposition); var testDocument = workspace.Documents.Single(); var document = workspace.CurrentSolution.Projects.Single().Documents.Single(); @@ -302,4 +303,38 @@ private event Action [|A|] { } Name=implicit operator int(C) Glyph=OperatorInternal HasItems=False """); } + + [Fact] + public async Task TestExtension1() + { + await TestNode(""" + static class C + { + [|extension|](int i) + { + } + + public static void [|M|](this int i) {} + } + """, """ + Name=extension(int) Glyph=ClassPublic HasItems=False + Name=M(int) : void Glyph=ExtensionMethodPublic HasItems=False + """); + } + + [Fact] + public async Task TestExtension2() + { + await TestNode(""" + static class C + { + extension(int i) + { + public void [|M|]() { } + } + } + """, """ + Name=M() : void Glyph=ExtensionMethodPublic HasItems=False + """); + } } From b2cd55ce775c5d6c41585f3598a37864a43a0a77 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 17:00:26 +0200 Subject: [PATCH 114/353] Add quotes --- ...tionExplorerSymbolTreeItemProviderTests.cs | 72 +++++++++---------- .../SymbolTree/SymbolTreeItem.cs | 2 +- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs index c80eced748dc5..ff9cae7151315 100644 --- a/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs +++ b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs @@ -65,7 +65,7 @@ class [|C|] { } """, """ - Name=C Glyph=ClassInternal HasItems=False + Name="C" Glyph=ClassInternal HasItems=False """); } @@ -81,8 +81,8 @@ class [|D|] { } """, """ - Name=C Glyph=ClassInternal HasItems=False - Name=D Glyph=ClassInternal HasItems=False + Name="C" Glyph=ClassInternal HasItems=False + Name="D" Glyph=ClassInternal HasItems=False """); } @@ -96,8 +96,8 @@ enum [|E|] { } """, """ - Name=D(int) : string Glyph=DelegateInternal HasItems=False - Name=E Glyph=EnumInternal HasItems=False + Name="D(int) : string" Glyph=DelegateInternal HasItems=False + Name="E" Glyph=EnumInternal HasItems=False """); } @@ -116,8 +116,8 @@ class [|D|] } } """, """ - Name=C Glyph=ClassInternal HasItems=False - Name=D Glyph=ClassInternal HasItems=False + Name="C" Glyph=ClassInternal HasItems=False + Name="D" Glyph=ClassInternal HasItems=False """); } @@ -135,8 +135,8 @@ class [|D|] { } """, """ - Name=C Glyph=ClassInternal HasItems=False - Name=D Glyph=ClassInternal HasItems=False + Name="C" Glyph=ClassInternal HasItems=False + Name="D" Glyph=ClassInternal HasItems=False """); } @@ -155,8 +155,8 @@ class [|D|] } } """, """ - Name=C Glyph=ClassInternal HasItems=False - Name=D Glyph=ClassInternal HasItems=False + Name="C" Glyph=ClassInternal HasItems=False + Name="D" Glyph=ClassInternal HasItems=False """); } @@ -170,7 +170,7 @@ await TestCompilationUnit($$""" { } """, $$""" - Name=C Glyph={{type switch { "Record" => "Class", "Struct" => "Structure", _ => type }}}{{accessibility}} HasItems=False + Name="C" Glyph={{type switch { "Record" => "Class", "Struct" => "Structure", _ => type }}}{{accessibility}} HasItems=False """); } @@ -184,7 +184,7 @@ await TestCompilationUnit($$""" int i; } """, $$""" - Name=C Glyph={{type switch { "Record" => "Class", "Struct" => "Structure", _ => type }}}Internal HasItems=True + Name="C" Glyph={{type switch { "Record" => "Class", "Struct" => "Structure", _ => type }}}Internal HasItems=True """); } @@ -199,7 +199,7 @@ enum [|E|] C } """, """ - Name=E Glyph=EnumInternal HasItems=True + Name="E" Glyph=EnumInternal HasItems=True """); } @@ -224,7 +224,7 @@ public async Task TestTypes( await TestCompilationUnit($$""" delegate void [|D|]({{parameterType}} x); """, $$""" - Name=D({{resultType}}) : void Glyph=DelegateInternal HasItems=False + Name="D({{resultType}}) : void" Glyph=DelegateInternal HasItems=False """); } @@ -236,7 +236,7 @@ class [|C|] { } """, """ - Name=C Glyph=ClassInternal HasItems=False + Name="C" Glyph=ClassInternal HasItems=False """); } @@ -246,7 +246,7 @@ public async Task TestGenericDelegate() await TestCompilationUnit(""" delegate void [|D|]() """, """ - Name=D() : void Glyph=DelegateInternal HasItems=False + Name="D() : void" Glyph=DelegateInternal HasItems=False """); } @@ -259,9 +259,9 @@ enum E [|A|], [|B|], [|C|] } """, """ - Name=A Glyph=EnumMemberPublic HasItems=False - Name=B Glyph=EnumMemberPublic HasItems=False - Name=C Glyph=EnumMemberPublic HasItems=False + Name="A" Glyph=EnumMemberPublic HasItems=False + Name="B" Glyph=EnumMemberPublic HasItems=False + Name="C" Glyph=EnumMemberPublic HasItems=False """); } @@ -288,19 +288,19 @@ private event Action [|A|] { } internal static implicit operator [|int|](C c1) => default; } """, """ - Name=a : int Glyph=FieldPrivate HasItems=False - Name=b : int Glyph=FieldPrivate HasItems=False - Name=Prop : P Glyph=PropertyPublic HasItems=False - Name=C() Glyph=MethodInternal HasItems=False - Name=~C() Glyph=MethodPrivate HasItems=False - Name=this[string] : R Glyph=PropertyProtected HasItems=False - Name=A : Action Glyph=EventPrivate HasItems=False - Name=B : Action Glyph=EventPublic HasItems=False - Name=C : Action Glyph=EventPublic HasItems=False - Name=M(int) : void Glyph=MethodPrivate HasItems=False - Name=O() : void Glyph=MethodPublic HasItems=False - Name=operator +(C, int) : Glyph=OperatorPublic HasItems=False - Name=implicit operator int(C) Glyph=OperatorInternal HasItems=False + Name="a : int" Glyph=FieldPrivate HasItems=False + Name="b : int" Glyph=FieldPrivate HasItems=False + Name="Prop : P" Glyph=PropertyPublic HasItems=False + Name="C()" Glyph=MethodInternal HasItems=False + Name="~C()" Glyph=MethodPrivate HasItems=False + Name="this[string] : R" Glyph=PropertyProtected HasItems=False + Name="A : Action" Glyph=EventPrivate HasItems=False + Name="B : Action" Glyph=EventPublic HasItems=False + Name="C : Action" Glyph=EventPublic HasItems=False + Name="M(int) : void" Glyph=MethodPrivate HasItems=False + Name="O() : void" Glyph=MethodPublic HasItems=False + Name="operator +(C, int) : " Glyph=OperatorPublic HasItems=False + Name="implicit operator int(C)" Glyph=OperatorInternal HasItems=False """); } @@ -317,8 +317,8 @@ static class C public static void [|M|](this int i) {} } """, """ - Name=extension(int) Glyph=ClassPublic HasItems=False - Name=M(int) : void Glyph=ExtensionMethodPublic HasItems=False + Name="extension(int)" Glyph=ClassPublic HasItems=False + Name="M(int) : void" Glyph=ExtensionMethodPublic HasItems=False """); } @@ -334,7 +334,7 @@ static class C } } """, """ - Name=M() : void Glyph=ExtensionMethodPublic HasItems=False + Name="M() : void" Glyph=ExtensionMethodPublic HasItems=False """); } } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index 7cb157b9034bf..8552ccfa7214f 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -39,7 +39,7 @@ public SymbolTreeItemData( } public override string ToString() - => $"Name={ItemKey.Name} Glyph={ItemKey.Glyph} HasItems={ItemKey.HasItems}"; + => $"""Name="{ItemKey.Name}" Glyph={ItemKey.Glyph} HasItems={ItemKey.HasItems}"""; } /// From 7c2d1c41f6e1c5b7ef3ae968b5cdaecad62492fe Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 17:07:44 +0200 Subject: [PATCH 115/353] Add common code for tests --- ...tionExplorerSymbolTreeItemProviderTests.cs | 37 ++++------------- ...tionExplorerSymbolTreeItemProviderTests.vb | 40 +++++++++++++++++++ 2 files changed, 48 insertions(+), 29 deletions(-) create mode 100644 src/VisualStudio/TestUtilities2/SolutionExplorer/AbstractSolutionExplorerSymbolTreeItemProviderTests.vb diff --git a/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs index ff9cae7151315..e184c774e9be1 100644 --- a/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs +++ b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs @@ -2,53 +2,32 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Linq; -using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; -using Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; using Microsoft.VisualStudio.LanguageServices.UnitTests; -using Roslyn.Test.Utilities; +using Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer; using Xunit; namespace Roslyn.VisualStudio.CSharp.UnitTests.SolutionExplorer; [UseExportProvider, Trait(Traits.Feature, Traits.Features.SolutionExplorer)] public sealed class CSharpSolutionExplorerSymbolTreeItemProviderTests + : AbstractSolutionExplorerSymbolTreeItemProviderTests { private static readonly TestComposition s_testComposition = VisualStudioTestCompositions.LanguageServices; - private static Task TestCompilationUnit( - string code, string expected) + protected override TestWorkspace CreateWorkspace(string code) { - return TestNode(code, expected); + return TestWorkspace.CreateCSharp( + code, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview), composition: s_testComposition); } - private static async Task TestNode( - string code, string expected) where TNode : SyntaxNode + private Task TestCompilationUnit( + string code, string expected) { - using var workspace = TestWorkspace.CreateCSharp - (code, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview), composition: s_testComposition); - - var testDocument = workspace.Documents.Single(); - var document = workspace.CurrentSolution.Projects.Single().Documents.Single(); - var root = await document.GetRequiredSyntaxRootAsync(CancellationToken.None); - - var service = document.GetRequiredLanguageService(); - - var node = root.DescendantNodesAndSelf().OfType().First(); - var items = service.GetItems(node, CancellationToken.None); - - var actual = string.Join("\r\n", items); - AssertEx.Equal(expected, actual); - - AssertEx.SequenceEqual( - testDocument.SelectedSpans, - items.Select(i => i.ItemSyntax.NavigationToken.Span)); + return TestNode(code, expected); } [Fact] diff --git a/src/VisualStudio/TestUtilities2/SolutionExplorer/AbstractSolutionExplorerSymbolTreeItemProviderTests.vb b/src/VisualStudio/TestUtilities2/SolutionExplorer/AbstractSolutionExplorerSymbolTreeItemProviderTests.vb new file mode 100644 index 0000000000000..286cbc0d333b9 --- /dev/null +++ b/src/VisualStudio/TestUtilities2/SolutionExplorer/AbstractSolutionExplorerSymbolTreeItemProviderTests.vb @@ -0,0 +1,40 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. +' See the LICENSE file in the project root for more information. + +Imports System.Threading +Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Shared.Extensions +Imports Microsoft.CodeAnalysis.Test.Utilities +Imports Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer +Imports Roslyn.Test.Utilities + +Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer + Public MustInherit Class AbstractSolutionExplorerSymbolTreeItemProviderTests + + Protected MustOverride Function CreateWorkspace(code As String) As TestWorkspace + + Protected Async Function TestNode(Of TNode As SyntaxNode)( + code As String, + expected As String) As Task + + Using workspace = CreateWorkspace(code) + Dim testDocument = workspace.Documents.Single() + Dim document = workspace.CurrentSolution.Projects.Single().Documents.Single() + Dim root = Await document.GetRequiredSyntaxRootAsync(CancellationToken.None) + + Dim service = document.GetRequiredLanguageService(Of ISolutionExplorerSymbolTreeItemProvider)() + + Dim node = root.DescendantNodesAndSelf().OfType(Of TNode)().First() + Dim items = service.GetItems(node, CancellationToken.None) + + Dim actual = String.Join(vbCrLf, items) + AssertEx.Equal(expected, actual) + + AssertEx.SequenceEqual( + testDocument.SelectedSpans, + items.Select(Function(i) i.ItemSyntax.NavigationToken.Span)) + End Using + End Function + End Class +End Namespace From 9f1b4d14d486e4ff0f449b1bead0b8cd816cd437 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 17:28:26 +0200 Subject: [PATCH 116/353] VB tests --- ...tionExplorerSymbolTreeItemProviderTests.vb | 249 ++++++++++++++++++ ...tionExplorerSymbolTreeItemProviderTests.vb | 4 +- .../FindSymbols/FindSymbolsUtilities.vb | 2 +- 3 files changed, 253 insertions(+), 2 deletions(-) create mode 100644 src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb diff --git a/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb b/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb new file mode 100644 index 0000000000000..313472d2c79bf --- /dev/null +++ b/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb @@ -0,0 +1,249 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. +' See the LICENSE file in the project root for more information. + +Imports Microsoft.CodeAnalysis.Test.Utilities +Imports Microsoft.CodeAnalysis.VisualBasic.Syntax +Imports Microsoft.VisualStudio.LanguageServices.UnitTests +Imports Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer + +Namespace Roslyn.VisualStudio.VisualBasic.UnitTests.SolutionExplorer + + Public NotInheritable Class VisualBasicSolutionExplorerSymbolTreeItemProviderTests + Inherits AbstractSolutionExplorerSymbolTreeItemProviderTests + + Protected Overrides Function CreateWorkspace(code As String) As TestWorkspace + Return TestWorkspace.CreateVisualBasic(code, composition:=VisualStudioTestCompositions.LanguageServices) + End Function + + Private Function TestCompilationUnit( + code As String, expected As String) As Task + + Return TestNode(Of CompilationUnitSyntax)(code, expected) + End Function + + + Public Async Function TestEmptyFile() As Task + Await TestCompilationUnit("", "") + End Function + + + Public Async Function TestTopLevelClass() As Task + Await TestCompilationUnit(" + class [|C|] + end class + ", " + Name=""C"" Glyph=ClassInternal HasItems=False + ") + End Function + + + Public Async Function TestTwoTopLevelTypes() As Task + Await TestCompilationUnit(" + class [|C|] + end class + + class [|D|] + end class + ", " + Name=""C"" Glyph=ClassInternal HasItems=False + Name=""D"" Glyph=ClassInternal HasItems=False + ") + End Function + + + Public Async Function TestDelegatesAndEnums() As Task + Await TestCompilationUnit(" + delegate function [|D|](x as Integer) as string; + + enum [|E|] + end enum + ", " + Name=""D(Integer) As string"" Glyph=DelegateInternal HasItems=False + Name=""E"" Glyph=EnumInternal HasItems=False + ") + End Function + + + Public Async Function TestTypesInBlockNamespace() As Task + Await TestCompilationUnit(" + namespace N + class [|C|] + end class + + class [|D|] + end class + end namespace + ", " + Name=""C"" Glyph=ClassInternal HasItems=False + Name=""D"" Glyph=ClassInternal HasItems=False + ") + End Function + + + Public Async Function TestTypesAcrossNamespaces() As Task + Await TestCompilationUnit(" + class [|C|] + end class + + namespace N + class [|D|] + end class + end namespace + ", " + Name=""C"" Glyph=ClassInternal HasItems=False + Name=""D"" Glyph=ClassInternal HasItems=False + ") + End Function + + ' + 'public async function TestTypePermutations( + ' [CombinatorialValues("Public", "Private", "Protected", "Internal")> string accessibility, + ' [CombinatorialValues("Record", "Class", "Interface", "Struct")> string type) + '{ + ' await TestCompilationUnit($$" + ' {{accessibility.ToLowerInvariant()}} {{type.ToLowerInvariant()}} [|C|] + ' { + ' } + ' ", $$" + ' Name=""C"" Glyph={{type switch { "Record" => "Class", "Struct" => "Structure", _ => type }}}{{accessibility}} HasItems=False + ' "); + '} + + '[Theory, CombinatorialData] + 'public async function TestTypeHasItems( + ' [CombinatorialValues("Record", "Class", "Interface", "Struct")> string type) + '{ + ' await TestCompilationUnit($$" + ' {{type.ToLowerInvariant()}} [|C|] + ' { + ' Integer i; + ' } + ' ", $$" + ' Name=""C"" Glyph={{type switch { "Record" => "Class", "Struct" => "Structure", _ => type }}}Internal HasItems=True + ' "); + '} + + + Public Async Function TestEnumHasItems() As Task + Await TestCompilationUnit(" + enum [|E|] + A + B + C + end enum + ", " + Name=""E"" Glyph=EnumInternal HasItems=True + ") + End Function + + ' + ' + ' + ' + ' + ' + ' + ' + ' + ' + ' + ' + '>", "B>")> + 'public async function TestTypes( + ' string parameterType, string resultType) + '{ + ' await TestCompilationUnit($$" + ' delegate void [|D|]({{parameterType}} x); + ' ", $$" + ' Name=""D({{resultType}}) As void"" Glyph=DelegateInternal HasItems=False + ' "); + 'end function + + + Public Async Function TestGenericClass() As Task + Await TestCompilationUnit(" + class [|C|](of T) + end class + ", " + Name=""C(Of T)"" Glyph=ClassInternal HasItems=False + ") + End Function + + + Public Async Function TestGenericDelegate() As Task + Await TestCompilationUnit(" + delegate sub [|D|](Of T)() + ", " + Name=""D(Of T)() As void"" Glyph=DelegateInternal HasItems=False + ") + End Function + + + Public Async Function TestEnumMembers() As Task + Await TestNode(Of EnumBlockSyntax)(" + enum E + [|A|] + [|B|] + [|C|] + end enum + ", " + Name=""A"" Glyph=EnumMemberPublic HasItems=False + Name=""B"" Glyph=EnumMemberPublic HasItems=False + Name=""C"" Glyph=EnumMemberPublic HasItems=False + ") + End Function + + + Public Async Function TestClassMembers() As Task + Await TestNode(Of ClassBlockSyntax)(" + class C + { + private Integer [|a|], [|b|]; + public P [|Prop|] => default; + internal [|C|]() { } + ~[|C|]() { } + + protected R [|this|][string s] => default; + private event Action [|A|] { } + public event Action [|B|], [|C|]; + + void [|M|](Integer a) { } + public void IInterface.[|O|]() { } + + public static operator [|+|](C c1, Integer a) => default; + + internal static implicit operator [|Integer|](C c1) => default; + } + ", " + Name=""a As Integer"" Glyph=FieldPrivate HasItems=False + Name=""b As Integer"" Glyph=FieldPrivate HasItems=False + Name=""Prop As P"" Glyph=PropertyPublic HasItems=False + Name=""C()"" Glyph=MethodInternal HasItems=False + Name=""~C()"" Glyph=MethodPrivate HasItems=False + Name=""this[string] As R"" Glyph=PropertyProtected HasItems=False + Name=""A As Action"" Glyph=EventPrivate HasItems=False + Name=""B As Action"" Glyph=EventPublic HasItems=False + Name=""C As Action"" Glyph=EventPublic HasItems=False + Name=""M(Integer) As void"" Glyph=MethodPrivate HasItems=False + Name=""O() As void"" Glyph=MethodPublic HasItems=False + Name=""operator +(C, Integer) As "" Glyph=OperatorPublic HasItems=False + Name=""implicit operator Integer(C)"" Glyph=OperatorInternal HasItems=False + ") + End Function + + + Public Async Function TestExtension1() As Task + Await TestNode(Of ModuleBlockSyntax)(" + module C + + public sub [|M|](this Integer i) + end sub + end module + ", " + Name=""M(Integer) As void"" Glyph=ExtensionMethodPublic HasItems=False + ") + End Function + End Class +End Namespace diff --git a/src/VisualStudio/TestUtilities2/SolutionExplorer/AbstractSolutionExplorerSymbolTreeItemProviderTests.vb b/src/VisualStudio/TestUtilities2/SolutionExplorer/AbstractSolutionExplorerSymbolTreeItemProviderTests.vb index 286cbc0d333b9..422d1065a3ff6 100644 --- a/src/VisualStudio/TestUtilities2/SolutionExplorer/AbstractSolutionExplorerSymbolTreeItemProviderTests.vb +++ b/src/VisualStudio/TestUtilities2/SolutionExplorer/AbstractSolutionExplorerSymbolTreeItemProviderTests.vb @@ -29,7 +29,9 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer Dim items = service.GetItems(node, CancellationToken.None) Dim actual = String.Join(vbCrLf, items) - AssertEx.Equal(expected, actual) + AssertEx.SequenceEqual( + expected.Trim().Split({vbCrLf}, StringSplitOptions.RemoveEmptyEntries).Select(Function(s) s.Trim()), + items.Select(Function(i) i.ToString())) AssertEx.SequenceEqual( testDocument.SelectedSpans, diff --git a/src/Workspaces/VisualBasic/Portable/FindSymbols/FindSymbolsUtilities.vb b/src/Workspaces/VisualBasic/Portable/FindSymbols/FindSymbolsUtilities.vb index c131cdafd3471..3f5181c246c74 100644 --- a/src/Workspaces/VisualBasic/Portable/FindSymbols/FindSymbolsUtilities.vb +++ b/src/Workspaces/VisualBasic/Portable/FindSymbols/FindSymbolsUtilities.vb @@ -8,7 +8,7 @@ Namespace Microsoft.CodeAnalysis.FindSymbols Friend Module FindSymbolsUtilities Public Function GetDeclaredSymbolInfoKind(typeBlock As TypeBlockSyntax) As DeclaredSymbolInfoKind Select Case typeBlock.Kind() - Case SyntaxKind.CaseBlock + Case SyntaxKind.ClassBlock Return DeclaredSymbolInfoKind.Class Case SyntaxKind.InterfaceBlock Return DeclaredSymbolInfoKind.Interface From 4bf50da09df1cc9df7b3516991b8784d0bf0b1f4 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 17:35:22 +0200 Subject: [PATCH 117/353] Add tests --- ...tionExplorerSymbolTreeItemProviderTests.cs | 4 +- ...tionExplorerSymbolTreeItemProviderTests.vb | 47 ++++++++++++------- ...tionExplorerSymbolTreeItemProviderTests.vb | 3 ++ 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs index e184c774e9be1..8abac010ce4dd 100644 --- a/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs +++ b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs @@ -223,7 +223,7 @@ class [|C|] public async Task TestGenericDelegate() { await TestCompilationUnit(""" - delegate void [|D|]() + delegate void [|D|](); """, """ Name="D() : void" Glyph=DelegateInternal HasItems=False """); @@ -262,7 +262,7 @@ private event Action [|A|] { } void [|M|](int a) { } public void IInterface.[|O|]() { } - public static operator [|+|](C c1, int a) => default; + public static C operator [|+|](C c1, int a) => default; internal static implicit operator [|int|](C c1) => default; } diff --git a/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb b/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb index 313472d2c79bf..a43c2d17f728b 100644 --- a/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb +++ b/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb @@ -54,7 +54,7 @@ Namespace Roslyn.VisualStudio.VisualBasic.UnitTests.SolutionExplorer Public Async Function TestDelegatesAndEnums() As Task Await TestCompilationUnit(" - delegate function [|D|](x as Integer) as string; + delegate function [|D|](x as Integer) as string enum [|E|] end enum @@ -176,7 +176,7 @@ Namespace Roslyn.VisualStudio.VisualBasic.UnitTests.SolutionExplorer Await TestCompilationUnit(" delegate sub [|D|](Of T)() ", " - Name=""D(Of T)() As void"" Glyph=DelegateInternal HasItems=False + Name=""D(Of T)()"" Glyph=DelegateInternal HasItems=False ") End Function @@ -199,23 +199,27 @@ Namespace Roslyn.VisualStudio.VisualBasic.UnitTests.SolutionExplorer Public Async Function TestClassMembers() As Task Await TestNode(Of ClassBlockSyntax)(" class C - { - private Integer [|a|], [|b|]; - public P [|Prop|] => default; - internal [|C|]() { } - ~[|C|]() { } + private [|a|], [|b|] as Integer + public readonly property [|Prop|] as P + sub [|New|]() { } - protected R [|this|][string s] => default; - private event Action [|A|] { } - public event Action [|B|], [|C|]; + protected readonly property R [|Item|](s as string) + get + end get + end property - void [|M|](Integer a) { } - public void IInterface.[|O|]() { } + private event [|A|] as Action + end event - public static operator [|+|](C c1, Integer a) => default; + sub [|M|](Of T)(a as Integer) + end sub + + public shared operator [|+|](c1 as C, a as Integer) + end operator - internal static implicit operator [|Integer|](C c1) => default; - } + internal shared widening operator [|CType|](c1 as C) as Integer + end operator + end class ", " Name=""a As Integer"" Glyph=FieldPrivate HasItems=False Name=""b As Integer"" Glyph=FieldPrivate HasItems=False @@ -238,12 +242,23 @@ Namespace Roslyn.VisualStudio.VisualBasic.UnitTests.SolutionExplorer Await TestNode(Of ModuleBlockSyntax)(" module C - public sub [|M|](this Integer i) + public sub [|M|](i as Integer) end sub end module ", " Name=""M(Integer) As void"" Glyph=ExtensionMethodPublic HasItems=False ") End Function + + + Public Async Function TestAsClauses() As Task + Await TestNode(Of ModuleBlockSyntax)(" + class C + dim x as new Y() + end class + ", " + Name=""M(Integer) As Y"" Glyph=ExtensionMethodPublic HasItems=False + ") + End Function End Class End Namespace diff --git a/src/VisualStudio/TestUtilities2/SolutionExplorer/AbstractSolutionExplorerSymbolTreeItemProviderTests.vb b/src/VisualStudio/TestUtilities2/SolutionExplorer/AbstractSolutionExplorerSymbolTreeItemProviderTests.vb index 422d1065a3ff6..9ac2543de1117 100644 --- a/src/VisualStudio/TestUtilities2/SolutionExplorer/AbstractSolutionExplorerSymbolTreeItemProviderTests.vb +++ b/src/VisualStudio/TestUtilities2/SolutionExplorer/AbstractSolutionExplorerSymbolTreeItemProviderTests.vb @@ -26,6 +26,9 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SolutionExplorer Dim service = document.GetRequiredLanguageService(Of ISolutionExplorerSymbolTreeItemProvider)() Dim node = root.DescendantNodesAndSelf().OfType(Of TNode)().First() + Dim diagnostics = node.GetDiagnostics() + Assert.Empty(diagnostics) + Dim items = service.GetItems(node, CancellationToken.None) Dim actual = String.Join(vbCrLf, items) From a7d466a26c96e9c27fe14ef9a942213bd357c8cc Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 17:49:11 +0200 Subject: [PATCH 118/353] vb tests --- ...tionExplorerSymbolTreeItemProviderTests.cs | 2 +- ...tionExplorerSymbolTreeItemProviderTests.vb | 39 +++++++++---------- ...cSolutionExplorerSymbolTreeItemProvider.vb | 12 +++++- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs index 8abac010ce4dd..78629e285bf9c 100644 --- a/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs +++ b/src/VisualStudio/CSharp/Test/SolutionExplorer/CSharpSolutionExplorerSymbolTreeItemProviderTests.cs @@ -278,7 +278,7 @@ private event Action [|A|] { } Name="C : Action" Glyph=EventPublic HasItems=False Name="M(int) : void" Glyph=MethodPrivate HasItems=False Name="O() : void" Glyph=MethodPublic HasItems=False - Name="operator +(C, int) : " Glyph=OperatorPublic HasItems=False + Name="operator +(C, int) : C" Glyph=OperatorPublic HasItems=False Name="implicit operator int(C)" Glyph=OperatorInternal HasItems=False """); } diff --git a/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb b/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb index a43c2d17f728b..80c69ad366a7d 100644 --- a/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb +++ b/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb @@ -201,14 +201,15 @@ Namespace Roslyn.VisualStudio.VisualBasic.UnitTests.SolutionExplorer class C private [|a|], [|b|] as Integer public readonly property [|Prop|] as P - sub [|New|]() { } + sub [|New|]() + end sub - protected readonly property R [|Item|](s as string) + protected readonly property [|Item|](s as string) as R get end get end property - private event [|A|] as Action + private custom event [|A|] as Action end event sub [|M|](Of T)(a as Integer) @@ -217,23 +218,19 @@ Namespace Roslyn.VisualStudio.VisualBasic.UnitTests.SolutionExplorer public shared operator [|+|](c1 as C, a as Integer) end operator - internal shared widening operator [|CType|](c1 as C) as Integer + friend shared widening operator [|CType|](c1 as C) as Integer end operator end class ", " - Name=""a As Integer"" Glyph=FieldPrivate HasItems=False - Name=""b As Integer"" Glyph=FieldPrivate HasItems=False - Name=""Prop As P"" Glyph=PropertyPublic HasItems=False - Name=""C()"" Glyph=MethodInternal HasItems=False - Name=""~C()"" Glyph=MethodPrivate HasItems=False - Name=""this[string] As R"" Glyph=PropertyProtected HasItems=False - Name=""A As Action"" Glyph=EventPrivate HasItems=False - Name=""B As Action"" Glyph=EventPublic HasItems=False - Name=""C As Action"" Glyph=EventPublic HasItems=False - Name=""M(Integer) As void"" Glyph=MethodPrivate HasItems=False - Name=""O() As void"" Glyph=MethodPublic HasItems=False - Name=""operator +(C, Integer) As "" Glyph=OperatorPublic HasItems=False - Name=""implicit operator Integer(C)"" Glyph=OperatorInternal HasItems=False + Name=""a As Integer"" Glyph=FieldPrivate HasItems=False, + Name=""b As Integer"" Glyph=FieldPrivate HasItems=False, + Name=""Prop As P"" Glyph=PropertyPublic HasItems=False, + Name=""New()"" Glyph=MethodPublic HasItems=False, + Name=""Item(string) As R"" Glyph=PropertyProtected HasItems=False, + Name=""A As Action"" Glyph=EventPrivate HasItems=False, + Name=""M(Of T)(Integer)"" Glyph=MethodPublic HasItems=False, + Name=""Operator +(C, Integer) As Object"" Glyph=OperatorPublic HasItems=False, + Name=""Operator CType(C) As Integer"" Glyph=OperatorInternal HasItems=False ") End Function @@ -246,18 +243,18 @@ Namespace Roslyn.VisualStudio.VisualBasic.UnitTests.SolutionExplorer end sub end module ", " - Name=""M(Integer) As void"" Glyph=ExtensionMethodPublic HasItems=False + Name=""M(Integer)"" Glyph=ExtensionMethodPublic HasItems=False ") End Function Public Async Function TestAsClauses() As Task - Await TestNode(Of ModuleBlockSyntax)(" + Await TestNode(Of ClassBlockSyntax)(" class C - dim x as new Y() + dim [|x|] as new Y() end class ", " - Name=""M(Integer) As Y"" Glyph=ExtensionMethodPublic HasItems=False + Name=""x As Y"" Glyph=FieldPrivate HasItems=False ") End Function End Class diff --git a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb index d011f24009477..8b6a5e1997759 100644 --- a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb +++ b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports System.Composition +Imports System.Linq Imports System.Text Imports System.Threading Imports Microsoft.CodeAnalysis @@ -10,6 +11,8 @@ Imports Microsoft.CodeAnalysis.FindSymbols Imports Microsoft.CodeAnalysis.Host.Mef Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.Shared.Extensions +Imports Microsoft.CodeAnalysis.VisualBasic +Imports Microsoft.CodeAnalysis.VisualBasic.Extensions Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer @@ -161,10 +164,17 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer AppendParameterList(nameBuilder, methodStatement.ParameterList) AppendAsClause(nameBuilder, methodStatement.AsClause) + Dim isExtension = container.IsKind(SyntaxKind.ModuleBlock) AndAlso methodStatement.AttributeLists.Any( + Function(list) list.Attributes.Any( + Function(attribute) + Dim name = attribute.Name.GetRightmostName().Identifier.ValueText + Return name = "Extension" OrElse name = "ExtensionAttribute" + End Function)) + Dim accesibility = GetAccessibility(container, methodStatement, methodStatement.Modifiers) items.Add(New SymbolTreeItemData( nameBuilder.ToStringAndClear(), - GlyphExtensions.GetGlyph(DeclaredSymbolInfoKind.Method, accesibility), + GlyphExtensions.GetGlyph(If(isExtension, DeclaredSymbolInfoKind.ExtensionMethod, DeclaredSymbolInfoKind.Method), accesibility), hasItems:=False, methodStatement, methodStatement.Identifier)) From b8b45a71d611cdaa2e66128d6b58959aef9b8cb0 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 17:51:10 +0200 Subject: [PATCH 119/353] vb tests --- ...olutionExplorerSymbolTreeItemProviderTests.vb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb b/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb index 80c69ad366a7d..dea649a7b5d69 100644 --- a/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb +++ b/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb @@ -222,14 +222,14 @@ Namespace Roslyn.VisualStudio.VisualBasic.UnitTests.SolutionExplorer end operator end class ", " - Name=""a As Integer"" Glyph=FieldPrivate HasItems=False, - Name=""b As Integer"" Glyph=FieldPrivate HasItems=False, - Name=""Prop As P"" Glyph=PropertyPublic HasItems=False, - Name=""New()"" Glyph=MethodPublic HasItems=False, - Name=""Item(string) As R"" Glyph=PropertyProtected HasItems=False, - Name=""A As Action"" Glyph=EventPrivate HasItems=False, - Name=""M(Of T)(Integer)"" Glyph=MethodPublic HasItems=False, - Name=""Operator +(C, Integer) As Object"" Glyph=OperatorPublic HasItems=False, + Name=""a As Integer"" Glyph=FieldPrivate HasItems=False + Name=""b As Integer"" Glyph=FieldPrivate HasItems=False + Name=""Prop As P"" Glyph=PropertyPublic HasItems=False + Name=""New()"" Glyph=MethodPublic HasItems=False + Name=""Item(string) As R"" Glyph=PropertyProtected HasItems=False + Name=""A As Action"" Glyph=EventPrivate HasItems=False + Name=""M(Of T)(Integer)"" Glyph=MethodPublic HasItems=False + Name=""Operator +(C, Integer) As Object"" Glyph=OperatorPublic HasItems=False Name=""Operator CType(C) As Integer"" Glyph=OperatorInternal HasItems=False ") End Function From e780485bdd044959b4bed3f5928a510fd2f3a8ce Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 17:55:56 +0200 Subject: [PATCH 120/353] vb tests --- ...tionExplorerSymbolTreeItemProviderTests.vb | 41 ++++++++----------- ...cSolutionExplorerSymbolTreeItemProvider.vb | 3 +- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb b/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb index dea649a7b5d69..90362e2ae9d66 100644 --- a/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb +++ b/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb @@ -137,29 +137,24 @@ Namespace Roslyn.VisualStudio.VisualBasic.UnitTests.SolutionExplorer ") End Function - ' - ' - ' - ' - ' - ' - ' - ' - ' - ' - ' - ' - '>", "B>")> - 'public async function TestTypes( - ' string parameterType, string resultType) - '{ - ' await TestCompilationUnit($$" - ' delegate void [|D|]({{parameterType}} x); - ' ", $$" - ' Name=""D({{resultType}}) As void"" Glyph=DelegateInternal HasItems=False - ' "); - 'end function + + + + + + + + + + + + Public Async Function TestTypes(parameterType As String, resultType As String) As Task + Await TestCompilationUnit($" + delegate sub [|D|](x as {parameterType}) + ", $" + Name=""D({resultType})"" Glyph=DelegateInternal HasItems=False + ") + End Function Public Async Function TestGenericClass() As Task diff --git a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb index 8b6a5e1997759..f8c85a1d57902 100644 --- a/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb +++ b/src/VisualStudio/VisualBasic/Impl/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProvider.vb @@ -381,7 +381,8 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.SolutionExplorer Dim namedTupleElement = TryCast(element, NamedTupleElementSyntax) If namedTupleElement IsNot Nothing Then - AppendType(namedTupleElement.AsClause?.Type, builder) + builder.Append(namedTupleElement.Identifier.ValueText) + AppendAsClause(builder, namedTupleElement.AsClause) Return End If From 9855cbdd102bc55f3e8ac983509f9a1412fa6897 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 17:56:42 +0200 Subject: [PATCH 121/353] Remove progression --- .../Core/Def/Progression/GraphProvider.cs | 208 ------------------ .../GraphQueries/CallsGraphQuery.cs | 67 ------ .../ContainsChildrenGraphQuery.cs | 83 ------- .../GraphQueries/ContainsGraphQuery.cs | 67 ------ .../GraphQueries/ImplementedByGraphQuery.cs | 46 ---- .../GraphQueries/ImplementsGraphQuery.cs | 56 ----- .../GraphQueries/InheritedByGraphQuery.cs | 58 ----- .../GraphQueries/InheritsGraphQuery.cs | 60 ----- .../GraphQueries/IsCalledByGraphQuery.cs | 43 ---- .../GraphQueries/IsUsedByGraphQuery.cs | 74 ------- .../GraphQueries/OverriddenByGraphQuery.cs | 39 ---- .../GraphQueries/OverridesGraphQuery.cs | 41 ---- 12 files changed, 842 deletions(-) delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphProvider.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphQueries/CallsGraphQuery.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphQueries/ContainsChildrenGraphQuery.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphQueries/ContainsGraphQuery.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphQueries/ImplementedByGraphQuery.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphQueries/ImplementsGraphQuery.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphQueries/InheritedByGraphQuery.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphQueries/InheritsGraphQuery.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphQueries/IsCalledByGraphQuery.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphQueries/IsUsedByGraphQuery.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphQueries/OverriddenByGraphQuery.cs delete mode 100644 src/VisualStudio/Core/Def/Progression/GraphQueries/OverridesGraphQuery.cs diff --git a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs b/src/VisualStudio/Core/Def/Progression/GraphProvider.cs deleted file mode 100644 index 613e9cc47df2c..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphProvider.cs +++ /dev/null @@ -1,208 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -//if (context.Direction == GraphContextDirection.Self && context.RequestedProperties.Contains(DgmlNodeProperties.ContainsChildren)) -//{ -// graphQueries.Add(new ContainsChildrenGraphQuery()); -//} - -//if (context.Direction == GraphContextDirection.Contains || -// (context.Direction == GraphContextDirection.Target && context.LinkCategories.Contains(CodeLinkCategories.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()); -// } -//} - - - -//EnsureInitialized(); - -//// Only nodes that explicitly state that they contain children (e.g., source files) and named types should -//// be expandable. -//if (nodes.Any(n => n.Properties.Any(p => p.Key == DgmlNodeProperties.ContainsChildren)) || -// nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType))) -//{ -// yield return new GraphCommand( -// GraphCommandDefinition.Contains, -// targetCategories: null, -// linkCategories: [GraphCommonSchema.Contains], -// trackChanges: true); -//} - -//// All graph commands below this point apply only to Roslyn-owned nodes. -//if (!nodes.All(n => IsRoslynNode(n))) -//{ -// yield break; -//} - -//// Only show 'Base Types' and 'Derived Types' on a class or interface. -//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && -// IsAnyTypeKind(n, TypeKind.Class, TypeKind.Interface, TypeKind.Struct, TypeKind.Enum, TypeKind.Delegate))) -//{ -// yield return new GraphCommand( -// GraphCommandDefinition.BaseTypes, -// targetCategories: null, -// linkCategories: [CodeLinkCategories.InheritsFrom], -// trackChanges: true); - -// yield return new GraphCommand( -// GraphCommandDefinition.DerivedTypes, -// targetCategories: null, -// linkCategories: [CodeLinkCategories.InheritsFrom], -// trackChanges: true); -//} - -//// Only show 'Calls' on an applicable member in a class or struct -//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property, SymbolKind.Field))) -//{ -// yield return new GraphCommand( -// GraphCommandDefinition.Calls, -// targetCategories: null, -// linkCategories: [CodeLinkCategories.Calls], -// trackChanges: true); -//} - -//// Only show 'Is Called By' on an applicable member in a class or struct -//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && -// IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct))) -//{ -// yield return new GraphCommand( -// GraphCommandDefinition.IsCalledBy, -// targetCategories: null, -// linkCategories: [CodeLinkCategories.Calls], -// trackChanges: true); -//} - -//// Show 'Is Used By' -//yield return new GraphCommand( -// GraphCommandDefinition.IsUsedBy, -// targetCategories: [CodeNodeCategories.SourceLocation], -// linkCategories: [CodeLinkCategories.SourceReferences], -// trackChanges: true); - -//// Show 'Implements' on a class or struct, or an applicable member in a class or struct. -//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && -// IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct))) -//{ -// yield return new GraphCommand( -// s_implementsCommandDefinition, -// targetCategories: null, -// linkCategories: [CodeLinkCategories.Implements], -// trackChanges: true); -//} - -//// Show 'Implements' on public, non-static members of a class or struct. Note: we should -//// also show it on explicit interface impls in C#. -//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && -// IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && -// !GetModifiers(n).IsStatic)) -//{ -// if (nodes.Any(n => CheckAccessibility(n, Accessibility.Public) || -// HasExplicitInterfaces(n))) -// { -// yield return new GraphCommand( -// s_implementsCommandDefinition, -// targetCategories: null, -// linkCategories: [CodeLinkCategories.Implements], -// trackChanges: true); -// } -//} - -//// Show 'Implemented By' on an interface. -//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.NamedType) && -// IsAnyTypeKind(n, TypeKind.Interface))) -//{ -// yield return new GraphCommand( -// s_implementedByCommandDefinition, -// targetCategories: null, -// linkCategories: [CodeLinkCategories.Implements], -// trackChanges: true); -//} - -//// Show 'Implemented By' on any member of an interface. -//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && -// IsAnyTypeKind(n, TypeKind.Interface))) -//{ -// yield return new GraphCommand( -// s_implementedByCommandDefinition, -// targetCategories: null, -// linkCategories: [CodeLinkCategories.Implements], -// trackChanges: true); -//} - -//// Show 'Overrides' on any applicable member of a class or struct -//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && -// IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && -// GetModifiers(n).IsOverride)) -//{ -// yield return new GraphCommand( -// s_overridesCommandDefinition, -// targetCategories: null, -// linkCategories: [RoslynGraphCategories.Overrides], -// trackChanges: true); -//} - -//// Show 'Overridden By' on any applicable member of a class or struct -//if (nodes.Any(n => IsAnySymbolKind(n, SymbolKind.Event, SymbolKind.Method, SymbolKind.Property) && -// IsAnyTypeKind(n, TypeKind.Class, TypeKind.Struct) && -// IsOverridable(n))) -//{ -// yield return new GraphCommand( -// s_overriddenByCommandDefinition, -// targetCategories: null, -// linkCategories: [RoslynGraphCategories.Overrides], -// trackChanges: true); -//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/CallsGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/CallsGraphQuery.cs deleted file mode 100644 index b9c71823f476b..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/CallsGraphQuery.cs +++ /dev/null @@ -1,67 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//#nullable disable - -//using System.Collections.Immutable; -//using System.Threading; -//using System.Threading.Tasks; -//using Microsoft.CodeAnalysis; -//using Microsoft.CodeAnalysis.Internal.Log; -//using Microsoft.CodeAnalysis.PooledObjects; -//using Microsoft.VisualStudio.GraphModel; -//using Microsoft.VisualStudio.GraphModel.Schemas; - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//internal sealed class CallsGraphQuery : IGraphQuery -//{ -// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) -// { -// using var _ = Logger.LogBlock(FunctionId.GraphQuery_Calls, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); - -// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - -// foreach (var node in context.InputNodes) -// { -// var symbol = graphBuilder.GetSymbol(node, cancellationToken); -// if (symbol != null) -// { -// foreach (var newSymbol in await GetCalledMethodSymbolsAsync(symbol, solution, cancellationToken).ConfigureAwait(false)) -// { -// cancellationToken.ThrowIfCancellationRequested(); - -// var newNode = await graphBuilder.AddNodeAsync(newSymbol, relatedNode: node, cancellationToken).ConfigureAwait(false); -// graphBuilder.AddLink(node, CodeLinkCategories.Calls, newNode, cancellationToken); -// } -// } -// } - -// return graphBuilder; -// } - -// private static async Task> GetCalledMethodSymbolsAsync( -// ISymbol symbol, Solution solution, CancellationToken cancellationToken) -// { -// using var _ = ArrayBuilder.GetInstance(out var symbols); - -// foreach (var reference in symbol.DeclaringSyntaxReferences) -// { -// var semanticModel = await solution.GetDocument(reference.SyntaxTree).GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); -// foreach (var syntaxNode in (await reference.GetSyntaxAsync(cancellationToken).ConfigureAwait(false)).DescendantNodes()) -// { -// cancellationToken.ThrowIfCancellationRequested(); - -// var newSymbol = semanticModel.GetSymbolInfo(syntaxNode, cancellationToken).Symbol; -// if (newSymbol != null && newSymbol is IMethodSymbol && -// (newSymbol.CanBeReferencedByName || ((IMethodSymbol)newSymbol).MethodKind == MethodKind.Constructor)) -// { -// symbols.Add(newSymbol); -// } -// } -// } - -// return symbols.ToImmutableAndClear(); -// } -//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/ContainsChildrenGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/ContainsChildrenGraphQuery.cs deleted file mode 100644 index 939a786978edc..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/ContainsChildrenGraphQuery.cs +++ /dev/null @@ -1,83 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//using System; -//using System.Linq; -//using System.Threading; -//using System.Threading.Tasks; -//using Microsoft.CodeAnalysis; -//using Microsoft.VisualStudio.GraphModel; -//using Microsoft.VisualStudio.GraphModel.Schemas; - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//internal sealed class ContainsChildrenGraphQuery : IGraphQuery -//{ -// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) -// { -// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - -// foreach (var node in context.InputNodes) -// { -// if (!cancellationToken.IsCancellationRequested) -// { -// var symbol = graphBuilder.GetSymbol(node, cancellationToken); -// if (symbol != null) -// { -// var containsChildren = SymbolContainment.GetContainedSymbols(symbol).Any(); -// graphBuilder.AddDeferredPropertySet( -// node, DgmlNodeProperties.ContainsChildren, containsChildren, cancellationToken); -// } -// else if (node.HasCategory(CodeNodeCategories.File)) -// { -// var document = graphBuilder.GetContextDocument(node, cancellationToken); -// if (document != null) -// { -// var childNodes = await SymbolContainment.GetContainedSyntaxNodesAsync(document, cancellationToken).ConfigureAwait(false); -// graphBuilder.AddDeferredPropertySet( -// node, DgmlNodeProperties.ContainsChildren, childNodes.Any(), cancellationToken); -// } -// else -// { -// var uri = node.Id.GetNestedValueByName(CodeGraphNodeIdName.File); -// if (uri != null) -// { -// // Since a solution load is not yet completed, there is no document available to answer this query. -// // The solution explorer presumes that if somebody doesn't answer for a file, they never will. -// // See Providers\GraphContextAttachedCollectionSource.cs for more. Therefore we should answer by setting -// // ContainsChildren property to either true or false, so any following updates will be tractable. -// // We will set it to false since the solution explorer assumes the default for this query response is 'false'. - -// // Todo: we may need fallback to check if this node actually represents a C# or VB language -// // even when its extension fails to say so. One option would be to call DTEWrapper.IsRegisteredForLangService, -// // which may not be called here however since deadlock could happen. - -// // The Uri returned by `GetNestedValueByName()` above isn't necessarily absolute and the `OriginalString` is -// // the only property that doesn't throw if the UriKind is relative, so `OriginalString` must be used instead -// // of `AbsolutePath`. -// var path = uri.OriginalString; - -// // Recorded in https://github.com/dotnet/roslyn/issues/27805, we -// // have seen crashes because the URI in the graph node has the -// // following form, including the quotes (which are invalid path -// // characters): -// // C:\path\to\"some path\App.config" -// // So we avoid calling Path.GetExtension here. Alternatively, we -// // could check for illegal path characters directly first, but then -// // that check would actually happen twice because GetExtension will -// // also perform the check. -// if (path.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) || path.EndsWith(".vb", StringComparison.OrdinalIgnoreCase)) -// { -// graphBuilder.AddDeferredPropertySet( -// node, DgmlNodeProperties.ContainsChildren, value: false, cancellationToken); -// } -// } -// } -// } -// } -// } - -// return graphBuilder; -// } -//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/ContainsGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/ContainsGraphQuery.cs deleted file mode 100644 index b0aaaba954729..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/ContainsGraphQuery.cs +++ /dev/null @@ -1,67 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//using System.Collections.Generic; -//using System.Threading; -//using System.Threading.Tasks; -//using Microsoft.CodeAnalysis; -//using Microsoft.CodeAnalysis.Internal.Log; -//using Microsoft.VisualStudio.GraphModel; -//using Microsoft.VisualStudio.GraphModel.Schemas; - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//internal sealed class ContainsGraphQuery : IGraphQuery -//{ -// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) -// { -// using var _ = Logger.LogBlock(FunctionId.GraphQuery_Contains, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); - -// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); -// var nodesToProcess = context.InputNodes; - -// for (var depth = 0; depth < context.LinkDepth; depth++) -// { -// // This is the list of nodes we created and will process -// var newNodes = new HashSet(); - -// foreach (var node in nodesToProcess) -// { -// cancellationToken.ThrowIfCancellationRequested(); - -// var symbol = graphBuilder.GetSymbol(node, cancellationToken); -// if (symbol != null) -// { -// foreach (var newSymbol in SymbolContainment.GetContainedSymbols(symbol)) -// { -// cancellationToken.ThrowIfCancellationRequested(); - -// var newNode = await graphBuilder.AddNodeAsync( -// newSymbol, relatedNode: node, cancellationToken).ConfigureAwait(false); -// graphBuilder.AddLink(node, GraphCommonSchema.Contains, newNode, cancellationToken); -// } -// } -// else if (node.HasCategory(CodeNodeCategories.File)) -// { -// var document = graphBuilder.GetContextDocument(node, cancellationToken); -// if (document != null) -// { -// foreach (var newSymbol in await SymbolContainment.GetContainedSymbolsAsync(document, cancellationToken).ConfigureAwait(false)) -// { -// cancellationToken.ThrowIfCancellationRequested(); - -// var newNode = await graphBuilder.AddNodeAsync( -// newSymbol, relatedNode: node, cancellationToken).ConfigureAwait(false); -// graphBuilder.AddLink(node, GraphCommonSchema.Contains, newNode, cancellationToken); -// } -// } -// } -// } - -// nodesToProcess = newNodes; -// } - -// return graphBuilder; -// } -//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/ImplementedByGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/ImplementedByGraphQuery.cs deleted file mode 100644 index 1d09043ea411f..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/ImplementedByGraphQuery.cs +++ /dev/null @@ -1,46 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//using System.Threading; -//using System.Threading.Tasks; -//using Microsoft.CodeAnalysis; -//using Microsoft.CodeAnalysis.FindSymbols; -//using Microsoft.CodeAnalysis.Internal.Log; -//using Microsoft.VisualStudio.GraphModel; -//using Microsoft.VisualStudio.GraphModel.Schemas; - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//internal sealed class ImplementedByGraphQuery : IGraphQuery -//{ -// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) -// { -// using (Logger.LogBlock(FunctionId.GraphQuery_ImplementedBy, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken)) -// { -// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - -// foreach (var node in context.InputNodes) -// { -// var symbol = graphBuilder.GetSymbol(node, cancellationToken); -// if (symbol is INamedTypeSymbol or -// IMethodSymbol or -// IPropertySymbol or -// IEventSymbol) -// { -// var implementations = await SymbolFinder.FindImplementationsAsync(symbol, solution, cancellationToken: cancellationToken).ConfigureAwait(false); - -// foreach (var implementation in implementations) -// { -// var symbolNode = await graphBuilder.AddNodeAsync( -// implementation, relatedNode: node, cancellationToken).ConfigureAwait(false); -// graphBuilder.AddLink( -// symbolNode, CodeLinkCategories.Implements, node, cancellationToken); -// } -// } -// } - -// return graphBuilder; -// } -// } -//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/ImplementsGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/ImplementsGraphQuery.cs deleted file mode 100644 index 9c356f8dc5d2a..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/ImplementsGraphQuery.cs +++ /dev/null @@ -1,56 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//using System.Collections.Immutable; -//using System.Threading; -//using System.Threading.Tasks; -//using Microsoft.CodeAnalysis; -//using Microsoft.CodeAnalysis.FindSymbols; -//using Microsoft.CodeAnalysis.Internal.Log; -//using Microsoft.VisualStudio.GraphModel; -//using Microsoft.VisualStudio.GraphModel.Schemas; - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//internal sealed class ImplementsGraphQuery : IGraphQuery -//{ -// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) -// { -// using (Logger.LogBlock(FunctionId.GraphQuery_Implements, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken)) -// { -// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - -// foreach (var node in context.InputNodes) -// { -// var symbol = graphBuilder.GetSymbol(node, cancellationToken); -// if (symbol is INamedTypeSymbol namedType) -// { -// var implementedSymbols = ImmutableArray.CastUp(namedType.AllInterfaces); - -// await AddImplementedSymbolsAsync(graphBuilder, node, implementedSymbols, cancellationToken).ConfigureAwait(false); -// } -// else if (symbol is IMethodSymbol or -// IPropertySymbol or -// IEventSymbol) -// { -// var implements = await SymbolFinder.FindImplementedInterfaceMembersArrayAsync(symbol, solution, cancellationToken: cancellationToken).ConfigureAwait(false); -// await AddImplementedSymbolsAsync(graphBuilder, node, implements, cancellationToken).ConfigureAwait(false); -// } -// } - -// return graphBuilder; -// } -// } - -// private static async Task AddImplementedSymbolsAsync( -// GraphBuilder graphBuilder, GraphNode node, ImmutableArray implementedSymbols, CancellationToken cancellationToken) -// { -// foreach (var interfaceType in implementedSymbols) -// { -// var interfaceTypeNode = await graphBuilder.AddNodeAsync( -// interfaceType, relatedNode: node, cancellationToken).ConfigureAwait(false); -// graphBuilder.AddLink(node, CodeLinkCategories.Implements, interfaceTypeNode, cancellationToken); -// } -// } -//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/InheritedByGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/InheritedByGraphQuery.cs deleted file mode 100644 index fc247d9dbb3db..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/InheritedByGraphQuery.cs +++ /dev/null @@ -1,58 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//using System.Threading; -//using System.Threading.Tasks; -//using Microsoft.CodeAnalysis; -//using Microsoft.CodeAnalysis.FindSymbols; -//using Microsoft.CodeAnalysis.Internal.Log; -//using Microsoft.VisualStudio.GraphModel; -//using Microsoft.VisualStudio.GraphModel.Schemas; -//using Roslyn.Utilities; - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//internal sealed class InheritedByGraphQuery : IGraphQuery -//{ -// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) -// { -// using var _ = Logger.LogBlock(FunctionId.GraphQuery_InheritedBy, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); - -// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - -// foreach (var node in context.InputNodes) -// { -// var symbol = graphBuilder.GetSymbol(node, cancellationToken); -// if (symbol is not INamedTypeSymbol namedType) -// continue; - -// if (namedType.TypeKind == TypeKind.Class) -// { -// var derivedTypes = await SymbolFinder.FindDerivedClassesArrayAsync( -// namedType, solution, transitive: false, cancellationToken: cancellationToken).ConfigureAwait(false); -// foreach (var derivedType in derivedTypes) -// { -// var symbolNode = await graphBuilder.AddNodeAsync( -// derivedType, relatedNode: node, cancellationToken).ConfigureAwait(false); -// graphBuilder.AddLink(symbolNode, CodeLinkCategories.InheritsFrom, node, cancellationToken); -// } -// } -// else if (namedType.TypeKind == TypeKind.Interface) -// { -// var implementingClassesAndStructs = await SymbolFinder.FindImplementationsArrayAsync( -// namedType, solution, transitive: false, cancellationToken: cancellationToken).ConfigureAwait(false); -// var derivedInterfaces = await SymbolFinder.FindDerivedInterfacesArrayAsync( -// namedType, solution, transitive: false, cancellationToken: cancellationToken).ConfigureAwait(false); -// foreach (var derivedType in implementingClassesAndStructs.ConcatFast(derivedInterfaces)) -// { -// var symbolNode = await graphBuilder.AddNodeAsync( -// derivedType, relatedNode: node, cancellationToken).ConfigureAwait(false); -// graphBuilder.AddLink(symbolNode, CodeLinkCategories.InheritsFrom, node, cancellationToken); -// } -// } -// } - -// return graphBuilder; -// } -//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/InheritsGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/InheritsGraphQuery.cs deleted file mode 100644 index 803449edba356..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/InheritsGraphQuery.cs +++ /dev/null @@ -1,60 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//using System.Collections.Generic; -//using System.Linq; -//using System.Threading; -//using System.Threading.Tasks; -//using Microsoft.CodeAnalysis; -//using Microsoft.CodeAnalysis.Internal.Log; -//using Microsoft.VisualStudio.GraphModel; -//using Microsoft.VisualStudio.GraphModel.Schemas; - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//internal sealed class InheritsGraphQuery : IGraphQuery -//{ -// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) -// { -// using var _ = Logger.LogBlock(FunctionId.GraphQuery_Inherits, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); - -// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); -// var nodesToProcess = context.InputNodes; - -// for (var depth = 0; depth < context.LinkDepth; depth++) -// { -// // This is the list of nodes we created and will process -// var newNodes = new HashSet(); - -// foreach (var node in nodesToProcess) -// { -// var symbol = graphBuilder.GetSymbol(node, cancellationToken); -// if (symbol is INamedTypeSymbol namedType) -// { -// if (namedType.BaseType != null) -// { -// var baseTypeNode = await graphBuilder.AddNodeAsync( -// namedType.BaseType, relatedNode: node, cancellationToken).ConfigureAwait(false); -// newNodes.Add(baseTypeNode); -// graphBuilder.AddLink(node, CodeLinkCategories.InheritsFrom, baseTypeNode, cancellationToken); -// } -// else if (namedType.TypeKind == TypeKind.Interface && !namedType.OriginalDefinition.AllInterfaces.IsEmpty) -// { -// foreach (var baseNode in namedType.OriginalDefinition.AllInterfaces.Distinct()) -// { -// var baseTypeNode = await graphBuilder.AddNodeAsync( -// baseNode, relatedNode: node, cancellationToken).ConfigureAwait(false); -// newNodes.Add(baseTypeNode); -// graphBuilder.AddLink(node, CodeLinkCategories.InheritsFrom, baseTypeNode, cancellationToken); -// } -// } -// } -// } - -// nodesToProcess = newNodes; -// } - -// return graphBuilder; -// } -//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/IsCalledByGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/IsCalledByGraphQuery.cs deleted file mode 100644 index 80c5d75597617..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/IsCalledByGraphQuery.cs +++ /dev/null @@ -1,43 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//using System.Linq; -//using System.Threading; -//using System.Threading.Tasks; -//using Microsoft.CodeAnalysis; -//using Microsoft.CodeAnalysis.FindSymbols; -//using Microsoft.CodeAnalysis.Internal.Log; -//using Microsoft.VisualStudio.GraphModel; -//using Microsoft.VisualStudio.GraphModel.Schemas; - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//internal sealed class IsCalledByGraphQuery : IGraphQuery -//{ -// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) -// { -// using (Logger.LogBlock(FunctionId.GraphQuery_IsCalledBy, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken)) -// { -// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - -// foreach (var node in context.InputNodes) -// { -// var symbol = graphBuilder.GetSymbol(node, cancellationToken); -// if (symbol != null) -// { -// var callers = await SymbolFinder.FindCallersAsync(symbol, solution, cancellationToken).ConfigureAwait(false); - -// foreach (var caller in callers.Where(c => c.IsDirect)) -// { -// var callerNode = await graphBuilder.AddNodeAsync( -// caller.CallingSymbol, relatedNode: node, cancellationToken).ConfigureAwait(false); -// graphBuilder.AddLink(callerNode, CodeLinkCategories.Calls, node, cancellationToken); -// } -// } -// } - -// return graphBuilder; -// } -// } -//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/IsUsedByGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/IsUsedByGraphQuery.cs deleted file mode 100644 index 3fb51862de848..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/IsUsedByGraphQuery.cs +++ /dev/null @@ -1,74 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//using System.Linq; -//using System.Threading; -//using System.Threading.Tasks; -//using Microsoft.CodeAnalysis; -//using Microsoft.CodeAnalysis.FindSymbols; -//using Microsoft.CodeAnalysis.Internal.Log; -//using Microsoft.VisualStudio.GraphModel; -//using Microsoft.VisualStudio.GraphModel.Schemas; - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//internal sealed class IsUsedByGraphQuery : IGraphQuery -//{ -// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) -// { -// using (Logger.LogBlock(FunctionId.GraphQuery_IsUsedBy, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken)) -// { -// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - -// foreach (var node in context.InputNodes) -// { -// var symbol = graphBuilder.GetSymbol(node, cancellationToken); -// var references = await SymbolFinder.FindReferencesAsync(symbol, solution, cancellationToken).ConfigureAwait(false); - -// foreach (var reference in references) -// { -// var referencedSymbol = reference.Definition; -// var projectId = graphBuilder.GetContextProject(node, cancellationToken).Id; - -// var allLocations = referencedSymbol.Locations.Concat(reference.Locations.Select(r => r.Location)) -// .Where(l => l != null && l.IsInSource); - -// foreach (var location in allLocations) -// { -// var locationNode = GetLocationNode(location, context, projectId, cancellationToken); -// if (locationNode != null) -// graphBuilder.AddLink(node, CodeLinkCategories.SourceReferences, locationNode, cancellationToken); -// } -// } -// } - -// return graphBuilder; -// } -// } - -// private static GraphNode? GetLocationNode(Location location, IGraphContext context, ProjectId projectId, CancellationToken cancellationToken) -// { -// var span = location.GetLineSpan(); -// if (location.SourceTree == null) -// return null; - -// var lineText = location.SourceTree.GetText(cancellationToken).Lines[span.StartLinePosition.Line].ToString(); -// var filePath = location.SourceTree.FilePath; -// var sourceLocation = GraphBuilder.TryCreateSourceLocation(filePath, span.Span); -// if (sourceLocation == null) -// return null; - -// var label = string.Format("{0} ({1}, {2}): {3}", -// System.IO.Path.GetFileName(filePath), -// span.StartLinePosition.Line + 1, -// span.StartLinePosition.Character + 1, -// lineText.TrimStart()); -// var locationNode = context.Graph.Nodes.GetOrCreate(sourceLocation.Value.CreateGraphNodeId(), label, CodeNodeCategories.SourceLocation); -// locationNode[CodeNodeProperties.SourceLocation] = sourceLocation.Value; -// locationNode[RoslynGraphProperties.ContextProjectId] = projectId; -// locationNode[DgmlNodeProperties.Icon] = IconHelper.GetIconName("Reference", Accessibility.NotApplicable); - -// return locationNode; -// } -//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/OverriddenByGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/OverriddenByGraphQuery.cs deleted file mode 100644 index af6f8006fb179..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/OverriddenByGraphQuery.cs +++ /dev/null @@ -1,39 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//using System.Threading; -//using System.Threading.Tasks; -//using Microsoft.CodeAnalysis; -//using Microsoft.CodeAnalysis.Internal.Log; -//using Microsoft.CodeAnalysis.Shared.Extensions; -//using Microsoft.VisualStudio.GraphModel; - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//internal sealed class OverriddenByGraphQuery : IGraphQuery -//{ -// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) -// { -// using var _ = Logger.LogBlock(FunctionId.GraphQuery_OverriddenBy, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken); - -// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - -// foreach (var node in context.InputNodes) -// { -// var symbol = graphBuilder.GetSymbol(node, cancellationToken); -// if (symbol != null) -// { -// var overriddenMember = symbol.GetOverriddenMember(); -// if (overriddenMember != null) -// { -// var symbolNode = await graphBuilder.AddNodeAsync( -// overriddenMember, relatedNode: node, cancellationToken).ConfigureAwait(false); -// graphBuilder.AddLink(node, RoslynGraphCategories.Overrides, symbolNode, cancellationToken); -// } -// } -// } - -// return graphBuilder; -// } -//} diff --git a/src/VisualStudio/Core/Def/Progression/GraphQueries/OverridesGraphQuery.cs b/src/VisualStudio/Core/Def/Progression/GraphQueries/OverridesGraphQuery.cs deleted file mode 100644 index 053be8c47e3a8..0000000000000 --- a/src/VisualStudio/Core/Def/Progression/GraphQueries/OverridesGraphQuery.cs +++ /dev/null @@ -1,41 +0,0 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. - -//using System.Threading; -//using System.Threading.Tasks; -//using Microsoft.CodeAnalysis; -//using Microsoft.CodeAnalysis.FindSymbols; -//using Microsoft.CodeAnalysis.Internal.Log; -//using Microsoft.VisualStudio.GraphModel; - -//namespace Microsoft.VisualStudio.LanguageServices.Implementation.Progression; - -//internal sealed class OverridesGraphQuery : IGraphQuery -//{ -// public async Task GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) -// { -// using (Logger.LogBlock(FunctionId.GraphQuery_Overrides, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken)) -// { -// var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); - -// foreach (var node in context.InputNodes) -// { -// var symbol = graphBuilder.GetSymbol(node, cancellationToken); -// if (symbol is IMethodSymbol or -// IPropertySymbol or -// IEventSymbol) -// { -// var overrides = await SymbolFinder.FindOverridesAsync(symbol, solution, cancellationToken: cancellationToken).ConfigureAwait(false); -// foreach (var o in overrides) -// { -// var symbolNode = await graphBuilder.AddNodeAsync(o, relatedNode: node, cancellationToken).ConfigureAwait(false); -// graphBuilder.AddLink(symbolNode, RoslynGraphCategories.Overrides, node, cancellationToken); -// } -// } -// } - -// return graphBuilder; -// } -// } -//} From 7a06fddcbaef04ed07dbbbae877db3d57a9a8776 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 18:07:55 +0200 Subject: [PATCH 122/353] Revert name change --- .../Core/Impl/SolutionExplorer/AnalyzerItem/AnalyzerItem.cs | 4 +--- .../AnalyzersFolderItem/AnalyzersFolderItem.cs | 4 +--- src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs | 5 ++--- .../Impl/SolutionExplorer/DiagnosticItem/DiagnosticItem.cs | 4 +--- .../SolutionExplorer/DiagnosticItem/SourceGeneratorItem.cs | 4 +--- .../Search/SolutionExplorerSearchDisplayItem.cs | 3 +-- .../NoSourceGeneratedFilesPlaceholderItem.cs | 4 +--- .../SourceGeneratedFileItems/SourceGeneratedFileItem.cs | 4 +--- .../Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs | 4 +--- 9 files changed, 10 insertions(+), 26 deletions(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzerItem/AnalyzerItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzerItem/AnalyzerItem.cs index 8c008faa79296..a937acffd58cd 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzerItem/AnalyzerItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzerItem/AnalyzerItem.cs @@ -13,10 +13,8 @@ internal sealed partial class AnalyzerItem( AnalyzersFolderItem analyzersFolder, AnalyzerReference analyzerReference, IContextMenuController contextMenuController) - : BaseItem + : BaseItem(GetNameText(analyzerReference)) { - public override string Name { get; } = GetNameText(analyzerReference); - public AnalyzersFolderItem AnalyzersFolder { get; } = analyzersFolder; public AnalyzerReference AnalyzerReference { get; } = analyzerReference; public override IContextMenuController ContextMenuController { get; } = contextMenuController; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersFolderItem/AnalyzersFolderItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersFolderItem/AnalyzersFolderItem.cs index b46a4e67f00fd..2a51d147d9a8c 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersFolderItem/AnalyzersFolderItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersFolderItem/AnalyzersFolderItem.cs @@ -18,15 +18,13 @@ internal sealed partial class AnalyzersFolderItem( Workspace workspace, ProjectId projectId, IVsHierarchyItem parentItem, - IContextMenuController contextMenuController) : BaseItem + IContextMenuController contextMenuController) : BaseItem(SolutionExplorerShim.Analyzers) { public readonly IThreadingContext ThreadingContext = threadingContext; public Workspace Workspace { get; } = workspace; public ProjectId ProjectId { get; } = projectId; public IVsHierarchyItem ParentItem { get; } = parentItem; - public override string Name => SolutionExplorerShim.Analyzers; - public override IContextMenuController ContextMenuController { get; } = contextMenuController; public override ImageMoniker IconMoniker => KnownMonikers.CodeInformation; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs index b57324d7512d4..992e16a6f0056 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/BaseItem.cs @@ -19,7 +19,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore /// Microsoft.VisualStudio.Shell.TreeNavigation.HierarchyProvider.dll and /// Microsoft.VisualStudio.Shell.TreeNavigation.GraphProvider.dll. /// -internal abstract class BaseItem(bool canPreview = false) : +internal abstract class BaseItem(string name, bool canPreview = false) : LocalizableProperties, ITreeDisplayItem, IInteractionPatternProvider, @@ -31,10 +31,9 @@ internal abstract class BaseItem(bool canPreview = false) : ISupportDisposalNotification, IPrioritizedComparable { - public bool CanPreview { get; } = canPreview; - public abstract string Name { get; } + public string Name { get; } = name; public virtual event PropertyChangedEventHandler PropertyChanged { add { } remove { } } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/DiagnosticItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/DiagnosticItem.cs index e209cabcf5fe4..79544dd6610a0 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/DiagnosticItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/DiagnosticItem.cs @@ -22,13 +22,11 @@ internal sealed partial class DiagnosticItem( DiagnosticDescriptor descriptor, ReportDiagnostic effectiveSeverity, IAnalyzersCommandHandler commandHandler) - : BaseItem, IEquatable + : BaseItem(descriptor.Id + ": " + descriptor.Title), IEquatable { private readonly AnalyzerReference _analyzerReference = analyzerReference; private readonly IAnalyzersCommandHandler _commandHandler = commandHandler; - public override string Name { get; } = descriptor.Id + ": " + descriptor.Title; - public ProjectId ProjectId { get; } = projectId; public DiagnosticDescriptor Descriptor { get; } = descriptor; private readonly ReportDiagnostic _effectiveSeverity = effectiveSeverity; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/SourceGeneratorItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/SourceGeneratorItem.cs index 9ed838781d810..d7a8ce4a0d773 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/SourceGeneratorItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/SourceGeneratorItem.cs @@ -13,14 +13,12 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplore internal sealed partial class SourceGeneratorItem( ProjectId projectId, SourceGeneratorIdentity identity, - string? path) : BaseItem, IEquatable + string? path) : BaseItem(identity.TypeName), IEquatable { public ProjectId ProjectId { get; } = projectId; public SourceGeneratorIdentity Identity { get; } = identity; private readonly string? _path = path; - public override string Name { get; } = identity.TypeName; - // TODO: do we need an icon for our use? public override ImageMoniker IconMoniker => KnownMonikers.Process; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItem.cs index e399518257f46..29b81c1a5d117 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/Search/SolutionExplorerSearchDisplayItem.cs @@ -17,12 +17,11 @@ internal sealed class SolutionExplorerSearchDisplayItem( INavigateToSearchResult result, string name, ImageMoniker imageMoniker) - : BaseItem(canPreview: true), + : BaseItem(name, canPreview: true), IInvocationController { public readonly INavigateToSearchResult Result = result; - public override string Name { get; } = name; public override ImageMoniker IconMoniker { get; } = imageMoniker; public override IInvocationController? InvocationController => this; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/NoSourceGeneratedFilesPlaceholderItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/NoSourceGeneratedFilesPlaceholderItem.cs index 8084cd50d1224..7355455aad6b4 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/NoSourceGeneratedFilesPlaceholderItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/NoSourceGeneratedFilesPlaceholderItem.cs @@ -7,10 +7,8 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; -internal sealed class NoSourceGeneratedFilesPlaceholderItem : BaseItem +internal sealed class NoSourceGeneratedFilesPlaceholderItem() : BaseItem(SolutionExplorerShim.This_generator_is_not_generating_files) { - public override string Name => SolutionExplorerShim.This_generator_is_not_generating_files; - public override ImageMoniker IconMoniker => KnownMonikers.StatusInformationNoColor; } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/SourceGeneratedFileItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/SourceGeneratedFileItem.cs index d718a369eac4e..6772e9d925fb0 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/SourceGeneratedFileItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/SourceGeneratedFileItem.cs @@ -20,13 +20,11 @@ internal sealed partial class SourceGeneratedFileItem( string hintName, string languageName, Workspace workspace) - : BaseItem + : BaseItem(hintName) { private readonly IThreadingContext _threadingContext = threadingContext; private readonly string _languageName = languageName; - public override string Name { get; } = hintName; - public DocumentId DocumentId { get; } = documentId; public string HintName { get; } = hintName; public Workspace Workspace { get; } = workspace; diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index 8552ccfa7214f..429aa931bcc61 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -67,7 +67,7 @@ public SymbolTreeItem( RootSymbolTreeItemSourceProvider rootProvider, DocumentId documentId, ISolutionExplorerSymbolTreeItemProvider itemProvider, - SymbolTreeItemKey itemKey) : base(canPreview: true) + SymbolTreeItemKey itemKey) : base(itemKey.Name, canPreview: true) { RootProvider = rootProvider; DocumentId = documentId; @@ -94,8 +94,6 @@ public SymbolTreeItemSyntax ItemSyntax } } - public override string Name => this.ItemKey.Name; - public override ImageMoniker IconMoniker => this.ItemKey.Glyph.GetImageMoniker(); public override IInvocationController? InvocationController => this; From 7e62b62697a59171ef0fce7c55b3567edba61392 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 18:12:10 +0200 Subject: [PATCH 123/353] Revert --- .../NoSourceGeneratedFilesPlaceholderItem.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/NoSourceGeneratedFilesPlaceholderItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/NoSourceGeneratedFilesPlaceholderItem.cs index 7355455aad6b4..9c8b2e5cc5265 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/NoSourceGeneratedFilesPlaceholderItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SourceGeneratedFileItems/NoSourceGeneratedFilesPlaceholderItem.cs @@ -7,7 +7,8 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; -internal sealed class NoSourceGeneratedFilesPlaceholderItem() : BaseItem(SolutionExplorerShim.This_generator_is_not_generating_files) +internal sealed class NoSourceGeneratedFilesPlaceholderItem() + : BaseItem(SolutionExplorerShim.This_generator_is_not_generating_files) { public override ImageMoniker IconMoniker => KnownMonikers.StatusInformationNoColor; From a3692b882e0c7c880df8da63ff24b8f9a5e97dbb Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 18:18:22 +0200 Subject: [PATCH 124/353] Add docs --- .../NonRootSymbolTreeItemSourceProvider.cs | 5 +++++ .../SymbolTree/RootSymbolTreeItemSourceProvider.cs | 14 +++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs index c0c0f665da605..6d1b37f9bd8e9 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/NonRootSymbolTreeItemSourceProvider.cs @@ -11,6 +11,11 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; +/// +/// Provides a collection source for getting the children of a given SymbolTreeItem on demand. This can be done +/// trivially as hold onto to the syntax node that they were created for. Note: if the root item is not expanded +/// then no actual calls into the syntax model are done to avoid creating parse trees unnecessarily. +/// [Export(typeof(IAttachedCollectionSourceProvider))] [Name(nameof(NonRootSymbolTreeItemSourceProvider))] [Order(Before = HierarchyItemsProviderNames.Contains)] diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index 0d850940c6e21..d03a726dc5a2a 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -27,6 +27,11 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; +/// +/// Source provider responsible for hearing about C#/VB files and attaching the root 'symbol tree' node. +/// Users can then expand that node to get access to the symbols within the file. Note: this tree is +/// built lazily (one level at a time), and only uses syntax so it can be done extremely quickly. +/// [Export(typeof(IAttachedCollectionSourceProvider))] [Name(nameof(RootSymbolTreeItemSourceProvider))] [Order(Before = HierarchyItemsProviderNames.Contains)] @@ -35,10 +40,15 @@ internal sealed partial class RootSymbolTreeItemSourceProvider : AttachedCollect { private readonly ConcurrentDictionary _hierarchyToCollectionSource = []; + /// + /// Queue of notifications we've heard about for changed documents. We'll then go update the symbol tree item + /// for each of these documents so that it is up to date. Note: if the symbol tree has never been expanded, + /// this will bail immediately to avoid doing unnecessary work. + /// private readonly AsyncBatchingWorkQueue _updateSourcesQueue; private readonly Workspace _workspace; - public readonly SolutionExplorerNavigationSupport NavigationSupport; + public readonly SolutionExplorerNavigationSupport NavigationSupport; public readonly IThreadingContext ThreadingContext; public readonly IAsynchronousOperationListener Listener; @@ -79,6 +89,7 @@ private async ValueTask UpdateCollectionSourcesAsync( documentIdSet.AddRange(documentIds); sources.AddRange(_hierarchyToCollectionSource.Values); + // Update all the affected documents in parallel. await RoslynParallel.ForEachAsync( sources, cancellationToken, @@ -127,6 +138,7 @@ await source.UpdateIfAffectedAsync(documentIdSet, cancellationToken) var source = new RootSymbolTreeItemCollectionSource(this, item); _hierarchyToCollectionSource[item] = source; + // Register to hear about if this hierarchy is disposed. We'll stop watching it if so. item.PropertyChanged += OnItemPropertyChanged; return source; From 16167ad512030497fd2bff8fc6d84a268bec7f7c Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 19:07:52 +0200 Subject: [PATCH 125/353] Add test --- ...tionExplorerSymbolTreeItemProviderTests.vb | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb b/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb index 90362e2ae9d66..d778a1d03fb54 100644 --- a/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb +++ b/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb @@ -96,19 +96,19 @@ Namespace Roslyn.VisualStudio.VisualBasic.UnitTests.SolutionExplorer ") End Function - ' - 'public async function TestTypePermutations( - ' [CombinatorialValues("Public", "Private", "Protected", "Internal")> string accessibility, - ' [CombinatorialValues("Record", "Class", "Interface", "Struct")> string type) - '{ - ' await TestCompilationUnit($$" - ' {{accessibility.ToLowerInvariant()}} {{type.ToLowerInvariant()}} [|C|] - ' { - ' } - ' ", $$" - ' Name=""C"" Glyph={{type switch { "Record" => "Class", "Struct" => "Structure", _ => type }}}{{accessibility}} HasItems=False - ' "); - '} + + Public Async Function TestTypePermutations( + + accessibility As String, + + type As String) As Task + Await TestCompilationUnit($" + {accessibility.ToLowerInvariant()} {type.ToLowerInvariant()} [|C|] + end {type.ToLowerInvariant()} + ", $" + Name=""C"" Glyph={type}{If(accessibility = "Friend", "Internal", accessibility)} HasItems=False + ") + End function '[Theory, CombinatorialData] 'public async function TestTypeHasItems( From 3e5ce6dd320848a8eb11cfe4f58e131ed4b85539 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 19:11:35 +0200 Subject: [PATCH 126/353] add tests --- ...tionExplorerSymbolTreeItemProviderTests.vb | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb b/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb index d778a1d03fb54..42d01b8351b7c 100644 --- a/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb +++ b/src/VisualStudio/Core/Test/SolutionExplorer/VisualBasicSolutionExplorerSymbolTreeItemProviderTests.vb @@ -108,21 +108,20 @@ Namespace Roslyn.VisualStudio.VisualBasic.UnitTests.SolutionExplorer ", $" Name=""C"" Glyph={type}{If(accessibility = "Friend", "Internal", accessibility)} HasItems=False ") - End function + End Function - '[Theory, CombinatorialData] - 'public async function TestTypeHasItems( - ' [CombinatorialValues("Record", "Class", "Interface", "Struct")> string type) - '{ - ' await TestCompilationUnit($$" - ' {{type.ToLowerInvariant()}} [|C|] - ' { - ' Integer i; - ' } - ' ", $$" - ' Name=""C"" Glyph={{type switch { "Record" => "Class", "Struct" => "Structure", _ => type }}}Internal HasItems=True - ' "); - '} + + Public Async Function TestTypeHasItems( + + type As String) As Task + Await TestCompilationUnit($" + {type.ToLowerInvariant()} [|C|] + readonly property P as string + end {type.ToLowerInvariant()} + ", $" + Name=""C"" Glyph={type}Internal HasItems=True + ") + End Function Public Async Function TestEnumHasItems() As Task From 97a4b87ed6bf17f4437ecdc3c4218250973027d7 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 19:13:08 +0200 Subject: [PATCH 127/353] Update src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersFolderItem/AnalyzersFolderItem.cs --- .../SolutionExplorer/AnalyzersFolderItem/AnalyzersFolderItem.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersFolderItem/AnalyzersFolderItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersFolderItem/AnalyzersFolderItem.cs index 2a51d147d9a8c..b2542ef39e496 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersFolderItem/AnalyzersFolderItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersFolderItem/AnalyzersFolderItem.cs @@ -24,7 +24,6 @@ internal sealed partial class AnalyzersFolderItem( public Workspace Workspace { get; } = workspace; public ProjectId ProjectId { get; } = projectId; public IVsHierarchyItem ParentItem { get; } = parentItem; - public override IContextMenuController ContextMenuController { get; } = contextMenuController; public override ImageMoniker IconMoniker => KnownMonikers.CodeInformation; From 51da119df66af961b975d87d11753564ac6a93a0 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 19:15:02 +0200 Subject: [PATCH 128/353] Revert --- .../Portable/FindSymbols/VisualBasicReferenceFinder.vb | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicReferenceFinder.vb b/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicReferenceFinder.vb index 37c62a5da70ef..37bf617330aca 100644 --- a/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicReferenceFinder.vb +++ b/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicReferenceFinder.vb @@ -7,7 +7,6 @@ Imports System.Composition Imports System.Threading Imports Microsoft.CodeAnalysis.FindSymbols.Finders Imports Microsoft.CodeAnalysis.Host.Mef -Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Microsoft.CodeAnalysis.VisualBasic.Utilities Namespace Microsoft.CodeAnalysis.FindSymbols From d4916a0ba7c1dac707b3ad2d7ac9e6bda08dbe33 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 19:47:11 +0200 Subject: [PATCH 129/353] Update to using unbound nameof(X<>) expressions --- Roslyn.sln | 7 ++-- ...nExpressionForBuilderDiagnosticAnalyzer.cs | 16 ++++----- ...onExpressionForFluentDiagnosticAnalyzer.cs | 36 +++++++++---------- ...ctionExpressionForNewDiagnosticAnalyzer.cs | 2 +- .../UseCollectionExpressionHelpers.cs | 12 +++---- ...ngeOperatorDiagnosticAnalyzer.InfoCache.cs | 2 +- ...rpMakeMethodAsynchronousCodeFixProvider.cs | 4 +-- .../UseUtf8StringLiteralCodeFixProvider.cs | 2 +- ...rnaryConditionalCheckDiagnosticAnalyzer.cs | 4 +-- .../UpdateExpressionState.cs | 2 +- ...actUseNullPropagationDiagnosticAnalyzer.cs | 2 +- .../AbstractForEachCastCodeFixProvider.cs | 2 +- .../AbstractGenerateMethodService.State.cs | 2 +- ...stractUseNullPropagationCodeFixProvider.cs | 2 +- .../Lightup/ISmartRenameSessionWrapper.cs | 4 +-- .../Diagnostics/DiagnosticTaggerWrapper.cs | 2 +- .../ToToListConverter.cs | 2 +- ...parisonOperatorsCodeRefactoringProvider.cs | 2 +- .../MethodHandlerDetails.cs | 4 +-- .../RequestExecutionQueue.cs | 2 +- .../Helpers/DiagnosticWellKnownNames.cs | 2 +- .../Core/AbstractApplyTraitToClass`1.cs | 2 +- .../Core/AbstractCreateTestAccessor`1.cs | 2 +- .../ExtensionMessageHandlerWrapper.cs | 2 +- .../CodeModel/AbstractFileCodeElementTests.cs | 2 +- .../CoreTest/UtilityTest/AsyncLazyTests.cs | 4 +-- .../TypeStyle/CSharpUseImplicitTypeHelper.cs | 2 +- .../Utilities/ReferenceCountedDisposable.cs | 2 +- .../Symbols/ITypeSymbolExtensions.cs | 4 +-- ...CSharpTypeInferenceService.TypeInferrer.cs | 4 +-- .../Extensions/SyntaxGeneratorExtensions.cs | 2 +- 31 files changed, 71 insertions(+), 68 deletions(-) diff --git a/Roslyn.sln b/Roslyn.sln index 6fca77405900e..980009f1a1d57 100644 --- a/Roslyn.sln +++ b/Roslyn.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31319.15 +# Visual Studio Version 18 +VisualStudioVersion = 18.0.10623.112 main MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RoslynDeployment", "src\Deployment\RoslynDeployment.csproj", "{600AF682-E097-407B-AD85-EE3CED37E680}" EndProject @@ -2207,8 +2207,11 @@ Global src\Workspaces\SharedUtilitiesAndExtensions\Workspace\VisualBasic\VisualBasicWorkspaceExtensions.projitems*{57ca988d-f010-4bf2-9a2e-07d6dcd2ff2c}*SharedItemsImports = 5 src\Analyzers\CSharp\Tests\CSharpAnalyzers.UnitTests.projitems*{58969243-7f59-4236-93d0-c93b81f569b3}*SharedItemsImports = 13 src\Dependencies\Collections\Microsoft.CodeAnalysis.Collections.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 + src\Dependencies\Contracts\Microsoft.CodeAnalysis.Contracts.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 src\Dependencies\PooledObjects\Microsoft.CodeAnalysis.PooledObjects.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 + src\Dependencies\Threading\Microsoft.CodeAnalysis.Threading.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 src\Workspaces\SharedUtilitiesAndExtensions\Compiler\Core\CompilerExtensions.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 + src\Workspaces\SharedUtilitiesAndExtensions\Compiler\Extensions\Microsoft.CodeAnalysis.Extensions.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 src\Workspaces\SharedUtilitiesAndExtensions\Workspace\Core\WorkspaceExtensions.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 src\Analyzers\Core\CodeFixes\CodeFixes.projitems*{5ff1e493-69cc-4d0b-83f2-039f469a04e1}*SharedItemsImports = 5 src\Workspaces\SharedUtilitiesAndExtensions\Workspace\Core\WorkspaceExtensions.projitems*{5ff1e493-69cc-4d0b-83f2-039f469a04e1}*SharedItemsImports = 5 diff --git a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForBuilderDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForBuilderDiagnosticAnalyzer.cs index 7406d96480af4..3f0c11bdaacc0 100644 --- a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForBuilderDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForBuilderDiagnosticAnalyzer.cs @@ -27,7 +27,7 @@ internal sealed partial class CSharpUseCollectionExpressionForBuilderDiagnosticA EnforceOnBuildValues.UseCollectionExpressionForBuilder) { private const string CreateBuilderName = nameof(ImmutableArray.CreateBuilder); - private const string GetInstanceName = nameof(ArrayBuilder.GetInstance); + private const string GetInstanceName = nameof(ArrayBuilder<>.GetInstance); protected override void InitializeWorker(CodeBlockStartAnalysisContext context, INamedTypeSymbol? expressionType) => context.RegisterSyntaxNodeAction(context => AnalyzeInvocationExpression(context, expressionType), SyntaxKind.InvocationExpression); @@ -117,7 +117,7 @@ void FadeOutCode(SyntaxNodeAnalysisContext context, AnalysisResult analysisResul return null; if (memberAccessExpression.Name.Identifier.ValueText == GetInstanceName && - memberAccessExpression.Expression is not GenericNameSyntax { Identifier.ValueText: nameof(ArrayBuilder) }) + memberAccessExpression.Expression is not GenericNameSyntax { Identifier.ValueText: nameof(ArrayBuilder<>) }) { return null; } @@ -217,12 +217,12 @@ identifierName.Parent is MemberAccessExpressionSyntax(SyntaxKind.SimpleMemberAcc memberAccess.Expression == identifierName && memberAccess.Parent is InvocationExpressionSyntax { ArgumentList.Arguments.Count: 0 } invocationExpression && memberAccess.Name.Identifier.ValueText - is nameof(ImmutableArray.Builder.ToImmutable) - or nameof(ImmutableArray.Builder.MoveToImmutable) - or nameof(ImmutableArray.Builder.ToArray) - or nameof(ArrayBuilder.ToImmutableAndClear) - or nameof(ArrayBuilder.ToImmutableAndFree) - or nameof(ArrayBuilder.ToArrayAndFree) + is nameof(ImmutableArray<>.Builder.ToImmutable) + or nameof(ImmutableArray<>.Builder.MoveToImmutable) + or nameof(ImmutableArray<>.Builder.ToArray) + or nameof(ArrayBuilder<>.ToImmutableAndClear) + or nameof(ArrayBuilder<>.ToImmutableAndFree) + or nameof(ArrayBuilder<>.ToArrayAndFree) or nameof(Enumerable.ToList)) { return invocationExpression; diff --git a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForFluentDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForFluentDiagnosticAnalyzer.cs index db35d9137dbb4..6a4510707005b 100644 --- a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForFluentDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForFluentDiagnosticAnalyzer.cs @@ -42,24 +42,24 @@ internal sealed partial class CSharpUseCollectionExpressionForFluentDiagnosticAn private static readonly ImmutableArray s_suffixes = [ nameof(Array), - nameof(Span), - nameof(ReadOnlySpan), - nameof(System.Collections.Generic.List), - nameof(HashSet), - nameof(LinkedList), - nameof(Queue), - nameof(SortedSet), - nameof(Stack), - nameof(ICollection), - nameof(IReadOnlyCollection), - nameof(IList), - nameof(IReadOnlyList), - nameof(ImmutableArray), - nameof(ImmutableHashSet), - nameof(ImmutableList), - nameof(ImmutableQueue), - nameof(ImmutableSortedSet), - nameof(ImmutableStack), + nameof(Span<>), + nameof(ReadOnlySpan<>), + nameof(System.Collections.Generic.List<>), + nameof(HashSet<>), + nameof(LinkedList<>), + nameof(Queue<>), + nameof(SortedSet<>), + nameof(Stack<>), + nameof(ICollection<>), + nameof(IReadOnlyCollection<>), + nameof(IList<>), + nameof(IReadOnlyList<>), + nameof(ImmutableArray<>), + nameof(ImmutableHashSet<>), + nameof(ImmutableList<>), + nameof(ImmutableQueue<>), + nameof(ImmutableSortedSet<>), + nameof(ImmutableStack<>), nameof(System.Collections.Immutable), ]; diff --git a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForNewDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForNewDiagnosticAnalyzer.cs index 24db63134a0ba..cd9f1f005d860 100644 --- a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForNewDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/CSharpUseCollectionExpressionForNewDiagnosticAnalyzer.cs @@ -53,7 +53,7 @@ private void AnalyzeBaseObjectCreationExpression( var symbol = semanticModel.GetSymbolInfo(objectCreationExpression, cancellationToken).Symbol; if (symbol is not IMethodSymbol { MethodKind: MethodKind.Constructor, Parameters: [var constructorParameter] } || - constructorParameter.Type.Name != nameof(IEnumerable)) + constructorParameter.Type.Name != nameof(IEnumerable<>)) { return; } diff --git a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/UseCollectionExpressionHelpers.cs b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/UseCollectionExpressionHelpers.cs index 3ad3e5986aad9..4a6ff87c46508 100644 --- a/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/UseCollectionExpressionHelpers.cs +++ b/src/Analyzers/CSharp/Analyzers/UseCollectionExpression/UseCollectionExpressionHelpers.cs @@ -193,11 +193,11 @@ bool IsSafeConversionWhenTypesDoNotMatch(out bool changesSemantics) var convertedType = originalTypeInfo.ConvertedType; var convertedToReadOnlySpan = - convertedType.Name == nameof(ReadOnlySpan) && + convertedType.Name == nameof(ReadOnlySpan<>) && convertedType.OriginalDefinition.Equals(compilation.ReadOnlySpanOfTType()); var convertedToSpan = - convertedType.Name == nameof(Span) && + convertedType.Name == nameof(Span<>) && convertedType.OriginalDefinition.Equals(compilation.SpanOfTType()); // ReadOnlySpan x = stackalloc[] ... @@ -206,7 +206,7 @@ bool IsSafeConversionWhenTypesDoNotMatch(out bool changesSemantics) // restrictive than Span var isSpanToReadOnlySpan = convertedToReadOnlySpan && - type.Name == nameof(Span) && + type.Name == nameof(Span<>) && type.OriginalDefinition.Equals(compilation.SpanOfTType()) && convertedType.GetTypeArguments()[0].Equals(type.GetTypeArguments()[0]); if (isSpanToReadOnlySpan) @@ -264,7 +264,7 @@ bool IsSafeConversionWhenTypesDoNotMatch(out bool changesSemantics) // disallow converting those types to ensure semantics are preserved. We do this even though // allowSemanticsChange is true because this will basically be certain to break semantics, as opposed to // the more common case where semantics may change slightly, but likely not in a way that breaks code. - if (type.Name is nameof(ObservableCollection) or nameof(ReadOnlyObservableCollection)) + if (type.Name is nameof(ObservableCollection<>) or nameof(ReadOnlyObservableCollection<>)) return false; // If the original expression was creating a set, but is being assigned to one of the well known @@ -933,7 +933,7 @@ bool IsCompatibleSignatureAndArguments( { Type: INamedTypeSymbol { - Name: nameof(IEnumerable), + Name: nameof(IEnumerable<>), TypeArguments: [ITypeParameterSymbol { TypeParameterKind: TypeParameterKind.Method }] } enumerableType }] && @@ -980,7 +980,7 @@ originalCreateMethod.Parameters is [ { Type: INamedTypeSymbol { - Name: nameof(Span) or nameof(ReadOnlySpan), + Name: nameof(Span<>) or nameof(ReadOnlySpan<>), TypeArguments: [ITypeParameterSymbol { TypeParameterKind: TypeParameterKind.Method }] } spanType }]) diff --git a/src/Analyzers/CSharp/Analyzers/UseIndexOrRangeOperator/CSharpUseRangeOperatorDiagnosticAnalyzer.InfoCache.cs b/src/Analyzers/CSharp/Analyzers/UseIndexOrRangeOperator/CSharpUseRangeOperatorDiagnosticAnalyzer.InfoCache.cs index 26ea15936fa4a..dee9c249b8a93 100644 --- a/src/Analyzers/CSharp/Analyzers/UseIndexOrRangeOperator/CSharpUseRangeOperatorDiagnosticAnalyzer.InfoCache.cs +++ b/src/Analyzers/CSharp/Analyzers/UseIndexOrRangeOperator/CSharpUseRangeOperatorDiagnosticAnalyzer.InfoCache.cs @@ -158,7 +158,7 @@ private MemberInfo ComputeMemberInfo(IMethodSymbol sliceLikeMethod, bool require // Also, look to see if the type has a `.Slice(int start, int length)` method. // This is also a method the compiler knows to look for when a user writes `x[a..b]` var actualSliceMethod = - sliceLikeMethod.ContainingType.GetMembers(nameof(Span.Slice)) + sliceLikeMethod.ContainingType.GetMembers(nameof(Span<>.Slice)) .OfType() .FirstOrDefault(s => IsTwoArgumentSliceLikeMethod(s)); if (actualSliceMethod != null) diff --git a/src/Analyzers/CSharp/CodeFixes/MakeMethodAsynchronous/CSharpMakeMethodAsynchronousCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/MakeMethodAsynchronous/CSharpMakeMethodAsynchronousCodeFixProvider.cs index ebdf9616f9161..1450fca34c80f 100644 --- a/src/Analyzers/CSharp/CodeFixes/MakeMethodAsynchronous/CSharpMakeMethodAsynchronousCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/MakeMethodAsynchronous/CSharpMakeMethodAsynchronousCodeFixProvider.cs @@ -131,13 +131,13 @@ private static TypeSyntax FixMethodReturnType( if (IsIEnumerable(returnType, knownTypes) && IsIterator(methodSymbol, cancellationToken)) { newReturnType = knownTypes.IAsyncEnumerableOfTType is null - ? MakeGenericType(nameof(IAsyncEnumerable), methodSymbol.ReturnType) + ? MakeGenericType(nameof(IAsyncEnumerable<>), methodSymbol.ReturnType) : knownTypes.IAsyncEnumerableOfTType.Construct(methodSymbol.ReturnType.GetTypeArguments()[0]).GenerateTypeSyntax(); } else if (IsIEnumerator(returnType, knownTypes) && IsIterator(methodSymbol, cancellationToken)) { newReturnType = knownTypes.IAsyncEnumeratorOfTType is null - ? MakeGenericType(nameof(IAsyncEnumerator), methodSymbol.ReturnType) + ? MakeGenericType(nameof(IAsyncEnumerator<>), methodSymbol.ReturnType) : knownTypes.IAsyncEnumeratorOfTType.Construct(methodSymbol.ReturnType.GetTypeArguments()[0]).GenerateTypeSyntax(); } else if (IsIAsyncEnumerableOrEnumerator(returnType, knownTypes)) diff --git a/src/Analyzers/CSharp/CodeFixes/UseUtf8StringLiteral/UseUtf8StringLiteralCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseUtf8StringLiteral/UseUtf8StringLiteralCodeFixProvider.cs index f82a29f839e6e..067362b58ca4f 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseUtf8StringLiteral/UseUtf8StringLiteralCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseUtf8StringLiteral/UseUtf8StringLiteralCodeFixProvider.cs @@ -206,7 +206,7 @@ private static ExpressionSyntax CreateUtf8String(SyntaxTriviaList leadingTrivia, MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, stringLiteral, - IdentifierName(nameof(ReadOnlySpan.ToArray)))) + IdentifierName(nameof(ReadOnlySpan<>.ToArray)))) .WithTrailingTrivia(trailingTrivia); } } diff --git a/src/Analyzers/Core/Analyzers/UseCoalesceExpression/AbstractUseCoalesceExpressionForNullableTernaryConditionalCheckDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseCoalesceExpression/AbstractUseCoalesceExpressionForNullableTernaryConditionalCheckDiagnosticAnalyzer.cs index 515eb7d8a2efa..92251b50c672f 100644 --- a/src/Analyzers/Core/Analyzers/UseCoalesceExpression/AbstractUseCoalesceExpressionForNullableTernaryConditionalCheckDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseCoalesceExpression/AbstractUseCoalesceExpressionForNullableTernaryConditionalCheckDiagnosticAnalyzer.cs @@ -80,7 +80,7 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context) syntaxFacts.GetPartsOfMemberAccessExpression(conditionMemberAccess, out var conditionExpression, out var conditionSimpleName); syntaxFacts.GetNameAndArityOfSimpleName(conditionSimpleName, out var conditionName, out _); - if (conditionName != nameof(Nullable.HasValue)) + if (conditionName != nameof(Nullable<>.HasValue)) return; var whenPartToCheck = notHasValueExpression ? whenFalseNodeLow : whenTrueNodeLow; @@ -90,7 +90,7 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context) syntaxFacts.GetPartsOfMemberAccessExpression(whenPartMemberAccess, out var whenPartExpression, out var whenPartSimpleName); syntaxFacts.GetNameAndArityOfSimpleName(whenPartSimpleName, out var whenPartName, out _); - if (whenPartName != nameof(Nullable.Value)) + if (whenPartName != nameof(Nullable<>.Value)) return; if (!syntaxFacts.AreEquivalent(conditionExpression, whenPartExpression)) diff --git a/src/Analyzers/Core/Analyzers/UseCollectionInitializer/UpdateExpressionState.cs b/src/Analyzers/Core/Analyzers/UseCollectionInitializer/UpdateExpressionState.cs index 73fd6a7f9a76f..274f8c9dc8f3f 100644 --- a/src/Analyzers/Core/Analyzers/UseCollectionInitializer/UpdateExpressionState.cs +++ b/src/Analyzers/Core/Analyzers/UseCollectionInitializer/UpdateExpressionState.cs @@ -26,7 +26,7 @@ internal readonly struct UpdateExpressionState< { private static readonly ImmutableArray<(string name, bool isLinq)> s_multiAddNames = [ - (nameof(List.AddRange), isLinq: false), + (nameof(List<>.AddRange), isLinq: false), (nameof(Enumerable.Concat), isLinq: true), (nameof(Enumerable.Append), isLinq: true), ]; diff --git a/src/Analyzers/Core/Analyzers/UseNullPropagation/AbstractUseNullPropagationDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseNullPropagation/AbstractUseNullPropagationDiagnosticAnalyzer.cs index 4bec6bacab283..aa4ad20955515 100644 --- a/src/Analyzers/Core/Analyzers/UseNullPropagation/AbstractUseNullPropagationDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseNullPropagation/AbstractUseNullPropagationDiagnosticAnalyzer.cs @@ -22,7 +22,7 @@ internal static class UseNullPropagationHelpers public static bool IsSystemNullableValueProperty([NotNullWhen(true)] ISymbol? symbol) => symbol is { - Name: nameof(Nullable.Value), + Name: nameof(Nullable<>.Value), ContainingType.OriginalDefinition.SpecialType: SpecialType.System_Nullable_T, }; } diff --git a/src/Analyzers/Core/CodeFixes/ForEachCast/AbstractForEachCastCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/ForEachCast/AbstractForEachCastCodeFixProvider.cs index cfd86259a4a42..9e8c2917accf2 100644 --- a/src/Analyzers/Core/CodeFixes/ForEachCast/AbstractForEachCastCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/ForEachCast/AbstractForEachCastCodeFixProvider.cs @@ -29,7 +29,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) { if (context.Diagnostics.First().Properties.ContainsKey(ForEachCastHelpers.IsFixable)) { - RegisterCodeFix(context, AnalyzersResources.Add_explicit_cast, nameof(AbstractForEachCastCodeFixProvider)); + RegisterCodeFix(context, AnalyzersResources.Add_explicit_cast, nameof(AbstractForEachCastCodeFixProvider<>)); } return Task.CompletedTask; diff --git a/src/Analyzers/Core/CodeFixes/GenerateParameterizedMember/AbstractGenerateMethodService.State.cs b/src/Analyzers/Core/CodeFixes/GenerateParameterizedMember/AbstractGenerateMethodService.State.cs index c558aa0d8f354..5e252f1496c75 100644 --- a/src/Analyzers/Core/CodeFixes/GenerateParameterizedMember/AbstractGenerateMethodService.State.cs +++ b/src/Analyzers/Core/CodeFixes/GenerateParameterizedMember/AbstractGenerateMethodService.State.cs @@ -167,7 +167,7 @@ private bool TryInitializeSimpleName( { // If we inferred Func/Action here, attempt to create better parameter names than the default // 'arg1/arg2/arg3' form that the delegate specifies. - var parameterNames = delegateInvokeMethod.ContainingType is { Name: nameof(Action) or nameof(Func), ContainingNamespace.Name: nameof(System) } + var parameterNames = delegateInvokeMethod.ContainingType is { Name: nameof(Action) or nameof(Func<>), ContainingNamespace.Name: nameof(System) } ? GenerateParameterNamesBasedOnParameterTypes(delegateInvokeMethod.Parameters) : delegateInvokeMethod.Parameters.SelectAsArray(p => p.Name); diff --git a/src/Analyzers/Core/CodeFixes/UseNullPropagation/AbstractUseNullPropagationCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseNullPropagation/AbstractUseNullPropagationCodeFixProvider.cs index c1e6714f1e0ac..87c4059ab1c3e 100644 --- a/src/Analyzers/Core/CodeFixes/UseNullPropagation/AbstractUseNullPropagationCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseNullPropagation/AbstractUseNullPropagationCodeFixProvider.cs @@ -243,7 +243,7 @@ private void FixIfStatement( syntaxFacts.GetNameAndArityOfSimpleName(nameNode, out var name, out var arity); var comparer = syntaxFacts.StringComparer; - if (arity == 0 && comparer.Equals(name, nameof(Nullable.Value))) + if (arity == 0 && comparer.Equals(name, nameof(Nullable<>.Value))) { // They're calling ".Value" off of a nullable. Because we're moving to ?. // we want to remove the .Value as well. i.e. we should generate: diff --git a/src/EditorFeatures/Core/Lightup/ISmartRenameSessionWrapper.cs b/src/EditorFeatures/Core/Lightup/ISmartRenameSessionWrapper.cs index 45efb9baff566..e81fc283634cf 100644 --- a/src/EditorFeatures/Core/Lightup/ISmartRenameSessionWrapper.cs +++ b/src/EditorFeatures/Core/Lightup/ISmartRenameSessionWrapper.cs @@ -63,10 +63,10 @@ static ISmartRenameSessionWrapper() defaultValue: SpecializedTasks.Null()); s_renameContextImmutableListBuilderAddAccessor = LightupHelpers.CreateActionAccessor(typeof(ImmutableArray<>.Builder).MakeGenericType(s_wrappedRenameContextType), - nameof(ImmutableArray.Builder.Add), + nameof(ImmutableArray<>.Builder.Add), s_wrappedRenameContextType); s_renameContextImmutableListBuilderToArrayAccessor = LightupHelpers.CreateFunctionAccessor(typeof(ImmutableArray<>.Builder).MakeGenericType(s_wrappedRenameContextType), - nameof(ImmutableArray.Builder.ToImmutable), + nameof(ImmutableArray<>.Builder.ToImmutable), typeof(ImmutableArray<>).MakeGenericType(s_wrappedRenameContextType)); var immutableArrayOfRenameContextType = typeof(ImmutableArray<>).MakeGenericType(s_wrappedRenameContextType); diff --git a/src/EditorFeatures/TestUtilities/Diagnostics/DiagnosticTaggerWrapper.cs b/src/EditorFeatures/TestUtilities/Diagnostics/DiagnosticTaggerWrapper.cs index 3dfd854ead0d1..9cdf858031e31 100644 --- a/src/EditorFeatures/TestUtilities/Diagnostics/DiagnosticTaggerWrapper.cs +++ b/src/EditorFeatures/TestUtilities/Diagnostics/DiagnosticTaggerWrapper.cs @@ -55,7 +55,7 @@ public AbstractDiagnosticsTaggerProvider TaggerProvider { if (_taggerProvider == null) { - WpfTestRunner.RequireWpfFact($"{nameof(DiagnosticTaggerWrapper)}.{nameof(TaggerProvider)} creates asynchronous taggers"); + WpfTestRunner.RequireWpfFact($"{nameof(DiagnosticTaggerWrapper<,>)}.{nameof(TaggerProvider)} creates asynchronous taggers"); if (typeof(TProvider) == typeof(InlineDiagnosticsTaggerProvider)) { diff --git a/src/Features/CSharp/Portable/ConvertLinq/ConvertForEachToLinqQuery/ToToListConverter.cs b/src/Features/CSharp/Portable/ConvertLinq/ConvertForEachToLinqQuery/ToToListConverter.cs index 5785807a26f2f..234c5ba672848 100644 --- a/src/Features/CSharp/Portable/ConvertLinq/ConvertForEachToLinqQuery/ToToListConverter.cs +++ b/src/Features/CSharp/Portable/ConvertLinq/ConvertForEachToLinqQuery/ToToListConverter.cs @@ -49,6 +49,6 @@ protected override StatementSyntax CreateDefaultStatement(ExpressionSyntax query SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, expression, - SyntaxFactory.IdentifierName(nameof(List.AddRange))), + SyntaxFactory.IdentifierName(nameof(List<>.AddRange))), SyntaxFactory.ArgumentList([SyntaxFactory.Argument(queryOrLinqInvocationExpression)]))); } diff --git a/src/Features/Core/Portable/GenerateComparisonOperators/GenerateComparisonOperatorsCodeRefactoringProvider.cs b/src/Features/Core/Portable/GenerateComparisonOperators/GenerateComparisonOperatorsCodeRefactoringProvider.cs index eedf9f85b4836..3eab31892e73a 100644 --- a/src/Features/Core/Portable/GenerateComparisonOperators/GenerateComparisonOperatorsCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/GenerateComparisonOperators/GenerateComparisonOperatorsCodeRefactoringProvider.cs @@ -119,7 +119,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte private static IMethodSymbol? TryGetCompareMethodImpl(INamedTypeSymbol containingType, ITypeSymbol comparableType) { - foreach (var member in comparableType.GetMembers(nameof(IComparable.CompareTo))) + foreach (var member in comparableType.GetMembers(nameof(IComparable<>.CompareTo))) { if (member is IMethodSymbol method) return (IMethodSymbol?)containingType.FindImplementationForInterfaceMember(method); diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/MethodHandlerDetails.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/MethodHandlerDetails.cs index 83f087cb0eb3e..62d8c66ad2c36 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/MethodHandlerDetails.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/MethodHandlerDetails.cs @@ -115,9 +115,9 @@ private static (string name, IEnumerable languages) GetRequestHandlerMet static LanguageServerEndpointAttribute? GetMethodAttributeFromHandlerMethod(Type handlerType, Type? requestType, Type contextType, Type? responseType) { - const string HandleRequestName = nameof(IRequestHandler.HandleRequestAsync); + const string HandleRequestName = nameof(IRequestHandler<,,>.HandleRequestAsync); const string HandleRequestSuffix = "." + HandleRequestName; - const string HandleNotificationName = nameof(INotificationHandler.HandleNotificationAsync); + const string HandleNotificationName = nameof(INotificationHandler<,>.HandleNotificationAsync); const string HandleNotificationSuffix = "." + HandleNotificationName; foreach (var methodInfo in handlerType.GetRuntimeMethods()) diff --git a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs index a45651f422bab..f8f0cb307fb63 100644 --- a/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs +++ b/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs @@ -55,7 +55,7 @@ namespace Microsoft.CommonLanguageServerProtocol.Framework; internal class RequestExecutionQueue : IRequestExecutionQueue { private static readonly MethodInfo s_processQueueCoreAsync = typeof(RequestExecutionQueue) - .GetMethod(nameof(RequestExecutionQueue.ProcessQueueCoreAsync), BindingFlags.NonPublic | BindingFlags.Instance)!; + .GetMethod(nameof(RequestExecutionQueue<>.ProcessQueueCoreAsync), BindingFlags.NonPublic | BindingFlags.Instance)!; protected readonly ILspLogger _logger; protected readonly AbstractHandlerProvider _handlerProvider; diff --git a/src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/Helpers/DiagnosticWellKnownNames.cs b/src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/Helpers/DiagnosticWellKnownNames.cs index 1cf75aeaeaf68..922f3132c659f 100644 --- a/src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/Helpers/DiagnosticWellKnownNames.cs +++ b/src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/Helpers/DiagnosticWellKnownNames.cs @@ -11,7 +11,7 @@ internal static class DiagnosticWellKnownNames internal const string RegisterSyntaxNodeActionName = nameof(AnalysisContext.RegisterSyntaxNodeAction); internal const string RegisterSymbolActionName = nameof(AnalysisContext.RegisterSymbolAction); internal const string RegisterCodeBlockStartActionName = nameof(AnalysisContext.RegisterCodeBlockStartAction); - internal const string RegisterCodeBlockEndActionName = nameof(CodeBlockStartAnalysisContext.RegisterCodeBlockEndAction); + internal const string RegisterCodeBlockEndActionName = nameof(CodeBlockStartAnalysisContext<>.RegisterCodeBlockEndAction); internal const string RegisterCodeBlockActionName = nameof(AnalysisContext.RegisterCodeBlockAction); internal const string RegisterOperationBlockStartActionName = nameof(AnalysisContext.RegisterOperationBlockStartAction); internal const string RegisterOperationBlockEndActionName = nameof(OperationBlockStartAnalysisContext.RegisterOperationBlockEndAction); diff --git a/src/RoslynAnalyzers/Roslyn.Diagnostics.Analyzers/Core/AbstractApplyTraitToClass`1.cs b/src/RoslynAnalyzers/Roslyn.Diagnostics.Analyzers/Core/AbstractApplyTraitToClass`1.cs index 7504d7d45c2ee..43e41122137b8 100644 --- a/src/RoslynAnalyzers/Roslyn.Diagnostics.Analyzers/Core/AbstractApplyTraitToClass`1.cs +++ b/src/RoslynAnalyzers/Roslyn.Diagnostics.Analyzers/Core/AbstractApplyTraitToClass`1.cs @@ -61,7 +61,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte CodeAction.Create( RoslynDiagnosticsAnalyzersResources.ApplyTraitToContainingType, cancellationToken => ApplyTraitToClassAsync(state, cancellationToken), - nameof(AbstractApplyTraitToClass))); + nameof(AbstractApplyTraitToClass<>))); } private async Task ApplyTraitToClassAsync(State state, CancellationToken cancellationToken) diff --git a/src/RoslynAnalyzers/Roslyn.Diagnostics.Analyzers/Core/AbstractCreateTestAccessor`1.cs b/src/RoslynAnalyzers/Roslyn.Diagnostics.Analyzers/Core/AbstractCreateTestAccessor`1.cs index 54dcd6456817b..4ac28004fcd50 100644 --- a/src/RoslynAnalyzers/Roslyn.Diagnostics.Analyzers/Core/AbstractCreateTestAccessor`1.cs +++ b/src/RoslynAnalyzers/Roslyn.Diagnostics.Analyzers/Core/AbstractCreateTestAccessor`1.cs @@ -49,7 +49,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte CodeAction.Create( RoslynDiagnosticsAnalyzersResources.CreateTestAccessorMessage, cancellationToken => CreateTestAccessorAsync(context.Document, location.SourceSpan, cancellationToken), - nameof(AbstractCreateTestAccessor))); + nameof(AbstractCreateTestAccessor<>))); } private static bool IsClassOrStruct(ITypeSymbol typeSymbol) diff --git a/src/Tools/ExternalAccess/Extensions/Internal/ExtensionMessageHandlerWrapper.cs b/src/Tools/ExternalAccess/Extensions/Internal/ExtensionMessageHandlerWrapper.cs index 7cc16748d45d3..f93565fcb6c1d 100644 --- a/src/Tools/ExternalAccess/Extensions/Internal/ExtensionMessageHandlerWrapper.cs +++ b/src/Tools/ExternalAccess/Extensions/Internal/ExtensionMessageHandlerWrapper.cs @@ -27,7 +27,7 @@ protected ExtensionHandlerWrapper(object handler, Type customMessageHandlerInter ExtensionIdentifier = extensionIdentifier; _executeAsyncMethod = customMessageHandlerInterface.GetMethod(nameof(ExecuteAsync)); - _responseTaskResultProperty = typeof(Task<>).MakeGenericType(ResponseType).GetProperty(nameof(Task.Result)); + _responseTaskResultProperty = typeof(Task<>).MakeGenericType(ResponseType).GetProperty(nameof(Task<>.Result)); } public Type MessageType { get; } diff --git a/src/VisualStudio/CSharp/Test/CodeModel/AbstractFileCodeElementTests.cs b/src/VisualStudio/CSharp/Test/CodeModel/AbstractFileCodeElementTests.cs index 8e648c1479f99..11dcb0e058834 100644 --- a/src/VisualStudio/CSharp/Test/CodeModel/AbstractFileCodeElementTests.cs +++ b/src/VisualStudio/CSharp/Test/CodeModel/AbstractFileCodeElementTests.cs @@ -61,7 +61,7 @@ protected static (EditorTestWorkspace workspace, FileCodeModel fileCodeModel) Cr protected CodeElement GetCodeElement(params object[] path) { - WpfTestRunner.RequireWpfFact($"Tests create {nameof(CodeElement)}s which use the affinitized {nameof(CleanableWeakComHandleTable)}"); + WpfTestRunner.RequireWpfFact($"Tests create {nameof(CodeElement)}s which use the affinitized {nameof(CleanableWeakComHandleTable<,>)}"); if (path.Length == 0) { diff --git a/src/Workspaces/CoreTest/UtilityTest/AsyncLazyTests.cs b/src/Workspaces/CoreTest/UtilityTest/AsyncLazyTests.cs index c9424a771e567..e0ee92943f719 100644 --- a/src/Workspaces/CoreTest/UtilityTest/AsyncLazyTests.cs +++ b/src/Workspaces/CoreTest/UtilityTest/AsyncLazyTests.cs @@ -183,7 +183,7 @@ private static void GetValueOrGetValueAsyncThrowsCorrectExceptionDuringCancellat try { doGetValue(lazy, cancellationTokenSource.Token); - AssertEx.Fail(nameof(AsyncLazy.GetValue) + " did not throw an exception."); + AssertEx.Fail(nameof(AsyncLazy<>.GetValue) + " did not throw an exception."); } catch (OperationCanceledException oce) { @@ -211,7 +211,7 @@ public void GetValueAsyncThatIsCancelledReturnsTaskCancelledWithCorrectToken() try { task.Wait(); - AssertEx.Fail(nameof(AsyncLazy.GetValueAsync) + " did not throw an exception."); + AssertEx.Fail(nameof(AsyncLazy<>.GetValueAsync) + " did not throw an exception."); } catch (AggregateException ex) { diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/TypeStyle/CSharpUseImplicitTypeHelper.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/TypeStyle/CSharpUseImplicitTypeHelper.cs index 0ad0363d96bfd..5f38dac59b397 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/TypeStyle/CSharpUseImplicitTypeHelper.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/TypeStyle/CSharpUseImplicitTypeHelper.cs @@ -321,7 +321,7 @@ protected override bool AssignmentSupportsStylePreference( return declaredType.Equals(initializerType) && declaredType is { - Name: nameof(Func) or nameof(Action), + Name: nameof(Func<>) or nameof(Action<>), ContainingSymbol: INamespaceSymbol { Name: nameof(System), ContainingNamespace.IsGlobalNamespace: true } }; } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/ReferenceCountedDisposable.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/ReferenceCountedDisposable.cs index e1d76bd0d909d..8dad134d0367b 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/ReferenceCountedDisposable.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/ReferenceCountedDisposable.cs @@ -115,7 +115,7 @@ private ReferenceCountedDisposable(T instance, BoxedReferenceCount referenceCoun /// it returns after any code invokes . /// /// The target object. - public T Target => _instance ?? throw new ObjectDisposedException(nameof(ReferenceCountedDisposable)); + public T Target => _instance ?? throw new ObjectDisposedException(nameof(ReferenceCountedDisposable<>)); /// /// Increments the reference count for the disposable object, and returns a new disposable reference to it. diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/ITypeSymbolExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/ITypeSymbolExtensions.cs index 66f23193e84ea..903d92bd3a723 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/ITypeSymbolExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Extensions/Symbols/ITypeSymbolExtensions.cs @@ -749,7 +749,7 @@ public static bool IsSpanOrReadOnlySpan([NotNullWhen(true)] this ITypeSymbol? ty public static bool IsSpan([NotNullWhen(true)] this ITypeSymbol? type) => type is INamedTypeSymbol { - Name: nameof(Span), + Name: nameof(Span<>), TypeArguments.Length: 1, ContainingNamespace: { Name: nameof(System), ContainingNamespace.IsGlobalNamespace: true } }; @@ -757,7 +757,7 @@ public static bool IsSpan([NotNullWhen(true)] this ITypeSymbol? type) public static bool IsReadOnlySpan([NotNullWhen(true)] this ISymbol? symbol) => symbol is INamedTypeSymbol { - Name: nameof(ReadOnlySpan), + Name: nameof(ReadOnlySpan<>), TypeArguments.Length: 1, ContainingNamespace: { Name: nameof(System), ContainingNamespace.IsGlobalNamespace: true } }; diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs index 85325ad9d36d0..ce0579c5c755c 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs @@ -1723,13 +1723,13 @@ private IEnumerable InferTypeForExpressionOfMemberAccessExpre // then we can figure out what 'goo' should be based on teh await // context. var name = memberAccessExpression.Name.Identifier.Value; - if (name.Equals(nameof(Task.ConfigureAwait)) && + if (name.Equals(nameof(Task<>.ConfigureAwait)) && memberAccessExpression?.Parent is InvocationExpressionSyntax invocation && memberAccessExpression.Parent.IsParentKind(SyntaxKind.AwaitExpression)) { return InferTypes(invocation); } - else if (name.Equals(nameof(Task.ContinueWith))) + else if (name.Equals(nameof(Task<>.ContinueWith))) { // goo.ContinueWith(...) // We want to infer Task. For now, we'll just do Task, diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/SyntaxGeneratorExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/SyntaxGeneratorExtensions.cs index 605627f735c8c..36f291679cddc 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/SyntaxGeneratorExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/SyntaxGeneratorExtensions.cs @@ -77,7 +77,7 @@ public static SyntaxNode GetDefaultEqualityComparer( { var equalityComparerType = compilation.EqualityComparerOfTType(); var typeExpression = equalityComparerType == null - ? factory.GenericName(nameof(EqualityComparer), type) + ? factory.GenericName(nameof(EqualityComparer<>), type) : generatorInternal.Type(equalityComparerType.Construct(type), typeContext: false); return factory.MemberAccessExpression(typeExpression, factory.IdentifierName(DefaultName)); From 7242b0dd01b95313c03d4bb85114e833349f4911 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 19:55:12 +0200 Subject: [PATCH 130/353] Update to using simple lambdas from C# 14 --- .../EditAndContinueLanguageServiceTests.cs | 2 +- .../ExpressionCompiler/CompilationContext.cs | 14 ++--- .../Test/ExpressionCompiler/LocalsTests.cs | 2 +- .../MissingAssemblyTests.cs | 14 ++--- .../Test/ExpressionCompiler/WinMdTests.cs | 2 +- .../ExpressionCompiler/ExpressionCompiler.cs | 2 +- .../FunctionResolver/FunctionResolver.cs | 10 ++-- ...CSharpConvertLinqQueryToForEachProvider.cs | 3 +- ...NotImplementedExceptionFixProviderTests.cs | 2 +- .../RemoteEditAndContinueServiceTests.cs | 2 +- ...LanguageServerClientTests.TestLspClient.cs | 2 +- .../PropertySetAnalysisTests.cs | 56 +++++++++---------- ...bstractCategorizedAnalyzerConfigOptions.cs | 2 +- ...gregateCategorizedAnalyzerConfigOptions.cs | 2 +- .../Options/AnalyzerOptionsExtensions.cs | 2 +- .../DisposeAnalysis/DisposeAnalysis.cs | 3 +- ...sis.PropertySetDataFlowOperationVisitor.cs | 8 +-- .../HardcodedSymmetricAlgorithmKeysSources.cs | 2 +- src/Tools/PrepareTests/Program.cs | 6 +- src/Tools/Source/RunTests/Options.cs | 34 +++++------ .../Common/TableControlFocusFixer.cs | 2 +- .../VisualStudioWorkspaceImpl.cs | 2 +- ...ferencesTableProvider.ColumnDefinitions.cs | 2 +- .../CSharpCodeGenerationService.cs | 4 +- 24 files changed, 89 insertions(+), 91 deletions(-) diff --git a/src/EditorFeatures/Test/EditAndContinue/EditAndContinueLanguageServiceTests.cs b/src/EditorFeatures/Test/EditAndContinue/EditAndContinueLanguageServiceTests.cs index cd9743e109eca..a5a4f2b6f7f2c 100644 --- a/src/EditorFeatures/Test/EditAndContinue/EditAndContinueLanguageServiceTests.cs +++ b/src/EditorFeatures/Test/EditAndContinue/EditAndContinueLanguageServiceTests.cs @@ -143,7 +143,7 @@ await localWorkspace.ChangeSolutionAsync(localWorkspace.CurrentSolution // EnterBreakStateAsync - mockEncService.BreakStateOrCapabilitiesChangedImpl = (bool? inBreakState) => + mockEncService.BreakStateOrCapabilitiesChangedImpl = inBreakState => { Assert.True(inBreakState); }; diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs index 04af7e975cd94..5ba924e7ba0ee 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs @@ -207,7 +207,7 @@ private EENamedTypeSymbol CreateSynthesizedType( typeName, methodName, this, - (EEMethodSymbol method, DiagnosticBag diags, out ImmutableArray declaredLocals, out ResultProperties properties) => + (method, diags, out declaredLocals, out properties) => { var hasDisplayClassThis = GetThisProxy(_displayClassVariables) != null; var binder = ExtendBinderChain( @@ -246,7 +246,7 @@ internal bool TryCompileAssignment( typeName, methodName, this, - (EEMethodSymbol method, DiagnosticBag diags, out ImmutableArray declaredLocals, out ResultProperties properties) => + (method, diags, out declaredLocals, out properties) => { var hasDisplayClassThis = GetThisProxy(_displayClassVariables) != null; var binder = ExtendBinderChain( @@ -367,7 +367,7 @@ private static string GetNextMethodName(ArrayBuilder builder) container, methodName, syntax, - (EEMethodSymbol method, DiagnosticBag diags, out ImmutableArray declaredLocals, out ResultProperties properties) => + (method, diags, out declaredLocals, out properties) => { declaredLocals = ImmutableArray.Empty; var expression = new BoundLocal(syntax, local, constantValueOpt: null, type: local.Type); @@ -620,7 +620,7 @@ internal EEMethodSymbol CreateMethod( private EEMethodSymbol GetLocalMethod(EENamedTypeSymbol container, string methodName, string localName, int localIndex) { var syntax = SyntaxFactory.IdentifierName(localName); - return CreateMethod(container, methodName, syntax, (EEMethodSymbol method, DiagnosticBag diagnostics, out ImmutableArray declaredLocals, out ResultProperties properties) => + return CreateMethod(container, methodName, syntax, (method, diagnostics, out declaredLocals, out properties) => { declaredLocals = ImmutableArray.Empty; @@ -643,7 +643,7 @@ private EEMethodSymbol GetLocalMethod(EENamedTypeSymbol container, string method private EEMethodSymbol GetParameterMethod(EENamedTypeSymbol container, string methodName, string parameterName, int parameterIndex) { var syntax = SyntaxFactory.IdentifierName(parameterName); - return CreateMethod(container, methodName, syntax, (EEMethodSymbol method, DiagnosticBag diagnostics, out ImmutableArray declaredLocals, out ResultProperties properties) => + return CreateMethod(container, methodName, syntax, (method, diagnostics, out declaredLocals, out properties) => { declaredLocals = ImmutableArray.Empty; var parameter = method.Parameters[parameterIndex]; @@ -656,7 +656,7 @@ private EEMethodSymbol GetParameterMethod(EENamedTypeSymbol container, string me private EEMethodSymbol GetThisMethod(EENamedTypeSymbol container, string methodName) { var syntax = SyntaxFactory.ThisExpression(); - return CreateMethod(container, methodName, syntax, (EEMethodSymbol method, DiagnosticBag diagnostics, out ImmutableArray declaredLocals, out ResultProperties properties) => + return CreateMethod(container, methodName, syntax, (method, diagnostics, out declaredLocals, out properties) => { declaredLocals = ImmutableArray.Empty; var expression = new BoundThisReference(syntax, GetNonDisplayClassContainer(container.SubstitutedSourceType)); @@ -668,7 +668,7 @@ private EEMethodSymbol GetThisMethod(EENamedTypeSymbol container, string methodN private EEMethodSymbol GetTypeVariablesMethod(EENamedTypeSymbol container, string methodName, NamedTypeSymbol typeVariablesType) { var syntax = SyntaxFactory.IdentifierName(SyntaxFactory.MissingToken(SyntaxKind.IdentifierToken)); - return CreateMethod(container, methodName, syntax, (EEMethodSymbol method, DiagnosticBag diagnostics, out ImmutableArray declaredLocals, out ResultProperties properties) => + return CreateMethod(container, methodName, syntax, (method, diagnostics, out declaredLocals, out properties) => { declaredLocals = ImmutableArray.Empty; var type = method.TypeMap.SubstituteNamedType(typeVariablesType); diff --git a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/LocalsTests.cs b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/LocalsTests.cs index b79db1b87fdbe..a3720823e5853 100644 --- a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/LocalsTests.cs +++ b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/LocalsTests.cs @@ -3825,7 +3825,7 @@ static void Main() var badConst = new MockSymUnmanagedConstant( "a", 1, - (int bufferLength, out int count, byte[] name) => + (bufferLength, out count, name) => { count = 0; return Roslyn.Test.Utilities.HResult.E_NOTIMPL; diff --git a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/MissingAssemblyTests.cs b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/MissingAssemblyTests.cs index 2a1b5564ebd61..63c89b8395aa9 100644 --- a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/MissingAssemblyTests.cs +++ b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/MissingAssemblyTests.cs @@ -445,7 +445,7 @@ IntPtr gmdbpf(AssemblyIdentity assemblyIdentity, out uint uSize) public void ShouldTryAgain_CORDBG_E_MISSING_METADATA() { ShouldTryAgain_False( - (AssemblyIdentity assemblyIdentity, out uint uSize) => + (assemblyIdentity, out uSize) => { Marshal.ThrowExceptionForHR(DkmExceptionUtilities.CORDBG_E_MISSING_METADATA); throw ExceptionUtilities.Unreachable(); @@ -456,7 +456,7 @@ public void ShouldTryAgain_CORDBG_E_MISSING_METADATA() public void ShouldTryAgain_COR_E_BADIMAGEFORMAT() { ShouldTryAgain_False( - (AssemblyIdentity assemblyIdentity, out uint uSize) => + (assemblyIdentity, out uSize) => { Marshal.ThrowExceptionForHR(DkmExceptionUtilities.COR_E_BADIMAGEFORMAT); throw ExceptionUtilities.Unreachable(); @@ -467,7 +467,7 @@ public void ShouldTryAgain_COR_E_BADIMAGEFORMAT() public void ShouldTryAgain_ObjectDisposedException() { ShouldTryAgain_False( - (AssemblyIdentity assemblyIdentity, out uint uSize) => + (assemblyIdentity, out uSize) => { throw new ObjectDisposedException("obj"); }); @@ -658,7 +658,7 @@ void M() diagnostics.Add(new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_NoTypeDef, "MissingType", missingIdentity), Location.None)); return null; }, - (AssemblyIdentity assemblyIdentity, out uint uSize) => + (assemblyIdentity, out uSize) => { uSize = (uint)missingModule.MetadataLength; return missingModule.MetadataAddress; @@ -707,7 +707,7 @@ void M() return null; } }, - (AssemblyIdentity assemblyIdentity, out uint uSize) => + (assemblyIdentity, out uSize) => { uSize = (uint)missingModule.MetadataLength; return missingModule.MetadataAddress; @@ -753,7 +753,7 @@ class UseLinq "args.Where(a => a.Length > 0)", ImmutableArray.Empty, (_1, _2) => context, // ignore new blocks and just keep using the same failed context... - (AssemblyIdentity assemblyIdentity, out uint uSize) => + (assemblyIdentity, out uSize) => { retryCount++; MetadataBlock block; @@ -924,7 +924,7 @@ private static void TupleContextNoSystemRuntime(string source, string methodName methodVersion: 1, ilOffset: 0, localSignatureToken: localSignatureToken), - (AssemblyIdentity assemblyIdentity, out uint uSize) => + (assemblyIdentity, out uSize) => { retryCount++; Assert.Equal("System.Runtime", assemblyIdentity.Name); diff --git a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/WinMdTests.cs b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/WinMdTests.cs index 28a79165f7940..d3fe89d45f834 100644 --- a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/WinMdTests.cs +++ b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/WinMdTests.cs @@ -351,7 +351,7 @@ static void M(C c) { return CreateMethodContext(runtime, "C.M"); }, - (AssemblyIdentity assembly, out uint size) => + (assembly, out size) => { // Compilation should succeed without retry if we redirect assembly refs correctly. // Throwing so that we don't loop forever (as we did before fix)... diff --git a/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/ExpressionCompiler.cs b/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/ExpressionCompiler.cs index efc3d3308e14d..f768667fd58b9 100644 --- a/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/ExpressionCompiler.cs +++ b/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/ExpressionCompiler.cs @@ -405,7 +405,7 @@ private bool TryCompileWithRetry( DiagnosticFormatter, createContext, compile, - (AssemblyIdentity assemblyIdentity, out uint size) => appDomain.GetMetaDataBytesPtr(assemblyIdentity.GetDisplayName(), out size), + (assemblyIdentity, out size) => appDomain.GetMetaDataBytesPtr(assemblyIdentity.GetDisplayName(), out size), out result, out errorMessage); } diff --git a/src/ExpressionEvaluator/Core/Source/FunctionResolver/FunctionResolver.cs b/src/ExpressionEvaluator/Core/Source/FunctionResolver/FunctionResolver.cs index 0a0ed3c08de17..7db3f89876645 100644 --- a/src/ExpressionEvaluator/Core/Source/FunctionResolver/FunctionResolver.cs +++ b/src/ExpressionEvaluator/Core/Source/FunctionResolver/FunctionResolver.cs @@ -150,11 +150,11 @@ internal sealed override Guid GetLanguageId(DkmRuntimeFunctionResolutionRequest private static OnFunctionResolvedDelegate OnFunctionResolved(DkmWorkList workList) { - return (DkmClrModuleInstance module, - DkmRuntimeFunctionResolutionRequest request, - int token, - int version, - int ilOffset) => + return (module, + request, + token, + version, + ilOffset) => { var address = DkmClrInstructionAddress.Create( module.RuntimeInstance, diff --git a/src/Features/CSharp/Portable/ConvertLinq/CSharpConvertLinqQueryToForEachProvider.cs b/src/Features/CSharp/Portable/ConvertLinq/CSharpConvertLinqQueryToForEachProvider.cs index 0babb22fbf6a6..b200a250d3aa4 100644 --- a/src/Features/CSharp/Portable/ConvertLinq/CSharpConvertLinqQueryToForEachProvider.cs +++ b/src/Features/CSharp/Portable/ConvertLinq/CSharpConvertLinqQueryToForEachProvider.cs @@ -760,8 +760,7 @@ private bool TryConvertIfInReturnStatement( // } // // yield break; - var statements = GenerateStatements((ExpressionSyntax expression) - => YieldStatement(SyntaxKind.YieldReturnStatement, expression), queryExpressionProcessingInfo); + var statements = GenerateStatements(expression => YieldStatement(SyntaxKind.YieldReturnStatement, expression), queryExpressionProcessingInfo); // add an yield break to avoid throws after the return. var yieldBreakStatement = YieldStatement(SyntaxKind.YieldBreakStatement); diff --git a/src/Features/CSharpTest/Copilot/CSharpImplementNotImplementedExceptionFixProviderTests.cs b/src/Features/CSharpTest/Copilot/CSharpImplementNotImplementedExceptionFixProviderTests.cs index 3e7bf465b0193..ef907cb0c55fa 100644 --- a/src/Features/CSharpTest/Copilot/CSharpImplementNotImplementedExceptionFixProviderTests.cs +++ b/src/Features/CSharpTest/Copilot/CSharpImplementNotImplementedExceptionFixProviderTests.cs @@ -176,7 +176,7 @@ public interface IMathService } .WithMockCopilotService(copilotService => { - copilotService.SetupFixAll = (Document document, ImmutableDictionary> memberReferences, CancellationToken cancellationToken) => + copilotService.SetupFixAll = (document, memberReferences, cancellationToken) => { // Create a map of method/property implementations var implementationMap = new Dictionary diff --git a/src/Features/Test/EditAndContinue/RemoteEditAndContinueServiceTests.cs b/src/Features/Test/EditAndContinue/RemoteEditAndContinueServiceTests.cs index 8c84333be83a5..4b2b996d589b3 100644 --- a/src/Features/Test/EditAndContinue/RemoteEditAndContinueServiceTests.cs +++ b/src/Features/Test/EditAndContinue/RemoteEditAndContinueServiceTests.cs @@ -154,7 +154,7 @@ await localWorkspace.ChangeSolutionAsync(localWorkspace.CurrentSolution // BreakStateChanged - mockEncService.BreakStateOrCapabilitiesChangedImpl = (bool? inBreakState) => + mockEncService.BreakStateOrCapabilitiesChangedImpl = inBreakState => { Assert.True(inBreakState); }; diff --git a/src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer.UnitTests/Utilities/AbstractLanguageServerClientTests.TestLspClient.cs b/src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer.UnitTests/Utilities/AbstractLanguageServerClientTests.TestLspClient.cs index 6c316b120015e..2bfef2e95b7e2 100644 --- a/src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer.UnitTests/Utilities/AbstractLanguageServerClientTests.TestLspClient.cs +++ b/src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer.UnitTests/Utilities/AbstractLanguageServerClientTests.TestLspClient.cs @@ -162,7 +162,7 @@ Action GetMessageLogger(string method) { var logger = _loggerFactory.CreateLogger($"LSP {method}"); - return (int type, string message) => + return (type, message) => { var logLevel = (MessageType)type switch { diff --git a/src/RoslynAnalyzers/Utilities.UnitTests/FlowAnalysis/Analysis/PropertySetAnalysis/PropertySetAnalysisTests.cs b/src/RoslynAnalyzers/Utilities.UnitTests/FlowAnalysis/Analysis/PropertySetAnalysis/PropertySetAnalysisTests.cs index 62a481955ac45..7bc11c1c05e9c 100644 --- a/src/RoslynAnalyzers/Utilities.UnitTests/FlowAnalysis/Analysis/PropertySetAnalysis/PropertySetAnalysisTests.cs +++ b/src/RoslynAnalyzers/Utilities.UnitTests/FlowAnalysis/Analysis/PropertySetAnalysis/PropertySetAnalysisTests.cs @@ -224,7 +224,7 @@ public static void StaticMethod(TestTypeToTrack staticMethodParameter) new PropertyMapperCollection( new PropertyMapper( // Definitely null => unflagged, definitely non-null => flagged, otherwise => maybe. "AString", - (PointsToAbstractValue pointsToAbstractValue) => + pointsToAbstractValue => { return pointsToAbstractValue.NullState switch { @@ -237,7 +237,7 @@ public static void StaticMethod(TestTypeToTrack staticMethodParameter) new HazardousUsageEvaluatorCollection( new HazardousUsageEvaluator( // When TypeToTrack.Method() is invoked, need to evaluate its state. "Method", - (IMethodSymbol methodSymbol, PropertySetAbstractValue abstractValue) => + (methodSymbol, abstractValue) => { // When doing this for reals, need to examine the method to make sure we're looking at the right method and arguments. @@ -253,7 +253,7 @@ public static void StaticMethod(TestTypeToTrack staticMethodParameter) "OtherClass", "OtherMethod", "t", - (IMethodSymbol methodSymbol, PropertySetAbstractValue abstractValue) => + (methodSymbol, abstractValue) => { // When doing this for reals, need to examine the method to make sure we're looking at the right method and arguments. @@ -270,7 +270,7 @@ public static void StaticMethod(TestTypeToTrack staticMethodParameter) "OtherClass", "StaticMethod", "staticMethodParameter", - (IMethodSymbol methodSymbol, PropertySetAbstractValue abstractValue) => + (methodSymbol, abstractValue) => { // When doing this for reals, need to examine the method to make sure we're looking at the right method and arguments. @@ -399,7 +399,7 @@ void TestMethod() new( "TestTypeToTrackWithConstructor", new ConstructorMapper( - (IMethodSymbol method, IReadOnlyList argumentPointsToAbstractValues) => + (method, argumentPointsToAbstractValues) => { // When doing this for reals, need to examine the method to make sure we're looking at the right method and arguments. PropertySetAbstractValueKind kind = PropertySetAbstractValueKind.Unknown; @@ -420,7 +420,7 @@ void TestMethod() new PropertyMapperCollection( new PropertyMapper( // Definitely null => unflagged, definitely non-null => flagged, otherwise => maybe. "AString", - (PointsToAbstractValue pointsToAbstractValue) => + pointsToAbstractValue => { return pointsToAbstractValue.NullState switch { @@ -433,7 +433,7 @@ void TestMethod() new HazardousUsageEvaluatorCollection( new HazardousUsageEvaluator( "Method", - (IMethodSymbol methodSymbol, PropertySetAbstractValue abstractValue) => + (methodSymbol, abstractValue) => { // When doing this for reals, need to examine the method to make sure we're looking at the right method and arguments. @@ -525,14 +525,14 @@ void TestMethod() new PropertyMapperCollection( new PropertyMapper( "AnEnum", - (ValueContentAbstractValue valueContentAbstractValue) => + valueContentAbstractValue => { return PropertySetCallbacks.EvaluateLiteralValues(valueContentAbstractValue, v => v is not null && v.Equals(0)); })), new HazardousUsageEvaluatorCollection( new HazardousUsageEvaluator( // When TypeToTrack.Method() is invoked, need to evaluate its state. "Method", - (IMethodSymbol methodSymbol, PropertySetAbstractValue abstractValue) => + (methodSymbol, abstractValue) => { // When doing this for reals, need to examine the method to make sure we're looking at the right method and arguments. @@ -586,7 +586,7 @@ void TestMethod() new( "TestTypeToTrackWithConstructor", new ConstructorMapper( - (IMethodSymbol method, IReadOnlyList argumentValueContentAbstractValues, IReadOnlyList argumentPointsToAbstractValues) => + (method, argumentValueContentAbstractValues, argumentPointsToAbstractValues) => { // When doing this for reals, need to examine the method to make sure we're looking at the right method and arguments. @@ -598,14 +598,14 @@ void TestMethod() new PropertyMapperCollection( new PropertyMapper( "AnEnum", - (ValueContentAbstractValue valueContentAbstractValue) => + valueContentAbstractValue => { return PropertySetCallbacks.EvaluateLiteralValues(valueContentAbstractValue, v => v is not null && v.Equals(0)); })), new HazardousUsageEvaluatorCollection( new HazardousUsageEvaluator( // When TypeToTrack.Method() is invoked, need to evaluate its state. "Method", - (IMethodSymbol methodSymbol, PropertySetAbstractValue abstractValue) => + (methodSymbol, abstractValue) => { // When doing this for reals, need to examine the method to make sure we're looking at the right method and arguments. @@ -663,7 +663,7 @@ void TestMethod() new PropertyMapperCollection( new PropertyMapper( "AString", - (ValueContentAbstractValue valueContentAbstractValue) => + valueContentAbstractValue => { return PropertySetCallbacks.EvaluateLiteralValues( valueContentAbstractValue, @@ -671,14 +671,14 @@ void TestMethod() }), new PropertyMapper( "AnEnum", - (ValueContentAbstractValue valueContentAbstractValue) => + valueContentAbstractValue => { return PropertySetCallbacks.EvaluateLiteralValues(valueContentAbstractValue, v => v is not null && v.Equals(2)); })), new HazardousUsageEvaluatorCollection( new HazardousUsageEvaluator( "Method", - (IMethodSymbol methodSymbol, PropertySetAbstractValue abstractValue) => + (methodSymbol, abstractValue) => { // When doing this for reals, need to examine the method to make sure we're looking at the right method and arguments. @@ -823,7 +823,7 @@ void TestMethod() new( "TestTypeToTrackWithConstructor", new ConstructorMapper( - (IMethodSymbol constructorMethodSymbol, IReadOnlyList argumentPointsToAbstractValues) => + (constructorMethodSymbol, argumentPointsToAbstractValues) => { // When doing this for reals, need to examine the method to make sure we're looking at the right method and arguments. @@ -845,7 +845,7 @@ void TestMethod() new PropertyMapperCollection( new PropertyMapper( "AnObject", - (PointsToAbstractValue pointsToAbstractValue) => + pointsToAbstractValue => { // Better to compare LocationTypeOpt to INamedTypeSymbol, but for this demonstration, just using MetadataName. PropertySetAbstractValueKind kind; @@ -865,7 +865,7 @@ void TestMethod() new HazardousUsageEvaluatorCollection( new HazardousUsageEvaluator( // When TypeToTrack.Method() is invoked, need to evaluate its state. "Method", - (IMethodSymbol methodSymbol, PropertySetAbstractValue abstractValue) => + (methodSymbol, abstractValue) => { // When doing this for reals, need to examine the method to make sure we're looking at the right method and arguments. @@ -946,9 +946,9 @@ void TestMethod() new( "TestTypeToTrackWithConstructor", new ConstructorMapper( - (IMethodSymbol constructorMethodSymbol, - IReadOnlyList argumentValueContentAbstractValues, - IReadOnlyList argumentPointsToAbstractValues) => + (constructorMethodSymbol, + argumentValueContentAbstractValues, + argumentPointsToAbstractValues) => { // When doing this for reals, need to examine the method to make sure we're looking at the right method and arguments. @@ -960,7 +960,7 @@ void TestMethod() new PropertyMapperCollection( new PropertyMapper( "AString", - (ValueContentAbstractValue valueContentAbstractValue) => + valueContentAbstractValue => { return PropertySetCallbacks.EvaluateLiteralValues( valueContentAbstractValue, @@ -969,7 +969,7 @@ void TestMethod() new HazardousUsageEvaluatorCollection( new HazardousUsageEvaluator( // When TypeToTrackWithConstructor.Method() is invoked, need to evaluate its state. "Method", - (IMethodSymbol methodSymbol, PropertySetAbstractValue abstractValue) => + (methodSymbol, abstractValue) => { // When doing this for reals, need to examine the method to make sure we're looking at the right method and arguments. @@ -1038,7 +1038,7 @@ TestTypeToTrackWithConstructor GetTestType() new PropertyMapperCollection( new PropertyMapper( // Definitely null => unflagged, definitely non-null => flagged, otherwise => maybe. "AString", - (PointsToAbstractValue pointsToAbstractValue) => + pointsToAbstractValue => { return pointsToAbstractValue.NullState switch { @@ -1051,7 +1051,7 @@ TestTypeToTrackWithConstructor GetTestType() new HazardousUsageEvaluatorCollection( new HazardousUsageEvaluator( HazardousUsageEvaluatorKind.Return, - (PropertySetAbstractValue abstractValue) => + abstractValue => { // With only one property being tracked, this is straightforward. return abstractValue[0] switch @@ -1142,7 +1142,7 @@ object TestMethod() new PropertyMapperCollection( new PropertyMapper( // Definitely null => unflagged, definitely non-null => flagged, otherwise => maybe. "AString", - (PointsToAbstractValue pointsToAbstractValue) => + pointsToAbstractValue => { return pointsToAbstractValue.NullState switch { @@ -1155,7 +1155,7 @@ object TestMethod() propertyIndex: 0), // Both AString and AnObject point to index 0. new PropertyMapper( // Definitely null => unflagged, definitely non-null => flagged, otherwise => maybe. "AnObject", - (PointsToAbstractValue pointsToAbstractValue) => + pointsToAbstractValue => { return pointsToAbstractValue.NullState switch { @@ -1169,7 +1169,7 @@ object TestMethod() new HazardousUsageEvaluatorCollection( new HazardousUsageEvaluator( // When TypeToTrack.Method() is invoked, need to evaluate its state. "Method", - (IMethodSymbol methodSymbol, PropertySetAbstractValue abstractValue) => + (methodSymbol, abstractValue) => { // When doing this for reals, need to examine the method to make sure we're looking at the right method and arguments. diff --git a/src/RoslynAnalyzers/Utilities/Compiler/Options/AbstractCategorizedAnalyzerConfigOptions.cs b/src/RoslynAnalyzers/Utilities/Compiler/Options/AbstractCategorizedAnalyzerConfigOptions.cs index 677f050498b13..45a7f16852e65 100644 --- a/src/RoslynAnalyzers/Utilities/Compiler/Options/AbstractCategorizedAnalyzerConfigOptions.cs +++ b/src/RoslynAnalyzers/Utilities/Compiler/Options/AbstractCategorizedAnalyzerConfigOptions.cs @@ -34,7 +34,7 @@ public T GetOptionValue(string optionName, SyntaxTree? tree, DiagnosticDescri optionName, kind, rule, - static (string s, TryParseValue tryParseValue, [MaybeNullWhen(returnValue: false)] out T parsedValue) => tryParseValue(s, out parsedValue), + static (s, tryParseValue, [MaybeNullWhen(returnValue: false)] out parsedValue) => tryParseValue(s, out parsedValue), tryParseValue, defaultValue, out var value)) diff --git a/src/RoslynAnalyzers/Utilities/Compiler/Options/AggregateCategorizedAnalyzerConfigOptions.cs b/src/RoslynAnalyzers/Utilities/Compiler/Options/AggregateCategorizedAnalyzerConfigOptions.cs index f2c2be47a47c2..1076a3673a69d 100644 --- a/src/RoslynAnalyzers/Utilities/Compiler/Options/AggregateCategorizedAnalyzerConfigOptions.cs +++ b/src/RoslynAnalyzers/Utilities/Compiler/Options/AggregateCategorizedAnalyzerConfigOptions.cs @@ -88,7 +88,7 @@ public T GetOptionValue(string optionName, SyntaxTree? tree, DiagnosticDescri kind, tree, rule, - static (string s, TryParseValue tryParseValue, [MaybeNullWhen(returnValue: false)] out T parsedValue) => tryParseValue(s, out parsedValue), + static (s, tryParseValue, [MaybeNullWhen(returnValue: false)] out parsedValue) => tryParseValue(s, out parsedValue), tryParseValue, defaultValue, out var value)) diff --git a/src/RoslynAnalyzers/Utilities/Compiler/Options/AnalyzerOptionsExtensions.cs b/src/RoslynAnalyzers/Utilities/Compiler/Options/AnalyzerOptionsExtensions.cs index 7591e6a8c8fe2..b22afb5a28d82 100644 --- a/src/RoslynAnalyzers/Utilities/Compiler/Options/AnalyzerOptionsExtensions.cs +++ b/src/RoslynAnalyzers/Utilities/Compiler/Options/AnalyzerOptionsExtensions.cs @@ -141,7 +141,7 @@ private static TEnum GetFlagsEnumOptionValue( var analyzerConfigOptions = options.GetOrComputeCategorizedAnalyzerConfigOptions(compilation); return analyzerConfigOptions.GetOptionValue( optionName, tree, rule, - tryParseValue: static (string value, out TEnum result) => Enum.TryParse(value, ignoreCase: true, result: out result), + tryParseValue: static (value, out result) => Enum.TryParse(value, ignoreCase: true, result: out result), defaultValue: defaultValue); } diff --git a/src/RoslynAnalyzers/Utilities/FlowAnalysis/FlowAnalysis/Analysis/DisposeAnalysis/DisposeAnalysis.cs b/src/RoslynAnalyzers/Utilities/FlowAnalysis/FlowAnalysis/Analysis/DisposeAnalysis/DisposeAnalysis.cs index 2809979ab4e9b..5ce34d0475b48 100644 --- a/src/RoslynAnalyzers/Utilities/FlowAnalysis/FlowAnalysis/Analysis/DisposeAnalysis/DisposeAnalysis.cs +++ b/src/RoslynAnalyzers/Utilities/FlowAnalysis/FlowAnalysis/Analysis/DisposeAnalysis/DisposeAnalysis.cs @@ -73,8 +73,7 @@ private DisposeAnalysis(DisposeAnalysisDomain analysisDomain, DisposeDataFlowOpe defaultPointsToAnalysisKind), performCopyAnalysis: analyzerOptions.GetCopyAnalysisOption(rule, owningSymbol, wellKnownTypeProvider.Compilation, defaultValue: performCopyAnalysisIfNotUserConfigured), - isDisposableTypeNotRequiringToBeDisposed: (ITypeSymbol typeSymbol) => - disposeAnalysisHelper?.IsDisposableTypeNotRequiringToBeDisposed(typeSymbol) == true + isDisposableTypeNotRequiringToBeDisposed: typeSymbol => disposeAnalysisHelper?.IsDisposableTypeNotRequiringToBeDisposed(typeSymbol) == true || analyzerOptions.IsConfiguredToSkipAnalysis(rule, typeSymbol, owningSymbol, wellKnownTypeProvider.Compilation), out pointsToAnalysisResult); } diff --git a/src/RoslynAnalyzers/Utilities/FlowAnalysis/FlowAnalysis/Analysis/PropertySetAnalysis/PropertySetAnalysis.PropertySetDataFlowOperationVisitor.cs b/src/RoslynAnalyzers/Utilities/FlowAnalysis/FlowAnalysis/Analysis/PropertySetAnalysis/PropertySetAnalysis.PropertySetDataFlowOperationVisitor.cs index c3e6515b97212..e49802c12a261 100644 --- a/src/RoslynAnalyzers/Utilities/FlowAnalysis/FlowAnalysis/Analysis/PropertySetAnalysis/PropertySetAnalysis.PropertySetDataFlowOperationVisitor.cs +++ b/src/RoslynAnalyzers/Utilities/FlowAnalysis/FlowAnalysis/Analysis/PropertySetAnalysis/PropertySetAnalysis.PropertySetDataFlowOperationVisitor.cs @@ -201,7 +201,7 @@ public override PropertySetAbstractValue VisitObjectCreation(IObjectCreationOper operation.Syntax, operation.Constructor, propertySetInstance, - (PropertySetAbstractValue abstractValue) => hazardousUsageEvaluator.InvocationEvaluator!( + abstractValue => hazardousUsageEvaluator.InvocationEvaluator!( operation.Constructor, abstractValue)); } @@ -466,7 +466,7 @@ public override PropertySetAbstractValue VisitInvocation_NonLambdaOrDelegateOrLo visitedArgument.Value.Syntax, null, visitedArgument.Value, - (PropertySetAbstractValue abstractValue) => argumentHazardousUsageEvaluator.ValueEvaluator!(abstractValue)); + abstractValue => argumentHazardousUsageEvaluator.ValueEvaluator!(abstractValue)); } } } @@ -490,7 +490,7 @@ public override PropertySetAbstractValue VisitInvocation_NonLambdaOrDelegateOrLo originalOperation.Syntax, method, propertySetInstance, - (PropertySetAbstractValue abstractValue) => hazardousUsageEvaluator!.InvocationEvaluator!(method, abstractValue)); + abstractValue => hazardousUsageEvaluator!.InvocationEvaluator!(method, abstractValue)); } else { @@ -659,7 +659,7 @@ protected override void ProcessReturnValue(IOperation? returnValue) returnValue.Syntax, null, returnValue, - (PropertySetAbstractValue abstractValue) => hazardousUsageEvaluator.ValueEvaluator!(abstractValue)); + abstractValue => hazardousUsageEvaluator.ValueEvaluator!(abstractValue)); } } diff --git a/src/RoslynAnalyzers/Utilities/FlowAnalysis/FlowAnalysis/Analysis/TaintedDataAnalysis/HardcodedSymmetricAlgorithmKeysSources.cs b/src/RoslynAnalyzers/Utilities/FlowAnalysis/FlowAnalysis/Analysis/TaintedDataAnalysis/HardcodedSymmetricAlgorithmKeysSources.cs index 703af4f7815bd..69a232747b7e6 100644 --- a/src/RoslynAnalyzers/Utilities/FlowAnalysis/FlowAnalysis/Analysis/TaintedDataAnalysis/HardcodedSymmetricAlgorithmKeysSources.cs +++ b/src/RoslynAnalyzers/Utilities/FlowAnalysis/FlowAnalysis/Analysis/TaintedDataAnalysis/HardcodedSymmetricAlgorithmKeysSources.cs @@ -38,7 +38,7 @@ private static ImmutableHashSet BuildSources() (argumentPointsTos, argumentValueContents) => argumentValueContents.Length == 1 && argumentValueContents[0].LiteralValues.Any( - (object? v) => v is string s && s.Length % 4 == 0 && IsLegalKeySize(s.Length * 3 / 4)) + v => v is string s && s.Length % 4 == 0 && IsLegalKeySize(s.Length * 3 / 4)) } ), }); diff --git a/src/Tools/PrepareTests/Program.cs b/src/Tools/PrepareTests/Program.cs index 9736449d3a423..4bc87e57c1389 100644 --- a/src/Tools/PrepareTests/Program.cs +++ b/src/Tools/PrepareTests/Program.cs @@ -21,10 +21,10 @@ public static int Main(string[] args) var options = new OptionSet() { - { "source=", "Path to binaries", (string s) => source = s }, - { "destination=", "Output path", (string s) => destination = s }, + { "source=", "Path to binaries", s => source = s }, + { "destination=", "Output path", s => destination = s }, { "unix", "If true, prepares tests for unix environment instead of Windows", o => isUnix = o is object }, - { "dotnetPath=", "Path to the dotnet CLI", (string s) => dotnetPath = s }, + { "dotnetPath=", "Path to the dotnet CLI", s => dotnetPath = s }, }; options.Parse(args); diff --git a/src/Tools/Source/RunTests/Options.cs b/src/Tools/Source/RunTests/Options.cs index 40460d1e477c9..a148c2dd517e0 100644 --- a/src/Tools/Source/RunTests/Options.cs +++ b/src/Tools/Source/RunTests/Options.cs @@ -166,30 +166,30 @@ public Options( string? targetBranchName = null; var optionSet = new OptionSet() { - { "dotnet=", "Path to dotnet", (string s) => dotnetFilePath = s }, - { "configuration=", "Configuration to test: Debug or Release", (string s) => configuration = s }, + { "dotnet=", "Path to dotnet", s => dotnetFilePath = s }, + { "configuration=", "Configuration to test: Debug or Release", s => configuration = s }, { "runtime=", "The runtime to test: both, core or framework", (TestRuntime t) => testRuntime = t}, - { "include=", "Expression for including unit test dlls: default *.UnitTests.dll", (string s) => includeFilter.Add(s) }, - { "exclude=", "Expression for excluding unit test dlls: default is empty", (string s) => excludeFilter.Add(s) }, - { "arch=", "Architecture to test on: x86, x64 or arm64", (string s) => architecture = s }, + { "include=", "Expression for including unit test dlls: default *.UnitTests.dll", s => includeFilter.Add(s) }, + { "exclude=", "Expression for excluding unit test dlls: default is empty", s => excludeFilter.Add(s) }, + { "arch=", "Architecture to test on: x86, x64 or arm64", s => architecture = s }, { "html", "Include HTML file output", o => includeHtml = o is object }, { "sequential", "Run tests sequentially", o => sequential = o is object }, { "helix", "Run tests on Helix", o => helix = o is object }, - { "helixQueueName=", "Name of the Helix queue to run tests on", (string s) => helixQueueName = s }, - { "helixApiAccessToken=", "Access token for internal helix queues", (string s) => helixApiAccessToken = s }, - { "testfilter=", "xUnit string to pass to --filter, e.g. FullyQualifiedName~TestClass1|Category=CategoryA", (string s) => testFilter = s }, + { "helixQueueName=", "Name of the Helix queue to run tests on", s => helixQueueName = s }, + { "helixApiAccessToken=", "Access token for internal helix queues", s => helixApiAccessToken = s }, + { "testfilter=", "xUnit string to pass to --filter, e.g. FullyQualifiedName~TestClass1|Category=CategoryA", s => testFilter = s }, { "timeout=", "Minute timeout to limit the tests to", (int i) => timeout = i }, - { "out=", "Test result file directory (when running on Helix, this is relative to the Helix work item directory)", (string s) => resultFileDirectory = s }, - { "logs=", "Log file directory (when running on Helix, this is relative to the Helix work item directory)", (string s) => logFileDirectory = s }, + { "out=", "Test result file directory (when running on Helix, this is relative to the Helix work item directory)", s => resultFileDirectory = s }, + { "logs=", "Log file directory (when running on Helix, this is relative to the Helix work item directory)", s => logFileDirectory = s }, { "display=", "Display", (Display d) => display = d }, - { "artifactspath=", "Path to the artifacts directory", (string s) => artifactsPath = s }, - { "procdumppath=", "Path to procdump", (string s) => procDumpFilePath = s }, + { "artifactspath=", "Path to the artifacts directory", s => artifactsPath = s }, + { "procdumppath=", "Path to procdump", s => procDumpFilePath = s }, { "collectdumps", "Whether or not to gather dumps on timeouts and crashes", o => collectDumps = o is object }, - { "accessToken=", "Pipeline access token with permissions to view test history", (string s) => accessToken = s }, - { "projectUri=", "ADO project containing the pipeline", (string s) => projectUri = s }, - { "pipelineDefinitionId=", "Pipeline definition id", (string s) => pipelineDefinitionId = s }, - { "phaseName=", "Pipeline phase name associated with this test run", (string s) => phaseName = s }, - { "targetBranchName=", "Target branch of this pipeline run", (string s) => targetBranchName = s }, + { "accessToken=", "Pipeline access token with permissions to view test history", s => accessToken = s }, + { "projectUri=", "ADO project containing the pipeline", s => projectUri = s }, + { "pipelineDefinitionId=", "Pipeline definition id", s => pipelineDefinitionId = s }, + { "phaseName=", "Pipeline phase name associated with this test run", s => phaseName = s }, + { "targetBranchName=", "Target branch of this pipeline run", s => targetBranchName = s }, }; List assemblyList; diff --git a/src/VisualStudio/Core/Def/EditorConfigSettings/Common/TableControlFocusFixer.cs b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/TableControlFocusFixer.cs index ec2563b334319..c077bc100d0c7 100644 --- a/src/VisualStudio/Core/Def/EditorConfigSettings/Common/TableControlFocusFixer.cs +++ b/src/VisualStudio/Core/Def/EditorConfigSettings/Common/TableControlFocusFixer.cs @@ -20,7 +20,7 @@ internal static class TableControlFocusFixer /// public static void DoNotLoseFocusOnBucketExpandOrCollapse(this IWpfTableControl tableControl) { - tableControl.Control.PreviewLostKeyboardFocus += (object sender, KeyboardFocusChangedEventArgs e) => + tableControl.Control.PreviewLostKeyboardFocus += (sender, e) => { // The tabular data control is a list view, the new focus changing to a different control tells us we've hit this case. // This workaround will break if the underlying implementation of the tabular data control is changed someday. diff --git a/src/VisualStudio/Core/Def/ProjectSystem/VisualStudioWorkspaceImpl.cs b/src/VisualStudio/Core/Def/ProjectSystem/VisualStudioWorkspaceImpl.cs index 5adcc2e5756bc..76b11a8c7963a 100644 --- a/src/VisualStudio/Core/Def/ProjectSystem/VisualStudioWorkspaceImpl.cs +++ b/src/VisualStudio/Core/Def/ProjectSystem/VisualStudioWorkspaceImpl.cs @@ -172,7 +172,7 @@ internal void SubscribeExternalErrorDiagnosticUpdateSourceToSolutionBuildEvents( // This pattern ensures that we are called whenever the build starts/completes even if it is already in progress. KnownUIContexts.SolutionBuildingContext.WhenActivated(() => { - KnownUIContexts.SolutionBuildingContext.UIContextChanged += (object _, UIContextChangedEventArgs e) => + KnownUIContexts.SolutionBuildingContext.UIContextChanged += (_, e) => { if (e.Activated) { diff --git a/src/VisualStudio/Core/Def/UnusedReferences/Dialog/UnusedReferencesTableProvider.ColumnDefinitions.cs b/src/VisualStudio/Core/Def/UnusedReferences/Dialog/UnusedReferencesTableProvider.ColumnDefinitions.cs index ec215d1bc0c40..1547f41a2f163 100644 --- a/src/VisualStudio/Core/Def/UnusedReferences/Dialog/UnusedReferencesTableProvider.ColumnDefinitions.cs +++ b/src/VisualStudio/Core/Def/UnusedReferences/Dialog/UnusedReferencesTableProvider.ColumnDefinitions.cs @@ -314,7 +314,7 @@ public override bool TryCreateColumnContent(ITableEntryHandle entry, bool single }; } - combobox.SelectionChanged += (object sender, SelectionChangedEventArgs e) => + combobox.SelectionChanged += (sender, e) => { var action = combobox.SelectedIndex switch { diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeGeneration/CSharpCodeGenerationService.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeGeneration/CSharpCodeGenerationService.cs index 2a2dace9c17a9..7334ce1a85a21 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeGeneration/CSharpCodeGenerationService.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/CodeGeneration/CSharpCodeGenerationService.cs @@ -454,13 +454,13 @@ private static SyntaxList RemoveAttributeFromAttributeLists if (attributes.Count == 1) { // Remove the entire attribute list. - ComputePositionAndTriviaForRemoveAttributeList(attributeList, (SyntaxTrivia t) => t.IsKind(SyntaxKind.EndOfLineTrivia), out positionOfRemovedNode, out trivia); + ComputePositionAndTriviaForRemoveAttributeList(attributeList, t => t.IsKind(SyntaxKind.EndOfLineTrivia), out positionOfRemovedNode, out trivia); newAttributeLists = attributeLists.Where(aList => aList != attributeList); } else { // Remove just the given attribute from the attribute list. - ComputePositionAndTriviaForRemoveAttributeFromAttributeList(attributeToRemove, (SyntaxToken t) => t.IsKind(SyntaxKind.CommaToken), out positionOfRemovedNode, out trivia); + ComputePositionAndTriviaForRemoveAttributeFromAttributeList(attributeToRemove, t => t.IsKind(SyntaxKind.CommaToken), out positionOfRemovedNode, out trivia); var newAttributes = SeparatedList(attributes.Where(a => a != attributeToRemove)); var newAttributeList = attributeList.WithAttributes(newAttributes); newAttributeLists = attributeLists.Select(attrList => attrList == attributeList ? newAttributeList : attrList); From 9dc7698ac1997f574a106a6f952db62c6b9a579f Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 19:56:40 +0200 Subject: [PATCH 131/353] Revert --- .../ExpressionCompiler/CompilationContext.cs | 14 +++++++------- .../CSharp/Test/ExpressionCompiler/LocalsTests.cs | 2 +- .../ExpressionCompiler/MissingAssemblyTests.cs | 14 +++++++------- .../CSharp/Test/ExpressionCompiler/WinMdTests.cs | 2 +- .../ExpressionCompiler/ExpressionCompiler.cs | 2 +- .../Source/FunctionResolver/FunctionResolver.cs | 10 +++++----- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs index 5ba924e7ba0ee..04af7e975cd94 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs @@ -207,7 +207,7 @@ private EENamedTypeSymbol CreateSynthesizedType( typeName, methodName, this, - (method, diags, out declaredLocals, out properties) => + (EEMethodSymbol method, DiagnosticBag diags, out ImmutableArray declaredLocals, out ResultProperties properties) => { var hasDisplayClassThis = GetThisProxy(_displayClassVariables) != null; var binder = ExtendBinderChain( @@ -246,7 +246,7 @@ internal bool TryCompileAssignment( typeName, methodName, this, - (method, diags, out declaredLocals, out properties) => + (EEMethodSymbol method, DiagnosticBag diags, out ImmutableArray declaredLocals, out ResultProperties properties) => { var hasDisplayClassThis = GetThisProxy(_displayClassVariables) != null; var binder = ExtendBinderChain( @@ -367,7 +367,7 @@ private static string GetNextMethodName(ArrayBuilder builder) container, methodName, syntax, - (method, diags, out declaredLocals, out properties) => + (EEMethodSymbol method, DiagnosticBag diags, out ImmutableArray declaredLocals, out ResultProperties properties) => { declaredLocals = ImmutableArray.Empty; var expression = new BoundLocal(syntax, local, constantValueOpt: null, type: local.Type); @@ -620,7 +620,7 @@ internal EEMethodSymbol CreateMethod( private EEMethodSymbol GetLocalMethod(EENamedTypeSymbol container, string methodName, string localName, int localIndex) { var syntax = SyntaxFactory.IdentifierName(localName); - return CreateMethod(container, methodName, syntax, (method, diagnostics, out declaredLocals, out properties) => + return CreateMethod(container, methodName, syntax, (EEMethodSymbol method, DiagnosticBag diagnostics, out ImmutableArray declaredLocals, out ResultProperties properties) => { declaredLocals = ImmutableArray.Empty; @@ -643,7 +643,7 @@ private EEMethodSymbol GetLocalMethod(EENamedTypeSymbol container, string method private EEMethodSymbol GetParameterMethod(EENamedTypeSymbol container, string methodName, string parameterName, int parameterIndex) { var syntax = SyntaxFactory.IdentifierName(parameterName); - return CreateMethod(container, methodName, syntax, (method, diagnostics, out declaredLocals, out properties) => + return CreateMethod(container, methodName, syntax, (EEMethodSymbol method, DiagnosticBag diagnostics, out ImmutableArray declaredLocals, out ResultProperties properties) => { declaredLocals = ImmutableArray.Empty; var parameter = method.Parameters[parameterIndex]; @@ -656,7 +656,7 @@ private EEMethodSymbol GetParameterMethod(EENamedTypeSymbol container, string me private EEMethodSymbol GetThisMethod(EENamedTypeSymbol container, string methodName) { var syntax = SyntaxFactory.ThisExpression(); - return CreateMethod(container, methodName, syntax, (method, diagnostics, out declaredLocals, out properties) => + return CreateMethod(container, methodName, syntax, (EEMethodSymbol method, DiagnosticBag diagnostics, out ImmutableArray declaredLocals, out ResultProperties properties) => { declaredLocals = ImmutableArray.Empty; var expression = new BoundThisReference(syntax, GetNonDisplayClassContainer(container.SubstitutedSourceType)); @@ -668,7 +668,7 @@ private EEMethodSymbol GetThisMethod(EENamedTypeSymbol container, string methodN private EEMethodSymbol GetTypeVariablesMethod(EENamedTypeSymbol container, string methodName, NamedTypeSymbol typeVariablesType) { var syntax = SyntaxFactory.IdentifierName(SyntaxFactory.MissingToken(SyntaxKind.IdentifierToken)); - return CreateMethod(container, methodName, syntax, (method, diagnostics, out declaredLocals, out properties) => + return CreateMethod(container, methodName, syntax, (EEMethodSymbol method, DiagnosticBag diagnostics, out ImmutableArray declaredLocals, out ResultProperties properties) => { declaredLocals = ImmutableArray.Empty; var type = method.TypeMap.SubstituteNamedType(typeVariablesType); diff --git a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/LocalsTests.cs b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/LocalsTests.cs index a3720823e5853..b79db1b87fdbe 100644 --- a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/LocalsTests.cs +++ b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/LocalsTests.cs @@ -3825,7 +3825,7 @@ static void Main() var badConst = new MockSymUnmanagedConstant( "a", 1, - (bufferLength, out count, name) => + (int bufferLength, out int count, byte[] name) => { count = 0; return Roslyn.Test.Utilities.HResult.E_NOTIMPL; diff --git a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/MissingAssemblyTests.cs b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/MissingAssemblyTests.cs index 63c89b8395aa9..2a1b5564ebd61 100644 --- a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/MissingAssemblyTests.cs +++ b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/MissingAssemblyTests.cs @@ -445,7 +445,7 @@ IntPtr gmdbpf(AssemblyIdentity assemblyIdentity, out uint uSize) public void ShouldTryAgain_CORDBG_E_MISSING_METADATA() { ShouldTryAgain_False( - (assemblyIdentity, out uSize) => + (AssemblyIdentity assemblyIdentity, out uint uSize) => { Marshal.ThrowExceptionForHR(DkmExceptionUtilities.CORDBG_E_MISSING_METADATA); throw ExceptionUtilities.Unreachable(); @@ -456,7 +456,7 @@ public void ShouldTryAgain_CORDBG_E_MISSING_METADATA() public void ShouldTryAgain_COR_E_BADIMAGEFORMAT() { ShouldTryAgain_False( - (assemblyIdentity, out uSize) => + (AssemblyIdentity assemblyIdentity, out uint uSize) => { Marshal.ThrowExceptionForHR(DkmExceptionUtilities.COR_E_BADIMAGEFORMAT); throw ExceptionUtilities.Unreachable(); @@ -467,7 +467,7 @@ public void ShouldTryAgain_COR_E_BADIMAGEFORMAT() public void ShouldTryAgain_ObjectDisposedException() { ShouldTryAgain_False( - (assemblyIdentity, out uSize) => + (AssemblyIdentity assemblyIdentity, out uint uSize) => { throw new ObjectDisposedException("obj"); }); @@ -658,7 +658,7 @@ void M() diagnostics.Add(new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_NoTypeDef, "MissingType", missingIdentity), Location.None)); return null; }, - (assemblyIdentity, out uSize) => + (AssemblyIdentity assemblyIdentity, out uint uSize) => { uSize = (uint)missingModule.MetadataLength; return missingModule.MetadataAddress; @@ -707,7 +707,7 @@ void M() return null; } }, - (assemblyIdentity, out uSize) => + (AssemblyIdentity assemblyIdentity, out uint uSize) => { uSize = (uint)missingModule.MetadataLength; return missingModule.MetadataAddress; @@ -753,7 +753,7 @@ class UseLinq "args.Where(a => a.Length > 0)", ImmutableArray.Empty, (_1, _2) => context, // ignore new blocks and just keep using the same failed context... - (assemblyIdentity, out uSize) => + (AssemblyIdentity assemblyIdentity, out uint uSize) => { retryCount++; MetadataBlock block; @@ -924,7 +924,7 @@ private static void TupleContextNoSystemRuntime(string source, string methodName methodVersion: 1, ilOffset: 0, localSignatureToken: localSignatureToken), - (assemblyIdentity, out uSize) => + (AssemblyIdentity assemblyIdentity, out uint uSize) => { retryCount++; Assert.Equal("System.Runtime", assemblyIdentity.Name); diff --git a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/WinMdTests.cs b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/WinMdTests.cs index d3fe89d45f834..28a79165f7940 100644 --- a/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/WinMdTests.cs +++ b/src/ExpressionEvaluator/CSharp/Test/ExpressionCompiler/WinMdTests.cs @@ -351,7 +351,7 @@ static void M(C c) { return CreateMethodContext(runtime, "C.M"); }, - (assembly, out size) => + (AssemblyIdentity assembly, out uint size) => { // Compilation should succeed without retry if we redirect assembly refs correctly. // Throwing so that we don't loop forever (as we did before fix)... diff --git a/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/ExpressionCompiler.cs b/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/ExpressionCompiler.cs index f768667fd58b9..efc3d3308e14d 100644 --- a/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/ExpressionCompiler.cs +++ b/src/ExpressionEvaluator/Core/Source/ExpressionCompiler/ExpressionCompiler.cs @@ -405,7 +405,7 @@ private bool TryCompileWithRetry( DiagnosticFormatter, createContext, compile, - (assemblyIdentity, out size) => appDomain.GetMetaDataBytesPtr(assemblyIdentity.GetDisplayName(), out size), + (AssemblyIdentity assemblyIdentity, out uint size) => appDomain.GetMetaDataBytesPtr(assemblyIdentity.GetDisplayName(), out size), out result, out errorMessage); } diff --git a/src/ExpressionEvaluator/Core/Source/FunctionResolver/FunctionResolver.cs b/src/ExpressionEvaluator/Core/Source/FunctionResolver/FunctionResolver.cs index 7db3f89876645..0a0ed3c08de17 100644 --- a/src/ExpressionEvaluator/Core/Source/FunctionResolver/FunctionResolver.cs +++ b/src/ExpressionEvaluator/Core/Source/FunctionResolver/FunctionResolver.cs @@ -150,11 +150,11 @@ internal sealed override Guid GetLanguageId(DkmRuntimeFunctionResolutionRequest private static OnFunctionResolvedDelegate OnFunctionResolved(DkmWorkList workList) { - return (module, - request, - token, - version, - ilOffset) => + return (DkmClrModuleInstance module, + DkmRuntimeFunctionResolutionRequest request, + int token, + int version, + int ilOffset) => { var address = DkmClrInstructionAddress.Create( module.RuntimeInstance, From 44c71585c8322c15a9d7be365f45cc5a7b1b60f3 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 20:05:29 +0200 Subject: [PATCH 132/353] Update code to use null propagation --- Roslyn.sln | 7 +++++-- .../GenerateEqualsAndGetHashCodeFromMembersTests.cs | 5 +---- .../Core/InlineRename/InlineRenameSession.cs | 9 +++------ .../InlineRename/UI/Adornment/RenameFlyoutViewModel.cs | 5 +---- .../Shared/Utilities/CaretPreservingEditTransaction.cs | 5 +---- ...atureHelpPresenter.SignatureHelpPresenterSession.cs | 5 +---- .../CodeActions/AbstractCodeActionTest.cs | 5 +---- .../GenerateOverridesWithDialogCodeAction.cs | 5 +---- .../Core/Portable/QuickInfo/QuickInfoUtilities.cs | 5 +---- .../AbstractCodeActionTest_NoEditor.cs | 5 +---- src/Scripting/Core/ScriptBuilder.cs | 5 +---- .../Def/InheritanceMargin/InheritanceMarginLogger.cs | 5 +---- src/VisualStudio/Core/Def/Utilities/TaskItemsEnum.cs | 5 +---- .../Impl/SolutionExplorer/AnalyzersCommandHandler.cs | 10 ++-------- 14 files changed, 21 insertions(+), 60 deletions(-) diff --git a/Roslyn.sln b/Roslyn.sln index 6fca77405900e..980009f1a1d57 100644 --- a/Roslyn.sln +++ b/Roslyn.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31319.15 +# Visual Studio Version 18 +VisualStudioVersion = 18.0.10623.112 main MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RoslynDeployment", "src\Deployment\RoslynDeployment.csproj", "{600AF682-E097-407B-AD85-EE3CED37E680}" EndProject @@ -2207,8 +2207,11 @@ Global src\Workspaces\SharedUtilitiesAndExtensions\Workspace\VisualBasic\VisualBasicWorkspaceExtensions.projitems*{57ca988d-f010-4bf2-9a2e-07d6dcd2ff2c}*SharedItemsImports = 5 src\Analyzers\CSharp\Tests\CSharpAnalyzers.UnitTests.projitems*{58969243-7f59-4236-93d0-c93b81f569b3}*SharedItemsImports = 13 src\Dependencies\Collections\Microsoft.CodeAnalysis.Collections.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 + src\Dependencies\Contracts\Microsoft.CodeAnalysis.Contracts.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 src\Dependencies\PooledObjects\Microsoft.CodeAnalysis.PooledObjects.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 + src\Dependencies\Threading\Microsoft.CodeAnalysis.Threading.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 src\Workspaces\SharedUtilitiesAndExtensions\Compiler\Core\CompilerExtensions.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 + src\Workspaces\SharedUtilitiesAndExtensions\Compiler\Extensions\Microsoft.CodeAnalysis.Extensions.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 src\Workspaces\SharedUtilitiesAndExtensions\Workspace\Core\WorkspaceExtensions.projitems*{5f8d2414-064a-4b3a-9b42-8e2a04246be5}*SharedItemsImports = 5 src\Analyzers\Core\CodeFixes\CodeFixes.projitems*{5ff1e493-69cc-4d0b-83f2-039f469a04e1}*SharedItemsImports = 5 src\Workspaces\SharedUtilitiesAndExtensions\Workspace\Core\WorkspaceExtensions.projitems*{5ff1e493-69cc-4d0b-83f2-039f469a04e1}*SharedItemsImports = 5 diff --git a/src/EditorFeatures/CSharpTest/CodeActions/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs index fbda58a3296d7..65c2b53b336f4 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs @@ -69,10 +69,7 @@ private static OptionsCollection PreferExplicitTypeWithInfo() internal static void EnableOption(ImmutableArray options, string id) { var option = options.FirstOrDefault(o => o.Id == id); - if (option != null) - { - option.Value = true; - } + option?.Value = true; } [Fact] diff --git a/src/EditorFeatures/Core/InlineRename/InlineRenameSession.cs b/src/EditorFeatures/Core/InlineRename/InlineRenameSession.cs index 8c1cdffb5808a..33efe8bdf1b58 100644 --- a/src/EditorFeatures/Core/InlineRename/InlineRenameSession.cs +++ b/src/EditorFeatures/Core/InlineRename/InlineRenameSession.cs @@ -809,12 +809,9 @@ private async Task CommitWorkerAsync(bool previewChanges, bool canUseBackg previewChanges = previewChanges || PreviewChanges; - if (editorUIOperationContext is not null) - { - // Prevent Editor's typing responsiveness auto canceling the rename operation. - // InlineRenameSession will call IUIThreadOperationExecutor to sets up our own IUIThreadOperationContext - editorUIOperationContext.TakeOwnership(); - } + // Prevent Editor's typing responsiveness auto canceling the rename operation. + // InlineRenameSession will call IUIThreadOperationExecutor to sets up our own IUIThreadOperationContext + editorUIOperationContext?.TakeOwnership(); try { diff --git a/src/EditorFeatures/Core/InlineRename/UI/Adornment/RenameFlyoutViewModel.cs b/src/EditorFeatures/Core/InlineRename/UI/Adornment/RenameFlyoutViewModel.cs index f0d2baf6d6704..0682af9dd88d2 100644 --- a/src/EditorFeatures/Core/InlineRename/UI/Adornment/RenameFlyoutViewModel.cs +++ b/src/EditorFeatures/Core/InlineRename/UI/Adornment/RenameFlyoutViewModel.cs @@ -325,10 +325,7 @@ protected virtual void Dispose(bool disposing) Session.ReplacementsComputed -= OnReplacementsComputed; Session.CommitStateChange -= CommitStateChange; - if (SmartRenameViewModel is not null) - { - SmartRenameViewModel.Dispose(); - } + SmartRenameViewModel?.Dispose(); UnregisterOleComponent(); } diff --git a/src/EditorFeatures/Core/Shared/Utilities/CaretPreservingEditTransaction.cs b/src/EditorFeatures/Core/Shared/Utilities/CaretPreservingEditTransaction.cs index 5bcb2e0203bce..7dfdafeb9d975 100644 --- a/src/EditorFeatures/Core/Shared/Utilities/CaretPreservingEditTransaction.cs +++ b/src/EditorFeatures/Core/Shared/Utilities/CaretPreservingEditTransaction.cs @@ -93,10 +93,7 @@ public IMergeTextUndoTransactionPolicy? MergePolicy set { - if (_transaction != null) - { - _transaction.MergePolicy = value; - } + _transaction?.MergePolicy = value; } } diff --git a/src/EditorFeatures/Core/SignatureHelp/Presentation/SignatureHelpPresenter.SignatureHelpPresenterSession.cs b/src/EditorFeatures/Core/SignatureHelp/Presentation/SignatureHelpPresenter.SignatureHelpPresenterSession.cs index 0c1dd62d2d604..95d84bf617814 100644 --- a/src/EditorFeatures/Core/SignatureHelp/Presentation/SignatureHelpPresenter.SignatureHelpPresenterSession.cs +++ b/src/EditorFeatures/Core/SignatureHelp/Presentation/SignatureHelpPresenter.SignatureHelpPresenterSession.cs @@ -97,10 +97,7 @@ public void PresentItems( Contract.ThrowIfNull(_signatureMap); var defaultValue = _signatureMap.GetValueOrDefault(_selectedItem); - if (_editorSessionOpt != null) - { - _editorSessionOpt.SelectedSignature = defaultValue; - } + _editorSessionOpt?.SelectedSignature = defaultValue; } finally { diff --git a/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/AbstractCodeActionTest.cs b/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/AbstractCodeActionTest.cs index aa5f7030fb9f9..7090b5e0b51a7 100644 --- a/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/AbstractCodeActionTest.cs +++ b/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/AbstractCodeActionTest.cs @@ -166,10 +166,7 @@ internal static void EnableOptions( internal static void EnableOption(ImmutableArray options, string id) { var option = options.FirstOrDefault(o => o.Id == id); - if (option != null) - { - option.Value = true; - } + option?.Value = true; } internal Task TestWithPickMembersDialogAsync( diff --git a/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesWithDialogCodeAction.cs b/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesWithDialogCodeAction.cs index bd8c52909be04..049fbf52bbe4c 100644 --- a/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesWithDialogCodeAction.cs +++ b/src/Features/Core/Portable/GenerateOverrides/GenerateOverridesWithDialogCodeAction.cs @@ -102,10 +102,7 @@ private sealed class ChangeOptionValueOperation(bool selectedAll) : CodeActionOp public override void Apply(Workspace workspace, CancellationToken cancellationToken) { var service = workspace.Services.GetService(); - if (service != null) - { - service.GenerateOverrides = _selectedAll; - } + service?.GenerateOverrides = _selectedAll; } } } diff --git a/src/Features/Core/Portable/QuickInfo/QuickInfoUtilities.cs b/src/Features/Core/Portable/QuickInfo/QuickInfoUtilities.cs index fdb53dfa525e5..a318927b44cfa 100644 --- a/src/Features/Core/Portable/QuickInfo/QuickInfoUtilities.cs +++ b/src/Features/Core/Portable/QuickInfo/QuickInfoUtilities.cs @@ -77,10 +77,7 @@ public static async Task CreateQuickInfoItemAsync( if (groups.TryGetValue(SymbolDescriptionGroups.Documentation, out var docParts) && !docParts.IsDefaultOrEmpty) { AddSection(QuickInfoSectionKinds.DocumentationComments, docParts); - if (onTheFlyDocsInfo != null) - { - onTheFlyDocsInfo.HasComments = true; - } + onTheFlyDocsInfo?.HasComments = true; } if (options.QuickInfoOptions.ShowRemarksInQuickInfo && diff --git a/src/Features/DiagnosticsTestUtilities/CodeActionsLegacy/AbstractCodeActionTest_NoEditor.cs b/src/Features/DiagnosticsTestUtilities/CodeActionsLegacy/AbstractCodeActionTest_NoEditor.cs index 887450a6e6f1a..12d8bd9c7eb01 100644 --- a/src/Features/DiagnosticsTestUtilities/CodeActionsLegacy/AbstractCodeActionTest_NoEditor.cs +++ b/src/Features/DiagnosticsTestUtilities/CodeActionsLegacy/AbstractCodeActionTest_NoEditor.cs @@ -174,10 +174,7 @@ internal static void EnableOptions( internal static void EnableOption(ImmutableArray options, string id) { var option = options.FirstOrDefault(o => o.Id == id); - if (option != null) - { - option.Value = true; - } + option?.Value = true; } internal Task TestWithPickMembersDialogAsync( diff --git a/src/Scripting/Core/ScriptBuilder.cs b/src/Scripting/Core/ScriptBuilder.cs index f345991323d38..68e2708651be0 100644 --- a/src/Scripting/Core/ScriptBuilder.cs +++ b/src/Scripting/Core/ScriptBuilder.cs @@ -152,10 +152,7 @@ private Func> Build( peStream.Position = 0; - if (pdbStreamOpt != null) - { - pdbStreamOpt.Position = 0; - } + pdbStreamOpt?.Position = 0; var assembly = _assemblyLoader.LoadAssemblyFromStream(peStream, pdbStreamOpt); var runtimeEntryPoint = GetEntryPointRuntimeMethod(entryPoint, assembly); diff --git a/src/VisualStudio/Core/Def/InheritanceMargin/InheritanceMarginLogger.cs b/src/VisualStudio/Core/Def/InheritanceMargin/InheritanceMarginLogger.cs index b88af7fc759c5..3783866bf71d3 100644 --- a/src/VisualStudio/Core/Def/InheritanceMargin/InheritanceMarginLogger.cs +++ b/src/VisualStudio/Core/Def/InheritanceMargin/InheritanceMarginLogger.cs @@ -34,10 +34,7 @@ public static void ReportTelemetry() static m => { var histogramLogAggregator = s_histogramLogAggregator.GetValue(ActionInfo.GetInheritanceMarginMembers); - if (histogramLogAggregator != null) - { - histogramLogAggregator.WriteTelemetryPropertiesTo(m, nameof(ActionInfo.GetInheritanceMarginMembers) + "."); - } + histogramLogAggregator?.WriteTelemetryPropertiesTo(m, nameof(ActionInfo.GetInheritanceMarginMembers) + "."); })); } } diff --git a/src/VisualStudio/Core/Def/Utilities/TaskItemsEnum.cs b/src/VisualStudio/Core/Def/Utilities/TaskItemsEnum.cs index d64bf30a8c9ed..b160cefe8ece0 100644 --- a/src/VisualStudio/Core/Def/Utilities/TaskItemsEnum.cs +++ b/src/VisualStudio/Core/Def/Utilities/TaskItemsEnum.cs @@ -29,10 +29,7 @@ int IVsEnumTaskItems.Next(uint celt, IVsTaskItem[] rgelt, uint[] pceltFetched) _next += i; - if (pceltFetched != null) - { - pceltFetched[0] = (uint)i; - } + pceltFetched?[0] = (uint)i; return (i == celt) ? VSConstants.S_OK : VSConstants.S_FALSE; } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersCommandHandler.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersCommandHandler.cs index f1fed7301863e..278eb376d90ca 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersCommandHandler.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzersCommandHandler.cs @@ -185,10 +185,7 @@ private bool ShouldShowAnalyzerContextMenu(IEnumerable items) private void UpdateAnalyzerContextMenu() { - if (_removeMenuItem != null) - { - _removeMenuItem.Enabled = _allowProjectSystemOperations; - } + _removeMenuItem?.Enabled = _allowProjectSystemOperations; } public IContextMenuController DiagnosticContextMenuController @@ -557,10 +554,7 @@ private static void UpdateProjectConfigurationsToUseRuleSetFile(EnvDTE.Project e { var codeAnalysisRuleSetFileProperty = properties?.Item("CodeAnalysisRuleSet"); - if (codeAnalysisRuleSetFileProperty != null) - { - codeAnalysisRuleSetFileProperty.Value = fileName; - } + codeAnalysisRuleSetFileProperty?.Value = fileName; } catch (ArgumentException) { From 859c168c49bd2ce02ba6ad748d1e8d15e87e5df7 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 20:57:11 +0200 Subject: [PATCH 133/353] REstore api --- .../Core/Def/Progression/GraphNodeCreation.cs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs diff --git a/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs b/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs new file mode 100644 index 0000000000000..5da619a21bf85 --- /dev/null +++ b/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.VisualStudio.GraphModel; + +namespace Microsoft.VisualStudio.LanguageServices.Progression; + +/// +/// A helper class that implements the creation of s. +/// +public static class GraphNodeCreation +{ + public static Task CreateNodeIdAsync(ISymbol symbol, Solution solution, CancellationToken cancellationToken) + { + throw new NotSupportedException(); + } + + public static Task CreateNodeAsync(this Graph graph, ISymbol symbol, Solution solution, CancellationToken cancellationToken) + { + throw new NotSupportedException(); + } +} From 0d8c514083b438320fefefe5a6bd5a64d864dbc6 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 28 May 2025 21:02:54 +0200 Subject: [PATCH 134/353] REstore api --- .../Core/Def/Progression/GraphNodeCreation.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs b/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs index 5da619a21bf85..0988533c78194 100644 --- a/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs +++ b/src/VisualStudio/Core/Def/Progression/GraphNodeCreation.cs @@ -2,12 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.VisualStudio.GraphModel; +#pragma warning disable IDE0060 // Remove unused parameter + namespace Microsoft.VisualStudio.LanguageServices.Progression; /// @@ -16,12 +17,8 @@ namespace Microsoft.VisualStudio.LanguageServices.Progression; public static class GraphNodeCreation { public static Task CreateNodeIdAsync(ISymbol symbol, Solution solution, CancellationToken cancellationToken) - { - throw new NotSupportedException(); - } + => Task.FromResult(GraphNodeId.Empty); public static Task CreateNodeAsync(this Graph graph, ISymbol symbol, Solution solution, CancellationToken cancellationToken) - { - throw new NotSupportedException(); - } + => Task.FromResult(graph.Nodes.GetOrCreate(GraphNodeId.Empty)); } From 95ae5173f02dafdcb27afa20ac15e2a02dda8586 Mon Sep 17 00:00:00 2001 From: Julia Feng Date: Wed, 28 May 2025 15:33:51 -0700 Subject: [PATCH 135/353] add to external access --- .../Analyzer/CopilotAnalysisUtilities.cs | 22 +++++++++++++++++++ .../Copilot/InternalAPI.Unshipped.txt | 3 +++ 2 files changed, 25 insertions(+) create mode 100644 src/Features/ExternalAccess/Copilot/Analyzer/CopilotAnalysisUtilities.cs diff --git a/src/Features/ExternalAccess/Copilot/Analyzer/CopilotAnalysisUtilities.cs b/src/Features/ExternalAccess/Copilot/Analyzer/CopilotAnalysisUtilities.cs new file mode 100644 index 0000000000000..087ab95f6563e --- /dev/null +++ b/src/Features/ExternalAccess/Copilot/Analyzer/CopilotAnalysisUtilities.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Copilot; +using Microsoft.CodeAnalysis.Text; + +namespace Microsoft.CodeAnalysis.ExternalAccess.Copilot; +internal class CopilotAnalysisUtilities +{ + public static Task AnalyzeCopilotChangeAsync( + Document document, + bool accepted, + string featureId, + string proposalId, + IEnumerable textChanges, + CancellationToken cancellationToken) + => CopilotChangeAnalysisUtilities.AnalyzeCopilotChangeAsync(document, accepted, featureId, proposalId, textChanges, cancellationToken); +} diff --git a/src/Features/ExternalAccess/Copilot/InternalAPI.Unshipped.txt b/src/Features/ExternalAccess/Copilot/InternalAPI.Unshipped.txt index 5203c1fd27fa9..b31b6145aee6b 100644 --- a/src/Features/ExternalAccess/Copilot/InternalAPI.Unshipped.txt +++ b/src/Features/ExternalAccess/Copilot/InternalAPI.Unshipped.txt @@ -30,6 +30,8 @@ Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion.TraitItem.TraitItem(Mic Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion.TraitItem.TraitItem(string! name, string! value, int importance = 0) -> void Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion.TraitItem.Value.get -> string! Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion.TraitItem.Value.init -> void +Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotAnalysisUtilities +Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotAnalysisUtilities.CopilotAnalysisUtilities() -> void Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotChecksumWrapper Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotChecksumWrapper.Equals(Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotChecksumWrapper? other) -> bool Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotDocumentationCommentProposalWrapper @@ -125,6 +127,7 @@ static Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion.CodeSnippetItem. static Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion.CodeSnippetItem.operator ==(Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion.CodeSnippetItem? left, Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion.CodeSnippetItem? right) -> bool static Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion.TraitItem.operator !=(Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion.TraitItem? left, Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion.TraitItem? right) -> bool static Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion.TraitItem.operator ==(Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion.TraitItem? left, Microsoft.CodeAnalysis.ExternalAccess.Copilot.Completion.TraitItem? right) -> bool +static Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotAnalysisUtilities.AnalyzeCopilotChangeAsync(Microsoft.CodeAnalysis.Document! document, bool accepted, string! featureId, string! proposalId, System.Collections.Generic.IEnumerable! textChanges, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! static Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotChecksumWrapper.Create(System.Collections.Immutable.ImmutableArray values) -> Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotChecksumWrapper! static Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotUtilities.GetContainingMethodDeclarationAsync(Microsoft.CodeAnalysis.Document! document, int position, bool useFullSpan, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! static Microsoft.CodeAnalysis.ExternalAccess.Copilot.CopilotUtilities.GetCopilotSuggestionDiagnosticTag() -> string! From 21d3658b5c4e04d4f9e2bf0027bae51d19e57f57 Mon Sep 17 00:00:00 2001 From: "gel@microsoft.com" Date: Wed, 28 May 2025 16:58:36 -0700 Subject: [PATCH 136/353] Add direct IVTs to internal projects --- eng/targets/Settings.props | 1 + .../Portable/Microsoft.CodeAnalysis.CSharp.Features.csproj | 1 + .../Core/Portable/Microsoft.CodeAnalysis.Features.csproj | 1 + .../Portable/Microsoft.CodeAnalysis.CSharp.Workspaces.csproj | 1 + .../Core/Portable/Microsoft.CodeAnalysis.Workspaces.csproj | 3 ++- 5 files changed, 6 insertions(+), 1 deletion(-) diff --git a/eng/targets/Settings.props b/eng/targets/Settings.props index d2f750758827c..04a339c26fc61 100644 --- a/eng/targets/Settings.props +++ b/eng/targets/Settings.props @@ -120,6 +120,7 @@ 002400000480000094000000060200000024000052534131000400000100010009f3c8fcb7cb2592cc6e6d3646d4d9a2bda9e7a243d357bc17a5a06f50ed0dae74a343cd9538fe45bbc90a3f7cbecb23558205e3b246b69f7f7730e520460d560da1c68cda9e2256e3b801629e2dc1fd588b1681aaf4f2c98abcfc50086ecbcd55f76f7dbaf018e708527d8ae3a2714b3ec9b62bd9aaf56cf55b3ffc9eee31aa 00240000048000009400000006020000002400005253413100040000010001005984d9e99e5722bb74ddbb59972bff1a2fd9e0ccb2d50e09ef85e39ec4a4e4bf2de896997de1af164be0558cdd5a50a283b9353fc4e5ccc1c87363e6e7d87af7bec8ca40281596fc8f5b5aad9904230f6f3892f8dde382cee7ba9854004d86ce93834a86b42ebdd0faf86d9fa6d935e05aed68cb4d828cea77df028739aaa9dc 002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293 + $(MicrosoftSharedPublicKey) + + + + @@ -476,7 +507,7 @@ IconAndText Clear - CleearStackTraceExplorerCommandName + ClearStackTraceExplorerCommandName ClearStackTraceExplorer ClearStackTraceExplorer @@ -774,14 +805,10 @@ - - - - - - - - + + + + @@ -790,6 +817,12 @@ + + + + + + diff --git a/src/VisualStudio/Core/Def/ID.RoslynCommands.cs b/src/VisualStudio/Core/Def/ID.RoslynCommands.cs index 39a4389e8f123..dda67b372c748 100644 --- a/src/VisualStudio/Core/Def/ID.RoslynCommands.cs +++ b/src/VisualStudio/Core/Def/ID.RoslynCommands.cs @@ -46,5 +46,10 @@ public static class RoslynCommands public const int DocumentOutlineSortByOrder = 0x314; public const int DocumentOutlineSortByType = 0x315; public const int DocumentOutlineToolbarGroup = 0x350; + + public const int SolutionExplorerSymbolItemContextMenu = 0x401; + public const int SolutionExplorerSymbolItemGoToBase = 0x402; + public const int SolutionExplorerSymbolItemGoToImplementation = 0x403; + public const int SolutionExplorerSymbolItemFindAllReferences = 0x404; } } diff --git a/src/VisualStudio/Core/Def/LanguageService/AbstractPackage.cs b/src/VisualStudio/Core/Def/LanguageService/AbstractPackage.cs index 05764a55f1fec..1b39a2ae14a0c 100644 --- a/src/VisualStudio/Core/Def/LanguageService/AbstractPackage.cs +++ b/src/VisualStudio/Core/Def/LanguageService/AbstractPackage.cs @@ -5,7 +5,6 @@ using System; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Options; using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Shell; diff --git a/src/VisualStudio/Core/Def/SolutionExplorer/SolutionExplorerSymbolItemCommandHandler.cs b/src/VisualStudio/Core/Def/SolutionExplorer/SolutionExplorerSymbolItemCommandHandler.cs new file mode 100644 index 0000000000000..d57a93b70d34f --- /dev/null +++ b/src/VisualStudio/Core/Def/SolutionExplorer/SolutionExplorerSymbolItemCommandHandler.cs @@ -0,0 +1,46 @@ +//// Licensed to the .NET Foundation under one or more agreements. +//// The .NET Foundation licenses this file to you under the MIT license. +//// See the LICENSE file in the project root for more information. + +//using System; +//using System.Collections.Generic; +//using System.ComponentModel.Composition; +//using System.ComponentModel.Design; +//using System.Linq; +//using System.Text; +//using System.Threading; +//using System.Threading.Tasks; +//using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +//using Microsoft.CodeAnalysis.Host.Mef; +//using Microsoft.VisualStudio.LanguageServices.Implementation.Utilities; +//using Microsoft.VisualStudio.LanguageServices.Setup; +//using Microsoft.VisualStudio.Shell; + +//namespace Microsoft.VisualStudio.LanguageServices.SolutionExplorer; + +//[Export(typeof(SolutionExplorerSymbolItemCommandHandler))] +//internal sealed class SolutionExplorerSymbolItemCommandHandler +//{ +// private readonly IThreadingContext _threadingContext; + +// [ImportingConstructor] +// [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] +// public SolutionExplorerSymbolItemCommandHandler( +// IThreadingContext threadingContext) +// { +// _threadingContext = threadingContext; +// } + +// public async Task InitializeAsync(IAsyncServiceProvider serviceProvider, CancellationToken cancellationToken) +// { +// // _serviceProvider = (IServiceProvider)serviceProvider; + +// // Hook up the "Remove Unused References" menu command for CPS based managed projects. +// var menuCommandService = await serviceProvider.GetServiceAsync(throwOnFailure: false, cancellationToken).ConfigureAwait(false); +// if (menuCommandService != null) +// { +// await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); +// VisualStudioCommandHandlerHelpers.AddCommand(menuCommandService, ID.RoslynCommands.SyncNamespaces, Guids.RoslynGroupId, OnSyncNamespacesForSelectedProject, OnSyncNamespacesForSelectedProjectStatus); +// } +// } +//} diff --git a/src/VisualStudio/Core/Def/xlf/Commands.vsct.cs.xlf b/src/VisualStudio/Core/Def/xlf/Commands.vsct.cs.xlf index f9bdc63e865e7..649e13e42170d 100644 --- a/src/VisualStudio/Core/Def/xlf/Commands.vsct.cs.xlf +++ b/src/VisualStudio/Core/Def/xlf/Commands.vsct.cs.xlf @@ -23,8 +23,8 @@ - CleearStackTraceExplorerCommandName - CleearStackTraceExplorerCommandName + ClearStackTraceExplorerCommandName + CleearStackTraceExplorerCommandName @@ -587,6 +587,36 @@ Přejít na implementaci + + Find All References + Find All References + + + + FindAllReferences + FindAllReferences + + + + Go To Base + Go To Base + + + + GoToBase + GoToBase + + + + Go To Implementation + Go To Implementation + + + + GoToImplementation + GoToImplementation + + Sync &Namespaces Synchronizovat obory &názvů diff --git a/src/VisualStudio/Core/Def/xlf/Commands.vsct.de.xlf b/src/VisualStudio/Core/Def/xlf/Commands.vsct.de.xlf index 3308cd21f2bd2..3da2e360a3a70 100644 --- a/src/VisualStudio/Core/Def/xlf/Commands.vsct.de.xlf +++ b/src/VisualStudio/Core/Def/xlf/Commands.vsct.de.xlf @@ -23,8 +23,8 @@ - CleearStackTraceExplorerCommandName - CleearStackTraceExplorerCommandName + ClearStackTraceExplorerCommandName + CleearStackTraceExplorerCommandName @@ -587,6 +587,36 @@ Zur Implementierung wechseln + + Find All References + Find All References + + + + FindAllReferences + FindAllReferences + + + + Go To Base + Go To Base + + + + GoToBase + GoToBase + + + + Go To Implementation + Go To Implementation + + + + GoToImplementation + GoToImplementation + + Sync &Namespaces &Namespaces synchronisieren diff --git a/src/VisualStudio/Core/Def/xlf/Commands.vsct.es.xlf b/src/VisualStudio/Core/Def/xlf/Commands.vsct.es.xlf index b32bea9149faf..0617214f28f86 100644 --- a/src/VisualStudio/Core/Def/xlf/Commands.vsct.es.xlf +++ b/src/VisualStudio/Core/Def/xlf/Commands.vsct.es.xlf @@ -23,8 +23,8 @@ - CleearStackTraceExplorerCommandName - CleearStackTraceExplorerCommandName + ClearStackTraceExplorerCommandName + CleearStackTraceExplorerCommandName @@ -587,6 +587,36 @@ Ir a la implementación + + Find All References + Find All References + + + + FindAllReferences + FindAllReferences + + + + Go To Base + Go To Base + + + + GoToBase + GoToBase + + + + Go To Implementation + Go To Implementation + + + + GoToImplementation + GoToImplementation + + Sync &Namespaces Sincronizar &espacio de nombres diff --git a/src/VisualStudio/Core/Def/xlf/Commands.vsct.fr.xlf b/src/VisualStudio/Core/Def/xlf/Commands.vsct.fr.xlf index 409be3dc72829..ede88313ed171 100644 --- a/src/VisualStudio/Core/Def/xlf/Commands.vsct.fr.xlf +++ b/src/VisualStudio/Core/Def/xlf/Commands.vsct.fr.xlf @@ -23,8 +23,8 @@ - CleearStackTraceExplorerCommandName - CleearStackTraceExplorerCommandName + ClearStackTraceExplorerCommandName + CleearStackTraceExplorerCommandName @@ -587,6 +587,36 @@ Accéder à l'implémentation + + Find All References + Find All References + + + + FindAllReferences + FindAllReferences + + + + Go To Base + Go To Base + + + + GoToBase + GoToBase + + + + Go To Implementation + Go To Implementation + + + + GoToImplementation + GoToImplementation + + Sync &Namespaces &Synchroniser les espaces de noms diff --git a/src/VisualStudio/Core/Def/xlf/Commands.vsct.it.xlf b/src/VisualStudio/Core/Def/xlf/Commands.vsct.it.xlf index 8cf86e9eb3fbe..4cfad24330db0 100644 --- a/src/VisualStudio/Core/Def/xlf/Commands.vsct.it.xlf +++ b/src/VisualStudio/Core/Def/xlf/Commands.vsct.it.xlf @@ -23,8 +23,8 @@ - CleearStackTraceExplorerCommandName - CleearStackTraceExplorerCommandName + ClearStackTraceExplorerCommandName + CleearStackTraceExplorerCommandName @@ -587,6 +587,36 @@ Vai all'implementazione + + Find All References + Find All References + + + + FindAllReferences + FindAllReferences + + + + Go To Base + Go To Base + + + + GoToBase + GoToBase + + + + Go To Implementation + Go To Implementation + + + + GoToImplementation + GoToImplementation + + Sync &Namespaces Sincronizza spazi dei &nomi diff --git a/src/VisualStudio/Core/Def/xlf/Commands.vsct.ja.xlf b/src/VisualStudio/Core/Def/xlf/Commands.vsct.ja.xlf index 9346873158dd3..15a22d87555ad 100644 --- a/src/VisualStudio/Core/Def/xlf/Commands.vsct.ja.xlf +++ b/src/VisualStudio/Core/Def/xlf/Commands.vsct.ja.xlf @@ -23,8 +23,8 @@ - CleearStackTraceExplorerCommandName - CleearStackTraceExplorerCommandName + ClearStackTraceExplorerCommandName + CleearStackTraceExplorerCommandName @@ -587,6 +587,36 @@ 実装に移動 + + Find All References + Find All References + + + + FindAllReferences + FindAllReferences + + + + Go To Base + Go To Base + + + + GoToBase + GoToBase + + + + Go To Implementation + Go To Implementation + + + + GoToImplementation + GoToImplementation + + Sync &Namespaces 名前空間の同期(&N) diff --git a/src/VisualStudio/Core/Def/xlf/Commands.vsct.ko.xlf b/src/VisualStudio/Core/Def/xlf/Commands.vsct.ko.xlf index fae98049f2f5f..9c4b0c180d24b 100644 --- a/src/VisualStudio/Core/Def/xlf/Commands.vsct.ko.xlf +++ b/src/VisualStudio/Core/Def/xlf/Commands.vsct.ko.xlf @@ -23,8 +23,8 @@ - CleearStackTraceExplorerCommandName - CleearStackTraceExplorerCommandName + ClearStackTraceExplorerCommandName + CleearStackTraceExplorerCommandName @@ -587,6 +587,36 @@ 구현으로 이동 + + Find All References + Find All References + + + + FindAllReferences + FindAllReferences + + + + Go To Base + Go To Base + + + + GoToBase + GoToBase + + + + Go To Implementation + Go To Implementation + + + + GoToImplementation + GoToImplementation + + Sync &Namespaces 네임스페이스 동기화(&N) diff --git a/src/VisualStudio/Core/Def/xlf/Commands.vsct.pl.xlf b/src/VisualStudio/Core/Def/xlf/Commands.vsct.pl.xlf index 078d491445636..27d34018bca08 100644 --- a/src/VisualStudio/Core/Def/xlf/Commands.vsct.pl.xlf +++ b/src/VisualStudio/Core/Def/xlf/Commands.vsct.pl.xlf @@ -23,8 +23,8 @@ - CleearStackTraceExplorerCommandName - CleearStackTraceExplorerCommandName + ClearStackTraceExplorerCommandName + CleearStackTraceExplorerCommandName @@ -587,6 +587,36 @@ Przejdź do implementacji + + Find All References + Find All References + + + + FindAllReferences + FindAllReferences + + + + Go To Base + Go To Base + + + + GoToBase + GoToBase + + + + Go To Implementation + Go To Implementation + + + + GoToImplementation + GoToImplementation + + Sync &Namespaces Synchronizuj &przestrzenie nazw diff --git a/src/VisualStudio/Core/Def/xlf/Commands.vsct.pt-BR.xlf b/src/VisualStudio/Core/Def/xlf/Commands.vsct.pt-BR.xlf index c44d090d4fde0..d5fa659163a5a 100644 --- a/src/VisualStudio/Core/Def/xlf/Commands.vsct.pt-BR.xlf +++ b/src/VisualStudio/Core/Def/xlf/Commands.vsct.pt-BR.xlf @@ -23,8 +23,8 @@ - CleearStackTraceExplorerCommandName - CleearStackTraceExplorerCommandName + ClearStackTraceExplorerCommandName + CleearStackTraceExplorerCommandName @@ -587,6 +587,36 @@ Ir para Implementação + + Find All References + Find All References + + + + FindAllReferences + FindAllReferences + + + + Go To Base + Go To Base + + + + GoToBase + GoToBase + + + + Go To Implementation + Go To Implementation + + + + GoToImplementation + GoToImplementation + + Sync &Namespaces Sincronizar &Namespaces diff --git a/src/VisualStudio/Core/Def/xlf/Commands.vsct.ru.xlf b/src/VisualStudio/Core/Def/xlf/Commands.vsct.ru.xlf index f61de2c07789e..81bc2c58fbad9 100644 --- a/src/VisualStudio/Core/Def/xlf/Commands.vsct.ru.xlf +++ b/src/VisualStudio/Core/Def/xlf/Commands.vsct.ru.xlf @@ -23,8 +23,8 @@ - CleearStackTraceExplorerCommandName - CleearStackTraceExplorerCommandName + ClearStackTraceExplorerCommandName + CleearStackTraceExplorerCommandName @@ -587,6 +587,36 @@ Перейти к реализации + + Find All References + Find All References + + + + FindAllReferences + FindAllReferences + + + + Go To Base + Go To Base + + + + GoToBase + GoToBase + + + + Go To Implementation + Go To Implementation + + + + GoToImplementation + GoToImplementation + + Sync &Namespaces Синхронизация пространства имен diff --git a/src/VisualStudio/Core/Def/xlf/Commands.vsct.tr.xlf b/src/VisualStudio/Core/Def/xlf/Commands.vsct.tr.xlf index 79db0634ba511..200c32422c343 100644 --- a/src/VisualStudio/Core/Def/xlf/Commands.vsct.tr.xlf +++ b/src/VisualStudio/Core/Def/xlf/Commands.vsct.tr.xlf @@ -23,8 +23,8 @@ - CleearStackTraceExplorerCommandName - CleearStackTraceExplorerCommandName + ClearStackTraceExplorerCommandName + CleearStackTraceExplorerCommandName @@ -587,6 +587,36 @@ Uygulamaya Git + + Find All References + Find All References + + + + FindAllReferences + FindAllReferences + + + + Go To Base + Go To Base + + + + GoToBase + GoToBase + + + + Go To Implementation + Go To Implementation + + + + GoToImplementation + GoToImplementation + + Sync &Namespaces Eşitle &Ad Alanları diff --git a/src/VisualStudio/Core/Def/xlf/Commands.vsct.zh-Hans.xlf b/src/VisualStudio/Core/Def/xlf/Commands.vsct.zh-Hans.xlf index 124820e5fe220..fdd46d994e7ae 100644 --- a/src/VisualStudio/Core/Def/xlf/Commands.vsct.zh-Hans.xlf +++ b/src/VisualStudio/Core/Def/xlf/Commands.vsct.zh-Hans.xlf @@ -23,8 +23,8 @@ - CleearStackTraceExplorerCommandName - CleearStackTraceExplorerCommandName + ClearStackTraceExplorerCommandName + CleearStackTraceExplorerCommandName @@ -587,6 +587,36 @@ 转到实现 + + Find All References + Find All References + + + + FindAllReferences + FindAllReferences + + + + Go To Base + Go To Base + + + + GoToBase + GoToBase + + + + Go To Implementation + Go To Implementation + + + + GoToImplementation + GoToImplementation + + Sync &Namespaces 同步命名空间(&N) diff --git a/src/VisualStudio/Core/Def/xlf/Commands.vsct.zh-Hant.xlf b/src/VisualStudio/Core/Def/xlf/Commands.vsct.zh-Hant.xlf index bf9a023f17311..c4d0aba747dbc 100644 --- a/src/VisualStudio/Core/Def/xlf/Commands.vsct.zh-Hant.xlf +++ b/src/VisualStudio/Core/Def/xlf/Commands.vsct.zh-Hant.xlf @@ -23,8 +23,8 @@ - CleearStackTraceExplorerCommandName - CleearStackTraceExplorerCommandName + ClearStackTraceExplorerCommandName + CleearStackTraceExplorerCommandName @@ -587,6 +587,36 @@ 前往實作 + + Find All References + Find All References + + + + FindAllReferences + FindAllReferences + + + + Go To Base + Go To Base + + + + GoToBase + GoToBase + + + + Go To Implementation + Go To Implementation + + + + GoToImplementation + GoToImplementation + + Sync &Namespaces 同步命名空間(&N) diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/ContextMenuController.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/ContextMenuController.cs index 6e16b60ffbfbe..c67811b83d66e 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/ContextMenuController.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/ContextMenuController.cs @@ -36,12 +36,11 @@ public bool ShowContextMenu(IEnumerable items, Point location) _updateMenu(); var guidContextMenu = Guids.RoslynGroupId; - var locationPoints = new[] { new POINTS() { x = (short)location.X, y = (short)location.Y } }; return Shell.Package.GetGlobalService(typeof(SVsUIShell)) is IVsUIShell shell && ErrorHandler.Succeeded(shell.ShowContextMenu( 0, ref guidContextMenu, _menuId, - locationPoints, + [new POINTS() { x = (short)location.X, y = (short)location.Y }], pCmdTrgtActive: null)); } } diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs index d03a726dc5a2a..8a65894ea5286 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/RootSymbolTreeItemSourceProvider.cs @@ -9,6 +9,7 @@ using System.ComponentModel; using System.ComponentModel.Composition; using System.IO; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; @@ -52,6 +53,8 @@ internal sealed partial class RootSymbolTreeItemSourceProvider : AttachedCollect public readonly IThreadingContext ThreadingContext; public readonly IAsynchronousOperationListener Listener; + public readonly ContextMenuController ContextMenuController; + [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] public RootSymbolTreeItemSourceProvider( @@ -78,6 +81,14 @@ public RootSymbolTreeItemSourceProvider( _updateSourcesQueue.AddWork(e.DocumentId); }, options: new WorkspaceEventOptions(RequiresMainThread: false)); + + this.ContextMenuController = new ContextMenuController( + ID.RoslynCommands.SolutionExplorerSymbolItemContextMenu, + shouldShowMenu: objects => objects.FirstOrDefault() is SymbolTreeItem, + updateMenu: () => + { + + }); } private async ValueTask UpdateCollectionSourcesAsync( diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index 50d984328df3d..846dfd4b9ec7c 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -6,12 +6,14 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; +using System.Windows; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor.Wpf; using Microsoft.CodeAnalysis.SolutionExplorer; using Microsoft.Internal.VisualStudio.PlatformUI; using Microsoft.VisualStudio.Imaging.Interop; using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; using Roslyn.Utilities; namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer; @@ -70,6 +72,7 @@ public SymbolTreeItemSyntax ItemSyntax public override ImageMoniker IconMoniker => this.ItemKey.Glyph.GetImageMoniker(); + // We act as our own invocation controller. public override IInvocationController? InvocationController => this; public bool Invoke(IEnumerable items, InputSource inputSource, bool preview) @@ -81,6 +84,38 @@ public bool Invoke(IEnumerable items, InputSource inputSource, bool prev return true; } + // We act as our own context menu controller. + public override IContextMenuController? ContextMenuController => new SymbolItemContextMenuController(this); + + private sealed class SymbolItemContextMenuController : IContextMenuController + { + private readonly SymbolTreeItem _symbolTreeItem; + + public SymbolItemContextMenuController(SymbolTreeItem symbolTreeItem) + { + _symbolTreeItem = symbolTreeItem; + } + + public bool ShowContextMenu(IEnumerable items, Point location) + { + if (items.FirstOrDefault() is not SymbolTreeItem item) + return false; + + var guidContextMenu = Guids.RoslynGroupId; + if (Shell.Package.GetGlobalService(typeof(SVsUIShell)) is not IVsUIShell shell) + return false; + + var result = shell.ShowContextMenu( + dwCompRole: 0, + ref guidContextMenu, + 0x400, + //ID.RoslynCommands.SolutionExplorerSymbolItemContextMenu, + [new() { x = (short)location.X, y = (short)location.Y }], + pCmdTrgtActive: null); + return ErrorHandler.Succeeded(result); + } + } + public void BeforeExpand() { ThrowIfNotOnMainThread(); From ae70d8056239ca9b05734276c45bb79f2ac7b7fb Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 29 May 2025 20:12:18 +0200 Subject: [PATCH 154/353] Enable --- .../Core/Def/PackageRegistration.pkgdef | 2 +- src/VisualStudio/Core/Def/RoslynPackage.cs | 1 + ...olutionExplorerSymbolItemCommandHandler.cs | 93 +++++++++++-------- .../SymbolTree/SymbolTreeItem.cs | 4 +- 4 files changed, 57 insertions(+), 43 deletions(-) diff --git a/src/VisualStudio/Core/Def/PackageRegistration.pkgdef b/src/VisualStudio/Core/Def/PackageRegistration.pkgdef index aaf0e6d907cd4..701193ed17739 100644 --- a/src/VisualStudio/Core/Def/PackageRegistration.pkgdef +++ b/src/VisualStudio/Core/Def/PackageRegistration.pkgdef @@ -1,5 +1,5 @@ [$RootKey$\Menus] -"{6cf2e545-6109-4730-8883-cf43d7aec3e1}"=", Menus.ctmenu, 21" +"{6cf2e545-6109-4730-8883-cf43d7aec3e1}"=", Menus.ctmenu, 22" // [ProvideUIContextRule( // Guids.EncCapableProjectExistsInWorkspaceUIContextString, diff --git a/src/VisualStudio/Core/Def/RoslynPackage.cs b/src/VisualStudio/Core/Def/RoslynPackage.cs index bb3f93c94449a..8e976075d2c58 100644 --- a/src/VisualStudio/Core/Def/RoslynPackage.cs +++ b/src/VisualStudio/Core/Def/RoslynPackage.cs @@ -159,6 +159,7 @@ protected override async Task LoadComponentsAsync(CancellationToken cancellation await this.ComponentModel.GetService().InitializeAsync(this, cancellationToken).ConfigureAwait(false); await this.ComponentModel.GetService().InitializeAsync(this, cancellationToken).ConfigureAwait(false); await this.ComponentModel.GetService().InitializeAsync(this, cancellationToken).ConfigureAwait(false); + await this.ComponentModel.GetService().InitializeAsync(this, cancellationToken).ConfigureAwait(false); await LoadAnalyzerNodeComponentsAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/VisualStudio/Core/Def/SolutionExplorer/SolutionExplorerSymbolItemCommandHandler.cs b/src/VisualStudio/Core/Def/SolutionExplorer/SolutionExplorerSymbolItemCommandHandler.cs index d57a93b70d34f..e2ffef1149984 100644 --- a/src/VisualStudio/Core/Def/SolutionExplorer/SolutionExplorerSymbolItemCommandHandler.cs +++ b/src/VisualStudio/Core/Def/SolutionExplorer/SolutionExplorerSymbolItemCommandHandler.cs @@ -1,46 +1,59 @@ -//// Licensed to the .NET Foundation under one or more agreements. -//// The .NET Foundation licenses this file to you under the MIT license. -//// See the LICENSE file in the project root for more information. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. -//using System; -//using System.Collections.Generic; -//using System.ComponentModel.Composition; -//using System.ComponentModel.Design; -//using System.Linq; -//using System.Text; -//using System.Threading; -//using System.Threading.Tasks; -//using Microsoft.CodeAnalysis.Editor.Shared.Utilities; -//using Microsoft.CodeAnalysis.Host.Mef; -//using Microsoft.VisualStudio.LanguageServices.Implementation.Utilities; -//using Microsoft.VisualStudio.LanguageServices.Setup; -//using Microsoft.VisualStudio.Shell; +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.ComponentModel.Design; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.VisualStudio.LanguageServices.Implementation.Utilities; +using Microsoft.VisualStudio.LanguageServices.Setup; +using Microsoft.VisualStudio.Shell; -//namespace Microsoft.VisualStudio.LanguageServices.SolutionExplorer; +namespace Microsoft.VisualStudio.LanguageServices.SolutionExplorer; -//[Export(typeof(SolutionExplorerSymbolItemCommandHandler))] -//internal sealed class SolutionExplorerSymbolItemCommandHandler -//{ -// private readonly IThreadingContext _threadingContext; +[Export(typeof(SolutionExplorerSymbolTreeItemCommandHandler))] +internal sealed class SolutionExplorerSymbolTreeItemCommandHandler +{ + private readonly IThreadingContext _threadingContext; -// [ImportingConstructor] -// [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -// public SolutionExplorerSymbolItemCommandHandler( -// IThreadingContext threadingContext) -// { -// _threadingContext = threadingContext; -// } + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public SolutionExplorerSymbolTreeItemCommandHandler( + IThreadingContext threadingContext) + { + _threadingContext = threadingContext; + } -// public async Task InitializeAsync(IAsyncServiceProvider serviceProvider, CancellationToken cancellationToken) -// { -// // _serviceProvider = (IServiceProvider)serviceProvider; + public async Task InitializeAsync(IAsyncServiceProvider serviceProvider, CancellationToken cancellationToken) + { + // _serviceProvider = (IServiceProvider)serviceProvider; -// // Hook up the "Remove Unused References" menu command for CPS based managed projects. -// var menuCommandService = await serviceProvider.GetServiceAsync(throwOnFailure: false, cancellationToken).ConfigureAwait(false); -// if (menuCommandService != null) -// { -// await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); -// VisualStudioCommandHandlerHelpers.AddCommand(menuCommandService, ID.RoslynCommands.SyncNamespaces, Guids.RoslynGroupId, OnSyncNamespacesForSelectedProject, OnSyncNamespacesForSelectedProjectStatus); -// } -// } -//} + // Hook up the "Remove Unused References" menu command for CPS based managed projects. + var menuCommandService = await serviceProvider.GetServiceAsync(throwOnFailure: false, cancellationToken).ConfigureAwait(false); + if (menuCommandService != null) + { + await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); + VisualStudioCommandHandlerHelpers.AddCommand( + menuCommandService, + ID.RoslynCommands.GoToImplementation, + Guids.RoslynGroupId, + (sender, args) => + { + var command = (OleMenuCommand)sender; + command.Visible = true; + command.Enabled = true; + }, + (sender, args) => + { + + }); + } + } +} diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index 846dfd4b9ec7c..6b809345bd564 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -108,8 +108,8 @@ public bool ShowContextMenu(IEnumerable items, Point location) var result = shell.ShowContextMenu( dwCompRole: 0, ref guidContextMenu, - 0x400, - //ID.RoslynCommands.SolutionExplorerSymbolItemContextMenu, + //0x400, + ID.RoslynCommands.SolutionExplorerSymbolItemContextMenu, [new() { x = (short)location.X, y = (short)location.Y }], pCmdTrgtActive: null); return ErrorHandler.Succeeded(result); From e47fbefa16bea1d6b671d4d473aa3e20b46f182f Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 29 May 2025 20:23:58 +0200 Subject: [PATCH 155/353] more --- src/VisualStudio/Core/Def/RoslynPackage.cs | 3 ++- .../SolutionExplorerSymbolItemCommandHandler.cs | 6 +++--- .../SymbolTree/SymbolTreeItem.cs | 17 +++++++++++++++-- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/VisualStudio/Core/Def/RoslynPackage.cs b/src/VisualStudio/Core/Def/RoslynPackage.cs index 8e976075d2c58..db5af99379ba2 100644 --- a/src/VisualStudio/Core/Def/RoslynPackage.cs +++ b/src/VisualStudio/Core/Def/RoslynPackage.cs @@ -28,6 +28,7 @@ using Microsoft.VisualStudio.LanguageServices.InheritanceMargin; using Microsoft.VisualStudio.LanguageServices.ProjectSystem; using Microsoft.VisualStudio.LanguageServices.ProjectSystem.BrokeredService; +using Microsoft.VisualStudio.LanguageServices.SolutionExplorer; using Microsoft.VisualStudio.LanguageServices.StackTraceExplorer; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; @@ -159,7 +160,7 @@ protected override async Task LoadComponentsAsync(CancellationToken cancellation await this.ComponentModel.GetService().InitializeAsync(this, cancellationToken).ConfigureAwait(false); await this.ComponentModel.GetService().InitializeAsync(this, cancellationToken).ConfigureAwait(false); await this.ComponentModel.GetService().InitializeAsync(this, cancellationToken).ConfigureAwait(false); - await this.ComponentModel.GetService().InitializeAsync(this, cancellationToken).ConfigureAwait(false); + await this.ComponentModel.GetService().InitializeAsync(this, cancellationToken).ConfigureAwait(false); await LoadAnalyzerNodeComponentsAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/VisualStudio/Core/Def/SolutionExplorer/SolutionExplorerSymbolItemCommandHandler.cs b/src/VisualStudio/Core/Def/SolutionExplorer/SolutionExplorerSymbolItemCommandHandler.cs index e2ffef1149984..d9adf3077ebc2 100644 --- a/src/VisualStudio/Core/Def/SolutionExplorer/SolutionExplorerSymbolItemCommandHandler.cs +++ b/src/VisualStudio/Core/Def/SolutionExplorer/SolutionExplorerSymbolItemCommandHandler.cs @@ -4,8 +4,8 @@ using System; using System.Collections.Generic; -using System.ComponentModel.Composition; using System.ComponentModel.Design; +using System.Composition; using System.Linq; using System.Text; using System.Threading; @@ -18,7 +18,7 @@ namespace Microsoft.VisualStudio.LanguageServices.SolutionExplorer; -[Export(typeof(SolutionExplorerSymbolTreeItemCommandHandler))] +[Export(typeof(SolutionExplorerSymbolTreeItemCommandHandler)), Shared] internal sealed class SolutionExplorerSymbolTreeItemCommandHandler { private readonly IThreadingContext _threadingContext; @@ -42,7 +42,7 @@ public async Task InitializeAsync(IAsyncServiceProvider serviceProvider, Cancell await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); VisualStudioCommandHandlerHelpers.AddCommand( menuCommandService, - ID.RoslynCommands.GoToImplementation, + ID.RoslynCommands.SolutionExplorerSymbolItemFindAllReferences, Guids.RoslynGroupId, (sender, args) => { diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs index 6b809345bd564..b450d8e3fed41 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; @@ -12,6 +13,8 @@ using Microsoft.CodeAnalysis.SolutionExplorer; using Microsoft.Internal.VisualStudio.PlatformUI; using Microsoft.VisualStudio.Imaging.Interop; +using Microsoft.VisualStudio.OLE.Interop; +using Microsoft.VisualStudio.ProjectSystem.VS; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Roslyn.Utilities; @@ -87,7 +90,7 @@ public bool Invoke(IEnumerable items, InputSource inputSource, bool prev // We act as our own context menu controller. public override IContextMenuController? ContextMenuController => new SymbolItemContextMenuController(this); - private sealed class SymbolItemContextMenuController : IContextMenuController + private sealed class SymbolItemContextMenuController : IContextMenuController, IOleCommandTarget { private readonly SymbolTreeItem _symbolTreeItem; @@ -111,9 +114,19 @@ public bool ShowContextMenu(IEnumerable items, Point location) //0x400, ID.RoslynCommands.SolutionExplorerSymbolItemContextMenu, [new() { x = (short)location.X, y = (short)location.Y }], - pCmdTrgtActive: null); + pCmdTrgtActive: this); return ErrorHandler.Succeeded(result); } + + public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText) + { + return HResult.OK; + } + + public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) + { + return HResult.OK; + } } public void BeforeExpand() From 060788877e8458143f50172495addff7dbebe3f6 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 29 May 2025 11:28:12 -0700 Subject: [PATCH 156/353] [main] Source code updates from dotnet/dotnet (#78745) * [VMR] Codeflow 4381944-4381944 [[ commit created by automation ]] * Update dependencies from https://github.com/dotnet/dotnet build 269884 No dependency updates to commit --------- Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 14028e430ed09..d5474a24c8db4 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,6 +1,6 @@ - + From c8a834b696c6e0d1504da2f0d9d13e2d539d9834 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 29 May 2025 20:32:10 +0200 Subject: [PATCH 157/353] In progress --- .../SolutionExplorerSymbolItemCommandHandler.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/VisualStudio/Core/Def/SolutionExplorer/SolutionExplorerSymbolItemCommandHandler.cs b/src/VisualStudio/Core/Def/SolutionExplorer/SolutionExplorerSymbolItemCommandHandler.cs index d9adf3077ebc2..d8106e293356a 100644 --- a/src/VisualStudio/Core/Def/SolutionExplorer/SolutionExplorerSymbolItemCommandHandler.cs +++ b/src/VisualStudio/Core/Def/SolutionExplorer/SolutionExplorerSymbolItemCommandHandler.cs @@ -52,7 +52,9 @@ public async Task InitializeAsync(IAsyncServiceProvider serviceProvider, Cancell }, (sender, args) => { - + var command = (OleMenuCommand)sender; + command.Visible = true; + command.Enabled = true; }); } } From 7beee16e5a36234815583533252e7ff931671723 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 29 May 2025 20:34:32 +0200 Subject: [PATCH 158/353] Make dynamic --- src/VisualStudio/Core/Def/Commands.vsct | 6 ++++++ src/VisualStudio/Core/Def/PackageRegistration.pkgdef | 2 +- .../Core/Impl/SolutionExplorer/SymbolTree/SymbolTreeItem.cs | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/VisualStudio/Core/Def/Commands.vsct b/src/VisualStudio/Core/Def/Commands.vsct index a8fb87e3444df..dbab3ee0f3e6e 100644 --- a/src/VisualStudio/Core/Def/Commands.vsct +++ b/src/VisualStudio/Core/Def/Commands.vsct @@ -386,6 +386,8 @@