diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs b/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs index ae09d517239e7..ed82f21baea0a 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs @@ -46,7 +46,6 @@ private partial class SymbolInlineRenameInfo : IInlineRenameInfoWithFileRename public bool CanRename { get; } public string LocalizedErrorMessage { get; } public TextSpan TriggerSpan { get; } - public SymbolAndProjectId RenameSymbolAndProjectId { get; } public bool HasOverloads { get; } public bool ForceRenameOverloads { get; } @@ -55,13 +54,13 @@ private partial class SymbolInlineRenameInfo : IInlineRenameInfoWithFileRename /// public ImmutableArray DefinitionLocations { get; } - public ISymbol RenameSymbol => RenameSymbolAndProjectId.Symbol; + public ISymbol RenameSymbol { get; } public SymbolInlineRenameInfo( IEnumerable refactorNotifyServices, Document document, TextSpan triggerSpan, - SymbolAndProjectId renameSymbolAndProjectId, + ISymbol renameSymbol, bool forceRenameOverloads, ImmutableArray definitionLocations, CancellationToken cancellationToken) @@ -70,9 +69,9 @@ public SymbolInlineRenameInfo( _refactorNotifyServices = refactorNotifyServices; _document = document; - this.RenameSymbolAndProjectId = renameSymbolAndProjectId; + this.RenameSymbol = renameSymbol; - this.HasOverloads = RenameLocations.GetOverloadedSymbols(this.RenameSymbolAndProjectId).Any(); + this.HasOverloads = RenameLocations.GetOverloadedSymbols(this.RenameSymbol).Any(); this.ForceRenameOverloads = forceRenameOverloads; _isRenamingAttributePrefix = CanRenameAttributePrefix(document, triggerSpan, cancellationToken); @@ -209,7 +208,7 @@ public Task FindRenameLocationsAsync(OptionSet optionS // If this is the first call, then just start finding the initial set of rename // locations. _underlyingFindRenameLocationsTask = RenameLocations.FindAsync( - this.RenameSymbolAndProjectId, _document.Project.Solution, optionSet, cancellationToken); + this.RenameSymbol, _document.Project.Solution, optionSet, cancellationToken); renameTask = _underlyingFindRenameLocationsTask; // null out the option set. We don't need it anymore, and this will ensure diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.cs b/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.cs index 03fd7c5aab40c..ce25d88d7b4b8 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.cs @@ -91,8 +91,7 @@ internal static async Task GetRenameInfoAsync( } } - var symbolAndProjectId = await RenameLocations.ReferenceProcessing.GetRenamableSymbolAsync(document, triggerToken.SpanStart, cancellationToken: cancellationToken).ConfigureAwait(false); - var symbol = symbolAndProjectId.Symbol; + var symbol = await RenameLocations.ReferenceProcessing.GetRenamableSymbolAsync(document, triggerToken.SpanStart, cancellationToken: cancellationToken).ConfigureAwait(false); if (symbol == null) { return new FailureInlineRenameInfo(EditorFeaturesResources.You_cannot_rename_this_element); @@ -200,7 +199,7 @@ internal static async Task GetRenameInfoAsync( return new SymbolInlineRenameInfo( refactorNotifyServices, document, triggerToken.Span, - symbolAndProjectId, forceRenameOverloads, documentSpans.ToImmutableAndFree(), cancellationToken); + symbol, forceRenameOverloads, documentSpans.ToImmutableAndFree(), cancellationToken); } private async Task GetTriggerTokenAsync(Document document, int position, CancellationToken cancellationToken) diff --git a/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.ProgressAdapter.cs b/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.ProgressAdapter.cs index ea40db44b93e1..89e540203dc6c 100644 --- a/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.ProgressAdapter.cs +++ b/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.ProgressAdapter.cs @@ -94,30 +94,30 @@ public FindReferencesProgressAdapter( // used by the FAR engine to the INavigableItems used by the streaming FAR // feature. - private async Task GetDefinitionItemAsync(SymbolAndProjectId definition) + private async Task GetDefinitionItemAsync(ISymbol definition) { - using (await _gate.DisposableWaitAsync(_context.CancellationToken).ConfigureAwait(false)) + var cancellationToken = _context.CancellationToken; + using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { - if (!_definitionToItem.TryGetValue(definition.Symbol, out var definitionItem)) + if (!_definitionToItem.TryGetValue(definition, out var definitionItem)) { - definitionItem = await definition.Symbol.ToClassifiedDefinitionItemAsync( - _solution.GetProject(definition.ProjectId), includeHiddenLocations: false, - _options, _context.CancellationToken).ConfigureAwait(false); + definitionItem = await definition.ToClassifiedDefinitionItemAsync( + _solution, includeHiddenLocations: false, _options, _context.CancellationToken).ConfigureAwait(false); - _definitionToItem[definition.Symbol] = definitionItem; + _definitionToItem[definition] = definitionItem; } return definitionItem; } } - public async Task OnDefinitionFoundAsync(SymbolAndProjectId definition) + public async Task OnDefinitionFoundAsync(ISymbol definition) { var definitionItem = await GetDefinitionItemAsync(definition).ConfigureAwait(false); await _context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); } - public async Task OnReferenceFoundAsync(SymbolAndProjectId definition, ReferenceLocation location) + public async Task OnReferenceFoundAsync(ISymbol definition, ReferenceLocation location) { var definitionItem = await GetDefinitionItemAsync(definition).ConfigureAwait(false); var referenceItem = await location.TryCreateSourceReferenceItemAsync( diff --git a/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.cs b/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.cs index de8e9fc9aef4a..a4f2849fa3610 100644 --- a/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.cs +++ b/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.cs @@ -38,7 +38,7 @@ await context.ReportMessageAsync( return; } - var (solution, symbolAndProjectId, implementations, message) = tupleOpt.Value; + var (solution, symbol, implementations, message) = tupleOpt.Value; if (message != null) { await context.ReportMessageAsync(message).ConfigureAwait(false); @@ -47,13 +47,13 @@ await context.ReportMessageAsync( await context.SetSearchTitleAsync( string.Format(EditorFeaturesResources._0_implementations, - FindUsagesHelpers.GetDisplayName(symbolAndProjectId.Symbol))).ConfigureAwait(false); + FindUsagesHelpers.GetDisplayName(symbol))).ConfigureAwait(false); foreach (var implementation in implementations) { - var definitionItem = await implementation.Symbol.ToClassifiedDefinitionItemAsync( - solution.GetProject(implementation.ProjectId), includeHiddenLocations: false, - FindReferencesSearchOptions.Default, cancellationToken: cancellationToken).ConfigureAwait(false); + var definitionItem = await implementation.ToClassifiedDefinitionItemAsync( + solution, includeHiddenLocations: false, FindReferencesSearchOptions.Default, cancellationToken).ConfigureAwait(false); + await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); } } @@ -121,16 +121,16 @@ private async Task FindSymbolReferencesAsync( cancellationToken.ThrowIfCancellationRequested(); // Find the symbol we want to search and the solution we want to search in. - var symbolAndProjectOpt = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync( + var symbolAndSolutionOpt = await FindUsagesHelpers.GetRelevantSymbolAndSolutionAtPositionAsync( document, position, cancellationToken).ConfigureAwait(false); - if (symbolAndProjectOpt == null) + if (symbolAndSolutionOpt == null) return; - var (symbol, project) = symbolAndProjectOpt.Value; + var (symbol, solution) = symbolAndSolutionOpt.Value; await FindSymbolReferencesAsync( _threadingContext, context, - symbol, project, + symbol, solution, cancellationToken).ConfigureAwait(false); } @@ -140,9 +140,9 @@ await FindSymbolReferencesAsync( /// public static async Task FindSymbolReferencesAsync( IThreadingContext threadingContext, IFindUsagesContext context, - ISymbol symbol, Project project, CancellationToken cancellationToken) + ISymbol symbol, Solution solution, CancellationToken cancellationToken) { - var monikerUsagesService = project.Solution.Workspace.Services.GetRequiredService(); + var monikerUsagesService = solution.Workspace.Services.GetRequiredService(); await context.SetSearchTitleAsync(string.Format(EditorFeaturesResources._0_references, FindUsagesHelpers.GetDisplayName(symbol))).ConfigureAwait(false); @@ -153,20 +153,13 @@ await context.SetSearchTitleAsync(string.Format(EditorFeaturesResources._0_refer // engine will push results into the 'progress' instance passed into it. // We'll take those results, massage them, and forward them along to the // FindReferencesContext instance we were given. + var progress = new FindReferencesProgressAdapter(threadingContext, solution, context, options); var normalFindReferencesTask = SymbolFinder.FindReferencesAsync( - SymbolAndProjectId.Create(symbol, project.Id), - project.Solution, - new FindReferencesProgressAdapter(threadingContext, project.Solution, context, options), - documents: null, - options, - cancellationToken); + symbol, solution, progress, documents: null, options, cancellationToken); // Kick off work to search the online code index system in parallel var codeIndexReferencesTask = FindSymbolMonikerReferencesAsync( - monikerUsagesService, - symbol, - context, - cancellationToken); + monikerUsagesService, symbol, context, cancellationToken); await Task.WhenAll(normalFindReferencesTask, codeIndexReferencesTask).ConfigureAwait(false); } diff --git a/src/EditorFeatures/Core/FindUsages/FindUsagesHelpers.cs b/src/EditorFeatures/Core/FindUsages/FindUsagesHelpers.cs index d98af742e2aae..b80755df56ece 100644 --- a/src/EditorFeatures/Core/FindUsages/FindUsagesHelpers.cs +++ b/src/EditorFeatures/Core/FindUsages/FindUsagesHelpers.cs @@ -31,7 +31,7 @@ public static string GetDisplayName(ISymbol symbol) /// there may be symbol mapping involved (for example in Metadata-As-Source /// scenarios). /// - public static async Task<(ISymbol symbol, Project project)?> GetRelevantSymbolAndProjectAtPositionAsync( + public static async Task<(ISymbol symbol, Solution solution)?> GetRelevantSymbolAndSolutionAtPositionAsync( Document document, int position, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -49,31 +49,30 @@ public static string GetDisplayName(ISymbol symbol) if (mapping == null) return null; - return (mapping.Symbol, mapping.Project); + return (mapping.Symbol, mapping.Project.Solution); } - public static async Task<(Solution solution, SymbolAndProjectId symboAndProjectId, ImmutableArray implementations, string message)?> FindSourceImplementationsAsync(Document document, int position, CancellationToken cancellationToken) + public static async Task<(Solution solution, ISymbol symbol, ImmutableArray implementations, string message)?> FindSourceImplementationsAsync(Document document, int position, CancellationToken cancellationToken) { - var symbolAndProjectOpt = await GetRelevantSymbolAndProjectAtPositionAsync( + var symbolAndSolutionOpt = await GetRelevantSymbolAndSolutionAtPositionAsync( document, position, cancellationToken).ConfigureAwait(false); - if (symbolAndProjectOpt == null) + if (symbolAndSolutionOpt == null) return null; - var (symbol, project) = symbolAndProjectOpt.Value; - var symbolAndProjectId = new SymbolAndProjectId(symbol, project.Id); + var (symbol, solution) = symbolAndSolutionOpt.Value; return await FindSourceImplementationsAsync( - project.Solution, symbolAndProjectId, cancellationToken).ConfigureAwait(false); + solution, symbol, cancellationToken).ConfigureAwait(false); } - private static async Task<(Solution solution, SymbolAndProjectId symbolAndProjectId, ImmutableArray implementations, string message)?> FindSourceImplementationsAsync( - Solution solution, SymbolAndProjectId symbolAndProjectId, CancellationToken cancellationToken) + private static async Task<(Solution solution, ISymbol symbol, ImmutableArray implementations, string message)?> FindSourceImplementationsAsync( + Solution solution, ISymbol symbol, CancellationToken cancellationToken) { - var builder = new HashSet(SymbolAndProjectIdComparer.SymbolEquivalenceInstance); + var builder = new HashSet(SymbolEquivalenceComparer.Instance); // If we're in a linked file, try to find all the symbols this links to, and find all the implementations of // each of those linked symbols. De-dupe the results so the user only gets unique results. var linkedSymbols = await SymbolFinder.FindLinkedSymbolsAsync( - solution, symbolAndProjectId, cancellationToken).ConfigureAwait(false); + symbol, solution, cancellationToken).ConfigureAwait(false); foreach (var linkedSymbol in linkedSymbols) { @@ -84,28 +83,28 @@ public static string GetDisplayName(ISymbol symbol) var result = builder.ToImmutableArray(); var message = result.IsEmpty ? EditorFeaturesResources.The_symbol_has_no_implementations : null; - return (solution, symbolAndProjectId, result, message); + return (solution, symbol, result, message); } - private static async Task> FindSourceImplementationsWorkerAsync( - Solution solution, SymbolAndProjectId symbolAndProjectId, CancellationToken cancellationToken) + private static async Task> FindSourceImplementationsWorkerAsync( + Solution solution, ISymbol symbol, CancellationToken cancellationToken) { - var implementations = await FindSourceAndMetadataImplementationsAsync(solution, symbolAndProjectId, cancellationToken).ConfigureAwait(false); - return implementations.WhereAsArray(s => s.Symbol.Locations.Any(l => l.IsInSource)); + var implementations = await FindSourceAndMetadataImplementationsAsync(solution, symbol, cancellationToken).ConfigureAwait(false); + return implementations.WhereAsArray(s => s.Locations.Any(l => l.IsInSource)); } - private static async Task> FindSourceAndMetadataImplementationsAsync( - Solution solution, SymbolAndProjectId symbolAndProjectId, CancellationToken cancellationToken) + private static async Task> FindSourceAndMetadataImplementationsAsync( + Solution solution, ISymbol symbol, CancellationToken cancellationToken) { - if (symbolAndProjectId.Symbol.IsInterfaceType() || symbolAndProjectId.Symbol.IsImplementableMember()) + if (symbol.IsInterfaceType() || symbol.IsImplementableMember()) { var implementations = await SymbolFinder.FindImplementationsAsync( - symbolAndProjectId, solution, cancellationToken: cancellationToken).ConfigureAwait(false); + symbol, solution, cancellationToken: cancellationToken).ConfigureAwait(false); // It's important we use a HashSet here -- we may have cases in an inheritance hierarchy where more than one method // in an overrides chain implements the same interface method, and we want to duplicate those. The easiest way to do it // is to just use a HashSet. - var implementationsAndOverrides = new HashSet(); + var implementationsAndOverrides = new HashSet(); foreach (var implementation in implementations) { @@ -113,7 +112,7 @@ private static async Task> FindSourceAndMetad // FindImplementationsAsync will only return the base virtual/abstract method, not that method and the overrides // of the method. We should also include those. - if (implementation.Symbol.IsOverridable()) + if (implementation.IsOverridable()) { var overrides = await SymbolFinder.FindOverridesAsync( implementation, solution, cancellationToken: cancellationToken).ConfigureAwait(false); @@ -121,32 +120,31 @@ private static async Task> FindSourceAndMetad } } - if (!symbolAndProjectId.Symbol.IsInterfaceType() && - !symbolAndProjectId.Symbol.IsAbstract) + if (!symbol.IsInterfaceType() && + !symbol.IsAbstract) { - implementationsAndOverrides.Add(symbolAndProjectId); + implementationsAndOverrides.Add(symbol); } return implementationsAndOverrides.ToImmutableArray(); } - else if (symbolAndProjectId.Symbol is INamedTypeSymbol { TypeKind: TypeKind.Class } namedType) + else if (symbol is INamedTypeSymbol { TypeKind: TypeKind.Class } namedType) { var derivedClasses = await SymbolFinder.FindDerivedClassesAsync( - symbolAndProjectId.WithSymbol(namedType), - solution, cancellationToken: cancellationToken).ConfigureAwait(false); + namedType, solution, cancellationToken: cancellationToken).ConfigureAwait(false); - return derivedClasses.SelectAsArray(s => (SymbolAndProjectId)s).Concat(symbolAndProjectId); + return derivedClasses.Concat(symbol).ToImmutableArray(); } - else if (symbolAndProjectId.Symbol.IsOverridable()) + else if (symbol.IsOverridable()) { var overrides = await SymbolFinder.FindOverridesAsync( - symbolAndProjectId, solution, cancellationToken: cancellationToken).ConfigureAwait(false); - return overrides.Concat(symbolAndProjectId); + symbol, solution, cancellationToken: cancellationToken).ConfigureAwait(false); + return overrides.Concat(symbol).ToImmutableArray(); } else { // This is something boring like a regular method or type, so we'll just go there directly - return ImmutableArray.Create(symbolAndProjectId); + return ImmutableArray.Create(symbol); } } diff --git a/src/EditorFeatures/Core/FindUsages/IDefinitionsAndReferencesFactory.cs b/src/EditorFeatures/Core/FindUsages/IDefinitionsAndReferencesFactory.cs index 942cd9660cfae..90c1c8dca826b 100644 --- a/src/EditorFeatures/Core/FindUsages/IDefinitionsAndReferencesFactory.cs +++ b/src/EditorFeatures/Core/FindUsages/IDefinitionsAndReferencesFactory.cs @@ -53,7 +53,7 @@ internal static class DefinitionItemExtensions { public static DefinitionItem ToNonClassifiedDefinitionItem( this ISymbol definition, - Project project, + Solution solution, bool includeHiddenLocations) { // Because we're passing in 'false' for 'includeClassifiedSpans', this won't ever have @@ -61,25 +61,25 @@ public static DefinitionItem ToNonClassifiedDefinitionItem( // to compute the classified spans for the locations of the definition. So it's totally // fine to pass in CancellationToken.None and block on the result. return ToDefinitionItemAsync( - definition, project, includeHiddenLocations, includeClassifiedSpans: false, + definition, solution, includeHiddenLocations, includeClassifiedSpans: false, options: FindReferencesSearchOptions.Default, cancellationToken: CancellationToken.None).WaitAndGetResult_CanCallOnBackground(CancellationToken.None); } public static Task ToClassifiedDefinitionItemAsync( this ISymbol definition, - Project project, + Solution solution, bool includeHiddenLocations, FindReferencesSearchOptions options, CancellationToken cancellationToken) { - return ToDefinitionItemAsync(definition, project, + return ToDefinitionItemAsync(definition, solution, includeHiddenLocations, includeClassifiedSpans: true, options, cancellationToken); } private static async Task ToDefinitionItemAsync( this ISymbol definition, - Project project, + Solution solution, bool includeHiddenLocations, bool includeClassifiedSpans, FindReferencesSearchOptions options, @@ -121,7 +121,7 @@ private static async Task ToDefinitionItemAsync( if (location.IsInMetadata) { return DefinitionItem.CreateMetadataDefinition( - tags, displayParts, nameDisplayParts, project, + tags, displayParts, nameDisplayParts, solution, definition, properties, displayIfNoReferences); } else if (location.IsInSource) @@ -132,7 +132,7 @@ private static async Task ToDefinitionItemAsync( continue; } - var document = project.Solution.GetDocument(location.SourceTree); + var document = solution.GetDocument(location.SourceTree); if (document != null) { var documentLocation = !includeClassifiedSpans diff --git a/src/EditorFeatures/Core/GoToBase/AbstractGoToBaseService.cs b/src/EditorFeatures/Core/GoToBase/AbstractGoToBaseService.cs index 8b789897a79bf..f6ece802cf919 100644 --- a/src/EditorFeatures/Core/GoToBase/AbstractGoToBaseService.cs +++ b/src/EditorFeatures/Core/GoToBase/AbstractGoToBaseService.cs @@ -16,20 +16,20 @@ internal abstract partial class AbstractGoToBaseService : IGoToBaseService public async Task FindBasesAsync(Document document, int position, IFindUsagesContext context) { var cancellationToken = context.CancellationToken; - var symbolAndProjectOpt = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync( + var symbolAndSolutionOpt = await FindUsagesHelpers.GetRelevantSymbolAndSolutionAtPositionAsync( document, position, cancellationToken).ConfigureAwait(false); - if (symbolAndProjectOpt == null) + if (symbolAndSolutionOpt == null) { await context.ReportMessageAsync( EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret).ConfigureAwait(false); return; } - var (symbol, project) = symbolAndProjectOpt.Value; + var (symbol, solution) = symbolAndSolutionOpt.Value; var bases = FindBaseHelpers.FindBases( - symbol, project, cancellationToken); + symbol, solution, cancellationToken); await context.SetSearchTitleAsync( string.Format(EditorFeaturesResources._0_bases, @@ -43,20 +43,19 @@ await context.SetSearchTitleAsync( foreach (var baseSymbol in bases) { var sourceDefinition = await SymbolFinder.FindSourceDefinitionAsync( - SymbolAndProjectId.Create(baseSymbol, project.Id), project.Solution, cancellationToken).ConfigureAwait(false); - if (sourceDefinition.Symbol != null) + baseSymbol, solution, cancellationToken).ConfigureAwait(false); + if (sourceDefinition != null) { - var definitionItem = await sourceDefinition.Symbol.ToClassifiedDefinitionItemAsync( - project.Solution.GetProject(sourceDefinition.ProjectId), includeHiddenLocations: false, - FindReferencesSearchOptions.Default, cancellationToken: cancellationToken) - .ConfigureAwait(false); + var definitionItem = await sourceDefinition.ToClassifiedDefinitionItemAsync( + solution, includeHiddenLocations: false, FindReferencesSearchOptions.Default, cancellationToken: cancellationToken).ConfigureAwait(false); + await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); found = true; } else if (baseSymbol.Locations.Any(l => l.IsInMetadata)) { var definitionItem = baseSymbol.ToNonClassifiedDefinitionItem( - project, includeHiddenLocations: true); + solution, includeHiddenLocations: true); await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); found = true; } diff --git a/src/EditorFeatures/Core/GoToBase/FindBaseHelpers.cs b/src/EditorFeatures/Core/GoToBase/FindBaseHelpers.cs index 5af8c6d06d4f1..660af290919af 100644 --- a/src/EditorFeatures/Core/GoToBase/FindBaseHelpers.cs +++ b/src/EditorFeatures/Core/GoToBase/FindBaseHelpers.cs @@ -11,7 +11,7 @@ namespace Microsoft.CodeAnalysis.Editor.GoToBase internal static class FindBaseHelpers { public static ImmutableArray FindBases( - ISymbol symbol, Project project, CancellationToken cancellationToken) + ISymbol symbol, Solution solution, CancellationToken cancellationToken) { if (symbol is INamedTypeSymbol namedTypeSymbol && (namedTypeSymbol.TypeKind == TypeKind.Class || @@ -24,8 +24,7 @@ public static ImmutableArray FindBases( symbol.Kind == SymbolKind.Method || symbol.Kind == SymbolKind.Event) { - return BaseTypeFinder.FindOverriddenAndImplementedMembers( - symbol, project, cancellationToken); + return BaseTypeFinder.FindOverriddenAndImplementedMembers(symbol, solution, cancellationToken); } else { diff --git a/src/EditorFeatures/Core/GoToDefinition/AbstractGoToDefinitionService.cs b/src/EditorFeatures/Core/GoToDefinition/AbstractGoToDefinitionService.cs index aed1b76caab61..2d0ee79f72ebe 100644 --- a/src/EditorFeatures/Core/GoToDefinition/AbstractGoToDefinitionService.cs +++ b/src/EditorFeatures/Core/GoToDefinition/AbstractGoToDefinitionService.cs @@ -63,7 +63,7 @@ public bool TryGoToDefinition(Document document, int position, CancellationToken var isThirdPartyNavigationAllowed = IsThirdPartyNavigationAllowed(symbol, position, document, cancellationToken); return GoToDefinitionHelpers.TryGoToDefinition(symbol, - document.Project, + document.Project.Solution, _streamingPresenter.Value, thirdPartyNavigationAllowed: isThirdPartyNavigationAllowed, cancellationToken: cancellationToken); @@ -100,7 +100,7 @@ private bool TryGoToAlternativeLocationIfAlreadyOnDefinition( var definitions = interfaceImpls.SelectMany( i => GoToDefinitionHelpers.GetDefinitions( - i, project, thirdPartyNavigationAllowed: false, cancellationToken)).ToImmutableArray(); + i, solution, thirdPartyNavigationAllowed: false, cancellationToken)).ToImmutableArray(); var title = string.Format(EditorFeaturesResources._0_implemented_members, FindUsagesHelpers.GetDisplayName(symbol)); diff --git a/src/EditorFeatures/Core/GoToDefinition/AbstractGoToSymbolService.cs b/src/EditorFeatures/Core/GoToDefinition/AbstractGoToSymbolService.cs index 0fc4ec602e518..7988b7d696ecd 100644 --- a/src/EditorFeatures/Core/GoToDefinition/AbstractGoToSymbolService.cs +++ b/src/EditorFeatures/Core/GoToDefinition/AbstractGoToSymbolService.cs @@ -40,8 +40,9 @@ public async Task GetSymbolsAsync(GoToSymbolContext context) await ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(alwaysYield: true, cancellationToken); cancellationToken.ThrowIfCancellationRequested(); - var definitions = GoToDefinitionHelpers.GetDefinitions(symbol, document.Project, thirdPartyNavigationAllowed: true, cancellationToken) - .WhereAsArray(d => d.CanNavigateTo(document.Project.Solution.Workspace)); + var solution = document.Project.Solution; + var definitions = GoToDefinitionHelpers.GetDefinitions(symbol, solution, thirdPartyNavigationAllowed: true, cancellationToken) + .WhereAsArray(d => d.CanNavigateTo(solution.Workspace)); await TaskScheduler.Default; diff --git a/src/EditorFeatures/Core/GoToDefinition/GoToDefinitionHelpers.cs b/src/EditorFeatures/Core/GoToDefinition/GoToDefinitionHelpers.cs index 92039318f63b4..6cd201c2f64be 100644 --- a/src/EditorFeatures/Core/GoToDefinition/GoToDefinitionHelpers.cs +++ b/src/EditorFeatures/Core/GoToDefinition/GoToDefinitionHelpers.cs @@ -20,7 +20,7 @@ internal static class GoToDefinitionHelpers { public static ImmutableArray GetDefinitions( ISymbol symbol, - Project project, + Solution solution, bool thirdPartyNavigationAllowed, CancellationToken cancellationToken) { @@ -36,13 +36,12 @@ public static ImmutableArray GetDefinitions( // VB global import aliases have a synthesized SyntaxTree. // We can't go to the definition of the alias, so use the target type. - var solution = project.Solution; if (alias != null) { var sourceLocations = NavigableItemFactory.GetPreferredSourceLocations( solution, symbol, cancellationToken); - if (sourceLocations.All(l => project.Solution.GetDocument(l.SourceTree) == null)) + if (sourceLocations.All(l => solution.GetDocument(l.SourceTree) == null)) { symbol = alias.Target; } @@ -81,7 +80,7 @@ public static ImmutableArray GetDefinitions( // So, if we only have a single location to go to, this does no unnecessary work. And, // if we do have multiple locations to show, it will just be done in the BG, unblocking // this command thread so it can return the user faster. - var definitionItem = symbol.ToNonClassifiedDefinitionItem(project, includeHiddenLocations: true); + var definitionItem = symbol.ToNonClassifiedDefinitionItem(solution, includeHiddenLocations: true); if (thirdPartyNavigationAllowed) { @@ -96,23 +95,23 @@ public static ImmutableArray GetDefinitions( public static bool TryGoToDefinition( ISymbol symbol, - Project project, + Solution solution, IStreamingFindUsagesPresenter streamingPresenter, CancellationToken cancellationToken, bool thirdPartyNavigationAllowed = true) { - var definitions = GetDefinitions(symbol, project, thirdPartyNavigationAllowed, cancellationToken); + var definitions = GetDefinitions(symbol, solution, thirdPartyNavigationAllowed, cancellationToken); var title = string.Format(EditorFeaturesResources._0_declarations, FindUsagesHelpers.GetDisplayName(symbol)); return streamingPresenter.TryNavigateToOrPresentItemsAsync( - project.Solution.Workspace, title, definitions).WaitAndGetResult(cancellationToken); + solution.Workspace, title, definitions).WaitAndGetResult(cancellationToken); } public static bool TryGoToDefinition( ImmutableArray definitions, - Project project, + Solution solution, string title, IStreamingFindUsagesPresenter streamingPresenter, CancellationToken cancellationToken) @@ -123,7 +122,7 @@ public static bool TryGoToDefinition( } return streamingPresenter.TryNavigateToOrPresentItemsAsync( - project.Solution.Workspace, title, definitions).WaitAndGetResult(cancellationToken); + solution.Workspace, title, definitions).WaitAndGetResult(cancellationToken); } } } diff --git a/src/EditorFeatures/Core/Implementation/IntelliSense/Helpers.cs b/src/EditorFeatures/Core/Implementation/IntelliSense/Helpers.cs index e4cd35feedc01..b3557315624c8 100644 --- a/src/EditorFeatures/Core/Implementation/IntelliSense/Helpers.cs +++ b/src/EditorFeatures/Core/Implementation/IntelliSense/Helpers.cs @@ -168,7 +168,7 @@ private static void NavigateToQuickInfoTarget(string navigationTarget, Document if (resolvedSymbolKey.GetAnySymbol() is { } symbol) { - GoToDefinitionHelpers.TryGoToDefinition(symbol, document.Project, streamingPresenter, CancellationToken.None); + GoToDefinitionHelpers.TryGoToDefinition(symbol, document.Project.Solution, streamingPresenter, CancellationToken.None); return; } } diff --git a/src/EditorFeatures/Core/Implementation/Peek/PeekableItemFactory.cs b/src/EditorFeatures/Core/Implementation/Peek/PeekableItemFactory.cs index 198196cd85743..27ea061e1c0a5 100644 --- a/src/EditorFeatures/Core/Implementation/Peek/PeekableItemFactory.cs +++ b/src/EditorFeatures/Core/Implementation/Peek/PeekableItemFactory.cs @@ -62,7 +62,7 @@ public async Task> GetPeekableItemsAsync( } var symbolNavigationService = solution.Workspace.Services.GetService(); - var definitionItem = symbol.ToNonClassifiedDefinitionItem(project, includeHiddenLocations: true); + var definitionItem = symbol.ToNonClassifiedDefinitionItem(solution, includeHiddenLocations: true); if (symbolNavigationService.WouldNavigateToSymbol( definitionItem, solution, cancellationToken, diff --git a/src/EditorFeatures/Core/NavigableSymbols/NavigableSymbolService.NavigableSymbol.cs b/src/EditorFeatures/Core/NavigableSymbols/NavigableSymbolService.NavigableSymbol.cs index 6be3268716e38..bba54735dbab1 100644 --- a/src/EditorFeatures/Core/NavigableSymbols/NavigableSymbolService.NavigableSymbol.cs +++ b/src/EditorFeatures/Core/NavigableSymbols/NavigableSymbolService.NavigableSymbol.cs @@ -52,7 +52,7 @@ public void Navigate(INavigableRelationship relationship) => showProgress: false, action: context => GoToDefinitionHelpers.TryGoToDefinition( _definitions, - _document.Project, + _document.Project.Solution, _definitions[0].NameDisplayParts.GetFullText(), _presenter, context.CancellationToken) diff --git a/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb b/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb index 1064be74c9d76..5b0bb63e9bec9 100644 --- a/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb +++ b/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb @@ -62,8 +62,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Rename Dim document = workspace.CurrentSolution.GetDocument(cursorDocument.Id) - Dim symbolAndProjectId = RenameLocations.ReferenceProcessing.GetRenamableSymbolAsync(document, cursorPosition, CancellationToken.None).Result - Dim symbol = symbolAndProjectId.Symbol + Dim symbol = RenameLocations.ReferenceProcessing.GetRenamableSymbolAsync(document, cursorPosition, CancellationToken.None).Result If symbol Is Nothing Then AssertEx.Fail("The symbol touching the $$ could not be found.") End If @@ -76,7 +75,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Rename Next End If - Dim locations = RenameLocations.FindAsync(symbolAndProjectId, workspace.CurrentSolution, optionSet, CancellationToken.None).Result + Dim locations = RenameLocations.FindAsync(symbol, workspace.CurrentSolution, optionSet, CancellationToken.None).Result Dim originalName = symbol.Name.Split("."c).Last() Dim result = ConflictResolver.ResolveConflictsAsync(locations, renameTo, nonConflictSymbols:=Nothing, cancellationToken:=CancellationToken.None).Result diff --git a/src/Features/CSharp/Portable/ChangeSignature/CSharpChangeSignatureService.cs b/src/Features/CSharp/Portable/ChangeSignature/CSharpChangeSignatureService.cs index f29bef3af1583..dcfd3f3d2e73b 100644 --- a/src/Features/CSharp/Portable/ChangeSignature/CSharpChangeSignatureService.cs +++ b/src/Features/CSharp/Portable/ChangeSignature/CSharpChangeSignatureService.cs @@ -790,12 +790,11 @@ private ImmutableArray VerifyAndPermuteParamNodes(IEnumerable> DetermineCascadedSymbolsFromDelegateInvokeAsync( - SymbolAndProjectId symbolAndProjectId, + public override async Task> DetermineCascadedSymbolsFromDelegateInvokeAsync( + IMethodSymbol symbol, Document document, CancellationToken cancellationToken) { - var symbol = symbolAndProjectId.Symbol; var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); @@ -824,9 +823,11 @@ public override async Task> DetermineCascaded return Equals(convertedType, symbol.ContainingType); }) - .SelectAsArray(n => semanticModel.GetSymbolInfo(n, cancellationToken).Symbol); + .Select(n => semanticModel.GetSymbolInfo(n, cancellationToken).Symbol) + .WhereNotNull() + .ToImmutableArray(); - return convertedMethodGroups.SelectAsArray(symbolAndProjectId.WithSymbol); + return convertedMethodGroups; } protected override IEnumerable GetFormattingRules(Document document) diff --git a/src/Features/CSharp/Portable/ImplementInterface/CSharpImplementExplicitlyCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ImplementInterface/CSharpImplementExplicitlyCodeRefactoringProvider.cs index 81a138908e800..4be1f3f1e874b 100644 --- a/src/Features/CSharp/Portable/ImplementInterface/CSharpImplementExplicitlyCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ImplementInterface/CSharpImplementExplicitlyCodeRefactoringProvider.cs @@ -57,8 +57,7 @@ protected override async Task UpdateReferencesAsync( // high fan-out (like IDisposable.Dispose()). var findRefsOptions = FindReferencesSearchOptions.Default.WithCascade(false); var references = await SymbolFinder.FindReferencesAsync( - new SymbolAndProjectId(implMember, project.Id), - solution, findRefsOptions, cancellationToken).ConfigureAwait(false); + implMember, solution, findRefsOptions, cancellationToken).ConfigureAwait(false); var implReferences = references.FirstOrDefault(); if (implReferences == null) diff --git a/src/Features/Core/Portable/AddImport/SearchScopes/AllSymbolsProjectSearchScope.cs b/src/Features/Core/Portable/AddImport/SearchScopes/AllSymbolsProjectSearchScope.cs index af8a62a6a13bf..f25c532d1c139 100644 --- a/src/Features/Core/Portable/AddImport/SearchScopes/AllSymbolsProjectSearchScope.cs +++ b/src/Features/Core/Portable/AddImport/SearchScopes/AllSymbolsProjectSearchScope.cs @@ -33,7 +33,7 @@ protected override async Task> FindDeclarationsAsync( var declarations = await DeclarationFinder.FindAllDeclarationsWithNormalQueryAsync( _project, searchQuery, filter, CancellationToken).ConfigureAwait(false); - return declarations.SelectAsArray(d => d.Symbol); + return declarations; } } } diff --git a/src/Features/Core/Portable/AddImport/SearchScopes/MetadataSymbolsSearchScope.cs b/src/Features/Core/Portable/AddImport/SearchScopes/MetadataSymbolsSearchScope.cs index b4dfdb2752abb..6f7ff8c3a0ade 100644 --- a/src/Features/Core/Portable/AddImport/SearchScopes/MetadataSymbolsSearchScope.cs +++ b/src/Features/Core/Portable/AddImport/SearchScopes/MetadataSymbolsSearchScope.cs @@ -58,7 +58,7 @@ protected override async Task> FindDeclarationsAsync( searchQuery, _assembly, _assemblyProjectId, filter, CancellationToken).ConfigureAwait(false); - return declarations.SelectAsArray(d => d.Symbol); + return declarations; } } } diff --git a/src/Features/Core/Portable/AddImport/SearchScopes/SourceSymbolsProjectSearchScope.cs b/src/Features/Core/Portable/AddImport/SearchScopes/SourceSymbolsProjectSearchScope.cs index 11700f743fca7..505060fa63905 100644 --- a/src/Features/Core/Portable/AddImport/SearchScopes/SourceSymbolsProjectSearchScope.cs +++ b/src/Features/Core/Portable/AddImport/SearchScopes/SourceSymbolsProjectSearchScope.cs @@ -48,10 +48,9 @@ protected override async Task> FindDeclarationsAsync( var lazyAssembly = _projectToAssembly.GetOrAdd(_project, CreateLazyAssembly); var declarations = await info.FindAsync( - searchQuery, lazyAssembly, _project.Id, - filter, CancellationToken).ConfigureAwait(false); + searchQuery, lazyAssembly, filter, CancellationToken).ConfigureAwait(false); - return declarations.SelectAsArray(d => d.Symbol); + return declarations; } private static AsyncLazy CreateLazyAssembly(Project project) diff --git a/src/Features/Core/Portable/AddParameter/AddParameterService.cs b/src/Features/Core/Portable/AddParameter/AddParameterService.cs index 195b2a535c119..b87119b8666ea 100644 --- a/src/Features/Core/Portable/AddParameter/AddParameterService.cs +++ b/src/Features/Core/Portable/AddParameter/AddParameterService.cs @@ -144,12 +144,8 @@ private static async Task> FindMethodDeclarationRe var progress = new StreamingProgressCollector(); await SymbolFinder.FindReferencesAsync( - symbolAndProjectId: SymbolAndProjectId.Create(method, invocationDocument.Project.Id), - solution: invocationDocument.Project.Solution, - documents: null, - progress: progress, - options: FindReferencesSearchOptions.Default, - cancellationToken: cancellationToken).ConfigureAwait(false); + method, invocationDocument.Project.Solution, progress: progress, + documents: null, FindReferencesSearchOptions.Default, cancellationToken).ConfigureAwait(false); var referencedSymbols = progress.GetReferencedSymbols(); return referencedSymbols.Select(referencedSymbol => referencedSymbol.Definition) .OfType() diff --git a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs index 5e699a590a734..48d9313b4d6d5 100644 --- a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs +++ b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs @@ -45,8 +45,8 @@ internal abstract class AbstractChangeSignatureService : ILanguageService /// public abstract SyntaxNode? FindNodeToUpdate(Document document, SyntaxNode node); - public abstract Task> DetermineCascadedSymbolsFromDelegateInvokeAsync( - SymbolAndProjectId symbolAndProjectId, Document document, CancellationToken cancellationToken); + public abstract Task> DetermineCascadedSymbolsFromDelegateInvokeAsync( + IMethodSymbol symbol, Document document, CancellationToken cancellationToken); public abstract Task ChangeSignatureAsync( Document document, @@ -226,7 +226,7 @@ internal ChangeSignatureResult ChangeSignatureWithContext(ChangeSignatureAnalysi } private static async Task> FindChangeSignatureReferencesAsync( - SymbolAndProjectId symbolAndProjectId, + ISymbol symbol, Solution solution, CancellationToken cancellationToken) { @@ -242,7 +242,7 @@ private static async Task> FindChangeSignatureR FindReferencesSearchOptions.Default, cancellationToken); - await engine.FindReferencesAsync(symbolAndProjectId).ConfigureAwait(false); + await engine.FindReferencesAsync(symbol).ConfigureAwait(false); return streamingProgress.GetReferencedSymbols(); } } @@ -263,8 +263,7 @@ private bool TryCreateUpdatedSolution( var hasLocationsInMetadata = false; var symbols = FindChangeSignatureReferencesAsync( - SymbolAndProjectId.Create(declaredSymbol, context.Document.Project.Id), - context.Solution, cancellationToken).WaitAndGetResult(cancellationToken); + declaredSymbol, context.Solution, cancellationToken).WaitAndGetResult(cancellationToken); var declaredSymbolParametersCount = declaredSymbol.GetParameters().Length; diff --git a/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs b/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs index 23bafc1b41a71..28196f5d5792b 100644 --- a/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs +++ b/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs @@ -30,20 +30,19 @@ internal class DelegateInvokeMethodReferenceFinder : AbstractReferenceFinder symbol.MethodKind == MethodKind.DelegateInvoke; - protected override async Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId symbolAndProjectId, + protected override async Task> DetermineCascadedSymbolsAsync( + IMethodSymbol symbol, Solution solution, IImmutableSet projects, FindReferencesSearchOptions options, CancellationToken cancellationToken) { - var result = ImmutableArray.CreateBuilder(); + var result = ImmutableArray.CreateBuilder(); - var symbol = symbolAndProjectId.Symbol; var beginInvoke = symbol.ContainingType.GetMembers(WellKnownMemberNames.DelegateBeginInvokeName).FirstOrDefault(); if (beginInvoke != null) { - result.Add(symbolAndProjectId.WithSymbol(beginInvoke)); + result.Add(beginInvoke); } // All method group references @@ -53,7 +52,7 @@ protected override async Task> DetermineCasca { var changeSignatureService = document.GetLanguageService(); result.AddRange(await changeSignatureService.DetermineCascadedSymbolsFromDelegateInvokeAsync( - symbolAndProjectId, document, cancellationToken).ConfigureAwait(false)); + symbol, document, cancellationToken).ConfigureAwait(false)); } } diff --git a/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractChangeNamespaceService.cs b/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractChangeNamespaceService.cs index 3adaaf391e1c0..1205f60791de6 100644 --- a/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractChangeNamespaceService.cs +++ b/src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractChangeNamespaceService.cs @@ -479,12 +479,8 @@ private static async Task> FindReferencesAsync( cancellationToken.ThrowIfCancellationRequested(); var progress = new StreamingProgressCollector(); await SymbolFinder.FindReferencesAsync( - symbolAndProjectId: SymbolAndProjectId.Create(symbol, document.Project.Id), - solution: document.Project.Solution, - documents: null, - progress: progress, - options: FindReferencesSearchOptions.Default, - cancellationToken: cancellationToken).ConfigureAwait(false); + symbol, document.Project.Solution, progress, documents: null, + FindReferencesSearchOptions.Default, cancellationToken).ConfigureAwait(false); return progress.GetReferencedSymbols(); } diff --git a/src/Features/Core/Portable/DocumentHighlighting/AbstractDocumentHighlightsService.cs b/src/Features/Core/Portable/DocumentHighlighting/AbstractDocumentHighlightsService.cs index 8bf39d94ed598..6865821782042 100644 --- a/src/Features/Core/Portable/DocumentHighlighting/AbstractDocumentHighlightsService.cs +++ b/src/Features/Core/Portable/DocumentHighlighting/AbstractDocumentHighlightsService.cs @@ -84,8 +84,7 @@ private async Task> GetDocumentHighlightsInCu // Get unique tags for referenced symbols return await GetTagsForReferencedSymbolAsync( - new SymbolAndProjectId(symbol, document.Project.Id), - document, documentsToSearch, cancellationToken).ConfigureAwait(false); + symbol, document, documentsToSearch, cancellationToken).ConfigureAwait(false); } private async Task> TryGetEmbeddedLanguageHighlightsAsync( @@ -127,12 +126,11 @@ private static async Task GetSymbolToSearchAsync(Document document, int } private async Task> GetTagsForReferencedSymbolAsync( - SymbolAndProjectId symbolAndProjectId, + ISymbol symbol, Document document, IImmutableSet documentsToSearch, CancellationToken cancellationToken) { - var symbol = symbolAndProjectId.Symbol; Contract.ThrowIfNull(symbol); if (ShouldConsiderSymbol(symbol)) { @@ -140,7 +138,7 @@ private async Task> GetTagsForReferencedSymbo var options = FindReferencesSearchOptions.GetFeatureOptionsForStartingSymbol(symbol); await SymbolFinder.FindReferencesAsync( - symbolAndProjectId, document.Project.Solution, progress, + symbol, document.Project.Solution, progress, documentsToSearch, options, cancellationToken).ConfigureAwait(false); return await FilterAndCreateSpansAsync( diff --git a/src/Features/Core/Portable/EncapsulateField/AbstractEncapsulateFieldService.cs b/src/Features/Core/Portable/EncapsulateField/AbstractEncapsulateFieldService.cs index 9e89eeba21ef7..9fc1cba9d727b 100644 --- a/src/Features/Core/Portable/EncapsulateField/AbstractEncapsulateFieldService.cs +++ b/src/Features/Core/Portable/EncapsulateField/AbstractEncapsulateFieldService.cs @@ -13,7 +13,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.Editing; -using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.PooledObjects; @@ -249,7 +248,7 @@ private async Task UpdateReferencesAsync( if (finalFieldName != field.Name && constructorLocations.Count > 0) { solution = await RenameAsync( - solution, SymbolAndProjectId.Create(field, projectId), finalFieldName, + solution, field, finalFieldName, location => IntersectsWithAny(location, constructorLocations), cancellationToken).ConfigureAwait(false); @@ -262,7 +261,7 @@ private async Task UpdateReferencesAsync( // Outside the constructor we want to rename references to the field to final property name. return await RenameAsync( - solution, SymbolAndProjectId.Create(field, projectId), generatedPropertyName, + solution, field, generatedPropertyName, location => !IntersectsWithAny(location, constructorLocations), cancellationToken).ConfigureAwait(false); } @@ -270,13 +269,13 @@ private async Task UpdateReferencesAsync( { // Just rename everything. return await Renamer.RenameSymbolAsync( - solution, SymbolAndProjectId.Create(field, projectId), generatedPropertyName, solution.Options, cancellationToken).ConfigureAwait(false); + solution, field, generatedPropertyName, solution.Options, cancellationToken).ConfigureAwait(false); } } private async Task RenameAsync( Solution solution, - SymbolAndProjectId field, + IFieldSymbol field, string finalName, Func filter, CancellationToken cancellationToken) diff --git a/src/Features/Core/Portable/FindUsages/DefinitionItem.cs b/src/Features/Core/Portable/FindUsages/DefinitionItem.cs index 40213db4b586f..b648e259c7147 100644 --- a/src/Features/Core/Portable/FindUsages/DefinitionItem.cs +++ b/src/Features/Core/Portable/FindUsages/DefinitionItem.cs @@ -213,7 +213,7 @@ internal static DefinitionItem CreateMetadataDefinition( ImmutableArray tags, ImmutableArray displayParts, ImmutableArray nameDisplayParts, - Project project, + Solution solution, ISymbol symbol, ImmutableDictionary properties = null, bool displayIfNoReferences = true) @@ -222,9 +222,12 @@ internal static DefinitionItem CreateMetadataDefinition( var symbolKey = symbol.GetSymbolKey().ToString(); + var projectId = solution.GetOriginatingProjectId(symbol); + Contract.ThrowIfNull(projectId); + properties = properties.Add(MetadataSymbolKey, symbolKey) - .Add(MetadataSymbolOriginatingProjectIdGuid, project.Id.Id.ToString()) - .Add(MetadataSymbolOriginatingProjectIdDebugName, project.Id.DebugName); + .Add(MetadataSymbolOriginatingProjectIdGuid, projectId.Id.ToString()) + .Add(MetadataSymbolOriginatingProjectIdDebugName, projectId.DebugName); var originationParts = GetOriginationParts(symbol); return new DefaultDefinitionItem( diff --git a/src/Features/Core/Portable/FullyQualify/AbstractFullyQualifyCodeFixProvider.cs b/src/Features/Core/Portable/FullyQualify/AbstractFullyQualifyCodeFixProvider.cs index 0693df5a273f3..b637e83c6b466 100644 --- a/src/Features/Core/Portable/FullyQualify/AbstractFullyQualifyCodeFixProvider.cs +++ b/src/Features/Core/Portable/FullyQualify/AbstractFullyQualifyCodeFixProvider.cs @@ -148,19 +148,18 @@ private async Task> GetMatchingTypesAsync( syntaxFacts.GetNameAndArityOfSimpleName(node, out var name, out var arity); var looksGeneric = syntaxFacts.LooksGeneric(node); - var symbolAndProjectIds = await DeclarationFinder.FindAllDeclarationsWithNormalQueryAsync( + var symbols = await DeclarationFinder.FindAllDeclarationsWithNormalQueryAsync( project, SearchQuery.Create(name, IgnoreCase), SymbolFilter.Type, cancellationToken).ConfigureAwait(false); - var symbols = symbolAndProjectIds.SelectAsArray(t => t.Symbol); // also lookup type symbols with the "Attribute" suffix. var inAttributeContext = syntaxFacts.IsAttributeName(node); if (inAttributeContext) { - var attributeSymbolAndProjectIds = await DeclarationFinder.FindAllDeclarationsWithNormalQueryAsync( + var attributeSymbols = await DeclarationFinder.FindAllDeclarationsWithNormalQueryAsync( project, SearchQuery.Create(name + "Attribute", IgnoreCase), SymbolFilter.Type, cancellationToken).ConfigureAwait(false); - symbols = symbols.Concat(attributeSymbolAndProjectIds.SelectAsArray(t => t.Symbol)); + symbols = symbols.Concat(attributeSymbols); } var validSymbols = symbols @@ -243,12 +242,10 @@ private async Task> GetMatchingNamespacesAsync( return ImmutableArray.Empty; } - var symbolAndProjectIds = await DeclarationFinder.FindAllDeclarationsWithNormalQueryAsync( + var symbols = await DeclarationFinder.FindAllDeclarationsWithNormalQueryAsync( project, SearchQuery.Create(name, IgnoreCase), SymbolFilter.Namespace, cancellationToken).ConfigureAwait(false); - var symbols = symbolAndProjectIds.SelectAsArray(t => t.Symbol); - // There might be multiple namespaces that this name will resolve successfully in. // Some of them may be 'better' results than others. For example, say you have // Y.Z and Y exists in both X1 and X2 diff --git a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/TypeParameterSubstitution.cs b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/TypeParameterSubstitution.cs index 9adadbf41c615..32f156180692e 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/TypeParameterSubstitution.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/TypeParameterSubstitution.cs @@ -134,14 +134,14 @@ private async Task> GetDerivedAndImplementedTypesAsync( { var solution = _project.Solution; - var symbolAndProjectId = SymbolAndProjectId.Create(constraintType, _project.Id); + var symbol = constraintType; var derivedClasses = await SymbolFinder.FindDerivedClassesAsync( - symbolAndProjectId, solution, projects, _cancellationToken).ConfigureAwait(false); + symbol, solution, projects, _cancellationToken).ConfigureAwait(false); var implementedTypes = await DependentTypeFinder.FindTransitivelyImplementingStructuresAndClassesAsync( - symbolAndProjectId, solution, projects, _cancellationToken).ConfigureAwait(false); + symbol, solution, projects, _cancellationToken).ConfigureAwait(false); - return derivedClasses.Concat(implementedTypes).Select(t => t.Symbol).ToSet(); + return derivedClasses.Concat(implementedTypes).ToSet(); } } } diff --git a/src/Features/Core/Portable/MakeMethodSynchronous/AbstractMakeMethodSynchronousCodeFixProvider.cs b/src/Features/Core/Portable/MakeMethodSynchronous/AbstractMakeMethodSynchronousCodeFixProvider.cs index 9000c30c52dff..9e1c4ea4e69be 100644 --- a/src/Features/Core/Portable/MakeMethodSynchronous/AbstractMakeMethodSynchronousCodeFixProvider.cs +++ b/src/Features/Core/Portable/MakeMethodSynchronous/AbstractMakeMethodSynchronousCodeFixProvider.cs @@ -125,8 +125,7 @@ private async Task RemoveAwaitFromCallersAsync( if (semanticModel.GetDeclaredSymbol(methodDeclaration) is IMethodSymbol methodSymbol) { var references = await SymbolFinder.FindRenamableReferencesAsync( - new SymbolAndProjectId(methodSymbol, document.Project.Id), - document.Project.Solution, cancellationToken).ConfigureAwait(false); + methodSymbol, document.Project.Solution, cancellationToken).ConfigureAwait(false); var referencedSymbol = references.FirstOrDefault(r => Equals(r.Definition, methodSymbol)); if (referencedSymbol != null) diff --git a/src/Features/Core/Portable/ReplaceMethodWithProperty/ReplaceMethodWithPropertyCodeRefactoringProvider.cs b/src/Features/Core/Portable/ReplaceMethodWithProperty/ReplaceMethodWithPropertyCodeRefactoringProvider.cs index 17af93dd3f2f3..cf1af4988f457 100644 --- a/src/Features/Core/Portable/ReplaceMethodWithProperty/ReplaceMethodWithPropertyCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ReplaceMethodWithProperty/ReplaceMethodWithPropertyCodeRefactoringProvider.cs @@ -167,11 +167,11 @@ private async Task ReplaceMethodsWithPropertyAsync( var project = document.Project; var originalSolution = project.Solution; var getMethodReferences = await SymbolFinder.FindReferencesAsync( - new SymbolAndProjectId(getMethod, project.Id), originalSolution, cancellationToken).ConfigureAwait(false); + getMethod, originalSolution, cancellationToken).ConfigureAwait(false); var setMethodReferences = setMethod == null ? SpecializedCollections.EmptyEnumerable() : await SymbolFinder.FindReferencesAsync( - new SymbolAndProjectId(setMethod, project.Id), originalSolution, cancellationToken).ConfigureAwait(false); + setMethod, originalSolution, cancellationToken).ConfigureAwait(false); // Get the warnings we'd like to put at the definition site. var definitionWarning = GetDefinitionIssues(getMethodReferences); diff --git a/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs b/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs index 227d2c0be09e4..d88a34b8aa739 100644 --- a/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs +++ b/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs @@ -13,7 +13,6 @@ using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editing; -using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Formatting.Rules; using Microsoft.CodeAnalysis.LanguageServices; @@ -86,8 +85,7 @@ private async Task ProcessResultAsync(CodeFixContext context, Diagnost var solution = context.Document.Project.Solution; var fieldLocations = await Renamer.GetRenameLocationsAsync( - solution, SymbolAndProjectId.Create(fieldSymbol, fieldDocument.Project.Id), - solution.Options, cancellationToken).ConfigureAwait(false); + solution, fieldSymbol, solution.Options, cancellationToken).ConfigureAwait(false); // First, create the updated property we want to replace the old property with var isWrittenToOutsideOfConstructor = IsWrittenToOutsideOfConstructorOrProperty(fieldSymbol, fieldLocations, property, cancellationToken); diff --git a/src/Features/VisualBasic/Portable/ChangeSignature/VisualBasicChangeSignatureService.vb b/src/Features/VisualBasic/Portable/ChangeSignature/VisualBasicChangeSignatureService.vb index 593c4e91310b9..34b7eb764a4de 100644 --- a/src/Features/VisualBasic/Portable/ChangeSignature/VisualBasicChangeSignatureService.vb +++ b/src/Features/VisualBasic/Portable/ChangeSignature/VisualBasicChangeSignatureService.vb @@ -636,11 +636,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ChangeSignature End Function Public Overrides Async Function DetermineCascadedSymbolsFromDelegateInvokeAsync( - methodAndProjectId As SymbolAndProjectId(Of IMethodSymbol), + method As IMethodSymbol, document As Document, - cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of SymbolAndProjectId)) + cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of ISymbol)) - Dim symbol = methodAndProjectId.Symbol + Dim symbol = method Dim root = Await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(False) Dim semanticModel = Await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(False) @@ -686,8 +686,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ChangeSignature End If Next - Return results.ToImmutableAndFree(). - SelectAsArray(Function(s) SymbolAndProjectId.Create(s, document.Project.Id)) + Return results.ToImmutableAndFree() End Function Protected Overrides Function GetFormattingRules(document As Document) As IEnumerable(Of AbstractFormattingRule) diff --git a/src/Features/VisualBasic/Portable/CodeFixes/GenerateEvent/GenerateEventCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/GenerateEvent/GenerateEventCodeFixProvider.vb index 96259e03e0edb..6b54a31e15122 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/GenerateEvent/GenerateEventCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/GenerateEvent/GenerateEventCodeFixProvider.vb @@ -121,10 +121,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.GenerateEvent Dim syntaxFactService = document.Project.Solution.Workspace.Services.GetLanguageServices(targetType.Language).GetService(Of ISyntaxFactsService) Dim eventHandlerName As String = actualEventName + "Handler" - Dim existingSymbolAndProjectIds = Await DeclarationFinder.FindSourceDeclarationsWithNormalQueryAsync( + Dim existingSymbols = Await DeclarationFinder.FindSourceDeclarationsWithNormalQueryAsync( document.Project.Solution, eventHandlerName, Not syntaxFactService.IsCaseSensitive, SymbolFilter.Type, cancellationToken).ConfigureAwait(False) - Dim existingSymbols = existingSymbolAndProjectIds.SelectAsArray(Function(t) t.Symbol) If existingSymbols.Any(Function(existingSymbol) existingSymbol IsNot Nothing _ AndAlso Equals(existingSymbol.ContainingNamespace, targetType.ContainingNamespace)) Then ' There already exists a delegate that matches the event handler name diff --git a/src/Tools/ExternalAccess/Debugger/DebuggerFindReferencesService.cs b/src/Tools/ExternalAccess/Debugger/DebuggerFindReferencesService.cs index 32da405a62e10..00052c316b061 100644 --- a/src/Tools/ExternalAccess/Debugger/DebuggerFindReferencesService.cs +++ b/src/Tools/ExternalAccess/Debugger/DebuggerFindReferencesService.cs @@ -39,7 +39,8 @@ public async Task FindSymbolReferencesAsync(ISymbol symbol, Project project, Can // the context object that the FAR service will push results into. var context = streamingPresenter.StartSearch(EditorFeaturesResources.Find_References, supportsReferences: true); - await AbstractFindUsagesService.FindSymbolReferencesAsync(_threadingContext, context, symbol, project, cancellationToken).ConfigureAwait(false); + await AbstractFindUsagesService.FindSymbolReferencesAsync( + _threadingContext, context, symbol, project.Solution, cancellationToken).ConfigureAwait(false); // Note: we don't need to put this in a finally. The only time we might not hit // this is if cancellation or another error gets thrown. In the former case, diff --git a/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/AbstractObjectBrowserLibraryManager.cs b/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/AbstractObjectBrowserLibraryManager.cs index c2cbdd4275bad..c178ab77d6d7b 100644 --- a/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/AbstractObjectBrowserLibraryManager.cs +++ b/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/AbstractObjectBrowserLibraryManager.cs @@ -553,8 +553,7 @@ private static async Task FindReferencesAsync(IThreadingContext threadingContext if (symbol != null) { await AbstractFindUsagesService.FindSymbolReferencesAsync( - threadingContext, - context, symbol, project, cancellationToken).ConfigureAwait(false); + threadingContext, context, symbol, project.Solution, cancellationToken).ConfigureAwait(false); } } } diff --git a/src/VisualStudio/Core/Def/Implementation/Progression/GraphBuilder.cs b/src/VisualStudio/Core/Def/Implementation/Progression/GraphBuilder.cs index 8346b3da4e6b7..56dca8dfa1222 100644 --- a/src/VisualStudio/Core/Def/Implementation/Progression/GraphBuilder.cs +++ b/src/VisualStudio/Core/Def/Implementation/Progression/GraphBuilder.cs @@ -35,7 +35,7 @@ internal sealed partial class GraphBuilder private readonly Dictionary _nodeToContextProjectMap = new Dictionary(); private readonly Dictionary _nodeToContextDocumentMap = new Dictionary(); - private readonly Dictionary _nodeToSymbolMap = new Dictionary(); + private readonly Dictionary _nodeToSymbolMap = new Dictionary(); /// /// The input solution. Never null. @@ -122,7 +122,7 @@ private async Task PopulateMapsForSymbolInputNodeAsync(GraphNode inputNode) var symbol = symbolId.Value.Resolve(compilation).Symbol; if (symbol != null) { - _nodeToSymbolMap.Add(inputNode, new SymbolAndProjectId(symbol, project.Id)); + _nodeToSymbolMap.Add(inputNode, symbol); } var documentId = (DocumentId)inputNode[RoslynGraphProperties.ContextDocumentId]; @@ -161,7 +161,7 @@ public Document GetContextDocument(GraphNode node) } } - public SymbolAndProjectId GetSymbolAndProjectId(GraphNode node) + public ISymbol GetSymbol(GraphNode node) { using (_gate.DisposableWait()) { @@ -170,17 +170,15 @@ public SymbolAndProjectId GetSymbolAndProjectId(GraphNode node) } } - public Task AddNodeAsync(SymbolAndProjectId symbol, GraphNode relatedNode) + public Task AddNodeAsync(ISymbol symbol, GraphNode relatedNode) { // 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), GetContextDocument(relatedNode)); } - public async Task AddNodeAsync(SymbolAndProjectId symbolAndProjectId, Project contextProject, Document contextDocument) + public async Task AddNodeAsync(ISymbol symbol, Project contextProject, Document contextDocument) { - var symbol = symbolAndProjectId.Symbol; - // 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); @@ -233,7 +231,7 @@ public async Task AddNodeAsync(SymbolAndProjectId symbolAndProjectId, // we won't double-count. _createdNodes.Add(node); - _nodeToSymbolMap[node] = symbolAndProjectId; + _nodeToSymbolMap[node] = symbol; _nodeToContextProjectMap[node] = contextProject; _nodeToContextDocumentMap[node] = contextDocument; diff --git a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/CallsGraphQuery.cs b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/CallsGraphQuery.cs index bb3233adcd05c..c61b43f1b23d5 100644 --- a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/CallsGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/CallsGraphQuery.cs @@ -21,10 +21,10 @@ public async Task GetGraphAsync(Solution solution, IGraphContext c foreach (var node in context.InputNodes) { - var symbolAndProjectId = graphBuilder.GetSymbolAndProjectId(node); - if (symbolAndProjectId.Symbol != null) + var symbol = graphBuilder.GetSymbol(node); + if (symbol != null) { - foreach (var newSymbol in await GetCalledMethodSymbolsAsync(symbolAndProjectId, solution, cancellationToken).ConfigureAwait(false)) + foreach (var newSymbol in await GetCalledMethodSymbolsAsync(symbol, solution, cancellationToken).ConfigureAwait(false)) { cancellationToken.ThrowIfCancellationRequested(); @@ -37,12 +37,12 @@ public async Task GetGraphAsync(Solution solution, IGraphContext c return graphBuilder; } - private static async Task> GetCalledMethodSymbolsAsync( - SymbolAndProjectId symbolAndProjectId, Solution solution, CancellationToken cancellationToken) + private static async Task> GetCalledMethodSymbolsAsync( + ISymbol symbol, Solution solution, CancellationToken cancellationToken) { - using var _ = ArrayBuilder.GetInstance(out var symbols); + using var _ = ArrayBuilder.GetInstance(out var symbols); - foreach (var reference in symbolAndProjectId.Symbol.DeclaringSyntaxReferences) + 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()) @@ -53,7 +53,7 @@ private static async Task> GetCalledMethodSym if (newSymbol != null && newSymbol is IMethodSymbol && (newSymbol.CanBeReferencedByName || ((IMethodSymbol)newSymbol).MethodKind == MethodKind.Constructor)) { - symbols.Add(symbolAndProjectId.WithSymbol(newSymbol)); + symbols.Add(newSymbol); } } } diff --git a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/ContainsChildrenGraphQuery.cs b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/ContainsChildrenGraphQuery.cs index 8df2acaee338e..df46e8b1967c4 100644 --- a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/ContainsChildrenGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/ContainsChildrenGraphQuery.cs @@ -23,11 +23,11 @@ public async Task GetGraphAsync(Solution solution, IGraphContext c { if (!cancellationToken.IsCancellationRequested) { - var symbolAndProjectId = graphBuilder.GetSymbolAndProjectId(node); + var symbol = graphBuilder.GetSymbol(node); - if (symbolAndProjectId.Symbol != null) + if (symbol != null) { - var containsChildren = SymbolContainment.GetContainedSymbols(symbolAndProjectId).Any(); + var containsChildren = SymbolContainment.GetContainedSymbols(symbol).Any(); graphBuilder.AddDeferredPropertySet(node, DgmlNodeProperties.ContainsChildren, containsChildren); } else if (node.HasCategory(CodeNodeCategories.File)) diff --git a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/ContainsGraphQuery.cs b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/ContainsGraphQuery.cs index a10e8d38cb94a..217274cb78dc4 100644 --- a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/ContainsGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/ContainsGraphQuery.cs @@ -31,9 +31,9 @@ public async Task GetGraphAsync(Solution solution, IGraphContext c { cancellationToken.ThrowIfCancellationRequested(); - var symbol = graphBuilder.GetSymbolAndProjectId(node); + var symbol = graphBuilder.GetSymbol(node); - if (symbol.Symbol != null) + if (symbol != null) { foreach (var newSymbol in SymbolContainment.GetContainedSymbols(symbol)) { diff --git a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/ImplementedByGraphQuery.cs b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/ImplementedByGraphQuery.cs index dd310c802e17e..5d7ddca111c92 100644 --- a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/ImplementedByGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/ImplementedByGraphQuery.cs @@ -22,11 +22,11 @@ public async Task GetGraphAsync(Solution solution, IGraphContext c foreach (var node in context.InputNodes) { - var symbol = graphBuilder.GetSymbolAndProjectId(node); - if (symbol.Symbol is INamedTypeSymbol || - symbol.Symbol is IMethodSymbol || - symbol.Symbol is IPropertySymbol || - symbol.Symbol is IEventSymbol) + var symbol = graphBuilder.GetSymbol(node); + if (symbol is INamedTypeSymbol || + symbol is IMethodSymbol || + symbol is IPropertySymbol || + symbol is IEventSymbol) { var implementations = await SymbolFinder.FindImplementationsAsync(symbol, solution, cancellationToken: cancellationToken).ConfigureAwait(false); diff --git a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/ImplementsGraphQuery.cs b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/ImplementsGraphQuery.cs index 59ea9df3847b1..5fe1b6fb45e9e 100644 --- a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/ImplementsGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/ImplementsGraphQuery.cs @@ -24,18 +24,18 @@ public async Task GetGraphAsync(Solution solution, IGraphContext c foreach (var node in context.InputNodes) { - var symbol = graphBuilder.GetSymbolAndProjectId(node); - if (symbol.Symbol is INamedTypeSymbol namedType) + var symbol = graphBuilder.GetSymbol(node); + if (symbol is INamedTypeSymbol namedType) { - var implementedSymbols = namedType.AllInterfaces.SelectAsArray(i => (SymbolAndProjectId)symbol.WithSymbol(i)); + var implementedSymbols = ImmutableArray.CastUp(namedType.AllInterfaces); await AddImplementedSymbolsAsync(graphBuilder, node, implementedSymbols).ConfigureAwait(false); } - else if (symbol.Symbol is IMethodSymbol || - symbol.Symbol is IPropertySymbol || - symbol.Symbol is IEventSymbol) + else if (symbol is IMethodSymbol || + symbol is IPropertySymbol || + symbol is IEventSymbol) { - var implements = await SymbolFinder.FindImplementedInterfaceMembersAsync(symbol, solution, cancellationToken: cancellationToken).ConfigureAwait(false); + var implements = await SymbolFinder.FindImplementedInterfaceMembersArrayAsync(symbol, solution, cancellationToken: cancellationToken).ConfigureAwait(false); await AddImplementedSymbolsAsync(graphBuilder, node, implements).ConfigureAwait(false); } } @@ -46,7 +46,7 @@ symbol.Symbol is IPropertySymbol || private static async Task AddImplementedSymbolsAsync( GraphBuilder graphBuilder, GraphNode node, - ImmutableArray implementedSymbols) + ImmutableArray implementedSymbols) { foreach (var interfaceType in implementedSymbols) { diff --git a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/InheritedByGraphQuery.cs b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/InheritedByGraphQuery.cs index 90bdc36fa0c79..58bd4ac68034c 100644 --- a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/InheritedByGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/InheritedByGraphQuery.cs @@ -19,14 +19,14 @@ public async Task GetGraphAsync(Solution solution, IGraphContext c foreach (var node in context.InputNodes) { - var symbolAndProjectId = graphBuilder.GetSymbolAndProjectId(node); - if (!(symbolAndProjectId.Symbol is INamedTypeSymbol namedType)) + var symbol = graphBuilder.GetSymbol(node); + if (!(symbol is INamedTypeSymbol namedType)) continue; if (namedType.TypeKind == TypeKind.Class) { var derivedTypes = await DependentTypeFinder.FindImmediatelyDerivedClassesAsync( - symbolAndProjectId.WithSymbol(namedType), solution, cancellationToken).ConfigureAwait(false); + namedType, solution, cancellationToken).ConfigureAwait(false); foreach (var derivedType in derivedTypes) { var symbolNode = await graphBuilder.AddNodeAsync( @@ -37,7 +37,7 @@ public async Task GetGraphAsync(Solution solution, IGraphContext c else if (namedType.TypeKind == TypeKind.Interface) { var derivedTypes = await DependentTypeFinder.FindImmediatelyDerivedAndImplementingTypesAsync( - symbolAndProjectId.WithSymbol(namedType), solution, cancellationToken).ConfigureAwait(false); + namedType, solution, cancellationToken).ConfigureAwait(false); foreach (var derivedType in derivedTypes) { var symbolNode = await graphBuilder.AddNodeAsync( diff --git a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/InheritsGraphQuery.cs b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/InheritsGraphQuery.cs index 0e5e7b62ecce3..80503d8f21288 100644 --- a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/InheritsGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/InheritsGraphQuery.cs @@ -31,13 +31,13 @@ public async Task GetGraphAsync(Solution solution, IGraphContext c foreach (var node in nodesToProcess) { - var symbolAndProjectId = graphBuilder.GetSymbolAndProjectId(node); - if (symbolAndProjectId.Symbol is INamedTypeSymbol namedType) + var symbol = graphBuilder.GetSymbol(node); + if (symbol is INamedTypeSymbol namedType) { if (namedType.BaseType != null) { var baseTypeNode = await graphBuilder.AddNodeAsync( - symbolAndProjectId.WithSymbol(namedType.BaseType), relatedNode: node).ConfigureAwait(false); + namedType.BaseType, relatedNode: node).ConfigureAwait(false); newNodes.Add(baseTypeNode); graphBuilder.AddLink(node, CodeLinkCategories.InheritsFrom, baseTypeNode); } @@ -46,7 +46,7 @@ public async Task GetGraphAsync(Solution solution, IGraphContext c foreach (var baseNode in namedType.OriginalDefinition.AllInterfaces.Distinct()) { var baseTypeNode = await graphBuilder.AddNodeAsync( - symbolAndProjectId.WithSymbol(baseNode), relatedNode: node).ConfigureAwait(false); + baseNode, relatedNode: node).ConfigureAwait(false); newNodes.Add(baseTypeNode); graphBuilder.AddLink(node, CodeLinkCategories.InheritsFrom, baseTypeNode); } diff --git a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/IsCalledByGraphQuery.cs b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/IsCalledByGraphQuery.cs index 9e1ef5286e16e..c395f900dda2c 100644 --- a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/IsCalledByGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/IsCalledByGraphQuery.cs @@ -23,14 +23,14 @@ public async Task GetGraphAsync(Solution solution, IGraphContext c foreach (var node in context.InputNodes) { - var symbol = graphBuilder.GetSymbolAndProjectId(node); - if (symbol.Symbol != null) + var symbol = graphBuilder.GetSymbol(node); + 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.CallingSymbolAndProjectId, relatedNode: node).ConfigureAwait(false); + var callerNode = await graphBuilder.AddNodeAsync(caller.CallingSymbol, relatedNode: node).ConfigureAwait(false); graphBuilder.AddLink(callerNode, CodeLinkCategories.Calls, node); } } diff --git a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/IsUsedByGraphQuery.cs b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/IsUsedByGraphQuery.cs index 9dd4dbed4d839..9274b84966169 100644 --- a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/IsUsedByGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/IsUsedByGraphQuery.cs @@ -24,7 +24,7 @@ public async Task GetGraphAsync(Solution solution, IGraphContext c foreach (var node in context.InputNodes) { - var symbol = graphBuilder.GetSymbolAndProjectId(node); + var symbol = graphBuilder.GetSymbol(node); var references = await SymbolFinder.FindReferencesAsync(symbol, solution, cancellationToken).ConfigureAwait(false); foreach (var reference in references) diff --git a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/OverriddenByGraphQuery.cs b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/OverriddenByGraphQuery.cs index f94af1cd33f85..d38b160c3b8fa 100644 --- a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/OverriddenByGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/OverriddenByGraphQuery.cs @@ -19,14 +19,14 @@ public async Task GetGraphAsync(Solution solution, IGraphContext c foreach (var node in context.InputNodes) { - var symbol = graphBuilder.GetSymbolAndProjectId(node); - if (symbol.Symbol != null) + var symbol = graphBuilder.GetSymbol(node); + if (symbol != null) { - var overriddenMember = symbol.Symbol.OverriddenMember(); + var overriddenMember = symbol.OverriddenMember(); if (overriddenMember != null) { var symbolNode = await graphBuilder.AddNodeAsync( - symbol.WithSymbol(overriddenMember), relatedNode: node).ConfigureAwait(false); + overriddenMember, relatedNode: node).ConfigureAwait(false); graphBuilder.AddLink(node, RoslynGraphCategories.Overrides, symbolNode); } } diff --git a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/OverridesGraphQuery.cs b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/OverridesGraphQuery.cs index 91b87378bebfd..6baf11de6ff8a 100644 --- a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/OverridesGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/OverridesGraphQuery.cs @@ -21,10 +21,10 @@ public async Task GetGraphAsync(Solution solution, IGraphContext c foreach (var node in context.InputNodes) { - var symbol = graphBuilder.GetSymbolAndProjectId(node); - if (symbol.Symbol is IMethodSymbol || - symbol.Symbol is IPropertySymbol || - symbol.Symbol is IEventSymbol) + var symbol = graphBuilder.GetSymbol(node); + if (symbol is IMethodSymbol || + symbol is IPropertySymbol || + symbol is IEventSymbol) { var overrides = await SymbolFinder.FindOverridesAsync(symbol, solution, cancellationToken: cancellationToken).ConfigureAwait(false); foreach (var o in overrides) diff --git a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/SearchGraphQuery.cs b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/SearchGraphQuery.cs index 2aff350d734ad..b4e42476e8026 100644 --- a/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/SearchGraphQuery.cs +++ b/src/VisualStudio/Core/Def/Implementation/Progression/GraphQueries/SearchGraphQuery.cs @@ -50,11 +50,11 @@ private async Task ProcessProjectAsync(Project project, GraphBuilder graphBuilde { cancellationToken.ThrowIfCancellationRequested(); - if (symbol.Symbol is INamedTypeSymbol namedType) + if (symbol is INamedTypeSymbol namedType) { await AddLinkedNodeForTypeAsync( - project, symbol.WithSymbol(namedType), graphBuilder, - symbol.Symbol.DeclaringSyntaxReferences.Select(d => d.SyntaxTree)).ConfigureAwait(false); + project, namedType, graphBuilder, + symbol.DeclaringSyntaxReferences.Select(d => d.SyntaxTree)).ConfigureAwait(false); } else { @@ -66,14 +66,14 @@ await AddLinkedNodeForTypeAsync( } private async Task AddLinkedNodeForTypeAsync( - Project project, SymbolAndProjectId namedTypeAndProjectId, GraphBuilder graphBuilder, IEnumerable syntaxTrees) + Project project, INamedTypeSymbol namedType, GraphBuilder graphBuilder, IEnumerable syntaxTrees) { // If this named type is contained in a parent type, then just link farther up - if (namedTypeAndProjectId.Symbol.ContainingType != null) + if (namedType.ContainingType != null) { var parentTypeNode = await AddLinkedNodeForTypeAsync( - project, namedTypeAndProjectId.WithSymbol(namedTypeAndProjectId.Symbol.ContainingType), graphBuilder, syntaxTrees).ConfigureAwait(false); - var typeNode = await graphBuilder.AddNodeAsync(namedTypeAndProjectId, relatedNode: parentTypeNode).ConfigureAwait(false); + project, namedType.ContainingType, graphBuilder, syntaxTrees).ConfigureAwait(false); + var typeNode = await graphBuilder.AddNodeAsync(namedType, relatedNode: parentTypeNode).ConfigureAwait(false); graphBuilder.AddLink(parentTypeNode, GraphCommonSchema.Contains, typeNode); return typeNode; @@ -81,7 +81,7 @@ private async Task AddLinkedNodeForTypeAsync( else { // From here, we can link back up to the containing project item - var typeNode = await graphBuilder.AddNodeAsync(namedTypeAndProjectId, contextProject: project, contextDocument: null).ConfigureAwait(false); + var typeNode = await graphBuilder.AddNodeAsync(namedType, contextProject: project, contextDocument: null).ConfigureAwait(false); foreach (var tree in syntaxTrees) { @@ -97,26 +97,26 @@ private async Task AddLinkedNodeForTypeAsync( } private async Task AddLinkedNodeForMemberAsync( - Project project, SymbolAndProjectId symbolAndProjectId, GraphBuilder graphBuilder) + Project project, ISymbol symbol, GraphBuilder graphBuilder) { - var member = symbolAndProjectId.Symbol; + var member = symbol; Contract.ThrowIfNull(member.ContainingType); var trees = member.DeclaringSyntaxReferences.Select(d => d.SyntaxTree); var parentTypeNode = await AddLinkedNodeForTypeAsync( - project, symbolAndProjectId.WithSymbol(member.ContainingType), graphBuilder, trees).ConfigureAwait(false); + project, member.ContainingType, graphBuilder, trees).ConfigureAwait(false); var memberNode = await graphBuilder.AddNodeAsync( - symbolAndProjectId, relatedNode: parentTypeNode).ConfigureAwait(false); + symbol, relatedNode: parentTypeNode).ConfigureAwait(false); graphBuilder.AddLink(parentTypeNode, GraphCommonSchema.Contains, memberNode); return memberNode; } - internal async Task> FindNavigableSourceSymbolsAsync( + internal async Task> FindNavigableSourceSymbolsAsync( Project project, CancellationToken cancellationToken) { - ImmutableArray declarations; + ImmutableArray declarations; // FindSourceDeclarationsWithPatternAsync calls into OOP to do the search; if something goes badly it // throws a SoftCrashException which inherits from OperationCanceledException. This is unfortunate, because @@ -139,13 +139,13 @@ internal async Task> FindNavigableSourceSymbo throw ExceptionUtilities.Unreachable; } - using var _ = ArrayBuilder.GetInstance(out var results); + using var _ = ArrayBuilder.GetInstance(out var results); foreach (var declaration in declarations) { cancellationToken.ThrowIfCancellationRequested(); - var symbol = declaration.Symbol; + var symbol = declaration; // Ignore constructors and namespaces. We don't want to expose them through this API. if (symbol.IsConstructor() || @@ -171,7 +171,7 @@ internal async Task> FindNavigableSourceSymbo // only constructors that were explicitly declared if (!constructor.IsImplicitlyDeclared) { - results.Add(declaration.WithSymbol(constructor)); + results.Add(constructor); } } } @@ -179,7 +179,7 @@ internal async Task> FindNavigableSourceSymbo // report both parts of partial methods if (symbol is IMethodSymbol method && method.PartialImplementationPart != null) { - results.Add(declaration.WithSymbol(method)); + results.Add(method); } } diff --git a/src/VisualStudio/Core/Def/Implementation/Progression/SymbolContainment.cs b/src/VisualStudio/Core/Def/Implementation/Progression/SymbolContainment.cs index 9b10112d7ba58..5e1664376da96 100644 --- a/src/VisualStudio/Core/Def/Implementation/Progression/SymbolContainment.cs +++ b/src/VisualStudio/Core/Def/Implementation/Progression/SymbolContainment.cs @@ -33,11 +33,11 @@ public static async Task> GetContainedSyntaxNodesAsync(D return progressionLanguageService.GetTopLevelNodesFromDocument(root, cancellationToken); } - public static async Task> GetContainedSymbolsAsync(Document document, CancellationToken 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); + using var _ = ArrayBuilder.GetInstance(out var symbols); foreach (var syntaxNode in syntaxNodes) { @@ -48,7 +48,7 @@ public static async Task> GetContainedSymbols !string.IsNullOrEmpty(symbol.Name) && IsTopLevelSymbol(symbol)) { - symbols.Add(new SymbolAndProjectId(symbol, document.Project.Id)); + symbols.Add(symbol); } } @@ -71,9 +71,9 @@ private static bool IsTopLevelSymbol(ISymbol symbol) } } - public static IEnumerable GetContainedSymbols(SymbolAndProjectId symbolAndProjectId) + public static IEnumerable GetContainedSymbols(ISymbol symbol) { - if (symbolAndProjectId.Symbol is INamedTypeSymbol namedType) + if (symbol is INamedTypeSymbol namedType) { foreach (var member in namedType.GetMembers()) { @@ -89,7 +89,7 @@ public static IEnumerable GetContainedSymbols(SymbolAndProje if (!string.IsNullOrEmpty(member.Name)) { - yield return symbolAndProjectId.WithSymbol(member); + yield return member; } } } diff --git a/src/VisualStudio/Core/Def/Implementation/Workspace/VisualStudioSymbolNavigationService.cs b/src/VisualStudio/Core/Def/Implementation/Workspace/VisualStudioSymbolNavigationService.cs index 60ab69b242cd1..d0dc05ec05208 100644 --- a/src/VisualStudio/Core/Def/Implementation/Workspace/VisualStudioSymbolNavigationService.cs +++ b/src/VisualStudio/Core/Def/Implementation/Workspace/VisualStudioSymbolNavigationService.cs @@ -178,14 +178,14 @@ public bool TryNavigateToSymbol(ISymbol symbol, Project project, OptionSet optio } public bool TrySymbolNavigationNotify(ISymbol symbol, Project project, CancellationToken cancellationToken) - => TryNotifyForSpecificSymbol(symbol, project, cancellationToken); + => TryNotifyForSpecificSymbol(symbol, project.Solution, cancellationToken); private bool TryNotifyForSpecificSymbol( - ISymbol symbol, Project project, CancellationToken cancellationToken) + ISymbol symbol, Solution solution, CancellationToken cancellationToken) { AssertIsForeground(); - var definitionItem = symbol.ToNonClassifiedDefinitionItem(project, includeHiddenLocations: true); + var definitionItem = symbol.ToNonClassifiedDefinitionItem(solution, includeHiddenLocations: true); definitionItem.Properties.TryGetValue(DefinitionItem.RQNameKey1, out var rqName); if (!TryGetNavigationAPIRequiredArguments( diff --git a/src/VisualStudio/Core/Impl/RoslynVisualStudioWorkspace.cs b/src/VisualStudio/Core/Impl/RoslynVisualStudioWorkspace.cs index 7c448ed6ce7bc..1b09fd5a3c26c 100644 --- a/src/VisualStudio/Core/Impl/RoslynVisualStudioWorkspace.cs +++ b/src/VisualStudio/Core/Impl/RoslynVisualStudioWorkspace.cs @@ -122,7 +122,7 @@ public override bool TryGoToDefinition( } return GoToDefinitionHelpers.TryGoToDefinition( - searchSymbol, searchProject, + searchSymbol, searchProject.Solution, _streamingPresenter.Value, cancellationToken); } diff --git a/src/VisualStudio/Core/Test/GoToDefinition/GoToDefinitionApiTests.vb b/src/VisualStudio/Core/Test/GoToDefinition/GoToDefinitionApiTests.vb index db9e4ccecdee0..85c2335e656f8 100644 --- a/src/VisualStudio/Core/Test/GoToDefinition/GoToDefinitionApiTests.vb +++ b/src/VisualStudio/Core/Test/GoToDefinition/GoToDefinitionApiTests.vb @@ -42,7 +42,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.GoToDefinition WpfTestRunner.RequireWpfFact($"{NameOf(GoToDefinitionHelpers)}.{NameOf(GoToDefinitionHelpers.TryGoToDefinition)} assumes it's on the UI thread with a {NameOf(TaskExtensions.WaitAndGetResult)} call") Dim success = GoToDefinitionHelpers.TryGoToDefinition( - symbolInfo.Symbol, document.Project, + symbolInfo.Symbol, document.Project.Solution, presenter, thirdPartyNavigationAllowed:=True, cancellationToken:=CancellationToken.None) diff --git a/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb b/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb index e3f053160f355..c498ddd5fdc2e 100644 --- a/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb +++ b/src/VisualStudio/Core/Test/Progression/ProgressionTestState.vb @@ -43,8 +43,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Progression End If Dim graphBuilder As New GraphBuilder(_workspace.CurrentSolution, CancellationToken.None) - graphBuilder.AddNodeAsync( - New SymbolAndProjectId(symbol, document.Project.Id), document.Project, document).Wait(CancellationToken.None) + graphBuilder.AddNodeAsync(symbol, document.Project, document).Wait(CancellationToken.None) Return graphBuilder.Graph End Function diff --git a/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs b/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs index ab4d6adef547b..d0b61fea24008 100644 --- a/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs +++ b/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs @@ -768,7 +768,7 @@ public override async Task> ComputeDeclarationConflicts string replacementText, ISymbol renamedSymbol, ISymbol renameSymbol, - IEnumerable referencedSymbols, + IEnumerable referencedSymbols, Solution baseSolution, Solution newSolution, IDictionary reverseMappedLocations, @@ -843,9 +843,9 @@ renamedSymbol.ContainingSymbol is IMethodSymbol methodSymbol && { var property = await RenameLocations.ReferenceProcessing.GetPropertyFromAccessorOrAnOverrideAsync( referencedSymbol, baseSolution, cancellationToken).ConfigureAwait(false); - if (property.Symbol != null) + if (property != null) { - properties.Add(property.Symbol); + properties.Add(property); } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/Declarations/DeclarationFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/Declarations/DeclarationFinder.cs index 363046284373b..40015bfaed7c0 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/Declarations/DeclarationFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/Declarations/DeclarationFinder.cs @@ -18,7 +18,7 @@ internal static partial class DeclarationFinder { private static Task AddCompilationDeclarationsWithNormalQueryAsync( Project project, SearchQuery query, SymbolFilter filter, - ArrayBuilder list, CancellationToken cancellationToken) + ArrayBuilder list, CancellationToken cancellationToken) { Contract.ThrowIfTrue(query.Kind == SearchKind.Custom, "Custom queries are not supported in this API"); return AddCompilationDeclarationsWithNormalQueryAsync( @@ -32,7 +32,7 @@ private static async Task AddCompilationDeclarationsWithNormalQueryAsync( Project project, SearchQuery query, SymbolFilter filter, - ArrayBuilder list, + ArrayBuilder list, Compilation startingCompilation, IAssemblySymbol startingAssembly, CancellationToken cancellationToken) @@ -70,14 +70,14 @@ private static async Task AddCompilationDeclarationsWithNormalQueryAsync( ? compilation.GetSymbolsWithName(query.Name, filter, cancellationToken) : compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken); - var symbolsWithName = symbols.SelectAsArray(s => new SymbolAndProjectId(s, project.Id)); + var symbolsWithName = symbols.ToImmutableArray(); if (startingCompilation != null && startingAssembly != null && !Equals(compilation.Assembly, startingAssembly)) { // Return symbols from skeleton assembly in this case so that symbols have // the same language as startingCompilation. - symbolsWithName = symbolsWithName.Select(s => s.WithSymbol(s.Symbol.GetSymbolKey().Resolve(startingCompilation, cancellationToken: cancellationToken).Symbol)) - .Where(s => s.Symbol != null) + symbolsWithName = symbolsWithName.Select(s => s.GetSymbolKey().Resolve(startingCompilation, cancellationToken: cancellationToken).Symbol) + .WhereNotNull() .ToImmutableArray(); } @@ -87,7 +87,7 @@ private static async Task AddCompilationDeclarationsWithNormalQueryAsync( private static async Task AddMetadataDeclarationsWithNormalQueryAsync( Project project, IAssemblySymbol assembly, PortableExecutableReference referenceOpt, - SearchQuery query, SymbolFilter filter, ArrayBuilder list, + SearchQuery query, SymbolFilter filter, ArrayBuilder list, CancellationToken cancellationToken) { // All entrypoints to this function are Find functions that are only searching @@ -108,8 +108,8 @@ private static async Task AddMetadataDeclarationsWithNormalQueryAsync( } } - internal static ImmutableArray FilterByCriteria(ImmutableArray symbols, SymbolFilter criteria) - => symbols.WhereAsArray(s => MeetCriteria(s.Symbol, criteria)); + internal static ImmutableArray FilterByCriteria(ImmutableArray symbols, SymbolFilter criteria) + => symbols.WhereAsArray(s => MeetCriteria(s, criteria)); private static bool MeetCriteria(ISymbol symbol, SymbolFilter filter) { diff --git a/src/Workspaces/Core/Portable/FindSymbols/Declarations/DeclarationFinder_AllDeclarations.cs b/src/Workspaces/Core/Portable/FindSymbols/Declarations/DeclarationFinder_AllDeclarations.cs index d3d87c82bc25f..069e6edf83746 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/Declarations/DeclarationFinder_AllDeclarations.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/Declarations/DeclarationFinder_AllDeclarations.cs @@ -19,7 +19,7 @@ namespace Microsoft.CodeAnalysis.FindSymbols internal static partial class DeclarationFinder { - public static async Task> FindAllDeclarationsWithNormalQueryAsync( + public static async Task> FindAllDeclarationsWithNormalQueryAsync( Project project, SearchQuery query, SymbolFilter criteria, CancellationToken cancellationToken) { // All entrypoints to this function are Find functions that are only searching @@ -33,7 +33,7 @@ public static async Task> FindAllDeclarations if (query.Name != null && string.IsNullOrWhiteSpace(query.Name)) { - return ImmutableArray.Empty; + return ImmutableArray.Empty; } var client = await RemoteHostClient.TryGetClientAsync(project, cancellationToken).ConfigureAwait(false); @@ -59,10 +59,10 @@ public static async Task> FindAllDeclarations project, query, criteria, cancellationToken).ConfigureAwait(false); } - internal static async Task> FindAllDeclarationsWithNormalQueryInCurrentProcessAsync( + internal static async Task> FindAllDeclarationsWithNormalQueryInCurrentProcessAsync( Project project, SearchQuery query, SymbolFilter criteria, CancellationToken cancellationToken) { - var list = ArrayBuilder.GetInstance(); + var list = ArrayBuilder.GetInstance(); if (project.SupportsCompilation) { @@ -94,12 +94,10 @@ await AddMetadataDeclarationsWithNormalQueryAsync( // for the passed in project. for (var i = 0; i < list.Count; i++) { - var symbolAndProjectId = list[i]; - if (symbolAndProjectId.Symbol is INamespaceSymbol ns) + var symbol = list[i]; + if (symbol is INamespaceSymbol ns) { - list[i] = new SymbolAndProjectId( - compilation.GetCompilationNamespace(ns), - project.Id); + list[i] = compilation.GetCompilationNamespace(ns); } } } @@ -107,10 +105,10 @@ await AddMetadataDeclarationsWithNormalQueryAsync( return list.ToImmutableAndFree(); } - private static async Task> RehydrateAsync( + private static async Task> RehydrateAsync( Solution solution, IList array, CancellationToken cancellationToken) { - var result = ArrayBuilder.GetInstance(array.Count); + var result = ArrayBuilder.GetInstance(array.Count); foreach (var dehydrated in array) { @@ -118,7 +116,7 @@ private static async Task> RehydrateAsync( var rehydrated = await dehydrated.TryRehydrateAsync(solution, cancellationToken).ConfigureAwait(false); if (rehydrated != null) { - result.Add(rehydrated.Value); + result.Add(rehydrated); } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/Declarations/DeclarationFinder_SourceDeclarations.cs b/src/Workspaces/Core/Portable/FindSymbols/Declarations/DeclarationFinder_SourceDeclarations.cs index fa8eeb8c3846f..240e590a69d81 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/Declarations/DeclarationFinder_SourceDeclarations.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/Declarations/DeclarationFinder_SourceDeclarations.cs @@ -23,7 +23,7 @@ internal static partial class DeclarationFinder // These are the public entrypoints to finding source declarations. They will attempt to // remote the query to the OOP process, and will fallback to local processing if they can't. - public static async Task> FindSourceDeclarationsWithNormalQueryAsync( + public static async Task> FindSourceDeclarationsWithNormalQueryAsync( Solution solution, string name, bool ignoreCase, SymbolFilter criteria, CancellationToken cancellationToken) { if (solution == null) @@ -38,7 +38,7 @@ public static async Task> FindSourceDeclarati if (string.IsNullOrWhiteSpace(name)) { - return ImmutableArray.Empty; + return ImmutableArray.Empty; } var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false); @@ -62,7 +62,7 @@ public static async Task> FindSourceDeclarati solution, name, ignoreCase, criteria, cancellationToken).ConfigureAwait(false); } - public static async Task> FindSourceDeclarationsWithNormalQueryAsync( + public static async Task> FindSourceDeclarationsWithNormalQueryAsync( Project project, string name, bool ignoreCase, SymbolFilter criteria, CancellationToken cancellationToken) { if (project == null) @@ -77,7 +77,7 @@ public static async Task> FindSourceDeclarati if (string.IsNullOrWhiteSpace(name)) { - return ImmutableArray.Empty; + return ImmutableArray.Empty; } var client = await RemoteHostClient.TryGetClientAsync(project, cancellationToken).ConfigureAwait(false); @@ -101,7 +101,7 @@ public static async Task> FindSourceDeclarati project, name, ignoreCase, criteria, cancellationToken).ConfigureAwait(false); } - public static async Task> FindSourceDeclarationsWithPatternAsync( + public static async Task> FindSourceDeclarationsWithPatternAsync( Solution solution, string pattern, SymbolFilter criteria, CancellationToken cancellationToken) { if (solution == null) @@ -136,7 +136,7 @@ public static async Task> FindSourceDeclarati solution, pattern, criteria, cancellationToken).ConfigureAwait(false); } - public static async Task> FindSourceDeclarationsWithPatternAsync( + public static async Task> FindSourceDeclarationsWithPatternAsync( Project project, string pattern, SymbolFilter criteria, CancellationToken cancellationToken) { if (project == null) @@ -178,12 +178,12 @@ public static async Task> FindSourceDeclarati // be called 'in proc' in the remote process if we are able to remote the request. Or they // will be called 'in proc' from within VS if we are not able to remote the request. - internal static async Task> FindSourceDeclarationsWithNormalQueryInCurrentProcessAsync( + internal static async Task> FindSourceDeclarationsWithNormalQueryInCurrentProcessAsync( Solution solution, string name, bool ignoreCase, SymbolFilter criteria, CancellationToken cancellationToken) { using var query = SearchQuery.Create(name, ignoreCase); - var result = ArrayBuilder.GetInstance(); + var result = ArrayBuilder.GetInstance(); foreach (var projectId in solution.ProjectIds) { var project = solution.GetProject(projectId); @@ -194,10 +194,10 @@ await AddCompilationDeclarationsWithNormalQueryAsync( return result.ToImmutableAndFree(); } - internal static async Task> FindSourceDeclarationsWithNormalQueryInCurrentProcessAsync( + internal static async Task> FindSourceDeclarationsWithNormalQueryInCurrentProcessAsync( Project project, string name, bool ignoreCase, SymbolFilter filter, CancellationToken cancellationToken) { - var list = ArrayBuilder.GetInstance(); + var list = ArrayBuilder.GetInstance(); using var query = SearchQuery.Create(name, ignoreCase); @@ -206,8 +206,8 @@ await AddCompilationDeclarationsWithNormalQueryAsync( return list.ToImmutableAndFree(); } - private static async Task> FindSourceDeclarationsWithPatternInCurrentProcessAsync( - string pattern, Func>> searchAsync) + private static async Task> FindSourceDeclarationsWithPatternInCurrentProcessAsync( + string pattern, Func>> searchAsync) { // The compiler API only supports a predicate which is given a symbol's name. Because // we only have the name, and nothing else, we need to check it against the last segment @@ -241,10 +241,10 @@ private static async Task> FindSourceDeclarat using var containerPatternMatcher = PatternMatcher.CreateDotSeparatedContainerMatcher(containerPart); return symbolAndProjectIds.WhereAsArray(t => - containerPatternMatcher.Matches(GetContainer(t.Symbol))); + containerPatternMatcher.Matches(GetContainer(t))); } - internal static Task> FindSourceDeclarationsWithPatternInCurrentProcessAsync( + internal static Task> FindSourceDeclarationsWithPatternInCurrentProcessAsync( Solution solution, string pattern, SymbolFilter criteria, CancellationToken cancellationToken) { return FindSourceDeclarationsWithPatternInCurrentProcessAsync( @@ -252,7 +252,7 @@ internal static Task> FindSourceDeclarationsW query => SymbolFinder.FindSourceDeclarationsWithCustomQueryAsync(solution, query, criteria, cancellationToken)); } - internal static Task> FindSourceDeclarationsWithPatternInCurrentProcessAsync( + internal static Task> FindSourceDeclarationsWithPatternInCurrentProcessAsync( Project project, string pattern, SymbolFilter criteria, CancellationToken cancellationToken) { return FindSourceDeclarationsWithPatternInCurrentProcessAsync( diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/BaseTypeFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/BaseTypeFinder.cs index 8d4683cf7f5b2..3fb742e9d33a4 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/BaseTypeFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/BaseTypeFinder.cs @@ -15,9 +15,8 @@ public static ImmutableArray FindBaseTypesAndInterfaces(INamedTypeSymbo => FindBaseTypes(type).AddRange(type.AllInterfaces).CastArray(); public static ImmutableArray FindOverriddenAndImplementedMembers( - ISymbol symbol, Project project, CancellationToken cancellationToken) + ISymbol symbol, Solution solution, CancellationToken cancellationToken) { - var solution = project.Solution; var results = ArrayBuilder.GetInstance(); // This is called for all: class, struct or interface member. diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs index 71bba1f63707f..1b0aab3d4fb2e 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs @@ -11,7 +11,9 @@ using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Shared.Utilities; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.FindSymbols @@ -22,7 +24,7 @@ namespace Microsoft.CodeAnalysis.FindSymbols // there may be a different set of related symbols found for each. using RelatedTypeCache = ConditionalWeakTable), AsyncLazy>>>; - using SymbolAndProjectIdSet = HashSet>; + using SymbolSet = HashSet; /// /// Provides helper methods for finding dependent types (derivations, implementations, @@ -44,8 +46,8 @@ internal static partial class DependentTypeFinder private static readonly Func s_isInterfaceOrNonSealedClass = t => t.TypeKind == TypeKind.Interface || s_isNonSealedClass(t); - private static readonly ObjectPool s_setPool = new ObjectPool( - () => new SymbolAndProjectIdSet(SymbolAndProjectIdComparer.SymbolEquivalenceInstance)); + private static readonly ObjectPool s_setPool = new ObjectPool( + () => new SymbolSet(SymbolEquivalenceComparer.Instance)); // Caches from a types to their related types (in the context of a specific solution). // Kept as a cache so that clients who make many calls into us won't end up computing @@ -60,48 +62,31 @@ internal static partial class DependentTypeFinder private static readonly RelatedTypeCache s_typeToTransitivelyImplementingStructuresClassesAndInterfacesMap = new RelatedTypeCache(); private static readonly RelatedTypeCache s_typeToImmediatelyDerivedAndImplementingTypesMap = new RelatedTypeCache(); - private static async Task>> FindTypesFromCacheOrComputeAsync( - SymbolAndProjectId type, + private static async Task> FindTypesFromCacheOrComputeAsync( + INamedTypeSymbol type, Solution solution, IImmutableSet projects, RelatedTypeCache cache, - Func>>> findAsync, + Func>> findAsync, CancellationToken cancellationToken) { var dictionary = cache.GetOrCreateValue(solution); - var result = default(ImmutableArray>); - // Do a quick lookup first to avoid the allocation. If it fails, go through the // slower allocating path. - var key = (type.Symbol.GetSymbolKey(), type.ProjectId, projects); + var key = (type.GetSymbolKey(), solution.GetOriginatingProjectId(type), projects); if (!dictionary.TryGetValue(key, out var lazy)) { lazy = dictionary.GetOrAdd(key, new AsyncLazy>( - async c => - { - // If we're the code that is actually computing the symbols, then just - // take our result and store it in the outer frame. That way the caller - // doesn't need to incur the cost of deserializing the symbol keys that - // we're create right below this. - result = await findAsync(c).ConfigureAwait(false); - return result.SelectAsArray(t => (t.Symbol.GetSymbolKey(), t.ProjectId)); - }, - cacheResult: true)); - } - - // If we were the caller that actually computed the symbols, then we can just return - // the values we got. - if (!result.IsDefault) - { - return result; + c => GetSymbolKeysAndProjectIdsAsync(solution, findAsync, c), + cacheResult: true)); ; } // Otherwise, someone else computed the symbols and cached the results as symbol // keys. Convert those symbol keys back to symbols and return. var symbolKeys = await lazy.GetValueAsync(cancellationToken).ConfigureAwait(false); - var builder = ArrayBuilder>.GetInstance(); + var builder = ArrayBuilder.GetInstance(); // Group by projectId so that we only process one project/compilation at a time. // Also, process in dependency order so that previous compilations are ready if @@ -126,7 +111,7 @@ private static async Task>> var resolvedSymbol = symbolKey.Resolve(compilation, cancellationToken: cancellationToken).GetAnySymbol(); if (resolvedSymbol is INamedTypeSymbol namedType) { - builder.Add(new SymbolAndProjectId(namedType, project.Id)); + builder.Add(namedType); } } } @@ -135,11 +120,24 @@ private static async Task>> return builder.ToImmutableAndFree(); } + private static async Task> GetSymbolKeysAndProjectIdsAsync( + Solution solution, + Func>> findAsync, + CancellationToken cancellationToken) + { + // If we're the code that is actually computing the symbols, then just + // take our result and store it in the outer frame. That way the caller + // doesn't need to incur the cost of deserializing the symbol keys that + // we're create right below this. + var result = await findAsync(cancellationToken).ConfigureAwait(false); + return result.SelectAsArray(t => (t.GetSymbolKey(), solution.GetOriginatingProjectId(t))); + } + /// /// Used for implementing the Inherited-By relation for progression. /// - public static Task>> FindImmediatelyDerivedClassesAsync( - SymbolAndProjectId type, + public static Task> FindImmediatelyDerivedClassesAsync( + INamedTypeSymbol type, Solution solution, CancellationToken cancellationToken) { @@ -152,10 +150,10 @@ public static Task>> FindImm } /// - /// This is an internal implementation of , which is a publically callable method. + /// This is an internal implementation of , which is a publically callable method. /// - public static Task>> FindTransitivelyDerivedClassesAsync( - SymbolAndProjectId type, + public static Task> FindTransitivelyDerivedClassesAsync( + INamedTypeSymbol type, Solution solution, IImmutableSet projects, CancellationToken cancellationToken) @@ -166,20 +164,20 @@ public static Task>> FindTra cancellationToken); } - private static Task>> FindDerivedClassesAsync( - SymbolAndProjectId type, + private static Task> FindDerivedClassesAsync( + INamedTypeSymbol type, Solution solution, IImmutableSet projects, bool transitive, CancellationToken cancellationToken) { - if (s_isNonSealedClass(type.Symbol)) + if (s_isNonSealedClass(type)) { - bool metadataTypeMatches(SymbolAndProjectIdSet set, INamedTypeSymbol metadataType) + bool metadataTypeMatches(SymbolSet set, INamedTypeSymbol metadataType) => TypeDerivesFrom(set, metadataType, transitive); - bool sourceTypeImmediatelyMatches(SymbolAndProjectIdSet set, INamedTypeSymbol metadataType) - => set.Contains(SymbolAndProjectId.Create(metadataType.BaseType?.OriginalDefinition, projectId: null)); + bool sourceTypeImmediatelyMatches(SymbolSet set, INamedTypeSymbol metadataType) + => set.Contains(metadataType.BaseType?.OriginalDefinition); return FindTypesAsync(type, solution, projects, metadataTypeMatches: metadataTypeMatches, @@ -189,15 +187,15 @@ bool sourceTypeImmediatelyMatches(SymbolAndProjectIdSet set, INamedTypeSymbol me cancellationToken: cancellationToken); } - return SpecializedTasks.EmptyImmutableArray>(); + return SpecializedTasks.EmptyImmutableArray(); } /// - /// Implementation of for + /// Implementation of for /// s /// - public static async Task>> FindTransitivelyImplementingStructuresAndClassesAsync( - SymbolAndProjectId type, + public static async Task> FindTransitivelyImplementingStructuresAndClassesAsync( + INamedTypeSymbol type, Solution solution, IImmutableSet projects, CancellationToken cancellationToken) @@ -206,15 +204,15 @@ public static async Task>> F // We only want implementing types here, not derived interfaces. return derivedAndImplementingTypes.WhereAsArray( - t => t.Symbol.TypeKind == TypeKind.Class || t.Symbol.TypeKind == TypeKind.Struct); + t => t.TypeKind == TypeKind.Class || t.TypeKind == TypeKind.Struct); } /// - /// Implementation of for + /// Implementation of for /// s /// - public static Task>> FindTransitivelyImplementingStructuresClassesAndInterfacesAsync( - SymbolAndProjectId type, + public static Task> FindTransitivelyImplementingStructuresClassesAndInterfacesAsync( + INamedTypeSymbol type, Solution solution, IImmutableSet projects, CancellationToken cancellationToken) @@ -225,8 +223,8 @@ public static Task>> FindTra cancellationToken); } - private static Task>> FindTransitivelyImplementingStructuresClassesAndInterfacesWorkerAsync( - SymbolAndProjectId type, + private static Task> FindTransitivelyImplementingStructuresClassesAndInterfacesWorkerAsync( + INamedTypeSymbol type, Solution solution, IImmutableSet projects, CancellationToken cancellationToken) @@ -238,8 +236,8 @@ private static Task>> FindTr /// /// Used for implementing the Inherited-By relation for progression. /// - public static Task>> FindImmediatelyDerivedAndImplementingTypesAsync( - SymbolAndProjectId type, + public static Task> FindImmediatelyDerivedAndImplementingTypesAsync( + INamedTypeSymbol type, Solution solution, CancellationToken cancellationToken) { @@ -251,17 +249,17 @@ public static Task>> FindImm cancellationToken: cancellationToken); } - private static Task>> FindDerivedAndImplementingTypesAsync( - SymbolAndProjectId type, + private static Task> FindDerivedAndImplementingTypesAsync( + INamedTypeSymbol type, Solution solution, IImmutableSet projects, bool transitive, CancellationToken cancellationToken) { // Only an interface can be implemented. - if (type.Symbol?.TypeKind == TypeKind.Interface) + if (type?.TypeKind == TypeKind.Interface) { - bool metadataTypeMatches(SymbolAndProjectIdSet s, INamedTypeSymbol t) + bool metadataTypeMatches(SymbolSet s, INamedTypeSymbol t) => TypeDerivesFrom(s, t, transitive) || TypeImplementsFrom(s, t, transitive); return FindTypesAsync(type, solution, projects, @@ -272,24 +270,24 @@ bool metadataTypeMatches(SymbolAndProjectIdSet s, INamedTypeSymbol t) cancellationToken: cancellationToken); } - return SpecializedTasks.EmptyImmutableArray>(); + return SpecializedTasks.EmptyImmutableArray(); } - private static async Task>> FindTypesAsync( - SymbolAndProjectId type, + private static async Task> FindTypesAsync( + INamedTypeSymbol type, Solution solution, IImmutableSet projects, - Func metadataTypeMatches, - Func sourceTypeImmediatelyMatches, + Func metadataTypeMatches, + Func sourceTypeImmediatelyMatches, Func shouldContinueSearching, bool transitive, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - type = type.WithSymbol(type.Symbol.OriginalDefinition); + type = type.OriginalDefinition; projects ??= ImmutableHashSet.Create(solution.Projects.ToArray()); - var searchInMetadata = type.Symbol.Locations.Any(s_isInMetadata); + var searchInMetadata = type.Locations.Any(s_isInMetadata); // Note: it is not sufficient to just walk the list of projects passed in, // searching only those for derived types. @@ -305,7 +303,7 @@ private static async Task>> // First find all the projects that could potentially reference this type. var projectsThatCouldReferenceType = await GetProjectsThatCouldReferenceTypeAsync( - type.Symbol, solution, searchInMetadata, cancellationToken).ConfigureAwait(false); + type, solution, searchInMetadata, cancellationToken).ConfigureAwait(false); // Now, based on the list of projects that could actually reference the type, // and the list of projects the caller wants to search, find the actual list of @@ -353,8 +351,8 @@ await FindTypesInProjectAsync( return ToImmutableAndFree(result); } - private static ImmutableArray> ToImmutableAndFree( - SymbolAndProjectIdSet set) + private static ImmutableArray ToImmutableAndFree( + SymbolSet set) { var array = set.ToImmutableArray(); s_setPool.ClearAndFree(set); @@ -363,12 +361,12 @@ private static ImmutableArray> ToImmutableA private static async Task FindTypesInProjectAsync( bool searchInMetadata, - SymbolAndProjectIdSet result, - SymbolAndProjectIdSet currentMetadataTypes, - SymbolAndProjectIdSet currentSourceAndMetadataTypes, + SymbolSet result, + SymbolSet currentMetadataTypes, + SymbolSet currentSourceAndMetadataTypes, Project project, - Func metadataTypeMatches, - Func sourceTypeImmediatelyMatches, + Func metadataTypeMatches, + Func sourceTypeImmediatelyMatches, Func shouldContinueSearching, bool transitive, CancellationToken cancellationToken) @@ -389,20 +387,19 @@ await AddAllMatchingMetadataTypesInProjectAsync( currentMetadataTypes, project, metadataTypeMatches, foundMetadataTypes, cancellationToken).ConfigureAwait(false); - foreach (var foundTypeAndProjectId in foundMetadataTypes) + foreach (var foundType in foundMetadataTypes) { cancellationToken.ThrowIfCancellationRequested(); - var foundType = foundTypeAndProjectId.Symbol; Debug.Assert(foundType.Locations.Any(s_isInMetadata)); // Add to the result list. - result.Add(foundTypeAndProjectId); + result.Add(foundType); if (transitive && shouldContinueSearching(foundType)) { - currentMetadataTypes.Add(foundTypeAndProjectId); - currentSourceAndMetadataTypes.Add(foundTypeAndProjectId); + currentMetadataTypes.Add(foundType); + currentSourceAndMetadataTypes.Add(foundType); } } } @@ -423,19 +420,18 @@ await AddSourceTypesInProjectAsync( transitive, foundSourceTypes, cancellationToken).ConfigureAwait(false); - foreach (var foundTypeAndProjectId in foundSourceTypes) + foreach (var foundType in foundSourceTypes) { cancellationToken.ThrowIfCancellationRequested(); - var foundType = foundTypeAndProjectId.Symbol; - Debug.Assert(foundType.Locations.All(s_isInSource)); + Debug.Assert(foundType.Locations.All(s_isInSource)); // Add to the result list. - result.Add(foundTypeAndProjectId); + result.Add(foundType); if (transitive && shouldContinueSearching(foundType)) { - currentSourceAndMetadataTypes.Add(foundTypeAndProjectId); + currentSourceAndMetadataTypes.Add(foundType); } } } @@ -563,10 +559,10 @@ private static IEnumerable GetProjectsToExamineWorker( } private static async Task AddAllMatchingMetadataTypesInProjectAsync( - SymbolAndProjectIdSet metadataTypes, + SymbolSet metadataTypes, Project project, - Func metadataTypeMatches, - SymbolAndProjectIdSet result, + Func metadataTypeMatches, + SymbolSet result, CancellationToken cancellationToken) { Debug.Assert(project.SupportsCompilation); @@ -604,12 +600,12 @@ await FindImmediateMatchingMetadataTypesInMetadataReferenceAsync( } private static async Task FindImmediateMatchingMetadataTypesInMetadataReferenceAsync( - SymbolAndProjectIdSet metadataTypes, + SymbolSet metadataTypes, Project project, - Func metadataTypeMatches, + Func metadataTypeMatches, Compilation compilation, PortableExecutableReference reference, - SymbolAndProjectIdSet result, + SymbolSet result, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -628,7 +624,7 @@ private static async Task FindImmediateMatchingMetadataTypesInMetadataReferenceA { cancellationToken.ThrowIfCancellationRequested(); - var baseTypeName = metadataType.Symbol.Name; + var baseTypeName = metadataType.Name; // For each derived type we find, see if we can map that back // to an actual symbol. Then check if that symbol actually fits @@ -639,7 +635,7 @@ private static async Task FindImmediateMatchingMetadataTypesInMetadataReferenceA { if (metadataTypeMatches(metadataTypes, derivedType)) { - result.Add(SymbolAndProjectId.Create(derivedType, project.Id)); + result.Add(derivedType); } } } @@ -647,14 +643,13 @@ private static async Task FindImmediateMatchingMetadataTypesInMetadataReferenceA } private static bool TypeDerivesFrom( - SymbolAndProjectIdSet metadataTypes, INamedTypeSymbol type, bool transitive) + SymbolSet metadataTypes, INamedTypeSymbol type, bool transitive) { if (transitive) { for (var current = type.BaseType; current != null; current = current.BaseType) { - if (metadataTypes.Contains( - SymbolAndProjectId.Create(current.OriginalDefinition, projectId: null))) + if (metadataTypes.Contains(current.OriginalDefinition)) { return true; } @@ -664,19 +659,18 @@ private static bool TypeDerivesFrom( } else { - return metadataTypes.Contains( - SymbolAndProjectId.Create(type.BaseType?.OriginalDefinition, projectId: null)); + return metadataTypes.Contains(type.BaseType?.OriginalDefinition); } } private static bool TypeImplementsFrom( - SymbolAndProjectIdSet metadataTypes, INamedTypeSymbol type, bool transitive) + SymbolSet metadataTypes, INamedTypeSymbol type, bool transitive) { var interfaces = transitive ? type.AllInterfaces : type.Interfaces; foreach (var interfaceType in interfaces) { - if (metadataTypes.Contains(SymbolAndProjectId.Create(interfaceType.OriginalDefinition, projectId: null))) + if (metadataTypes.Contains(interfaceType.OriginalDefinition)) { return true; } @@ -686,12 +680,12 @@ private static bool TypeImplementsFrom( } private static async Task AddSourceTypesInProjectAsync( - SymbolAndProjectIdSet sourceAndMetadataTypes, + SymbolSet sourceAndMetadataTypes, Project project, - Func sourceTypeImmediatelyMatches, + Func sourceTypeImmediatelyMatches, Func shouldContinueSearching, bool transitive, - SymbolAndProjectIdSet finalResult, + SymbolSet finalResult, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -718,7 +712,7 @@ private static async Task AddSourceTypesInProjectAsync( { cancellationToken.ThrowIfCancellationRequested(); - switch (type.Symbol.SpecialType) + switch (type.SpecialType) { case SpecialType.System_Object: await AddMatchingTypesAsync( @@ -745,7 +739,7 @@ await AddMatchingTypesAsync( await AddTypesThatDeriveFromNameAsync( sourceTypeImmediatelyMatches, cachedModels, typesToSearchFor, - projectIndex, localBuffer, type.Symbol.Name, cancellationToken).ConfigureAwait(false); + projectIndex, localBuffer, type.Name, cancellationToken).ConfigureAwait(false); } // Clear out the information about the types we're looking for. We'll @@ -757,7 +751,7 @@ await AddTypesThatDeriveFromNameAsync( { if (finalResult.Add(derivedType)) { - if (transitive && shouldContinueSearching(derivedType.Symbol)) + if (transitive && shouldContinueSearching(derivedType)) { typesToSearchFor.Add(derivedType); } @@ -769,16 +763,16 @@ await AddTypesThatDeriveFromNameAsync( } private static bool ImmediatelyDerivesOrImplementsFrom( - SymbolAndProjectIdSet typesToSearchFor, INamedTypeSymbol type) + SymbolSet typesToSearchFor, INamedTypeSymbol type) { - if (typesToSearchFor.Contains(SymbolAndProjectId.Create(type.BaseType?.OriginalDefinition, projectId: null))) + if (typesToSearchFor.Contains(type.BaseType?.OriginalDefinition)) { return true; } foreach (var interfaceType in type.Interfaces) { - if (typesToSearchFor.Contains(SymbolAndProjectId.Create(interfaceType.OriginalDefinition, projectId: null))) + if (typesToSearchFor.Contains(interfaceType.OriginalDefinition)) { return true; } @@ -788,11 +782,11 @@ private static bool ImmediatelyDerivesOrImplementsFrom( } private static async Task AddTypesThatDeriveFromNameAsync( - Func typeImmediatelyMatches, + Func typeImmediatelyMatches, ConcurrentSet cachedModels, - SymbolAndProjectIdSet typesToSearchFor, + SymbolSet typesToSearchFor, ProjectIndex index, - SymbolAndProjectIdSet result, + SymbolSet result, string name, CancellationToken cancellationToken) { @@ -807,7 +801,7 @@ private static async Task AddTypesThatDeriveFromNameAsync( if (resolvedType is INamedTypeSymbol namedType && typeImmediatelyMatches(typesToSearchFor, namedType)) { - result.Add(new SymbolAndProjectId(namedType, document.Project.Id)); + result.Add(namedType); } } } @@ -815,7 +809,7 @@ private static async Task AddTypesThatDeriveFromNameAsync( private static async Task AddMatchingTypesAsync( ConcurrentSet cachedModels, MultiDictionary documentToInfos, - SymbolAndProjectIdSet result, + SymbolSet result, Func predicateOpt, CancellationToken cancellationToken) { @@ -837,14 +831,14 @@ private static async Task AddMatchingTypesAsync( if (predicateOpt == null || predicateOpt(namedType)) { - result.Add(new SymbolAndProjectId(namedType, document.Project.Id)); + result.Add(namedType); } } } } } - private static SymbolAndProjectIdSet CreateSymbolAndProjectIdSet() + private static SymbolSet CreateSymbolAndProjectIdSet() => s_setPool.Allocate(); } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine.cs index 22dbef8a576bb..2c90cab0039c6 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine.cs @@ -15,7 +15,7 @@ namespace Microsoft.CodeAnalysis.FindSymbols { - using ProjectToDocumentMap = Dictionary>; + using ProjectToDocumentMap = Dictionary>; internal partial class FindReferencesSearchEngine { @@ -47,14 +47,14 @@ public FindReferencesSearchEngine( _progressTracker = progress.ProgressTracker; } - public async Task FindReferencesAsync(SymbolAndProjectId symbolAndProjectId) + public async Task FindReferencesAsync(ISymbol symbol) { await _progress.OnStartedAsync().ConfigureAwait(false); try { await using var _ = await _progressTracker.AddSingleItemAsync().ConfigureAwait(false); - var symbols = await DetermineAllSymbolsAsync(symbolAndProjectId).ConfigureAwait(false); + var symbols = await DetermineAllSymbolsAsync(symbol).ConfigureAwait(false); var projectMap = await CreateProjectMapAsync(symbols).ConfigureAwait(false); var projectToDocumentMap = await CreateProjectToDocumentMapAsync(projectMap).ConfigureAwait(false); @@ -112,7 +112,7 @@ await ProcessProjectsAsync( private static void ValidateProjectToDocumentMap( ProjectToDocumentMap projectToDocumentMap) { - var set = new HashSet<(SymbolAndProjectId symbolAndProjectId, IReferenceFinder finder)>(); + var set = new HashSet<(ISymbol symbol, IReferenceFinder finder)>(); foreach (var documentMap in projectToDocumentMap.Values) { @@ -128,7 +128,7 @@ private static void ValidateProjectToDocumentMap( } } - private Task HandleLocationAsync(SymbolAndProjectId symbolAndProjectId, ReferenceLocation location) - => _progress.OnReferenceFoundAsync(symbolAndProjectId, location); + private Task HandleLocationAsync(ISymbol symbol, ReferenceLocation location) + => _progress.OnReferenceFoundAsync(symbol, location); } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_DocumentProcessing.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_DocumentProcessing.cs index e8ed28e10bee9..c201d0894889b 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_DocumentProcessing.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_DocumentProcessing.cs @@ -10,7 +10,7 @@ namespace Microsoft.CodeAnalysis.FindSymbols { - using DocumentMap = MultiDictionary; + using DocumentMap = MultiDictionary; internal partial class FindReferencesSearchEngine { @@ -49,18 +49,18 @@ private async Task ProcessDocumentQueueAsync( private async Task ProcessDocumentAsync( Document document, SemanticModel semanticModel, - SymbolAndProjectId symbolAndProjectId, + ISymbol symbol, IReferenceFinder finder) { - using (Logger.LogBlock(FunctionId.FindReference_ProcessDocumentAsync, s_logDocument, document, symbolAndProjectId.Symbol, _cancellationToken)) + using (Logger.LogBlock(FunctionId.FindReference_ProcessDocumentAsync, s_logDocument, document, symbol, _cancellationToken)) { try { var references = await finder.FindReferencesInDocumentAsync( - symbolAndProjectId, document, semanticModel, _options, _cancellationToken).ConfigureAwait(false); + symbol, document, semanticModel, _options, _cancellationToken).ConfigureAwait(false); foreach (var (_, location) in references) { - await HandleLocationAsync(symbolAndProjectId, location).ConfigureAwait(false); + await HandleLocationAsync(symbol, location).ConfigureAwait(false); } } finally diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_MapCreation.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_MapCreation.cs index 8bb73c782e97f..6659e2b25010f 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_MapCreation.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_MapCreation.cs @@ -13,9 +13,9 @@ namespace Microsoft.CodeAnalysis.FindSymbols { - using DocumentMap = MultiDictionary; - using ProjectMap = MultiDictionary; - using ProjectToDocumentMap = Dictionary>; + using DocumentMap = MultiDictionary; + using ProjectMap = MultiDictionary; + using ProjectToDocumentMap = Dictionary>; internal partial class FindReferencesSearchEngine { @@ -36,9 +36,7 @@ private async Task CreateProjectToDocumentMapAsync(Project { _cancellationToken.ThrowIfCancellationRequested(); - var symbolAndProjectId = symbolAndFinder.symbolAndProjectId; - var symbol = symbolAndProjectId.Symbol; - var finder = symbolAndFinder.finder; + var (symbol, finder) = symbolAndFinder; var documents = await finder.DetermineDocumentsToSearchAsync( symbol, project, _documents, _options, _cancellationToken).ConfigureAwait(false); @@ -63,25 +61,25 @@ private async Task CreateProjectToDocumentMapAsync(Project } } - private async Task CreateProjectMapAsync(ConcurrentSet symbols) + private async Task CreateProjectMapAsync(ConcurrentSet symbols) { using (Logger.LogBlock(FunctionId.FindReference_CreateProjectMapAsync, _cancellationToken)) { var projectMap = new ProjectMap(); var scope = _documents?.Select(d => d.Project).ToImmutableHashSet(); - foreach (var symbolAndProjectId in symbols) + foreach (var symbol in symbols) { foreach (var finder in _finders) { _cancellationToken.ThrowIfCancellationRequested(); - var projects = await finder.DetermineProjectsToSearchAsync(symbolAndProjectId.Symbol, _solution, scope, _cancellationToken).ConfigureAwait(false); + var projects = await finder.DetermineProjectsToSearchAsync(symbol, _solution, scope, _cancellationToken).ConfigureAwait(false); foreach (var project in projects.Distinct().WhereNotNull()) { if (scope == null || scope.Contains(project)) { - projectMap.Add(project, (symbolAndProjectId, finder)); + projectMap.Add(project, (symbol, finder)); } } } @@ -92,36 +90,34 @@ private async Task CreateProjectMapAsync(ConcurrentSet> DetermineAllSymbolsAsync( - SymbolAndProjectId symbolAndProjectId) + private async Task> DetermineAllSymbolsAsync( + ISymbol symbol) { using (Logger.LogBlock(FunctionId.FindReference_DetermineAllSymbolsAsync, _cancellationToken)) { - var result = new ConcurrentSet( - new SymbolAndProjectIdComparer(MetadataUnifyingEquivalenceComparer.Instance)); - await DetermineAllSymbolsCoreAsync(symbolAndProjectId, result).ConfigureAwait(false); + var result = new ConcurrentSet(MetadataUnifyingEquivalenceComparer.Instance); + await DetermineAllSymbolsCoreAsync(symbol, result).ConfigureAwait(false); return result; } } private async Task DetermineAllSymbolsCoreAsync( - SymbolAndProjectId symbolAndProjectId, ConcurrentSet result) + ISymbol symbol, ConcurrentSet result) { _cancellationToken.ThrowIfCancellationRequested(); - var searchSymbolAndProjectId = MapToAppropriateSymbol(symbolAndProjectId); + var searchSymbol = MapToAppropriateSymbol(symbol); // 2) Try to map this back to source symbol if this was a metadata symbol. - var sourceSymbolAndProjectId = await SymbolFinder.FindSourceDefinitionAsync(searchSymbolAndProjectId, _solution, _cancellationToken).ConfigureAwait(false); - if (sourceSymbolAndProjectId.Symbol != null) + var sourceSymbol = await SymbolFinder.FindSourceDefinitionAsync(searchSymbol, _solution, _cancellationToken).ConfigureAwait(false); + if (sourceSymbol != null) { - searchSymbolAndProjectId = sourceSymbolAndProjectId; + searchSymbol = sourceSymbol; } - var searchSymbol = searchSymbolAndProjectId.Symbol; - if (searchSymbol != null && result.Add(searchSymbolAndProjectId)) + if (searchSymbol != null && result.Add(searchSymbol)) { - await _progress.OnDefinitionFoundAsync(searchSymbolAndProjectId).ConfigureAwait(false); + await _progress.OnDefinitionFoundAsync(searchSymbol).ConfigureAwait(false); // get project to search var projects = GetProjectScope(); @@ -136,7 +132,7 @@ private async Task DetermineAllSymbolsCoreAsync( var symbolTasks = new List(); var symbols = await f.DetermineCascadedSymbolsAsync( - searchSymbolAndProjectId, _solution, projects, _options, _cancellationToken).ConfigureAwait(false); + searchSymbol, _solution, projects, _options, _cancellationToken).ConfigureAwait(false); AddSymbolTasks(result, symbols, symbolTasks); // Defer to the language to see if it wants to cascade here in some special way. @@ -145,7 +141,7 @@ private async Task DetermineAllSymbolsCoreAsync( if (service != null) { symbols = await service.DetermineCascadedSymbolsAsync( - searchSymbolAndProjectId, symbolProject, _cancellationToken).ConfigureAwait(false); + searchSymbol, symbolProject, _cancellationToken).ConfigureAwait(false); AddSymbolTasks(result, symbols, symbolTasks); } @@ -160,8 +156,8 @@ private async Task DetermineAllSymbolsCoreAsync( } private void AddSymbolTasks( - ConcurrentSet result, - ImmutableArray symbols, + ConcurrentSet result, + ImmutableArray symbols, List symbolTasks) { if (!symbols.IsDefault) @@ -199,13 +195,11 @@ private ImmutableHashSet GetProjectScope() return builder.ToImmutable(); } - private static SymbolAndProjectId MapToAppropriateSymbol( - SymbolAndProjectId symbolAndProjectId) + private static ISymbol MapToAppropriateSymbol(ISymbol symbol) { // Never search for an alias. Always search for it's target. Note: if the caller was // actually searching for an alias, they can always get that information out in the end // by checking the ReferenceLocations that are returned. - var symbol = symbolAndProjectId.Symbol; var searchSymbol = symbol; if (searchSymbol is IAliasSymbol) @@ -222,7 +216,7 @@ private static SymbolAndProjectId MapToAppropriateSymbol( searchSymbol = symbol.ContainingType; } - return symbolAndProjectId.WithSymbol(searchSymbol); + return searchSymbol; } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_ProjectProcessing.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_ProjectProcessing.cs index 9cb349823b92c..f00b242cc0250 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_ProjectProcessing.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_ProjectProcessing.cs @@ -11,8 +11,8 @@ namespace Microsoft.CodeAnalysis.FindSymbols { - using DocumentMap = MultiDictionary; - using ProjectToDocumentMap = Dictionary>; + using DocumentMap = MultiDictionary; + using ProjectToDocumentMap = Dictionary>; internal partial class FindReferencesSearchEngine { diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractMethodOrPropertyOrEventSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractMethodOrPropertyOrEventSymbolReferenceFinder.cs index 26f4afc311c8f..f42002c1b0ff3 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractMethodOrPropertyOrEventSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractMethodOrPropertyOrEventSymbolReferenceFinder.cs @@ -17,38 +17,37 @@ protected AbstractMethodOrPropertyOrEventSymbolReferenceFinder() { } - protected override async Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId symbolAndProjectId, + protected override async Task> DetermineCascadedSymbolsAsync( + TSymbol symbol, Solution solution, IImmutableSet projects, FindReferencesSearchOptions options, CancellationToken cancellationToken) { // Static methods can't cascade. - var symbol = symbolAndProjectId.Symbol; if (!symbol.IsStatic) { if (symbol.ContainingType.TypeKind == TypeKind.Interface) { // We have an interface method. Find all implementations of that method and // cascade to them. - return await SymbolFinder.FindImplementationsAsync(symbolAndProjectId, solution, projects, cancellationToken).ConfigureAwait(false); + return await SymbolFinder.FindImplementationsArrayAsync(symbol, solution, projects, cancellationToken).ConfigureAwait(false); } else { // We have a normal method. Find any interface methods that it implicitly or // explicitly implements and cascade down to those. - var interfaceMembersImplemented = await SymbolFinder.FindImplementedInterfaceMembersAsync( - symbolAndProjectId, solution, projects, cancellationToken).ConfigureAwait(false); + var interfaceMembersImplemented = await SymbolFinder.FindImplementedInterfaceMembersArrayAsync( + symbol, solution, projects, cancellationToken).ConfigureAwait(false); // Finally, methods can cascade through virtual/override inheritance. NOTE(cyrusn): // We only need to go up or down one level. Then, when we're finding references on // those members, we'll end up traversing the entire hierarchy. - var overrides = await SymbolFinder.FindOverridesAsync( - symbolAndProjectId, solution, projects, cancellationToken).ConfigureAwait(false); + var overrides = await SymbolFinder.FindOverridesArrayAsync( + symbol, solution, projects, cancellationToken).ConfigureAwait(false); - var overriddenMember = symbolAndProjectId.WithSymbol(symbol.OverriddenMember()); - if (overriddenMember.Symbol == null) + var overriddenMember = symbol.OverriddenMember(); + if (overriddenMember == null) { return interfaceMembersImplemented.Concat(overrides); } @@ -57,7 +56,7 @@ protected override async Task> DetermineCasca } } - return ImmutableArray.Empty; + return ImmutableArray.Empty; } protected ImmutableArray GetReferencedAccessorSymbols( diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs index 014bc273d8d30..4aed46cd3912f 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs @@ -24,8 +24,8 @@ internal abstract partial class AbstractReferenceFinder : IReferenceFinder public const string ContainingTypeInfoPropertyName = "ContainingTypeInfo"; public const string ContainingMemberInfoPropertyName = "ContainingMemberInfo"; - public abstract Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId symbolAndProject, Solution solution, IImmutableSet projects, + public abstract Task> DetermineCascadedSymbolsAsync( + ISymbol symbol, Solution solution, IImmutableSet projects, FindReferencesSearchOptions options, CancellationToken cancellationToken); public abstract Task> DetermineProjectsToSearchAsync(ISymbol symbol, Solution solution, IImmutableSet projects, CancellationToken cancellationToken); @@ -34,7 +34,7 @@ public abstract Task> DetermineDocumentsToSearchAsync( ISymbol symbol, Project project, IImmutableSet documents, FindReferencesSearchOptions options, CancellationToken cancellationToken); public abstract Task> FindReferencesInDocumentAsync( - SymbolAndProjectId symbolAndProjectId, Document document, SemanticModel semanticModel, FindReferencesSearchOptions options, CancellationToken cancellationToken); + ISymbol symbol, Document document, SemanticModel semanticModel, FindReferencesSearchOptions options, CancellationToken cancellationToken); protected static bool TryGetNameWithoutAttributeSuffix( string name, @@ -834,29 +834,28 @@ public override Task> DetermineDocumentsToSearchAsync( } public override Task> FindReferencesInDocumentAsync( - SymbolAndProjectId symbolAndProjectId, Document document, SemanticModel semanticModel, + ISymbol symbol, Document document, SemanticModel semanticModel, FindReferencesSearchOptions options, CancellationToken cancellationToken) { - var symbol = symbolAndProjectId.Symbol; return symbol is TSymbol && CanFind((TSymbol)symbol) ? FindReferencesInDocumentAsync((TSymbol)symbol, document, semanticModel, options, cancellationToken) : SpecializedTasks.EmptyImmutableArray(); } - public override Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId symbolAndProjectId, Solution solution, IImmutableSet projects, + public override Task> DetermineCascadedSymbolsAsync( + ISymbol symbol, Solution solution, IImmutableSet projects, FindReferencesSearchOptions options, CancellationToken cancellationToken) { if (options.Cascade && - symbolAndProjectId.Symbol is TSymbol typedSymbol && + symbol is TSymbol typedSymbol && CanFind(typedSymbol)) { return DetermineCascadedSymbolsAsync( - symbolAndProjectId.WithSymbol(typedSymbol), + typedSymbol, solution, projects, options, cancellationToken); } - return SpecializedTasks.EmptyImmutableArray(); + return SpecializedTasks.EmptyImmutableArray(); } protected virtual Task> DetermineProjectsToSearchAsync( @@ -866,11 +865,11 @@ protected virtual Task> DetermineProjectsToSearchAsync( symbol, solution, projects, cancellationToken); } - protected virtual Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId symbolAndProject, Solution solution, IImmutableSet projects, + protected virtual Task> DetermineCascadedSymbolsAsync( + TSymbol symbol, Solution solution, IImmutableSet projects, FindReferencesSearchOptions options, CancellationToken cancellationToken) { - return SpecializedTasks.EmptyImmutableArray(); + return SpecializedTasks.EmptyImmutableArray(); } protected static Task> FindReferencesInDocumentUsingSymbolNameAsync( diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/DestructorSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/DestructorSymbolReferenceFinder.cs index 18e9c9556bedd..139048d7ad1f9 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/DestructorSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/DestructorSymbolReferenceFinder.cs @@ -14,14 +14,14 @@ internal class DestructorSymbolReferenceFinder : AbstractReferenceFinder symbol.MethodKind == MethodKind.Destructor; - protected override Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId symbol, + protected override Task> DetermineCascadedSymbolsAsync( + IMethodSymbol symbol, Solution solution, IImmutableSet projects, FindReferencesSearchOptions options, CancellationToken cancellationToken) { - return SpecializedTasks.EmptyImmutableArray(); + return SpecializedTasks.EmptyImmutableArray(); } protected override Task> DetermineDocumentsToSearchAsync( diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/EventSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/EventSymbolReferenceFinder.cs index 55a279c5ff638..3c573b4bd5da8 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/EventSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/EventSymbolReferenceFinder.cs @@ -14,30 +14,26 @@ internal class EventSymbolReferenceFinder : AbstractMethodOrPropertyOrEventSymbo protected override bool CanFind(IEventSymbol symbol) => true; - protected override async Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId symbolAndProjectId, + protected override async Task> DetermineCascadedSymbolsAsync( + IEventSymbol symbol, Solution solution, IImmutableSet projects, FindReferencesSearchOptions options, CancellationToken cancellationToken) { var baseSymbols = await base.DetermineCascadedSymbolsAsync( - symbolAndProjectId, solution, projects, options, cancellationToken).ConfigureAwait(false); + symbol, solution, projects, options, cancellationToken).ConfigureAwait(false); - var symbol = symbolAndProjectId.Symbol; var backingFields = symbol.ContainingType.GetMembers() .OfType() .Where(f => symbol.Equals(f.AssociatedSymbol)) - .Select(s => (SymbolAndProjectId)symbolAndProjectId.WithSymbol(s)) .ToImmutableArray(); var associatedNamedTypes = symbol.ContainingType.GetTypeMembers() - .Where(n => symbol.Equals(n.AssociatedSymbol)) - .Select(s => (SymbolAndProjectId)symbolAndProjectId.WithSymbol(s)) - .ToImmutableArray(); + .WhereAsArray(n => symbol.Equals(n.AssociatedSymbol)); - return baseSymbols.Concat(backingFields) - .Concat(associatedNamedTypes); + return baseSymbols.Concat(ImmutableArray.CastUp(backingFields)) + .Concat(ImmutableArray.CastUp(associatedNamedTypes)); } protected override Task> DetermineDocumentsToSearchAsync( diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ExplicitInterfaceMethodReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ExplicitInterfaceMethodReferenceFinder.cs index 33fc34a0a522a..4fd2ec03545f2 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ExplicitInterfaceMethodReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ExplicitInterfaceMethodReferenceFinder.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Collections.Immutable; -using System.Linq; using System.Threading; using System.Threading.Tasks; using Roslyn.Utilities; @@ -15,17 +14,15 @@ internal class ExplicitInterfaceMethodReferenceFinder : AbstractReferenceFinder< protected override bool CanFind(IMethodSymbol symbol) => symbol.MethodKind == MethodKind.ExplicitInterfaceImplementation; - protected override Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId symbolAndProjectId, + protected override Task> DetermineCascadedSymbolsAsync( + IMethodSymbol symbol, Solution solution, IImmutableSet projects, FindReferencesSearchOptions options, CancellationToken cancellationToken) { // An explicit interface method will cascade to all the methods that it implements. - return Task.FromResult( - symbolAndProjectId.Symbol.ExplicitInterfaceImplementations.Select( - ei => symbolAndProjectId.WithSymbol((ISymbol)ei)).ToImmutableArray()); + return Task.FromResult(ImmutableArray.CastUp(symbol.ExplicitInterfaceImplementations)); } protected override Task> DetermineDocumentsToSearchAsync( diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/FieldSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/FieldSymbolReferenceFinder.cs index 908fb8ef356ec..d715677785150 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/FieldSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/FieldSymbolReferenceFinder.cs @@ -14,22 +14,20 @@ internal class FieldSymbolReferenceFinder : AbstractReferenceFinder true; - protected override Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId symbolAndProjectId, + protected override Task> DetermineCascadedSymbolsAsync( + IFieldSymbol symbol, Solution solution, IImmutableSet projects, FindReferencesSearchOptions options, CancellationToken cancellationToken) { - var symbol = symbolAndProjectId.Symbol; if (symbol.AssociatedSymbol != null) { - return Task.FromResult( - ImmutableArray.Create(symbolAndProjectId.WithSymbol(symbol.AssociatedSymbol))); + return Task.FromResult(ImmutableArray.Create(symbol.AssociatedSymbol)); } else { - return SpecializedTasks.EmptyImmutableArray(); + return SpecializedTasks.EmptyImmutableArray(); } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ILanguageServiceReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ILanguageServiceReferenceFinder.cs index 0070150f837d6..737e35400968d 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ILanguageServiceReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ILanguageServiceReferenceFinder.cs @@ -16,7 +16,7 @@ namespace Microsoft.CodeAnalysis.FindSymbols.Finders /// internal interface ILanguageServiceReferenceFinder : ILanguageService { - Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId symbolAndProjectId, Project project, CancellationToken cancellationToken); + Task> DetermineCascadedSymbolsAsync( + ISymbol symbol, Project project, CancellationToken cancellationToken); } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/IReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/IReferenceFinder.cs index 584f95e3b7dcc..5f41df416d4f1 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/IReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/IReferenceFinder.cs @@ -24,8 +24,8 @@ internal interface IReferenceFinder /// /// Implementations of this method must be thread-safe. /// - Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId symbolAndProject, Solution solution, IImmutableSet projects, + Task> DetermineCascadedSymbolsAsync( + ISymbol symbol, Solution solution, IImmutableSet projects, FindReferencesSearchOptions options, CancellationToken cancellationToken); /// @@ -68,7 +68,7 @@ Task> DetermineDocumentsToSearchAsync( /// Implementations of this method must be thread-safe. /// Task> FindReferencesInDocumentAsync( - SymbolAndProjectId symbolAndProjectId, Document document, SemanticModel semanticModel, + ISymbol symbol, Document document, SemanticModel semanticModel, FindReferencesSearchOptions options, CancellationToken cancellationToken); } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/LinkedFileReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/LinkedFileReferenceFinder.cs index 0ca33eb4bf39e..bf1980ceebb15 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/LinkedFileReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/LinkedFileReferenceFinder.cs @@ -11,11 +11,11 @@ namespace Microsoft.CodeAnalysis.FindSymbols.Finders { internal class LinkedFileReferenceFinder : IReferenceFinder { - public Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId symbolAndProjectId, Solution solution, IImmutableSet projects, + public Task> DetermineCascadedSymbolsAsync( + ISymbol symbol, Solution solution, IImmutableSet projects, FindReferencesSearchOptions options, CancellationToken cancellationToken) { - return SymbolFinder.FindLinkedSymbolsAsync(solution, symbolAndProjectId, cancellationToken); + return SymbolFinder.FindLinkedSymbolsAsync(symbol, solution, cancellationToken); } public Task> DetermineDocumentsToSearchAsync( @@ -29,7 +29,7 @@ public Task> DetermineProjectsToSearchAsync(ISymbol symb => SpecializedTasks.EmptyImmutableArray(); public Task> FindReferencesInDocumentAsync( - SymbolAndProjectId symbolAndProjectId, Document document, SemanticModel semanticModel, + ISymbol symbol, Document document, SemanticModel semanticModel, FindReferencesSearchOptions options, CancellationToken cancellationToken) { return SpecializedTasks.EmptyImmutableArray(); diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/MethodTypeParameterSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/MethodTypeParameterSymbolReferenceFinder.cs index 621e5303e121a..1b76032f82bb5 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/MethodTypeParameterSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/MethodTypeParameterSymbolReferenceFinder.cs @@ -14,14 +14,13 @@ internal class MethodTypeParameterSymbolReferenceFinder : AbstractReferenceFinde protected override bool CanFind(ITypeParameterSymbol symbol) => symbol.TypeParameterKind == TypeParameterKind.Method; - protected override Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId symbolAndProjectId, + protected override Task> DetermineCascadedSymbolsAsync( + ITypeParameterSymbol symbol, Solution solution, IImmutableSet projects, FindReferencesSearchOptions options, CancellationToken cancellationToken) { - var symbol = symbolAndProjectId.Symbol; var method = (IMethodSymbol)symbol.ContainingSymbol; var ordinal = method.TypeParameters.IndexOf(symbol); @@ -29,18 +28,18 @@ protected override Task> DetermineCascadedSym { if (method.PartialDefinitionPart != null && ordinal < method.PartialDefinitionPart.TypeParameters.Length) { - return Task.FromResult(ImmutableArray.Create( - symbolAndProjectId.WithSymbol((ISymbol)method.PartialDefinitionPart.TypeParameters[ordinal]))); + return Task.FromResult(ImmutableArray.Create( + method.PartialDefinitionPart.TypeParameters[ordinal])); } if (method.PartialImplementationPart != null && ordinal < method.PartialImplementationPart.TypeParameters.Length) { - return Task.FromResult(ImmutableArray.Create( - symbolAndProjectId.WithSymbol((ISymbol)method.PartialImplementationPart.TypeParameters[ordinal]))); + return Task.FromResult(ImmutableArray.Create( + method.PartialImplementationPart.TypeParameters[ordinal])); } } - return SpecializedTasks.EmptyImmutableArray(); + return SpecializedTasks.EmptyImmutableArray(); } protected override Task> DetermineDocumentsToSearchAsync( diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamedTypeSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamedTypeSymbolReferenceFinder.cs index 34ae534e788fd..ddb1e18706308 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamedTypeSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamedTypeSymbolReferenceFinder.cs @@ -18,37 +18,32 @@ internal class NamedTypeSymbolReferenceFinder : AbstractReferenceFinder symbol.TypeKind != TypeKind.Error; - protected override Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId symbolAndProjectId, + protected override Task> DetermineCascadedSymbolsAsync( + INamedTypeSymbol symbol, Solution solution, IImmutableSet projects, FindReferencesSearchOptions options, CancellationToken cancellationToken) { - var result = ArrayBuilder.GetInstance(); + var result = ArrayBuilder.GetInstance(); - var symbol = symbolAndProjectId.Symbol; if (symbol.AssociatedSymbol != null) { - Add(result, symbolAndProjectId, ImmutableArray.Create(symbol.AssociatedSymbol)); + Add(result, ImmutableArray.Create(symbol.AssociatedSymbol)); } // cascade to constructors - Add(result, symbolAndProjectId, symbol.Constructors); + Add(result, symbol.Constructors); // cascade to destructor - Add(result, symbolAndProjectId, symbol.GetMembers(WellKnownMemberNames.DestructorName)); + Add(result, symbol.GetMembers(WellKnownMemberNames.DestructorName)); return Task.FromResult(result.ToImmutableAndFree()); } - private void Add( - ArrayBuilder result, - SymbolAndProjectId symbolAndProjectId, - ImmutableArray enumerable) where TSymbol : ISymbol + private void Add(ArrayBuilder result, ImmutableArray enumerable) where TSymbol : ISymbol { - result.AddRange(enumerable.Select( - s => symbolAndProjectId.WithSymbol((ISymbol)s))); + result.AddRange(enumerable.Cast()); } protected override async Task> DetermineDocumentsToSearchAsync( diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/OrdinaryMethodReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/OrdinaryMethodReferenceFinder.cs index 7cae22c1de55f..1784c35af123a 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/OrdinaryMethodReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/OrdinaryMethodReferenceFinder.cs @@ -20,8 +20,8 @@ protected override bool CanFind(IMethodSymbol symbol) symbol.MethodKind == MethodKind.LocalFunction; } - protected override async Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId symbolAndProjectId, + protected override async Task> DetermineCascadedSymbolsAsync( + IMethodSymbol symbol, Solution solution, IImmutableSet projects, FindReferencesSearchOptions options, @@ -29,44 +29,38 @@ protected override async Task> DetermineCasca { // If it's a delegate method, then cascade to the type as well. These guys are // practically equivalent for users. - var symbol = symbolAndProjectId.Symbol; if (symbol.ContainingType.TypeKind == TypeKind.Delegate) { - return ImmutableArray.Create( - symbolAndProjectId.WithSymbol((ISymbol)symbol.ContainingType)); + return ImmutableArray.Create(symbol.ContainingType); } else { - var otherPartsOfPartial = GetOtherPartsOfPartial(symbolAndProjectId); + var otherPartsOfPartial = GetOtherPartsOfPartial(symbol); var baseCascadedSymbols = await base.DetermineCascadedSymbolsAsync( - symbolAndProjectId, solution, projects, options, cancellationToken).ConfigureAwait(false); + symbol, solution, projects, options, cancellationToken).ConfigureAwait(false); if (otherPartsOfPartial == null && baseCascadedSymbols == null) { - return ImmutableArray.Empty; + return ImmutableArray.Empty; } return otherPartsOfPartial.Concat(baseCascadedSymbols); } } - private ImmutableArray GetOtherPartsOfPartial( - SymbolAndProjectId symbolAndProjectId) + private ImmutableArray GetOtherPartsOfPartial(IMethodSymbol symbol) { - var symbol = symbolAndProjectId.Symbol; if (symbol.PartialDefinitionPart != null) { - return ImmutableArray.Create( - symbolAndProjectId.WithSymbol((ISymbol)symbol.PartialDefinitionPart)); + return ImmutableArray.Create(symbol.PartialDefinitionPart); } if (symbol.PartialImplementationPart != null) { - return ImmutableArray.Create( - symbolAndProjectId.WithSymbol((ISymbol)symbol.PartialImplementationPart)); + return ImmutableArray.Create(symbol.PartialImplementationPart); } - return ImmutableArray.Empty; + return ImmutableArray.Empty; } protected override async Task> DetermineDocumentsToSearchAsync( diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ParameterSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ParameterSymbolReferenceFinder.cs index e2e01ca15f4eb..0e2c5729aa156 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ParameterSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ParameterSymbolReferenceFinder.cs @@ -95,36 +95,34 @@ protected override Task> FindReferencesInDocument }; } - protected override async Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId parameterAndProjectId, + protected override async Task> DetermineCascadedSymbolsAsync( + IParameterSymbol parameter, Solution solution, IImmutableSet projects, FindReferencesSearchOptions options, CancellationToken cancellationToken) { - var parameter = parameterAndProjectId.Symbol; if (parameter.IsThis) { - return ImmutableArray.Empty; + return ImmutableArray.Empty; } - var result = ArrayBuilder.GetInstance(); + var result = ArrayBuilder.GetInstance(); - await CascadeBetweenAnonymousFunctionParametersAsync(solution, parameterAndProjectId, result, cancellationToken).ConfigureAwait(false); - CascadeBetweenPropertyAndAccessorParameters(parameterAndProjectId, result); - CascadeBetweenDelegateMethodParameters(parameterAndProjectId, result); - CascadeBetweenPartialMethodParameters(parameterAndProjectId, result); + await CascadeBetweenAnonymousFunctionParametersAsync(solution, parameter, result, cancellationToken).ConfigureAwait(false); + CascadeBetweenPropertyAndAccessorParameters(parameter, result); + CascadeBetweenDelegateMethodParameters(parameter, result); + CascadeBetweenPartialMethodParameters(parameter, result); return result.ToImmutableAndFree(); } private async Task CascadeBetweenAnonymousFunctionParametersAsync( Solution solution, - SymbolAndProjectId parameterAndProjectId, - ArrayBuilder results, + IParameterSymbol parameter, + ArrayBuilder results, CancellationToken cancellationToken) { - var parameter = parameterAndProjectId.Symbol; if (parameter.ContainingSymbol.IsAnonymousFunction()) { var parameterNode = parameter.DeclaringSyntaxReferences.Select(r => r.GetSyntax(cancellationToken)).FirstOrDefault(); @@ -148,7 +146,7 @@ private async Task CascadeBetweenAnonymousFunctionParametersAsync( if (container != null) { CascadeBetweenAnonymousFunctionParameters( - document, semanticModel, container, parameterAndProjectId, + document, semanticModel, container, parameter, convertedType, results, cancellationToken); } } @@ -162,12 +160,11 @@ private void CascadeBetweenAnonymousFunctionParameters( Document document, SemanticModel semanticModel, SyntaxNode container, - SymbolAndProjectId parameterAndProjectId, + IParameterSymbol parameter, ITypeSymbol convertedType1, - ArrayBuilder results, + ArrayBuilder results, CancellationToken cancellationToken) { - var parameter = parameterAndProjectId.Symbol; var syntaxFacts = document.GetLanguageService(); foreach (var token in container.DescendantTokens()) { @@ -184,7 +181,7 @@ private void CascadeBetweenAnonymousFunctionParameters( if (convertedType1.Equals(convertedType2)) { - results.Add(parameterAndProjectId.WithSymbol(symbol)); + results.Add(symbol); } } } @@ -220,10 +217,9 @@ private SyntaxNode GetContainer(SemanticModel semanticModel, SyntaxNode paramete } private void CascadeBetweenPropertyAndAccessorParameters( - SymbolAndProjectId parameterAndProjectId, - ArrayBuilder results) + IParameterSymbol parameter, + ArrayBuilder results) { - var parameter = parameterAndProjectId.Symbol; var ordinal = parameter.Ordinal; var containingSymbol = parameter.ContainingSymbol; if (containingSymbol is IMethodSymbol containingMethod) @@ -231,7 +227,7 @@ private void CascadeBetweenPropertyAndAccessorParameters( if (containingMethod.AssociatedSymbol is IPropertySymbol property) { AddParameterAtIndex( - parameterAndProjectId, results, + parameter, results, ordinal, property.Parameters); } } @@ -239,21 +235,20 @@ private void CascadeBetweenPropertyAndAccessorParameters( { if (containingProperty.GetMethod != null && ordinal < containingProperty.GetMethod.Parameters.Length) { - results.Add(parameterAndProjectId.WithSymbol(containingProperty.GetMethod.Parameters[ordinal])); + results.Add(containingProperty.GetMethod.Parameters[ordinal]); } if (containingProperty.SetMethod != null && ordinal < containingProperty.SetMethod.Parameters.Length) { - results.Add(parameterAndProjectId.WithSymbol(containingProperty.SetMethod.Parameters[ordinal])); + results.Add(containingProperty.SetMethod.Parameters[ordinal]); } } } private void CascadeBetweenDelegateMethodParameters( - SymbolAndProjectId parameterAndProjectId, - ArrayBuilder results) + IParameterSymbol parameter, + ArrayBuilder results) { - var parameter = parameterAndProjectId.Symbol; var ordinal = parameter.Ordinal; if (parameter.ContainingSymbol is IMethodSymbol containingMethod) { @@ -267,7 +262,7 @@ private void CascadeBetweenDelegateMethodParameters( .OfType() .FirstOrDefault(); AddParameterAtIndex( - parameterAndProjectId, results, + parameter, results, ordinal, beginInvokeMethod?.Parameters); } else if (containingMethod.ContainingType.IsDelegateType() && @@ -275,7 +270,7 @@ private void CascadeBetweenDelegateMethodParameters( { // cascade to the corresponding parameter in the Invoke method. AddParameterAtIndex( - parameterAndProjectId, results, + parameter, results, ordinal, containingType.DelegateInvokeMethod?.Parameters); } } @@ -283,36 +278,33 @@ private void CascadeBetweenDelegateMethodParameters( } private static void AddParameterAtIndex( - SymbolAndProjectId parameterAndProjectId, - ArrayBuilder results, + IParameterSymbol parameter, + ArrayBuilder results, int ordinal, ImmutableArray? parameters) { if (parameters != null && ordinal < parameters.Value.Length) { - results.Add(parameterAndProjectId.WithSymbol(parameters.Value[ordinal])); + results.Add(parameters.Value[ordinal]); } } private void CascadeBetweenPartialMethodParameters( - SymbolAndProjectId parameterAndProjectId, - ArrayBuilder results) + IParameterSymbol parameter, + ArrayBuilder results) { - var parameter = parameterAndProjectId.Symbol; if (parameter.ContainingSymbol is IMethodSymbol) { var ordinal = parameter.Ordinal; var method = (IMethodSymbol)parameter.ContainingSymbol; if (method.PartialDefinitionPart != null && ordinal < method.PartialDefinitionPart.Parameters.Length) { - results.Add( - parameterAndProjectId.WithSymbol(method.PartialDefinitionPart.Parameters[ordinal])); + results.Add(method.PartialDefinitionPart.Parameters[ordinal]); } if (method.PartialImplementationPart != null && ordinal < method.PartialImplementationPart.Parameters.Length) { - results.Add( - parameterAndProjectId.WithSymbol(method.PartialImplementationPart.Parameters[ordinal])); + results.Add(method.PartialImplementationPart.Parameters[ordinal]); } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs index b4c016abc0862..edb09a00f7187 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs @@ -15,24 +15,23 @@ internal class PropertyAccessorSymbolReferenceFinder : AbstractMethodOrPropertyO protected override bool CanFind(IMethodSymbol symbol) => symbol.MethodKind.IsPropertyAccessor(); - protected override async Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId symbolAndProjectId, + protected override async Task> DetermineCascadedSymbolsAsync( + IMethodSymbol symbol, Solution solution, IImmutableSet projects, FindReferencesSearchOptions options, CancellationToken cancellationToken) { var result = await base.DetermineCascadedSymbolsAsync( - symbolAndProjectId, solution, projects, options, cancellationToken).ConfigureAwait(false); + symbol, solution, projects, options, cancellationToken).ConfigureAwait(false); // If we've been asked to search for specific accessors, then do not cascade. // We don't want to produce results for the associated property. if (!options.AssociatePropertyReferencesWithSpecificAccessor) { - var symbol = symbolAndProjectId.Symbol; if (symbol.AssociatedSymbol != null) { - result = result.Add(symbolAndProjectId.WithSymbol(symbol.AssociatedSymbol)); + result = result.Add(symbol.AssociatedSymbol); } } @@ -77,7 +76,7 @@ protected override async Task> FindReferencesInDo options.AssociatePropertyReferencesWithSpecificAccessor) { var propertyReferences = await ReferenceFinders.Property.FindReferencesInDocumentAsync( - new SymbolAndProjectId(property, document.Project.Id), document, semanticModel, + property, document, semanticModel, options.WithAssociatePropertyReferencesWithSpecificAccessor(false), cancellationToken).ConfigureAwait(false); diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs index db6bf4e186b76..9cda70ae9d4bc 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs @@ -24,33 +24,31 @@ internal class PropertySymbolReferenceFinder : AbstractMethodOrPropertyOrEventSy protected override bool CanFind(IPropertySymbol symbol) => true; - protected override async Task> DetermineCascadedSymbolsAsync( - SymbolAndProjectId symbolAndProjectId, + protected override async Task> DetermineCascadedSymbolsAsync( + IPropertySymbol symbol, Solution solution, IImmutableSet projects, FindReferencesSearchOptions options, CancellationToken cancellationToken) { var baseSymbols = await base.DetermineCascadedSymbolsAsync( - symbolAndProjectId, solution, projects, options, cancellationToken).ConfigureAwait(false); + symbol, solution, projects, options, cancellationToken).ConfigureAwait(false); - var symbol = symbolAndProjectId.Symbol; var backingFields = symbol.ContainingType.GetMembers() .OfType() .Where(f => symbol.Equals(f.AssociatedSymbol)) - .Select(f => (SymbolAndProjectId)symbolAndProjectId.WithSymbol(f)) - .ToImmutableArray(); + .ToImmutableArray(); var result = baseSymbols.Concat(backingFields); if (symbol.GetMethod != null) { - result = result.Add(symbolAndProjectId.WithSymbol(symbol.GetMethod)); + result = result.Add(symbol.GetMethod); } if (symbol.SetMethod != null) { - result = result.Add(symbolAndProjectId.WithSymbol(symbol.SetMethod)); + result = result.Add(symbol.SetMethod); } return result; diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/NoOpStreamingFindReferencesProgress.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/NoOpStreamingFindReferencesProgress.cs index bd578c071ab52..7c4a120f64c86 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/NoOpStreamingFindReferencesProgress.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/NoOpStreamingFindReferencesProgress.cs @@ -26,8 +26,8 @@ private NoOpStreamingFindReferencesProgress() public Task OnCompletedAsync() => Task.CompletedTask; public Task OnStartedAsync() => Task.CompletedTask; - public Task OnDefinitionFoundAsync(SymbolAndProjectId symbol) => Task.CompletedTask; - public Task OnReferenceFoundAsync(SymbolAndProjectId symbol, ReferenceLocation location) => Task.CompletedTask; + public Task OnDefinitionFoundAsync(ISymbol symbol) => Task.CompletedTask; + public Task OnReferenceFoundAsync(ISymbol symbol, ReferenceLocation location) => Task.CompletedTask; public Task OnFindInDocumentStartedAsync(Document document) => Task.CompletedTask; public Task OnFindInDocumentCompletedAsync(Document document) => Task.CompletedTask; diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/StreamingFindReferencesProgress.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/StreamingFindReferencesProgress.cs index 9b4e65120b545..c9e46f9d5e03b 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/StreamingFindReferencesProgress.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/StreamingFindReferencesProgress.cs @@ -33,9 +33,9 @@ public Task OnCompletedAsync() return Task.CompletedTask; } - public Task OnDefinitionFoundAsync(SymbolAndProjectId symbolAndProjectId) + public Task OnDefinitionFoundAsync(ISymbol symbol) { - _progress.OnDefinitionFound(symbolAndProjectId.Symbol); + _progress.OnDefinitionFound(symbol); return Task.CompletedTask; } @@ -51,9 +51,9 @@ public Task OnFindInDocumentStartedAsync(Document document) return Task.CompletedTask; } - public Task OnReferenceFoundAsync(SymbolAndProjectId symbolAndProjectId, ReferenceLocation location) + public Task OnReferenceFoundAsync(ISymbol symbol, ReferenceLocation location) { - _progress.OnReferenceFound(symbolAndProjectId.Symbol, location); + _progress.OnReferenceFound(symbol, location); return Task.CompletedTask; } diff --git a/src/Workspaces/Core/Portable/FindSymbols/IStreamingFindReferencesProgress.cs b/src/Workspaces/Core/Portable/FindSymbols/IStreamingFindReferencesProgress.cs index 50ab3b4f53009..d05e6732d9104 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/IStreamingFindReferencesProgress.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/IStreamingFindReferencesProgress.cs @@ -22,8 +22,8 @@ internal interface IStreamingFindReferencesProgress Task OnFindInDocumentStartedAsync(Document document); Task OnFindInDocumentCompletedAsync(Document document); - Task OnDefinitionFoundAsync(SymbolAndProjectId symbolAndProjectId); - Task OnReferenceFoundAsync(SymbolAndProjectId symbolAndProjectId, ReferenceLocation location); + Task OnDefinitionFoundAsync(ISymbol symbol); + Task OnReferenceFoundAsync(ISymbol symbol, ReferenceLocation location); } internal interface IStreamingFindLiteralReferencesProgress diff --git a/src/Workspaces/Core/Portable/FindSymbols/ReferenceLocationExtensions.cs b/src/Workspaces/Core/Portable/FindSymbols/ReferenceLocationExtensions.cs index a5ccf3b4a3e48..9d4ea03d84a01 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/ReferenceLocationExtensions.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/ReferenceLocationExtensions.cs @@ -13,13 +13,13 @@ namespace Microsoft.CodeAnalysis.FindSymbols { internal static class ReferenceLocationExtensions { - public static async Task>> FindReferencingSymbolsAsync( + public static async Task>> FindReferencingSymbolsAsync( this IEnumerable referenceLocations, CancellationToken cancellationToken) { var documentGroups = referenceLocations.GroupBy(loc => loc.Document); var projectGroups = documentGroups.GroupBy(g => g.Key.Project); - var result = new Dictionary>(); + var result = new Dictionary>(); foreach (var projectGroup in projectGroups) { @@ -48,18 +48,17 @@ private static void AddSymbols( Document document, SemanticModel semanticModel, IEnumerable references, - Dictionary> result) + Dictionary> result) { foreach (var reference in references) { var containingSymbol = GetEnclosingMethodOrPropertyOrField(semanticModel, reference); if (containingSymbol != null) { - var symbolAndProjectId = new SymbolAndProjectId(containingSymbol, document.Project.Id); - if (!result.TryGetValue(symbolAndProjectId, out var locations)) + if (!result.TryGetValue(containingSymbol, out var locations)) { locations = new List(); - result.Add(symbolAndProjectId, locations); + result.Add(containingSymbol, locations); } locations.Add(reference.Location); diff --git a/src/Workspaces/Core/Portable/FindSymbols/ReferencedSymbol.cs b/src/Workspaces/Core/Portable/FindSymbols/ReferencedSymbol.cs index aab7716d7cd83..8bb349f5aecde 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/ReferencedSymbol.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/ReferencedSymbol.cs @@ -23,9 +23,7 @@ public class ReferencedSymbol /// /// The symbol definition that these are references to. /// - public ISymbol Definition => DefinitionAndProjectId.Symbol; - - internal SymbolAndProjectId DefinitionAndProjectId { get; } + public ISymbol Definition { get; } /// /// The set of reference locations in the solution. @@ -33,10 +31,10 @@ public class ReferencedSymbol public IEnumerable Locations { get; } internal ReferencedSymbol( - SymbolAndProjectId definitionAndProjectId, + ISymbol definition, IEnumerable locations) { - this.DefinitionAndProjectId = definitionAndProjectId; + this.Definition = definition; this.Locations = (locations ?? SpecializedCollections.EmptyEnumerable()).ToReadOnlyCollection(); } diff --git a/src/Workspaces/Core/Portable/FindSymbols/StreamingProgressCollector.cs b/src/Workspaces/Core/Portable/FindSymbols/StreamingProgressCollector.cs index 81a75713ae74d..fb3bf5876c39f 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/StreamingProgressCollector.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/StreamingProgressCollector.cs @@ -23,8 +23,8 @@ internal class StreamingProgressCollector : IStreamingFindReferencesProgress private readonly object _gate = new object(); private readonly IStreamingFindReferencesProgress _underlyingProgress; - private readonly Dictionary> _symbolToLocations = - new Dictionary>(); + private readonly Dictionary> _symbolToLocations = + new Dictionary>(); public IStreamingProgressTracker ProgressTracker => _underlyingProgress.ProgressTracker; @@ -59,7 +59,7 @@ public ImmutableArray GetReferencedSymbols() public Task OnFindInDocumentCompletedAsync(Document document) => _underlyingProgress.OnFindInDocumentCompletedAsync(document); public Task OnFindInDocumentStartedAsync(Document document) => _underlyingProgress.OnFindInDocumentStartedAsync(document); - public Task OnDefinitionFoundAsync(SymbolAndProjectId definition) + public Task OnDefinitionFoundAsync(ISymbol definition) { lock (_gate) { @@ -69,7 +69,7 @@ public Task OnDefinitionFoundAsync(SymbolAndProjectId definition) return _underlyingProgress.OnDefinitionFoundAsync(definition); } - public Task OnReferenceFoundAsync(SymbolAndProjectId definition, ReferenceLocation location) + public Task OnReferenceFoundAsync(ISymbol definition, ReferenceLocation location) { lock (_gate) { diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolAndProjectId.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolAndProjectId.cs deleted file mode 100644 index ed1b15db394a7..0000000000000 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolAndProjectId.cs +++ /dev/null @@ -1,187 +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 Microsoft.CodeAnalysis.Shared.Utilities; - -namespace Microsoft.CodeAnalysis.FindSymbols -{ - /// - /// Represents a symbol and the project it was acquired from. - /// It should always be the case that if you have the original solution - /// that this symbol came from, that you'll be able to find this symbol - /// in the compilation for the specified project. - /// - /// Note that the 'Same' symbol could be acquired from many different projects - /// (after all, each project sees, at least, all the public symbols for all the - /// projects it references). As such, a single ISymbol could be found in many - /// places. The ProjectId at least gives us a single place to look for it again. - /// - /// The purpose of this type is to support serializing/deserializing symbols - /// and allowing features to work out-of-process (OOP). In OOP scenarios, - /// we will need to marshal s to and from the host and - /// the external process. That means being able to recover the - /// on either side. With the this becomes possible. - /// - /// Accordingly, it is ok to have a that does - /// not have a . It just means that that data cannot - /// be marshalled in an OOP scenario. Existing features, and third party clients - /// will then have code that still works (albeit just in-process). However, - /// code that updates to use this can then opt-into working OOP. - /// - /// Note: for purposes of Equality/Hashing, all that we use is the underlying - /// Symbol. That's because nearly all IDE features only care if they're looking - /// at the same symbol, they don't care if hte symbol came from a different - /// project or not. i.e. a feature like FAR doesn't want to cascade into the - /// "same" symbol even if it hits it in another project. As such, we do not - /// include the ProjectId when computing the result. - /// - internal struct SymbolAndProjectId - { - public readonly ISymbol Symbol; - public readonly ProjectId ProjectId; - - public SymbolAndProjectId(ISymbol symbol, ProjectId projectId) - { - Symbol = symbol; - ProjectId = projectId; - } - - public override bool Equals(object obj) => Equals((SymbolAndProjectId)obj); - - public bool Equals(SymbolAndProjectId other) - { - // See class comment on why we only use Symbol and ignore ProjectId. - return Equals(this.Symbol, other.Symbol); - } - - public override int GetHashCode() - { - // See class comment on why we only use Symbol and ignore ProjectId. - return this.Symbol.GetHashCode(); - } - - public static SymbolAndProjectId Create( - ISymbol symbol, ProjectId projectId) - { - return new SymbolAndProjectId(symbol, projectId); - } - - public static SymbolAndProjectId Create( - TSymbol symbol, ProjectId projectId) where TSymbol : ISymbol - { - return new SymbolAndProjectId(symbol, projectId); - } - - public SymbolAndProjectId WithSymbol(TOther other) - where TOther : ISymbol - { - return new SymbolAndProjectId(other, this.ProjectId); - } - - public SymbolAndProjectId WithSymbol(ISymbol other) - => new SymbolAndProjectId(other, this.ProjectId); - } - - internal struct SymbolAndProjectId where TSymbol : ISymbol - { - public readonly TSymbol Symbol; - public readonly ProjectId ProjectId; - - public SymbolAndProjectId(TSymbol symbol, ProjectId projectId) - { - Symbol = symbol; - ProjectId = projectId; - } - - public static implicit operator SymbolAndProjectId(SymbolAndProjectId value) - => new SymbolAndProjectId(value.Symbol, value.ProjectId); - - public SymbolAndProjectId WithSymbol(TOther other) - where TOther : ISymbol - { - return new SymbolAndProjectId(other, this.ProjectId); - } - - public SymbolAndProjectId WithSymbol(ISymbol other) - => new SymbolAndProjectId(other, this.ProjectId); - } - - internal static class SymbolAndProjectIdExtensions - { - public static IEnumerable> Convert( - this IEnumerable> list) - where TOriginal : ISymbol - where TConvert : ISymbol - { - return list.Select(s => SymbolAndProjectId.Create((TConvert)(object)s.Symbol, s.ProjectId)); - } - } - - /// - /// Provides a way for us to store and compare SymbolAndProjectId in the - /// sets that we're using. For the purposes of the operations in - /// these entities are the same if they - /// point to Symbols that are considered the same. For example, if - /// we find a derived type of 'X' called 'Y' in a metadata assembly 'M' - /// in project A and we also find a derived type of 'X' called 'Y' in a - /// metadata assembly 'M' in project B, then we consider these the same. - /// What project we were searching in does not matter to us in terms of - /// deciding if these symbols are the same or not. We're only keeping - /// the projects to return to the caller information about what project - /// we were searching when we found the symbol. - /// - internal class SymbolAndProjectIdComparer : IEqualityComparer> - where TSymbol : ISymbol - { - public static readonly SymbolAndProjectIdComparer SymbolEquivalenceInstance = new SymbolAndProjectIdComparer(); - - /// - /// Note(cyrusn): We're using SymbolEquivalenceComparer.Instance as the underlying - /// way of comparing symbols. That's probably not correct as it won't appropriately - /// deal with forwarded types. However, that's the behavior that we've already had - /// in this type for a while, so this is just preserving that logic. If this is an - /// issue in the future, this underlying comparer can absolutely be changed to something - /// more appropriate. - /// - private static readonly IEqualityComparer _underlyingComparer = - SymbolEquivalenceComparer.Instance; - - private SymbolAndProjectIdComparer() - { - } - - public bool Equals(SymbolAndProjectId x, SymbolAndProjectId y) - => _underlyingComparer.Equals(x.Symbol, y.Symbol); - - public int GetHashCode(SymbolAndProjectId obj) - => _underlyingComparer.GetHashCode(obj.Symbol); - } - - internal class SymbolAndProjectIdComparer : IEqualityComparer - { - /// - /// Note(cyrusn): We're using SymbolEquivalenceComparer.Instance as the underlying - /// way of comparing symbols. That's probably not correct as it won't appropriately - /// deal with forwarded types. However, that's the behavior that we've already had - /// in this type for a while, so this is just preserving that logic. If this is an - /// issue in the future, this underlying comparer can absolutely be changed to something - /// more appropriate. - /// - public static readonly SymbolAndProjectIdComparer SymbolEquivalenceInstance = - new SymbolAndProjectIdComparer(SymbolEquivalenceComparer.Instance); - - private readonly IEqualityComparer _underlyingComparer; - - public SymbolAndProjectIdComparer(IEqualityComparer underlyingComparer) - => _underlyingComparer = underlyingComparer; - - public bool Equals(SymbolAndProjectId x, SymbolAndProjectId y) - => _underlyingComparer.Equals(x.Symbol, y.Symbol); - - public int GetHashCode(SymbolAndProjectId obj) - => _underlyingComparer.GetHashCode(obj.Symbol); - } -} diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolCallerInfo.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolCallerInfo.cs index 6b3c32812d543..97a1e0555d9c1 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolCallerInfo.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolCallerInfo.cs @@ -20,9 +20,7 @@ public struct SymbolCallerInfo /// /// The symbol that is calling the symbol being called. /// - public ISymbol CallingSymbol => CallingSymbolAndProjectId.Symbol; - - internal SymbolAndProjectId CallingSymbolAndProjectId { get; } + public ISymbol CallingSymbol { get; } /// /// The locations inside the calling symbol where the called symbol is referenced. @@ -32,9 +30,7 @@ public struct SymbolCallerInfo /// /// The symbol being called. /// - public ISymbol CalledSymbol => CalledSymbolAndProjectId.Symbol; - - internal SymbolAndProjectId CalledSymbolAndProjectId { get; } + public ISymbol CalledSymbol { get; } /// /// True if the CallingSymbol is directly calling CalledSymbol. False if it is calling a @@ -45,13 +41,13 @@ public struct SymbolCallerInfo public bool IsDirect { get; } internal SymbolCallerInfo( - SymbolAndProjectId callingSymbol, - SymbolAndProjectId calledSymbol, + ISymbol callingSymbol, + ISymbol calledSymbol, IEnumerable locations, bool isDirect) { - CallingSymbolAndProjectId = callingSymbol; - CalledSymbolAndProjectId = calledSymbol; + CallingSymbol = callingSymbol; + CalledSymbol = calledSymbol; this.IsDirect = isDirect; this.Locations = locations; } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.FindReferencesServerCallback.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.FindReferencesServerCallback.cs index b7ae067e29832..e186c7b091626 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.FindReferencesServerCallback.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.FindReferencesServerCallback.cs @@ -22,13 +22,7 @@ internal sealed class FindReferencesServerCallback : IEqualityComparer - /// Note: for purposes of Equality/Hashing, all that we use is the underlying SymbolKey. That's because FAR - /// only cares if it is looking at the same symbol, it don't care if the symbol came from a different - /// project or not. - /// - private readonly Dictionary _definitionMap; + private readonly Dictionary _definitionMap; public FindReferencesServerCallback( Solution solution, @@ -38,7 +32,7 @@ public FindReferencesServerCallback( _solution = solution; _progress = progress; _cancellationToken = cancellationToken; - _definitionMap = new Dictionary(this); + _definitionMap = new Dictionary(this); } public Task AddItemsAsync(int count) => _progress.ProgressTracker.AddItemsAsync(count); @@ -61,35 +55,33 @@ public Task OnFindInDocumentCompletedAsync(DocumentId documentId) public async Task OnDefinitionFoundAsync(SerializableSymbolAndProjectId definition) { - var symbolAndProjectId = await definition.TryRehydrateAsync( + var symbol = await definition.TryRehydrateAsync( _solution, _cancellationToken).ConfigureAwait(false); - if (!symbolAndProjectId.HasValue) - { + if (symbol == null) return; - } lock (_gate) { - _definitionMap[definition] = symbolAndProjectId.Value; + _definitionMap[definition] = symbol; } - await _progress.OnDefinitionFoundAsync(symbolAndProjectId.Value).ConfigureAwait(false); + await _progress.OnDefinitionFoundAsync(symbol).ConfigureAwait(false); } public async Task OnReferenceFoundAsync( SerializableSymbolAndProjectId definition, SerializableReferenceLocation reference) { - SymbolAndProjectId symbolAndProjectId; + ISymbol symbol; lock (_gate) { - symbolAndProjectId = _definitionMap[definition]; + symbol = _definitionMap[definition]; } var referenceLocation = await reference.RehydrateAsync( _solution, _cancellationToken).ConfigureAwait(false); - await _progress.OnReferenceFoundAsync(symbolAndProjectId, referenceLocation).ConfigureAwait(false); + await _progress.OnReferenceFoundAsync(symbol, referenceLocation).ConfigureAwait(false); } bool IEqualityComparer.Equals(SerializableSymbolAndProjectId x, SerializableSymbolAndProjectId y) diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.cs index cafcfeb3d6189..d063f25556ada 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.cs @@ -90,23 +90,12 @@ public static async Task FindSymbolAtPositionAsync( /// Finds the definition symbol declared in source code for a corresponding reference symbol. /// Returns null if no such symbol can be found in the specified solution. /// - public static async Task FindSourceDefinitionAsync( + public static Task FindSourceDefinitionAsync( ISymbol symbol, Solution solution, CancellationToken cancellationToken = default) { - var result = await FindSourceDefinitionAsync( - SymbolAndProjectId.Create(symbol, projectId: null), - solution, cancellationToken).ConfigureAwait(false); - return result.Symbol; - } - - internal static Task FindSourceDefinitionAsync( - SymbolAndProjectId symbolAndProjectId, Solution solution, CancellationToken cancellationToken = default) - { - var symbol = symbolAndProjectId.Symbol; if (symbol != null) { symbol = symbol.GetOriginalUnreducedDefinition(); - symbolAndProjectId = symbolAndProjectId.WithSymbol(symbol); switch (symbol.Kind) { case SymbolKind.Event: @@ -118,19 +107,18 @@ internal static Task FindSourceDefinitionAsync( case SymbolKind.Property: case SymbolKind.TypeParameter: case SymbolKind.Namespace: - return FindSourceDefinitionWorkerAsync(symbolAndProjectId, solution, cancellationToken); + return FindSourceDefinitionWorkerAsync(symbol, solution, cancellationToken); } } - return SpecializedTasks.Default(); + return SpecializedTasks.Null(); } - private static async Task FindSourceDefinitionWorkerAsync( - SymbolAndProjectId symbolAndProjectId, + private static async Task FindSourceDefinitionWorkerAsync( + ISymbol symbol, Solution solution, CancellationToken cancellationToken) { - var symbol = symbolAndProjectId.Symbol; // If it's already in source, then we might already be done if (InSource(symbol)) { @@ -138,7 +126,7 @@ private static async Task FindSourceDefinitionWorkerAsync( // symbol somewhere else. The common case for this is a merged INamespaceSymbol that spans assemblies. if (symbol.ContainingAssembly == null) { - return symbolAndProjectId; + return symbol; } // Just because it's a source symbol doesn't mean we have the final symbol we actually want. In retargeting cases, @@ -147,7 +135,6 @@ private static async Task FindSourceDefinitionWorkerAsync( // then we have a retargeting scenario and want to take our usual path below as if it was a metadata reference foreach (var sourceProject in solution.Projects) { - // If our symbol is actually a "regular" source symbol, then we know the compilation is holding the symbol alive // and thus TryGetCompilation is sufficient. For another example of this pattern, see Solution.GetProject(IAssemblySymbol) // which we happen to call below. @@ -155,7 +142,7 @@ private static async Task FindSourceDefinitionWorkerAsync( { if (symbol.ContainingAssembly.Equals(compilation.Assembly)) { - return SymbolAndProjectId.Create(symbol, sourceProject.Id); + return symbol; } } } @@ -163,7 +150,7 @@ private static async Task FindSourceDefinitionWorkerAsync( else if (!symbol.Locations.Any(loc => loc.IsInMetadata)) { // We have a symbol that's neither in source nor metadata - return default; + return null; } var project = solution.GetProject(symbol.ContainingAssembly, cancellationToken); @@ -175,15 +162,15 @@ private static async Task FindSourceDefinitionWorkerAsync( if (result.Symbol != null && InSource(result.Symbol)) { - return SymbolAndProjectId.Create(result.Symbol, project.Id); + return result.Symbol; } else { - return SymbolAndProjectId.Create(result.CandidateSymbols.FirstOrDefault(InSource), project.Id); + return result.CandidateSymbols.FirstOrDefault(InSource); } } - return default; + return null; } private static bool InSource(ISymbol symbol) @@ -236,21 +223,20 @@ public static IEnumerable FindSimilarSymbols(TSymbol symbol, C } /// - /// If is declared in a linked file, then this function returns all the symbols that + /// If is declared in a linked file, then this function returns all the symbols that /// are defined by the same symbol's syntax in the all projects that the linked file is referenced from. /// /// In order to be returned the other symbols must have the same and as . This matches general user intuition that these are all + /// cref="ISymbol.Kind"/> as . This matches general user intuition that these are all /// the 'same' symbol, and should be examined, regardless of the project context and they /// originally started with. /// - internal static async Task> FindLinkedSymbolsAsync( - Solution solution, SymbolAndProjectId symbolAndProjectId, CancellationToken cancellationToken) + internal static async Task> FindLinkedSymbolsAsync( + ISymbol symbol, Solution solution, CancellationToken cancellationToken) { // Add the original symbol to the result set. - var linkedSymbols = new HashSet { symbolAndProjectId }; + var linkedSymbols = new HashSet { symbol }; - var symbol = symbolAndProjectId.Symbol; foreach (var location in symbol.DeclaringSyntaxReferences) { var originalDocument = solution.GetDocument(location.SyntaxTree); @@ -275,7 +261,7 @@ internal static async Task> FindLinkedSymbols linkedSymbol.Kind == symbol.Kind && linkedSymbol.Name == symbol.Name) { - linkedSymbols.Add(SymbolAndProjectId.Create(linkedSymbol, linkedDocument.Project.Id)); + linkedSymbols.Add(linkedSymbol); } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Declarations_AllDeclarations.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Declarations_AllDeclarations.cs index 2ddb38e2efe06..abafabd2fae30 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Declarations_AllDeclarations.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Declarations_AllDeclarations.cs @@ -19,7 +19,7 @@ public static async Task> FindDeclarationsAsync( using var query = SearchQuery.Create(name, ignoreCase); var declarations = await DeclarationFinder.FindAllDeclarationsWithNormalQueryAsync( project, query, SymbolFilter.All, cancellationToken).ConfigureAwait(false); - return declarations.SelectAsArray(t => t.Symbol); + return declarations; } /// @@ -31,7 +31,7 @@ public static async Task> FindDeclarationsAsync( using var query = SearchQuery.Create(name, ignoreCase); var declarations = await DeclarationFinder.FindAllDeclarationsWithNormalQueryAsync( project, query, filter, cancellationToken).ConfigureAwait(false); - return declarations.SelectAsArray(t => t.Symbol); + return declarations; } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Declarations_CustomQueries.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Declarations_CustomQueries.cs index c382a6aa52ddc..99ffb270377f0 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Declarations_CustomQueries.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Declarations_CustomQueries.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Internal.Log; @@ -37,10 +36,10 @@ public static async Task> FindSourceDeclarationsAsync(Solut var declarations = await FindSourceDeclarationsWithCustomQueryAsync( solution, query, filter, cancellationToken).ConfigureAwait(false); - return declarations.SelectAsArray(d => d.Symbol); + return declarations; } - internal static async Task> FindSourceDeclarationsWithCustomQueryAsync( + internal static async Task> FindSourceDeclarationsWithCustomQueryAsync( Solution solution, SearchQuery query, SymbolFilter filter, CancellationToken cancellationToken) { if (solution == null) @@ -50,12 +49,12 @@ internal static async Task> FindSourceDeclara if (query.Name != null && string.IsNullOrWhiteSpace(query.Name)) { - return ImmutableArray.Empty; + return ImmutableArray.Empty; } using (Logger.LogBlock(FunctionId.SymbolFinder_Solution_Predicate_FindSourceDeclarationsAsync, cancellationToken)) { - var result = ArrayBuilder.GetInstance(); + var result = ArrayBuilder.GetInstance(); foreach (var projectId in solution.ProjectIds) { var project = solution.GetProject(projectId); @@ -82,10 +81,10 @@ public static async Task> FindSourceDeclarationsAsync(Proje var declarations = await FindSourceDeclarationsWithCustomQueryAsync( project, query, filter, cancellationToken).ConfigureAwait(false); - return declarations.SelectAsArray(d => d.Symbol); + return declarations; } - internal static async Task> FindSourceDeclarationsWithCustomQueryAsync( + internal static async Task> FindSourceDeclarationsWithCustomQueryAsync( Project project, SearchQuery query, SymbolFilter filter, CancellationToken cancellationToken) { if (project == null) @@ -95,7 +94,7 @@ internal static async Task> FindSourceDeclara if (query.Name != null && string.IsNullOrWhiteSpace(query.Name)) { - return ImmutableArray.Empty; + return ImmutableArray.Empty; } using (Logger.LogBlock(FunctionId.SymbolFinder_Project_Predicate_FindSourceDeclarationsAsync, cancellationToken)) @@ -105,14 +104,13 @@ internal static async Task> FindSourceDeclara var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); var unfiltered = compilation.GetSymbolsWithName(query.GetPredicate(), filter, cancellationToken) - .Select(s => new SymbolAndProjectId(s, project.Id)) .ToImmutableArray(); return DeclarationFinder.FilterByCriteria(unfiltered, filter); } } - return ImmutableArray.Empty; + return ImmutableArray.Empty; } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Declarations_SourceDeclarations.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Declarations_SourceDeclarations.cs index a35d489f730d5..9b923bb6f38ef 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Declarations_SourceDeclarations.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Declarations_SourceDeclarations.cs @@ -30,7 +30,7 @@ public static async Task> FindSourceDeclarationsAsync( { var declarations = await DeclarationFinder.FindSourceDeclarationsWithNormalQueryAsync( solution, name, ignoreCase, filter, cancellationToken).ConfigureAwait(false); - return declarations.SelectAsArray(t => t.Symbol); + return declarations; } } @@ -51,7 +51,7 @@ public static async Task> FindSourceDeclarationsAsync( var declarations = await DeclarationFinder.FindSourceDeclarationsWithNormalQueryAsync( project, name, ignoreCase, filter, cancellationToken).ConfigureAwait(false); - return declarations.SelectAsArray(t => t.Symbol); + return declarations; } } @@ -81,7 +81,7 @@ public static async Task> FindSourceDeclarationsWithPattern { var declarations = await DeclarationFinder.FindSourceDeclarationsWithPatternAsync( solution, pattern, filter, cancellationToken).ConfigureAwait(false); - return declarations.SelectAsArray(t => t.Symbol); + return declarations; } } @@ -110,7 +110,7 @@ public static async Task> FindSourceDeclarationsWithPattern var declarations = await DeclarationFinder.FindSourceDeclarationsWithPatternAsync( project, pattern, filter, cancellationToken).ConfigureAwait(false); - return declarations.SelectAsArray(t => t.Symbol); + return declarations; } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindReferences_Current.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindReferences_Current.cs index 74f071a6c16ea..2329ab5efd4c8 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindReferences_Current.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindReferences_Current.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.FindSymbols.Finders; using Microsoft.CodeAnalysis.Internal.Log; using Microsoft.CodeAnalysis.Remote; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.FindSymbols { @@ -19,56 +20,53 @@ namespace Microsoft.CodeAnalysis.FindSymbols public static partial class SymbolFinder { internal static async Task FindReferencesAsync( - SymbolAndProjectId symbolAndProjectId, + ISymbol symbol, Solution solution, IStreamingFindReferencesProgress progress, IImmutableSet documents, FindReferencesSearchOptions options, CancellationToken cancellationToken) { + Contract.ThrowIfNull(solution.GetOriginatingProjectId(symbol), WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution); + using (Logger.LogBlock(FunctionId.FindReference, cancellationToken)) { - // If ProjectId is null then this is a call through our old public API. We don't have - // the necessary data to effectively run the call out of proc. - if (symbolAndProjectId.ProjectId != null) + var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false); + if (client != null) { - var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false); - if (client != null) - { - // Create a callback that we can pass to the server process to hear about the - // results as it finds them. When we hear about results we'll forward them to - // the 'progress' parameter which will then update the UI. - var serverCallback = new FindReferencesServerCallback(solution, progress, cancellationToken); - - var success = await client.TryRunRemoteAsync( - WellKnownServiceHubServices.CodeAnalysisService, - nameof(IRemoteSymbolFinder.FindReferencesAsync), - solution, - new object[] - { - SerializableSymbolAndProjectId.Dehydrate(solution, symbolAndProjectId.Symbol, cancellationToken), - documents?.Select(d => d.Id).ToArray(), - SerializableFindReferencesSearchOptions.Dehydrate(options), - }, - serverCallback, - cancellationToken).ConfigureAwait(false); + // Create a callback that we can pass to the server process to hear about the + // results as it finds them. When we hear about results we'll forward them to + // the 'progress' parameter which will then update the UI. + var serverCallback = new FindReferencesServerCallback(solution, progress, cancellationToken); - if (success) + var success = await client.TryRunRemoteAsync( + WellKnownServiceHubServices.CodeAnalysisService, + nameof(IRemoteSymbolFinder.FindReferencesAsync), + solution, + new object[] { - return; - } + SerializableSymbolAndProjectId.Dehydrate(solution, symbol, cancellationToken), + documents?.Select(d => d.Id).ToArray(), + SerializableFindReferencesSearchOptions.Dehydrate(options), + }, + serverCallback, + cancellationToken).ConfigureAwait(false); + + if (success) + { + return; } } // Couldn't effectively search in OOP. Perform the search in-proc. await FindReferencesInCurrentProcessAsync( - symbolAndProjectId, solution, progress, + symbol, solution, progress, documents, options, cancellationToken).ConfigureAwait(false); } } internal static Task FindReferencesInCurrentProcessAsync( - SymbolAndProjectId symbolAndProjectId, + ISymbol symbolAndProjectId, Solution solution, IStreamingFindReferencesProgress progress, IImmutableSet documents, diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindReferences_Legacy.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindReferences_Legacy.cs index 34912f0c8a9d0..a7b4654b9457d 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindReferences_Legacy.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindReferences_Legacy.cs @@ -2,10 +2,12 @@ // 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.Threading; using System.Threading.Tasks; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.FindSymbols { @@ -27,21 +29,23 @@ public static Task> FindReferencesAsync( Solution solution, CancellationToken cancellationToken = default) { - return FindReferencesAsync(new SymbolAndProjectId(symbol, projectId: null), solution, cancellationToken); - } + if (solution.GetOriginatingProjectId(symbol) == null) + throw new ArgumentException(WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution, nameof(symbol)); - internal static Task> FindReferencesAsync(SymbolAndProjectId symbolAndProjectId, Solution solution, CancellationToken cancellationToken) - => FindReferencesAsync(symbolAndProjectId, solution, FindReferencesSearchOptions.Default, cancellationToken); + return FindReferencesAsync(symbol, solution, FindReferencesSearchOptions.Default, cancellationToken); + } internal static async Task> FindReferencesAsync( - SymbolAndProjectId symbolAndProjectId, + ISymbol symbol, Solution solution, FindReferencesSearchOptions options, CancellationToken cancellationToken) { + Contract.ThrowIfNull(solution.GetOriginatingProjectId(symbol), WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution); + var progressCollector = new StreamingProgressCollector(); await FindReferencesAsync( - symbolAndProjectId, solution, progressCollector, + symbol, solution, progressCollector, documents: null, options, cancellationToken).ConfigureAwait(false); return progressCollector.GetReferencedSymbols(); } @@ -59,6 +63,9 @@ public static Task> FindReferencesAsync( IImmutableSet documents, CancellationToken cancellationToken = default) { + if (solution.GetOriginatingProjectId(symbol) == null) + throw new ArgumentException(WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution, nameof(symbol)); + return FindReferencesAsync(symbol, solution, progress: null, documents: documents, cancellationToken: cancellationToken); } @@ -78,6 +85,9 @@ public static Task> FindReferencesAsync( IImmutableSet documents, CancellationToken cancellationToken = default) { + if (solution.GetOriginatingProjectId(symbol) == null) + throw new ArgumentException(WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution, nameof(symbol)); + return FindReferencesAsync( symbol, solution, progress, documents, FindReferencesSearchOptions.Default, cancellationToken); @@ -91,12 +101,13 @@ private static async Task> FindReferencesAsync( FindReferencesSearchOptions options, CancellationToken cancellationToken) { + Contract.ThrowIfNull(solution.GetOriginatingProjectId(symbol), WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution); + progress ??= NoOpFindReferencesProgress.Instance; var streamingProgress = new StreamingProgressCollector( new StreamingFindReferencesProgressAdapter(progress)); await FindReferencesAsync( - SymbolAndProjectId.Create(symbol, projectId: null), - solution, streamingProgress, documents, + symbol, solution, streamingProgress, documents, options, cancellationToken).ConfigureAwait(false); return streamingProgress.GetReferencedSymbols(); } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindRenamableReferences.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindRenamableReferences.cs index cc01708f4cba1..98cea5ce58619 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindRenamableReferences.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_FindRenamableReferences.cs @@ -13,7 +13,7 @@ namespace Microsoft.CodeAnalysis.FindSymbols public static partial class SymbolFinder { internal static async Task> FindRenamableReferencesAsync( - SymbolAndProjectId symbolAndProjectId, + ISymbol symbol, Solution solution, CancellationToken cancellationToken) { @@ -30,7 +30,7 @@ internal static async Task> FindRenamableRefere FindReferencesSearchOptions.Default, cancellationToken); - await engine.FindReferencesAsync(symbolAndProjectId).ConfigureAwait(false); + await engine.FindReferencesAsync(symbol).ConfigureAwait(false); return streamingProgress.GetReferencedSymbols(); } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Hierarchy_Current.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Hierarchy.cs similarity index 74% rename from src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Hierarchy_Current.cs rename to src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Hierarchy.cs index 5028bd1b63afc..3a6676914dd4a 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Hierarchy_Current.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Hierarchy.cs @@ -19,31 +19,42 @@ namespace Microsoft.CodeAnalysis.FindSymbols { public static partial class SymbolFinder { - internal static async Task> FindOverridesAsync( - SymbolAndProjectId symbolAndProjectId, Solution solution, IImmutableSet projects = null, CancellationToken cancellationToken = default) + /// + /// Find symbols for members that override the specified member symbol. + /// + public static async Task> FindOverridesAsync( + ISymbol symbol, Solution solution, IImmutableSet projects = null, CancellationToken cancellationToken = default) + { + if (solution.GetOriginatingProjectId(symbol) == null) + throw new ArgumentException(WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution, nameof(symbol)); + + return await FindOverridesArrayAsync(symbol, solution, projects, cancellationToken).ConfigureAwait(false); + } + + internal static async Task> FindOverridesArrayAsync( + ISymbol symbol, Solution solution, IImmutableSet projects = null, CancellationToken cancellationToken = default) { - var results = ArrayBuilder.GetInstance(); + var results = ArrayBuilder.GetInstance(); - var symbol = symbolAndProjectId.Symbol?.OriginalDefinition; + symbol = symbol?.OriginalDefinition; if (symbol.IsOverridable()) { // To find the overrides, we need to walk down the type hierarchy and check all // derived types. var containingType = symbol.ContainingType; var derivedTypes = await FindDerivedClassesAsync( - symbolAndProjectId.WithSymbol(containingType), - solution, projects, cancellationToken).ConfigureAwait(false); + containingType, solution, projects, cancellationToken).ConfigureAwait(false); foreach (var type in derivedTypes) { - foreach (var m in type.Symbol.GetMembers(symbol.Name)) + foreach (var m in type.GetMembers(symbol.Name)) { var sourceMember = await FindSourceDefinitionAsync(m, solution, cancellationToken).ConfigureAwait(false); var bestMember = sourceMember ?? m; if (IsOverride(solution, bestMember, symbol, cancellationToken)) { - results.Add(new SymbolAndProjectId(bestMember, type.ProjectId)); + results.Add(bestMember); } } } @@ -66,18 +77,29 @@ internal static bool IsOverride( return false; } - internal static async Task> FindImplementedInterfaceMembersAsync( - SymbolAndProjectId symbolAndProjectId, Solution solution, IImmutableSet projects = null, CancellationToken cancellationToken = default) + /// + /// Find symbols for declarations that implement members of the specified interface symbol + /// + public static async Task> FindImplementedInterfaceMembersAsync( + ISymbol symbol, Solution solution, IImmutableSet projects = null, CancellationToken cancellationToken = default) + { + if (solution.GetOriginatingProjectId(symbol) == null) + throw new ArgumentException(WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution, nameof(symbol)); + + return await FindImplementedInterfaceMembersArrayAsync(symbol, solution, projects, cancellationToken).ConfigureAwait(false); + } + + internal static async Task> FindImplementedInterfaceMembersArrayAsync( + ISymbol symbol, Solution solution, IImmutableSet projects = null, CancellationToken cancellationToken = default) { // Member can only implement interface members if it is an explicit member, or if it is // public and non static. - var symbol = symbolAndProjectId.Symbol; if (symbol != null) { var explicitImplementations = symbol.ExplicitInterfaceImplementations(); if (explicitImplementations.Length > 0) { - return explicitImplementations.SelectAsArray(symbolAndProjectId.WithSymbol); + return explicitImplementations; } else if ( symbol.DeclaredAccessibility == Accessibility.Public && !symbol.IsStatic && @@ -95,17 +117,16 @@ internal static async Task> FindImplementedIn // // In this case, Base.Goo *does* implement IGoo.Goo in the context of the type // Derived. - var containingType = symbolAndProjectId.WithSymbol( - symbol.ContainingType.OriginalDefinition); + var containingType = symbol.ContainingType.OriginalDefinition; var derivedClasses = await SymbolFinder.FindDerivedClassesAsync( containingType, solution, projects, cancellationToken).ConfigureAwait(false); var allTypes = derivedClasses.Concat(containingType); - using var _ = ArrayBuilder.GetInstance(out var builder); + using var _ = ArrayBuilder.GetInstance(out var builder); - foreach (var type in allTypes.Convert()) + foreach (var type in allTypes) { - foreach (var interfaceType in GetAllInterfaces(type)) + foreach (var interfaceType in type.AllInterfaces) { // We don't want to look inside this type if we can avoid it. So first // make sure that the interface even contains a symbol with the same @@ -113,19 +134,19 @@ internal static async Task> FindImplementedIn var nameToLookFor = symbol.IsPropertyAccessor() ? ((IMethodSymbol)symbol).AssociatedSymbol.Name : symbol.Name; - if (interfaceType.Symbol.MemberNames.Contains(nameToLookFor)) + if (interfaceType.MemberNames.Contains(nameToLookFor)) { - foreach (var m in GetMembers(interfaceType, symbol.Name)) + foreach (var m in interfaceType.GetMembers(symbol.Name)) { var sourceMethod = await FindSourceDefinitionAsync(m, solution, cancellationToken).ConfigureAwait(false); - var bestMethod = sourceMethod.Symbol != null ? sourceMethod : m; + var bestMethod = sourceMethod ?? m; var implementations = await type.FindImplementationsForInterfaceMemberAsync( bestMethod, solution, cancellationToken).ConfigureAwait(false); foreach (var implementation in implementations) { - if (implementation.Symbol != null && - SymbolEquivalenceComparer.Instance.Equals(implementation.Symbol.OriginalDefinition, symbol.OriginalDefinition)) + if (implementation != null && + SymbolEquivalenceComparer.Instance.Equals(implementation.OriginalDefinition, symbol.OriginalDefinition)) { builder.Add(bestMethod); } @@ -135,88 +156,94 @@ internal static async Task> FindImplementedIn } } - return builder.Distinct(SymbolAndProjectIdComparer.SymbolEquivalenceInstance) - .ToImmutableArray(); + return builder.Distinct(SymbolEquivalenceComparer.Instance).ToImmutableArray(); } } - return ImmutableArray.Empty; + return ImmutableArray.Empty; } - private static IEnumerable GetMembers( - SymbolAndProjectId interfaceType, string name) - { - return interfaceType.Symbol.GetMembers(name).Select(interfaceType.WithSymbol); - } - - private static IEnumerable> GetAllInterfaces( - SymbolAndProjectId type) - { - return type.Symbol.AllInterfaces.Select(type.WithSymbol); - } - - internal static Task>> FindDerivedClassesAsync( - SymbolAndProjectId typeAndProjectId, Solution solution, IImmutableSet projects = null, CancellationToken cancellationToken = default) + /// + /// Finds the derived classes of the given type. Implementations of an interface are not considered "derived", but can be found + /// with . + /// + /// The symbol to find derived types of. + /// The solution to search in. + /// The projects to search. Can be null to search the entire solution. + /// + /// The derived types of the symbol. The symbol passed in is not included in this list. + public static async Task> FindDerivedClassesAsync( + INamedTypeSymbol type, Solution solution, IImmutableSet projects = null, CancellationToken cancellationToken = default) { - var type = typeAndProjectId.Symbol; if (type == null) throw new ArgumentNullException(nameof(type)); if (solution == null) throw new ArgumentNullException(nameof(solution)); - return DependentTypeFinder.FindTransitivelyDerivedClassesAsync(typeAndProjectId, solution, projects, cancellationToken); + if (solution.GetOriginatingProjectId(type) == null) + throw new ArgumentException(WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution, nameof(type)); + + return await DependentTypeFinder.FindTransitivelyDerivedClassesAsync( + type, solution, projects, cancellationToken).ConfigureAwait(false); } - internal static async Task> FindImplementationsAsync( - SymbolAndProjectId symbolAndProjectId, Solution solution, IImmutableSet projects = null, CancellationToken cancellationToken = default) + /// + /// Finds the symbols that implement an interface or interface member. + /// + public static async Task> FindImplementationsAsync( + ISymbol symbol, Solution solution, IImmutableSet projects = null, CancellationToken cancellationToken = default) + { + if (solution.GetOriginatingProjectId(symbol) == null) + throw new ArgumentException(WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution, nameof(symbol)); + + return await FindImplementationsArrayAsync(symbol, solution, projects, cancellationToken).ConfigureAwait(false); + } + + internal static async Task> FindImplementationsArrayAsync( + ISymbol symbol, Solution solution, IImmutableSet projects = null, CancellationToken cancellationToken = default) { // A symbol can only have implementations if it's an interface or a // method/property/event from an interface. - var symbol = symbolAndProjectId.Symbol; if (symbol is INamedTypeSymbol namedTypeSymbol) { var implementingTypes = await DependentTypeFinder.FindTransitivelyImplementingStructuresAndClassesAsync( - symbolAndProjectId.WithSymbol(namedTypeSymbol), solution, projects, cancellationToken).ConfigureAwait(false); - return implementingTypes.Select(s => (SymbolAndProjectId)s) - .Where(IsAccessible) - .ToImmutableArray(); + namedTypeSymbol, solution, projects, cancellationToken).ConfigureAwait(false); + return ImmutableArray.CastUp(implementingTypes).WhereAsArray(IsAccessible); } else if (symbol.IsImplementableMember()) { var containingType = symbol.ContainingType.OriginalDefinition; var allTypes = await DependentTypeFinder.FindTransitivelyImplementingStructuresClassesAndInterfacesAsync( - symbolAndProjectId.WithSymbol(containingType), solution, projects, cancellationToken).ConfigureAwait(false); + containingType, solution, projects, cancellationToken).ConfigureAwait(false); - ImmutableArray.Builder results = null; - foreach (var t in allTypes.Convert()) + ImmutableArray.Builder results = null; + foreach (var t in allTypes) { - var implementations = await t.FindImplementationsForInterfaceMemberAsync(symbolAndProjectId, solution, cancellationToken).ConfigureAwait(false); + var implementations = await t.FindImplementationsForInterfaceMemberAsync(symbol, solution, cancellationToken).ConfigureAwait(false); foreach (var implementation in implementations) { var sourceDef = await FindSourceDefinitionAsync(implementation, solution, cancellationToken).ConfigureAwait(false); - var bestDef = sourceDef.Symbol != null ? sourceDef : implementation; + var bestDef = sourceDef ?? implementation; if (IsAccessible(bestDef)) { - results ??= ImmutableArray.CreateBuilder(); - results.Add(bestDef.WithSymbol(bestDef.Symbol.OriginalDefinition)); + results ??= ImmutableArray.CreateBuilder(); + results.Add(bestDef.OriginalDefinition); } } } if (results != null) { - return results.Distinct(SymbolAndProjectIdComparer.SymbolEquivalenceInstance) - .ToImmutableArray(); + return results.Distinct(SymbolEquivalenceComparer.Instance).ToImmutableArray(); } } - return ImmutableArray.Empty; + return ImmutableArray.Empty; } - private static bool IsAccessible(SymbolAndProjectId symbolAndProjectId) + private static bool IsAccessible(ISymbol symbol) { - var symbol = symbolAndProjectId.Symbol; if (symbol.Locations.Any(l => l.IsInMetadata)) { var accessibility = symbol.DeclaredAccessibility; @@ -231,26 +258,32 @@ private static bool IsAccessible(SymbolAndProjectId symbolAndProjectId) /// /// Finds all the callers of a specified symbol. /// - internal static Task> FindCallersAsync( - SymbolAndProjectId symbolAndProjectId, Solution solution, CancellationToken cancellationToken = default) + public static Task> FindCallersAsync( + ISymbol symbol, Solution solution, CancellationToken cancellationToken = default) { - return FindCallersAsync(symbolAndProjectId, solution, documents: null, cancellationToken: cancellationToken); + if (solution.GetOriginatingProjectId(symbol) == null) + throw new ArgumentException(WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution, nameof(symbol)); + + return FindCallersAsync(symbol, solution, documents: null, cancellationToken: cancellationToken); } /// /// Finds all the callers of a specified symbol. /// - internal static async Task> FindCallersAsync( - SymbolAndProjectId symbolAndProjectId, Solution solution, IImmutableSet documents, CancellationToken cancellationToken = default) + public static async Task> FindCallersAsync( + ISymbol symbol, Solution solution, IImmutableSet documents, CancellationToken cancellationToken = default) { - symbolAndProjectId = symbolAndProjectId.WithSymbol(symbolAndProjectId.Symbol.OriginalDefinition); - var foundSymbol = await FindSourceDefinitionAsync(symbolAndProjectId, solution, cancellationToken).ConfigureAwait(false); - symbolAndProjectId = foundSymbol.Symbol != null ? foundSymbol : symbolAndProjectId; + if (solution.GetOriginatingProjectId(symbol) == null) + throw new ArgumentException(WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution, nameof(symbol)); - var references = await FindCallReferencesAsync(solution, symbolAndProjectId, documents, cancellationToken).ConfigureAwait(false); + symbol = symbol.OriginalDefinition; + var foundSymbol = await FindSourceDefinitionAsync(symbol, solution, cancellationToken).ConfigureAwait(false); + symbol = foundSymbol ?? symbol; + + var references = await FindCallReferencesAsync(solution, symbol, documents, cancellationToken).ConfigureAwait(false); var directReference = references.Where( - r => SymbolEquivalenceComparer.Instance.Equals(symbolAndProjectId.Symbol, r.Definition)).FirstOrDefault(); + r => SymbolEquivalenceComparer.Instance.Equals(symbol, r.Definition)).FirstOrDefault(); var indirectReferences = references.WhereAsArray(r => r != directReference); @@ -273,18 +306,19 @@ async Task AddReferencingSymbols(ReferencedSymbol reference, bool isDirect) var result = await reference.Locations.FindReferencingSymbolsAsync(cancellationToken).ConfigureAwait(false); foreach (var (callingSymbol, locations) in result) { - results.Add(new SymbolCallerInfo(callingSymbol, reference.DefinitionAndProjectId, locations, isDirect)); + results.Add(new SymbolCallerInfo(callingSymbol, reference.Definition, locations, isDirect)); } } } private static async Task> FindCallReferencesAsync( Solution solution, - SymbolAndProjectId symbolAndProjectId, + ISymbol symbol, IImmutableSet documents, CancellationToken cancellationToken = default) { - var symbol = symbolAndProjectId.Symbol; + Contract.ThrowIfNull(solution.GetOriginatingProjectId(symbol), WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution); + if (symbol != null) { if (symbol.Kind == SymbolKind.Event || @@ -293,7 +327,7 @@ private static async Task> FindCallReferencesAs { var collector = new StreamingProgressCollector(); await FindReferencesAsync( - symbolAndProjectId, solution, collector, documents, + symbol, solution, collector, documents, FindReferencesSearchOptions.Default, cancellationToken).ConfigureAwait(false); return collector.GetReferencedSymbols(); } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Hierarchy_Legacy.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Hierarchy_Legacy.cs deleted file mode 100644 index dd3e64998913f..0000000000000 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder_Hierarchy_Legacy.cs +++ /dev/null @@ -1,96 +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.Collections.Immutable; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.CodeAnalysis.FindSymbols -{ - // This file contains the legacy SymbolFinder APIs. The APIs are legacy because they - // do not contain enough information for us to effectively remote them over to the OOP - // process to do the work. Specifically, they lack the "current project context" necessary - // to be able to effectively serialize symbols to/from the remote process. - - public static partial class SymbolFinder - { - /// - /// Find symbols for members that override the specified member symbol. - /// - public static async Task> FindOverridesAsync( - ISymbol symbol, Solution solution, IImmutableSet projects = null, CancellationToken cancellationToken = default) - { - var result = await FindOverridesAsync( - SymbolAndProjectId.Create(symbol, projectId: null), - solution, projects, cancellationToken).ConfigureAwait(false); - - return result.SelectAsArray(s => s.Symbol); - } - - /// - /// Find symbols for declarations that implement members of the specified interface symbol - /// - public static async Task> FindImplementedInterfaceMembersAsync( - ISymbol symbol, Solution solution, IImmutableSet projects = null, CancellationToken cancellationToken = default) - { - var result = await FindImplementedInterfaceMembersAsync( - SymbolAndProjectId.Create(symbol, projectId: null), - solution, projects, cancellationToken).ConfigureAwait(false); - return result.SelectAsArray(s => s.Symbol); - } - - /// - /// Finds the derived classes of the given type. Implementations of an interface are not considered "derived", but can be found - /// with . - /// - /// The symbol to find derived types of. - /// The solution to search in. - /// The projects to search. Can be null to search the entire solution. - /// - /// The derived types of the symbol. The symbol passed in is not included in this list. - public static async Task> FindDerivedClassesAsync( - INamedTypeSymbol type, Solution solution, IImmutableSet projects = null, CancellationToken cancellationToken = default) - { - var result = await FindDerivedClassesAsync( - SymbolAndProjectId.Create(type, projectId: null), - solution, projects, cancellationToken).ConfigureAwait(false); - return result.SelectAsArray(s => s.Symbol); - } - - /// - /// Finds the symbols that implement an interface or interface member. - /// - public static async Task> FindImplementationsAsync( - ISymbol symbol, Solution solution, IImmutableSet projects = null, CancellationToken cancellationToken = default) - { - var result = await FindImplementationsAsync( - SymbolAndProjectId.Create(symbol, projectId: null), - solution, projects, cancellationToken).ConfigureAwait(false); - return result.SelectAsArray(s => s.Symbol); - } - - /// - /// Finds all the callers of a specified symbol. - /// - public static Task> FindCallersAsync( - ISymbol symbol, Solution solution, CancellationToken cancellationToken = default) - { - return FindCallersAsync( - SymbolAndProjectId.Create(symbol, projectId: null), - solution, documents: null, cancellationToken); - } - - /// - /// Finds all the callers of a specified symbol. - /// - public static Task> FindCallersAsync( - ISymbol symbol, Solution solution, IImmutableSet documents, CancellationToken cancellationToken = default) - { - return FindCallersAsync( - SymbolAndProjectId.Create(symbol, projectId: null), - solution, documents, cancellationToken); - } - } -} diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs index 9a8086f68bd11..a54d7f39e1fac 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs @@ -167,7 +167,7 @@ public SymbolTreeInfo WithChecksum(Checksum checksum) checksum, _concatenatedNames, _nodes, _spellCheckerTask, _inheritanceMap, _extensionMethodOfComplexType, _simpleTypeNameToExtensionMethodMap); } - public Task> FindAsync( + public Task> FindAsync( SearchQuery query, IAssemblySymbol assembly, ProjectId assemblyProjectId, SymbolFilter filter, CancellationToken cancellationToken) { // All entrypoints to this function are Find functions that are only searching @@ -175,12 +175,11 @@ public Task> FindAsync( Contract.ThrowIfTrue(query.Kind == SearchKind.Custom, "Custom queries are not supported in this API"); return this.FindAsync( - query, new AsyncLazy(assembly), - assemblyProjectId, filter, cancellationToken); + query, new AsyncLazy(assembly), filter, cancellationToken); } - public async Task> FindAsync( - SearchQuery query, AsyncLazy lazyAssembly, ProjectId assemblyProjectId, + public async Task> FindAsync( + SearchQuery query, AsyncLazy lazyAssembly, SymbolFilter filter, CancellationToken cancellationToken) { // All entrypoints to this function are Find functions that are only searching @@ -189,9 +188,7 @@ public async Task> FindAsync( var symbols = await FindCoreAsync(query, lazyAssembly, cancellationToken).ConfigureAwait(false); - return DeclarationFinder.FilterByCriteria( - symbols.SelectAsArray(s => new SymbolAndProjectId(s, assemblyProjectId)), - filter); + return DeclarationFinder.FilterByCriteria(symbols, filter); } private Task> FindCoreAsync( diff --git a/src/Workspaces/Core/Portable/Remote/RemoteArguments.cs b/src/Workspaces/Core/Portable/Remote/RemoteArguments.cs index 9a1b616882dfe..a7f2c7ddaa1a0 100644 --- a/src/Workspaces/Core/Portable/Remote/RemoteArguments.cs +++ b/src/Workspaces/Core/Portable/Remote/RemoteArguments.cs @@ -54,7 +54,7 @@ public static SerializableSymbolAndProjectId Dehydrate( Solution solution, ISymbol symbol, CancellationToken cancellationToken) { var symbolKey = symbol.GetSymbolKey(cancellationToken); - var projectId = solution.GetExactProjectId(symbol); + var projectId = solution.GetOriginatingProjectId(symbol); Contract.ThrowIfNull(projectId, WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution); return new SerializableSymbolAndProjectId @@ -64,7 +64,7 @@ public static SerializableSymbolAndProjectId Dehydrate( }; } - public async Task TryRehydrateAsync( + public async Task TryRehydrateAsync( Solution solution, CancellationToken cancellationToken) { var projectId = ProjectId; @@ -89,7 +89,7 @@ public static SerializableSymbolAndProjectId Dehydrate( } } - return new SymbolAndProjectId(symbol, projectId); + return symbol; } } @@ -193,12 +193,10 @@ private async Task RehydrateAliasAsync( Solution solution, CancellationToken cancellationToken) { if (Alias == null) - { return null; - } - var symbolAndProjectId = await Alias.TryRehydrateAsync(solution, cancellationToken).ConfigureAwait(false); - return symbolAndProjectId.GetValueOrDefault().Symbol as IAliasSymbol; + var symbol = await Alias.TryRehydrateAsync(solution, cancellationToken).ConfigureAwait(false); + return symbol as IAliasSymbol; } } diff --git a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs index 6bc652f273c4a..5218ee3ffaf19 100644 --- a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs +++ b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs @@ -167,7 +167,7 @@ private static async Task AddImplicitConflictsAsync( private static async Task AddDeclarationConflictsAsync( ISymbol renamedSymbol, ISymbol renameSymbol, - IEnumerable referencedSymbols, + IEnumerable referencedSymbols, ConflictResolution conflictResolution, IDictionary reverseMappedLocations, CancellationToken cancellationToken) diff --git a/src/Workspaces/Core/Portable/Rename/IRenameRewriterLanguageService.cs b/src/Workspaces/Core/Portable/Rename/IRenameRewriterLanguageService.cs index fcc2429827f48..a68b6f0b0f6a4 100644 --- a/src/Workspaces/Core/Portable/Rename/IRenameRewriterLanguageService.cs +++ b/src/Workspaces/Core/Portable/Rename/IRenameRewriterLanguageService.cs @@ -53,7 +53,7 @@ Task> ComputeDeclarationConflictsAsync( string replacementText, ISymbol renamedSymbol, ISymbol renameSymbol, - IEnumerable referencedSymbols, + IEnumerable referencedSymbols, Solution baseSolution, Solution newSolution, IDictionary reverseMappedLocations, @@ -123,7 +123,7 @@ bool IsIdentifierValid( internal abstract class AbstractRenameRewriterLanguageService : IRenameRewriterLanguageService { public abstract SyntaxNode AnnotateAndRename(RenameRewriterParameters parameters); - public abstract Task> ComputeDeclarationConflictsAsync(string replacementText, ISymbol renamedSymbol, ISymbol renameSymbol, IEnumerable referencedSymbols, Solution baseSolution, Solution newSolution, IDictionary reverseMappedLocations, CancellationToken cancellationToken); + public abstract Task> ComputeDeclarationConflictsAsync(string replacementText, ISymbol renamedSymbol, ISymbol renameSymbol, IEnumerable referencedSymbols, Solution baseSolution, Solution newSolution, IDictionary reverseMappedLocations, CancellationToken cancellationToken); public abstract Task> ComputeImplicitReferenceConflictsAsync(ISymbol renameSymbol, ISymbol renamedSymbol, IEnumerable implicitReferenceLocations, CancellationToken cancellationToken); public abstract ImmutableArray ComputePossibleImplicitUsageConflicts(ISymbol renamedSymbol, SemanticModel semanticModel, Location originalDeclarationLocation, int newDeclarationLocationStartingPosition, CancellationToken cancellationToken); public abstract SyntaxNode GetExpansionTargetForLocation(SyntaxToken token); diff --git a/src/Workspaces/Core/Portable/Rename/RenameLocation.ReferenceProcessing.cs b/src/Workspaces/Core/Portable/Rename/RenameLocation.ReferenceProcessing.cs index 8eb45a22b3d03..1631b53c1d1c3 100644 --- a/src/Workspaces/Core/Portable/Rename/RenameLocation.ReferenceProcessing.cs +++ b/src/Workspaces/Core/Portable/Rename/RenameLocation.ReferenceProcessing.cs @@ -31,18 +31,17 @@ internal static class ReferenceProcessing /// Given a symbol in a document, returns the "right" symbol that should be renamed in /// the case the name binds to things like aliases _and_ the underlying type at once. /// - public static async Task GetRenamableSymbolAsync( + public static async Task GetRenamableSymbolAsync( Document document, int position, CancellationToken cancellationToken) { var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position, cancellationToken: cancellationToken).ConfigureAwait(false); if (symbol == null) { - return default; + return null; } - var symbolAndProjectId = SymbolAndProjectId.Create(symbol, document.Project.Id); - var definitionSymbol = await FindDefinitionSymbolAsync(symbolAndProjectId, document.Project.Solution, cancellationToken).ConfigureAwait(false); - Contract.ThrowIfNull(definitionSymbol.Symbol); + var definitionSymbol = await FindDefinitionSymbolAsync(symbol, document.Project.Solution, cancellationToken).ConfigureAwait(false); + Contract.ThrowIfNull(definitionSymbol); return definitionSymbol; } @@ -50,21 +49,18 @@ public static async Task GetRenamableSymbolAsync( /// /// Given a symbol, finds the symbol that actually defines the name that we're using. /// - public static async Task FindDefinitionSymbolAsync( - SymbolAndProjectId symbolAndProjectId, Solution solution, CancellationToken cancellationToken) + public static async Task FindDefinitionSymbolAsync( + ISymbol symbol, Solution solution, CancellationToken cancellationToken) { - var symbol = symbolAndProjectId.Symbol; Contract.ThrowIfNull(symbol); Contract.ThrowIfNull(solution); // Make sure we're on the original source definition if we can be - var foundSymbolAndProjectId = await SymbolFinder.FindSourceDefinitionAsync( - symbolAndProjectId, solution, cancellationToken).ConfigureAwait(false); + var foundSymbol = await SymbolFinder.FindSourceDefinitionAsync( + symbol, solution, cancellationToken).ConfigureAwait(false); - var bestSymbolAndProjectId = foundSymbolAndProjectId.Symbol != null - ? foundSymbolAndProjectId - : symbolAndProjectId; - symbol = bestSymbolAndProjectId.Symbol; + var bestSymbol = foundSymbol ?? symbol; + symbol = bestSymbol; // If we're renaming a property, it might be a synthesized property for a method // backing field. @@ -79,8 +75,7 @@ public static async Task FindDefinitionSymbolAsync( var ordinal = containingMethod.Parameters.IndexOf((IParameterSymbol)symbol); if (ordinal < associatedPropertyOrEvent.Parameters.Length) { - return bestSymbolAndProjectId.WithSymbol( - associatedPropertyOrEvent.Parameters[ordinal]); + return associatedPropertyOrEvent.Parameters[ordinal]; } } } @@ -92,8 +87,7 @@ public static async Task FindDefinitionSymbolAsync( var typeSymbol = (INamedTypeSymbol)symbol; if (typeSymbol.IsImplicitlyDeclared && typeSymbol.IsDelegateType() && typeSymbol.AssociatedSymbol != null) { - return bestSymbolAndProjectId.WithSymbol( - typeSymbol.AssociatedSymbol); + return typeSymbol.AssociatedSymbol; } } @@ -105,8 +99,7 @@ public static async Task FindDefinitionSymbolAsync( methodSymbol.MethodKind == MethodKind.StaticConstructor || methodSymbol.MethodKind == MethodKind.Destructor) { - return bestSymbolAndProjectId.WithSymbol( - methodSymbol.ContainingType); + return methodSymbol.ContainingType; } } @@ -117,17 +110,14 @@ public static async Task FindDefinitionSymbolAsync( if (fieldSymbol.IsImplicitlyDeclared && fieldSymbol.AssociatedSymbol.IsKind(SymbolKind.Property)) { - return bestSymbolAndProjectId.WithSymbol( - fieldSymbol.AssociatedSymbol); + return fieldSymbol.AssociatedSymbol; } } // in case this is e.g. an overridden property accessor, we'll treat the property itself as the definition symbol - var propertyAndProjectId = await GetPropertyFromAccessorOrAnOverrideAsync(bestSymbolAndProjectId, solution, cancellationToken).ConfigureAwait(false); + var property = await GetPropertyFromAccessorOrAnOverrideAsync(bestSymbol, solution, cancellationToken).ConfigureAwait(false); - return propertyAndProjectId.Symbol != null - ? propertyAndProjectId - : bestSymbolAndProjectId; + return property ?? bestSymbol; } private static async Task ShouldIncludeSymbolAsync( @@ -224,23 +214,20 @@ static bool IsConstructorForType(ISymbol possibleConstructor, ISymbol possibleTy } } - internal static async Task GetPropertyFromAccessorOrAnOverrideAsync( - SymbolAndProjectId symbolAndProjectId, Solution solution, CancellationToken cancellationToken) + internal static async Task GetPropertyFromAccessorOrAnOverrideAsync( + ISymbol symbol, Solution solution, CancellationToken cancellationToken) { - var symbol = symbolAndProjectId.Symbol; if (symbol.IsPropertyAccessor()) { - return symbolAndProjectId.WithSymbol( - ((IMethodSymbol)symbol).AssociatedSymbol); + return ((IMethodSymbol)symbol).AssociatedSymbol; } if (symbol.IsOverride && symbol.OverriddenMember() != null) { var originalSourceSymbol = await SymbolFinder.FindSourceDefinitionAsync( - symbolAndProjectId.WithSymbol(symbol.OverriddenMember()), - solution, cancellationToken).ConfigureAwait(false); + symbol.OverriddenMember(), solution, cancellationToken).ConfigureAwait(false); - if (originalSourceSymbol.Symbol != null) + if (originalSourceSymbol != null) { return await GetPropertyFromAccessorOrAnOverrideAsync(originalSourceSymbol, solution, cancellationToken).ConfigureAwait(false); } @@ -250,28 +237,27 @@ internal static async Task GetPropertyFromAccessorOrAnOverri symbol.ContainingType.TypeKind == TypeKind.Interface) { var methodImplementors = await SymbolFinder.FindImplementationsAsync( - symbolAndProjectId, solution, cancellationToken: cancellationToken).ConfigureAwait(false); + symbol, solution, cancellationToken: cancellationToken).ConfigureAwait(false); foreach (var methodImplementor in methodImplementors) { var propertyAccessorOrAnOverride = await GetPropertyFromAccessorOrAnOverrideAsync(methodImplementor, solution, cancellationToken).ConfigureAwait(false); - if (propertyAccessorOrAnOverride.Symbol != null) + if (propertyAccessorOrAnOverride != null) { return propertyAccessorOrAnOverride; } } } - return default; + return null; } private static async Task IsPropertyAccessorOrAnOverrideAsync( ISymbol symbol, Solution solution, CancellationToken cancellationToken) { var result = await GetPropertyFromAccessorOrAnOverrideAsync( - SymbolAndProjectId.Create(symbol, projectId: null), - solution, cancellationToken).ConfigureAwait(false); - return result.Symbol != null; + symbol, solution, cancellationToken).ConfigureAwait(false); + return result != null; } private static string TrimNameToAfterLastDot(string name) diff --git a/src/Workspaces/Core/Portable/Rename/RenameLocations.cs b/src/Workspaces/Core/Portable/Rename/RenameLocations.cs index 7e1a6022516cf..4475c1f31922f 100644 --- a/src/Workspaces/Core/Portable/Rename/RenameLocations.cs +++ b/src/Workspaces/Core/Portable/Rename/RenameLocations.cs @@ -27,12 +27,12 @@ private class SearchResult { public readonly ImmutableHashSet Locations; public readonly ImmutableArray ImplicitLocations; - public readonly ImmutableArray ReferencedSymbols; + public readonly ImmutableArray ReferencedSymbols; public SearchResult( ImmutableHashSet locations, ImmutableArray implicitLocations, - ImmutableArray referencedSymbols) + ImmutableArray referencedSymbols) { this.Locations = locations; this.ImplicitLocations = implicitLocations; @@ -41,7 +41,7 @@ public SearchResult( } // never null fields - private readonly SymbolAndProjectId _symbolAndProjectId; + private readonly ISymbol _symbol; private readonly Solution _solution; private readonly SearchResult _mergedResult; internal OptionSet Options { get; } @@ -56,20 +56,20 @@ public SearchResult( internal RenameLocations( ImmutableHashSet locations, - SymbolAndProjectId symbolAndProjectId, + ISymbol symbol, Solution solution, - ImmutableArray referencedSymbols, + ImmutableArray referencedSymbols, ImmutableArray implicitLocations, OptionSet options) { - _symbolAndProjectId = symbolAndProjectId; + _symbol = symbol; _solution = solution; _mergedResult = new SearchResult(locations, implicitLocations, referencedSymbols); Options = options; } private RenameLocations( - SymbolAndProjectId symbolAndProjectId, + ISymbol symbol, Solution solution, OptionSet options, SearchResult originalSymbolResult, @@ -77,7 +77,7 @@ private RenameLocations( ImmutableArray stringsResult, ImmutableArray commentsResult) { - _symbolAndProjectId = symbolAndProjectId; + _symbol = symbol; _solution = solution; Options = options; _originalSymbolResult = originalSymbolResult; @@ -86,7 +86,7 @@ private RenameLocations( _commentsResult = commentsResult; var mergedLocations = ImmutableHashSet.CreateBuilder(); - using var _1 = ArrayBuilder.GetInstance(out var mergedReferencedSymbols); + using var _1 = ArrayBuilder.GetInstance(out var mergedReferencedSymbols); using var _2 = ArrayBuilder.GetInstance(out var mergedImplicitLocations); if (options.GetOption(RenameOptions.RenameInStrings)) @@ -100,7 +100,7 @@ private RenameLocations( } var renameMethodGroupReferences = - options.GetOption(RenameOptions.RenameOverloads) || !GetOverloadedSymbols(symbolAndProjectId).Any(); + options.GetOption(RenameOptions.RenameOverloads) || !GetOverloadedSymbols(symbol).Any(); var overloadsToMerge = options.GetOption(RenameOptions.RenameOverloads) ? overloadsResult.NullToEmpty() : ImmutableArray.Empty; @@ -119,25 +119,24 @@ private RenameLocations( } public ISet Locations => _mergedResult.Locations; - public SymbolAndProjectId SymbolAndProjectId => _symbolAndProjectId; - public ISymbol Symbol => _symbolAndProjectId.Symbol; + public ISymbol Symbol => _symbol; public Solution Solution => _solution; - public ImmutableArray ReferencedSymbols => _mergedResult.ReferencedSymbols; + public ImmutableArray ReferencedSymbols => _mergedResult.ReferencedSymbols; public ImmutableArray ImplicitLocations => _mergedResult.ImplicitLocations; /// /// Find the locations that need to be renamed. /// internal static async Task FindAsync( - SymbolAndProjectId symbolAndProjectId, Solution solution, OptionSet optionSet, CancellationToken cancellationToken) + ISymbol symbol, Solution solution, OptionSet optionSet, CancellationToken cancellationToken) { - Contract.ThrowIfNull(symbolAndProjectId.Symbol); + Contract.ThrowIfNull(symbol); using (Logger.LogBlock(FunctionId.Rename_AllRenameLocations, cancellationToken)) { - symbolAndProjectId = await ReferenceProcessing.FindDefinitionSymbolAsync(symbolAndProjectId, solution, cancellationToken).ConfigureAwait(false); - var originalSymbolResult = await AddLocationsReferenceSymbolsAsync(symbolAndProjectId, solution, cancellationToken).ConfigureAwait(false); + symbol = await ReferenceProcessing.FindDefinitionSymbolAsync(symbol, solution, cancellationToken).ConfigureAwait(false); + var originalSymbolResult = await AddLocationsReferenceSymbolsAsync(symbol, solution, cancellationToken).ConfigureAwait(false); var intermediateResult = new RenameLocations( - symbolAndProjectId, solution, optionSet, originalSymbolResult, overloadsResult: default, stringsResult: default, commentsResult: default); + symbol, solution, optionSet, originalSymbolResult, overloadsResult: default, stringsResult: default, commentsResult: default); return await intermediateResult.FindWithUpdatedOptionsAsync(optionSet, cancellationToken).ConfigureAwait(false); } @@ -151,11 +150,11 @@ internal async Task FindWithUpdatedOptionsAsync(OptionSet optio var overloadsResult = !_overloadsResult.IsDefault ? _overloadsResult : optionSet.GetOption(RenameOptions.RenameOverloads) - ? await GetOverloadsAsync(_symbolAndProjectId, _solution, cancellationToken).ConfigureAwait(false) + ? await GetOverloadsAsync(_symbol, _solution, cancellationToken).ConfigureAwait(false) : default; var stringsAndComments = await ReferenceProcessing.GetRenamableLocationsInStringsAndCommentsAsync( - _symbolAndProjectId.Symbol, + _symbol, _solution, _originalSymbolResult.Locations, optionSet.GetOption(RenameOptions.RenameInStrings) && _stringsResult.IsDefault, @@ -163,7 +162,7 @@ internal async Task FindWithUpdatedOptionsAsync(OptionSet optio cancellationToken).ConfigureAwait(false); return new RenameLocations( - _symbolAndProjectId, _solution, optionSet, _originalSymbolResult, + _symbol, _solution, optionSet, _originalSymbolResult, _overloadsResult.IsDefault ? overloadsResult : _overloadsResult, _stringsResult.IsDefault ? stringsAndComments.Item1 : _stringsResult, _commentsResult.IsDefault ? stringsAndComments.Item2 : _commentsResult); @@ -171,19 +170,17 @@ internal async Task FindWithUpdatedOptionsAsync(OptionSet optio } private static async Task> GetOverloadsAsync( - SymbolAndProjectId symbolAndProjectId, Solution solution, CancellationToken cancellationToken) + ISymbol symbol, Solution solution, CancellationToken cancellationToken) { using var _ = ArrayBuilder.GetInstance(out var overloadsResult); - foreach (var overloadedSymbol in GetOverloadedSymbols(symbolAndProjectId)) + foreach (var overloadedSymbol in GetOverloadedSymbols(symbol)) overloadsResult.Add(await AddLocationsReferenceSymbolsAsync(overloadedSymbol, solution, cancellationToken).ConfigureAwait(false)); return overloadsResult.ToImmutable(); } - internal static IEnumerable GetOverloadedSymbols( - SymbolAndProjectId symbolAndProjectId) + internal static IEnumerable GetOverloadedSymbols(ISymbol symbol) { - var symbol = symbolAndProjectId.Symbol; if (symbol is IMethodSymbol) { var containingType = symbol.ContainingType; @@ -193,7 +190,7 @@ internal static IEnumerable GetOverloadedSymbols( { if (string.Equals(member.MetadataName, symbol.MetadataName, StringComparison.Ordinal) && member is IMethodSymbol && !member.Equals(symbol)) { - yield return symbolAndProjectId.WithSymbol(member); + yield return member; } } } @@ -201,14 +198,13 @@ internal static IEnumerable GetOverloadedSymbols( } private static async Task AddLocationsReferenceSymbolsAsync( - SymbolAndProjectId symbolAndProjectId, + ISymbol symbol, Solution solution, CancellationToken cancellationToken) { - var symbol = symbolAndProjectId.Symbol; var locations = ImmutableHashSet.CreateBuilder(); var referenceSymbols = await SymbolFinder.FindRenamableReferencesAsync( - symbolAndProjectId, solution, cancellationToken).ConfigureAwait(false); + symbol, solution, cancellationToken).ConfigureAwait(false); foreach (var referencedSymbol in referenceSymbols) { @@ -222,7 +218,7 @@ await referencedSymbol.Locations.SelectManyAsync refSym.Locations).Where(loc => loc.IsImplicit).ToImmutableArray(); - var referencedSymbols = referenceSymbols.Select(r => r.DefinitionAndProjectId).Where(r => !r.Symbol.Equals(symbol)).ToImmutableArray(); + var referencedSymbols = referenceSymbols.Select(r => r.Definition).Where(r => !r.Equals(symbol)).ToImmutableArray(); return new SearchResult(locations.ToImmutable(), implicitLocations, referencedSymbols); } @@ -230,7 +226,7 @@ await referencedSymbol.Locations.SelectManyAsync filter) => new RenameLocations( this.Locations.Where(loc => filter(loc.Location)).ToImmutableHashSet(), - this.SymbolAndProjectId, this.Solution, + this.Symbol, this.Solution, this.ReferencedSymbols, this.ImplicitLocations.WhereAsArray(loc => filter(loc.Location)), this.Options); } diff --git a/src/Workspaces/Core/Portable/Rename/Renamer.cs b/src/Workspaces/Core/Portable/Rename/Renamer.cs index 1be67f8779b56..5f4864004dcd9 100644 --- a/src/Workspaces/Core/Portable/Rename/Renamer.cs +++ b/src/Workspaces/Core/Portable/Rename/Renamer.cs @@ -6,7 +6,6 @@ using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Rename.ConflictEngine; @@ -17,36 +16,27 @@ public static class Renamer public static Task RenameSymbolAsync( Solution solution, ISymbol symbol, string newName, OptionSet optionSet, CancellationToken cancellationToken = default) { - return RenameSymbolAsync( - solution, - SymbolAndProjectId.Create(symbol, projectId: null), - newName, optionSet, cancellationToken); - } - - internal static Task RenameSymbolAsync( - Solution solution, SymbolAndProjectId symbolAndProjectId, string newName, OptionSet optionSet, CancellationToken cancellationToken = default) - { - return RenameSymbolAsync(solution, symbolAndProjectId, newName, optionSet, nonConflictSymbols: null, cancellationToken); + return RenameSymbolAsync(solution, symbol, newName, optionSet, nonConflictSymbols: null, cancellationToken); } internal static Task GetRenameLocationsAsync( - Solution solution, SymbolAndProjectId symbolAndProjectId, OptionSet options, CancellationToken cancellationToken) + Solution solution, ISymbol symbol, OptionSet options, CancellationToken cancellationToken) { if (solution == null) { throw new ArgumentNullException(nameof(solution)); } - if (symbolAndProjectId.Symbol == null) + if (symbol == null) { - throw new ArgumentNullException(nameof(symbolAndProjectId)); + throw new ArgumentNullException(nameof(symbol)); } cancellationToken.ThrowIfCancellationRequested(); options ??= solution.Options; return RenameLocations.FindAsync( - symbolAndProjectId, solution, options, cancellationToken); + symbol, solution, options, cancellationToken); } internal static async Task RenameAsync( @@ -68,22 +58,22 @@ internal static async Task RenameAsync( internal static async Task RenameSymbolAsync( Solution solution, - SymbolAndProjectId symbolAndProjectId, + ISymbol symbol, string newName, OptionSet options, - ImmutableHashSet nonConflictSymbols = null, - CancellationToken cancellationToken = default) + ImmutableHashSet nonConflictSymbols, + CancellationToken cancellationToken) { if (solution == null) throw new ArgumentNullException(nameof(solution)); - if (symbolAndProjectId.Symbol == null) - throw new ArgumentNullException(nameof(symbolAndProjectId)); + if (symbol == null) + throw new ArgumentNullException(nameof(symbol)); cancellationToken.ThrowIfCancellationRequested(); options ??= solution.Workspace.Options; - var renameLocations = await GetRenameLocationsAsync(solution, symbolAndProjectId, options, cancellationToken).ConfigureAwait(false); + var renameLocations = await GetRenameLocationsAsync(solution, symbol, options, cancellationToken).ConfigureAwait(false); return await RenameAsync(renameLocations, newName, nonConflictSymbols, cancellationToken).ConfigureAwait(false); } } diff --git a/src/Workspaces/Core/Portable/Shared/Extensions/IFindReferencesResultExtensions.cs b/src/Workspaces/Core/Portable/Shared/Extensions/IFindReferencesResultExtensions.cs index ead720fe90cd6..123dfe1b9daf7 100644 --- a/src/Workspaces/Core/Portable/Shared/Extensions/IFindReferencesResultExtensions.cs +++ b/src/Workspaces/Core/Portable/Shared/Extensions/IFindReferencesResultExtensions.cs @@ -100,7 +100,7 @@ public static IEnumerable FilterToAliasMatches( return from r in result let aliasLocations = r.Locations.Where(loc => SymbolEquivalenceComparer.Instance.Equals(loc.Alias, aliasSymbol)) where aliasLocations.Any() - select new ReferencedSymbol(r.DefinitionAndProjectId, aliasLocations); + select new ReferencedSymbol(r.Definition, aliasLocations); } public static IEnumerable FilterNonMatchingMethodNames( diff --git a/src/Workspaces/Core/Portable/Shared/Extensions/ITypeSymbolExtensions.cs b/src/Workspaces/Core/Portable/Shared/Extensions/ITypeSymbolExtensions.cs index 58c85667a5794..92d89f5e23aaa 100644 --- a/src/Workspaces/Core/Portable/Shared/Extensions/ITypeSymbolExtensions.cs +++ b/src/Workspaces/Core/Portable/Shared/Extensions/ITypeSymbolExtensions.cs @@ -28,9 +28,9 @@ internal static partial class ITypeSymbolExtensions /// interfaceMember, or this type doesn't supply a member that successfully implements /// interfaceMember). /// - public static async Task> FindImplementationsForInterfaceMemberAsync( - this SymbolAndProjectId typeSymbolAndProjectId, - SymbolAndProjectId interfaceMemberAndProjectId, + public static async Task> FindImplementationsForInterfaceMemberAsync( + this ITypeSymbol typeSymbol, + ISymbol interfaceMember, Solution solution, CancellationToken cancellationToken) { @@ -43,12 +43,10 @@ public static async Task> FindImplementations // If you're looking for the implementations of IGoo.Goo then you want to find both // results in C. - var arrBuilder = ArrayBuilder.GetInstance(); - var interfaceMember = interfaceMemberAndProjectId.Symbol; + var arrBuilder = ArrayBuilder.GetInstance(); // TODO(cyrusn): Implement this using the actual code for // TypeSymbol.FindImplementationForInterfaceMember - var typeSymbol = typeSymbolAndProjectId.Symbol; if (typeSymbol == null || interfaceMember == null) { return arrBuilder.ToImmutableAndFree(); @@ -102,8 +100,8 @@ public static async Task> FindImplementations // OriginalSymbolMatch allows types to be matched across different assemblies // if they are considered to be the same type, which provides a more accurate // implementations list for interfaces. - var typeSymbolProject = solution.GetProject(typeSymbolAndProjectId.ProjectId); - var interfaceMemberProject = solution.GetProject(interfaceMemberAndProjectId.ProjectId); + var typeSymbolProject = solution.GetOriginatingProject(typeSymbol); + var interfaceMemberProject = solution.GetOriginatingProject(interfaceMember); var typeSymbolCompilation = await GetCompilationOrNullAsync(typeSymbolProject, cancellationToken).ConfigureAwait(false); var interfaceMemberCompilation = await GetCompilationOrNullAsync(interfaceMemberProject, cancellationToken).ConfigureAwait(false); @@ -139,7 +137,7 @@ public static async Task> FindImplementations if (result != null) { - arrBuilder.Add(typeSymbolAndProjectId.WithSymbol(result)); + arrBuilder.Add(result); break; } } diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/Solution.cs b/src/Workspaces/Core/Portable/Workspace/Solution/Solution.cs index 219a199485557..e52fda9850e90 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/Solution.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/Solution.cs @@ -146,8 +146,12 @@ private static Project CreateProject(ProjectId projectId, Solution solution) /// features this is an acceptable abstraction. However, for some cases (Find-References in particular) it is /// necessary to resolve symbols back to the actual project/compilation that produced them for correctness. /// - internal ProjectId? GetExactProjectId(ISymbol symbol) - => _state.GetExactProjectId(symbol); + internal ProjectId? GetOriginatingProjectId(ISymbol symbol) + => _state.GetOriginatingProjectId(symbol); + + /// + internal Project? GetOriginatingProject(ISymbol symbol) + => GetProject(GetOriginatingProjectId(symbol)); /// /// True if the solution contains the document in one of its projects diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.SymbolToProjectId.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.SymbolToProjectId.cs index c0f9834ef284f..403d2cfbbf909 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.SymbolToProjectId.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.SymbolToProjectId.cs @@ -12,8 +12,8 @@ namespace Microsoft.CodeAnalysis { internal partial class SolutionState { - /// - public ProjectId? GetExactProjectId(ISymbol? symbol) + /// + public ProjectId? GetOriginatingProjectId(ISymbol? symbol) { LazyInitialization.EnsureInitialized(ref _assemblyOrModuleSymbolToProjectId, s_createTable); @@ -42,7 +42,7 @@ internal partial class SolutionState // A namespace that spans a compilation. These don't belong to an assembly/module directly. // However, as we're looking for the project this corresponds to, we can look for the // source-module component (the first in the constituent namespaces) and then search using that. - return GetExactProjectId(ns.ConstituentNamespaces[0]); + return GetOriginatingProjectId(ns.ConstituentNamespaces[0]); } } else if (symbol.IsKind(SymbolKind.Assembly) || diff --git a/src/Workspaces/CoreTest/DependentTypeFinderTests.cs b/src/Workspaces/CoreTest/DependentTypeFinderTests.cs index 7f7a62f26bf83..dcf1cdafc5893 100644 --- a/src/Workspaces/CoreTest/DependentTypeFinderTests.cs +++ b/src/Workspaces/CoreTest/DependentTypeFinderTests.cs @@ -50,9 +50,9 @@ public class DerivedClass : BaseClass { } // verify that the dependent types of `N.BaseClass` correctly resolve to `M.DerivedCLass` var derivedFromBase = await DependentTypeFinder.FindImmediatelyDerivedClassesAsync( - SymbolAndProjectId.Create(baseClassSymbol, portableProject.Id), solution, CancellationToken.None); + baseClassSymbol, solution, CancellationToken.None); var derivedDependentType = derivedFromBase.Single(); - Assert.Equal(derivedClassSymbol, derivedDependentType.Symbol); + Assert.Equal(derivedClassSymbol, derivedDependentType); } private static Project GetPortableProject(Solution solution) @@ -100,9 +100,9 @@ public class DerivedClass : Alias2 { } // verify that the dependent types of `N.BaseClass` correctly resolve to `M.DerivedCLass` var derivedFromBase = await DependentTypeFinder.FindImmediatelyDerivedClassesAsync( - SymbolAndProjectId.Create(baseClassSymbol, portableProject.Id), solution, CancellationToken.None); + baseClassSymbol, solution, CancellationToken.None); var derivedDependentType = derivedFromBase.Single(); - Assert.Equal(derivedClassSymbol, derivedDependentType.Symbol); + Assert.Equal(derivedClassSymbol, derivedDependentType); } [WorkItem(4973, "https://github.com/dotnet/roslyn/issues/4973")] @@ -142,9 +142,9 @@ public class DerivedClass : BaseClass { } // verify that the dependent types of `N.BaseClass` correctly resolve to `M.DerivedCLass` var derivedFromBase = await DependentTypeFinder.FindImmediatelyDerivedClassesAsync( - SymbolAndProjectId.Create(baseClassSymbol, portableProject.Id), solution, CancellationToken.None); + baseClassSymbol, solution, CancellationToken.None); var derivedDependentType = derivedFromBase.Single(); - Assert.Equal(derivedClassSymbol, derivedDependentType.Symbol); + Assert.Equal(derivedClassSymbol, derivedDependentType); } [WorkItem(4973, "https://github.com/dotnet/roslyn/issues/4973")] @@ -185,9 +185,9 @@ End Namespace // verify that the dependent types of `N.BaseClass` correctly resolve to `M.DerivedCLass` var derivedFromBase = await DependentTypeFinder.FindImmediatelyDerivedClassesAsync( - SymbolAndProjectId.Create(baseClassSymbol, portableProject.Id), solution, CancellationToken.None); + baseClassSymbol, solution, CancellationToken.None); var derivedDependentType = derivedFromBase.Single(); - Assert.Equal(derivedClassSymbol, derivedDependentType.Symbol); + Assert.Equal(derivedClassSymbol, derivedDependentType); } [WorkItem(4973, "https://github.com/dotnet/roslyn/issues/4973")] @@ -228,9 +228,9 @@ End Namespace // verify that the dependent types of `N.BaseClass` correctly resolve to `M.DerivedCLass` var derivedFromBase = await DependentTypeFinder.FindImmediatelyDerivedClassesAsync( - SymbolAndProjectId.Create(baseClassSymbol, portableProject.Id), solution, CancellationToken.None); + baseClassSymbol, solution, CancellationToken.None); var derivedDependentType = derivedFromBase.Single(); - Assert.Equal(derivedClassSymbol, derivedDependentType.Symbol); + Assert.Equal(derivedClassSymbol, derivedDependentType); } [WorkItem(4973, "https://github.com/dotnet/roslyn/issues/4973")] @@ -270,8 +270,8 @@ public class ImplementingClass : IBaseInterface { } // verify that the implementing types of `N.IBaseInterface` correctly resolve to `M.ImplementingClass` var typesThatImplementInterface = await DependentTypeFinder.FindImmediatelyDerivedAndImplementingTypesAsync( - SymbolAndProjectId.Create(baseInterfaceSymbol, portableProject.Id), solution, CancellationToken.None); - Assert.Equal(implementingClassSymbol, typesThatImplementInterface.Single().Symbol); + baseInterfaceSymbol, solution, CancellationToken.None); + Assert.Equal(implementingClassSymbol, typesThatImplementInterface.Single()); } [WorkItem(4973, "https://github.com/dotnet/roslyn/issues/4973")] @@ -312,8 +312,8 @@ End Namespace // verify that the implementing types of `N.IBaseInterface` correctly resolve to `M.ImplementingClass` var typesThatImplementInterface = await DependentTypeFinder.FindImmediatelyDerivedAndImplementingTypesAsync( - SymbolAndProjectId.Create(baseInterfaceSymbol, portableProject.Id), solution, CancellationToken.None); - Assert.Equal(implementingClassSymbol, typesThatImplementInterface.Single().Symbol); + baseInterfaceSymbol, solution, CancellationToken.None); + Assert.Equal(implementingClassSymbol, typesThatImplementInterface.Single()); } [WorkItem(4973, "https://github.com/dotnet/roslyn/issues/4973")] @@ -353,8 +353,8 @@ public class ImplementingClass : IBaseInterface { } // verify that the implementing types of `N.IBaseInterface` correctly resolve to `M.ImplementingClass` var typesThatImplementInterface = await DependentTypeFinder.FindImmediatelyDerivedAndImplementingTypesAsync( - SymbolAndProjectId.Create(baseInterfaceSymbol, portableProject.Id), solution, CancellationToken.None); - Assert.Equal(implementingClassSymbol, typesThatImplementInterface.Single().Symbol); + baseInterfaceSymbol, solution, CancellationToken.None); + Assert.Equal(implementingClassSymbol, typesThatImplementInterface.Single()); } } } diff --git a/src/Workspaces/CoreTest/FindReferencesTests.cs b/src/Workspaces/CoreTest/FindReferencesTests.cs index 35e38433f2b25..a0261269c34ac 100644 --- a/src/Workspaces/CoreTest/FindReferencesTests.cs +++ b/src/Workspaces/CoreTest/FindReferencesTests.cs @@ -322,7 +322,12 @@ public System.Uri Get() var references = (await SymbolFinder.FindReferencesAsync(interfaceMethod, solution)).ToList(); Assert.Equal(2, references.Count); - Assert.True(references.Any(r => r.DefinitionAndProjectId.ProjectId == desktopProject.Id)); + + var projectIds = new HashSet(); + foreach (var r in references) + projectIds.Add(solution.GetOriginatingProjectId(r.Definition)); + + Assert.True(projectIds.Contains(desktopProject.Id)); } [Fact, WorkItem(35786, "https://github.com/dotnet/roslyn/issues/35786")] diff --git a/src/Workspaces/CoreTest/ReferencedSymbolTests.cs b/src/Workspaces/CoreTest/ReferencedSymbolTests.cs index d4bb2bf88a20b..fff048a858d53 100644 --- a/src/Workspaces/CoreTest/ReferencedSymbolTests.cs +++ b/src/Workspaces/CoreTest/ReferencedSymbolTests.cs @@ -51,8 +51,7 @@ private static ReferencedSymbol CreateReferencedSymbol( locations.Add(new ReferenceLocation()); } - var referencedSymbol = new ReferencedSymbol( - SymbolAndProjectId.Create(symbol, projectId: null), locations); + var referencedSymbol = new ReferencedSymbol(symbol, locations); return referencedSymbol; } diff --git a/src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_SymbolFinder.cs b/src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_SymbolFinder.cs index 07b3fdb8debf5..4bfc59e094bce 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_SymbolFinder.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_SymbolFinder.cs @@ -31,12 +31,12 @@ public Task FindReferencesAsync( { var solution = await GetSolutionAsync(solutionInfo, cancellationToken).ConfigureAwait(false); - var symbolAndProjectId = await symbolAndProjectIdArg.TryRehydrateAsync( + var symbol = await symbolAndProjectIdArg.TryRehydrateAsync( solution, cancellationToken).ConfigureAwait(false); var progressCallback = new FindReferencesProgressCallback(solution, EndPoint, cancellationToken); - if (!symbolAndProjectId.HasValue) + if (symbol == null) { await progressCallback.OnStartedAsync().ConfigureAwait(false); await progressCallback.OnCompletedAsync().ConfigureAwait(false); @@ -52,7 +52,7 @@ public Task FindReferencesAsync( .ToImmutableHashSet(); await SymbolFinder.FindReferencesInCurrentProcessAsync( - symbolAndProjectId.Value, solution, progressCallback, + symbol, solution, progressCallback, documents, options.Rehydrate(), cancellationToken).ConfigureAwait(false); } }, cancellationToken); @@ -74,12 +74,12 @@ await SymbolFinder.FindLiteralReferencesInCurrentProcessAsync( }, cancellationToken); } - private ImmutableArray Convert(ImmutableArray items, Solution solution, CancellationToken cancellationToken) + private ImmutableArray Convert(ImmutableArray items, Solution solution, CancellationToken cancellationToken) { using var _ = ArrayBuilder.GetInstance(out var result); foreach (var item in items) - result.Add(SerializableSymbolAndProjectId.Dehydrate(solution, item.Symbol, cancellationToken)); + result.Add(SerializableSymbolAndProjectId.Dehydrate(solution, item, cancellationToken)); return result.ToImmutable(); } @@ -239,17 +239,17 @@ public Task OnFindInDocumentStartedAsync(Document document) public Task OnFindInDocumentCompletedAsync(Document document) => _endPoint.InvokeAsync(nameof(SymbolFinder.FindReferencesServerCallback.OnFindInDocumentCompletedAsync), new object[] { document.Id }, _cancellationToken); - public Task OnDefinitionFoundAsync(SymbolAndProjectId definition) + public Task OnDefinitionFoundAsync(ISymbol definition) => _endPoint.InvokeAsync( nameof(SymbolFinder.FindReferencesServerCallback.OnDefinitionFoundAsync), - new object[] { SerializableSymbolAndProjectId.Dehydrate(_solution, definition.Symbol, _cancellationToken) }, _cancellationToken); + new object[] { SerializableSymbolAndProjectId.Dehydrate(_solution, definition, _cancellationToken) }, _cancellationToken); - public Task OnReferenceFoundAsync(SymbolAndProjectId definition, ReferenceLocation reference) + public Task OnReferenceFoundAsync(ISymbol definition, ReferenceLocation reference) => _endPoint.InvokeAsync( nameof(SymbolFinder.FindReferencesServerCallback.OnReferenceFoundAsync), new object[] { - SerializableSymbolAndProjectId.Dehydrate(_solution, definition.Symbol, _cancellationToken), + SerializableSymbolAndProjectId.Dehydrate(_solution, definition, _cancellationToken), SerializableReferenceLocation.Dehydrate(reference, _cancellationToken), }, _cancellationToken); diff --git a/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicReferenceFinder.vb b/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicReferenceFinder.vb index fc7b565605c64..8ac1d1115e28a 100644 --- a/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicReferenceFinder.vb +++ b/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicReferenceFinder.vb @@ -19,42 +19,37 @@ Namespace Microsoft.CodeAnalysis.FindSymbols Public Sub New() End Sub - Public Function DetermineCascadedSymbolsAsync(symbolAndProjectId As SymbolAndProjectId, + Public Function DetermineCascadedSymbolsAsync(symbol As ISymbol, project As Project, - cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of SymbolAndProjectId)) Implements ILanguageServiceReferenceFinder.DetermineCascadedSymbolsAsync - Dim symbol = symbolAndProjectId.Symbol + cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of ISymbol)) Implements ILanguageServiceReferenceFinder.DetermineCascadedSymbolsAsync If symbol.Kind = SymbolKind.Property Then Return DetermineCascadedSymbolsAsync( - symbolAndProjectId.WithSymbol(DirectCast(symbol, IPropertySymbol)), - project, cancellationToken) + DirectCast(symbol, IPropertySymbol), project, cancellationToken) ElseIf symbol.Kind = SymbolKind.NamedType Then Return DetermineCascadedSymbolsAsync( - symbolAndProjectId.WithSymbol(DirectCast(symbol, INamedTypeSymbol)), - project, cancellationToken) + DirectCast(symbol, INamedTypeSymbol), project, cancellationToken) Else - Return Task.FromResult(ImmutableArray(Of SymbolAndProjectId).Empty) + Return Task.FromResult(ImmutableArray(Of ISymbol).Empty) End If End Function Private Async Function DetermineCascadedSymbolsAsync( - [propertyAndProjectId] As SymbolAndProjectId(Of IPropertySymbol), + [property] As IPropertySymbol, project As Project, - cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of SymbolAndProjectId)) + cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of ISymbol)) - Dim [property] = propertyAndProjectId.Symbol Dim compilation = Await project.GetCompilationAsync(cancellationToken).ConfigureAwait(False) Dim relatedSymbol = [property].FindRelatedExplicitlyDeclaredSymbol(compilation) Return If([property].Equals(relatedSymbol), - ImmutableArray(Of SymbolAndProjectId).Empty, - ImmutableArray.Create( - SymbolAndProjectId.Create(relatedSymbol, project.Id))) + ImmutableArray(Of ISymbol).Empty, + ImmutableArray.Create(relatedSymbol)) End Function Private Async Function DetermineCascadedSymbolsAsync( - namedType As SymbolAndProjectId(Of INamedTypeSymbol), + namedType As INamedTypeSymbol, project As Project, - cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of SymbolAndProjectId)) + cancellationToken As CancellationToken) As Task(Of ImmutableArray(Of ISymbol)) Dim compilation = Await project.GetCompilationAsync(cancellationToken).ConfigureAwait(False) @@ -66,17 +61,17 @@ Namespace Microsoft.CodeAnalysis.FindSymbols End Function Private Function GetMatchingMyPropertySymbols( - namedType As SymbolAndProjectId(Of INamedTypeSymbol), + namedType As INamedTypeSymbol, projectId As ProjectId, compilation As Compilation, - cancellationToken As CancellationToken) As IEnumerable(Of SymbolAndProjectId) + cancellationToken As CancellationToken) As IEnumerable(Of ISymbol) Return From childNamespace In compilation.RootNamespace.GetNamespaceMembers() Where childNamespace.IsMyNamespace(compilation) From type In childNamespace.GetAllTypes(cancellationToken) Where type.Name = "MyForms" From childProperty In type.GetMembers().OfType(Of IPropertySymbol) - Where childProperty.IsImplicitlyDeclared AndAlso childProperty.Type.Equals(namedType.Symbol) - Select SymbolAndProjectId.Create(DirectCast(childProperty, ISymbol), projectId) + Where childProperty.IsImplicitlyDeclared AndAlso childProperty.Type.Equals(namedType) + Select DirectCast(childProperty, ISymbol) End Function End Class End Namespace diff --git a/src/Workspaces/VisualBasic/Portable/Rename/VisualBasicRenameRewriterLanguageService.vb b/src/Workspaces/VisualBasic/Portable/Rename/VisualBasicRenameRewriterLanguageService.vb index dc6896e0a2de7..da901d1f5ace7 100644 --- a/src/Workspaces/VisualBasic/Portable/Rename/VisualBasicRenameRewriterLanguageService.vb +++ b/src/Workspaces/VisualBasic/Portable/Rename/VisualBasicRenameRewriterLanguageService.vb @@ -667,7 +667,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Rename replacementText As String, renamedSymbol As ISymbol, renameSymbol As ISymbol, - referencedSymbols As IEnumerable(Of SymbolAndProjectId), + referencedSymbols As IEnumerable(Of ISymbol), baseSolution As Solution, newSolution As Solution, reverseMappedLocations As IDictionary(Of Location, Location), @@ -747,7 +747,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Rename DeclarationConflictHelpers.GetMembersWithConflictingSignatures(DirectCast(renamedSymbol, IPropertySymbol), trimOptionalParameters:=True) _ .Select(Function(loc) reverseMappedLocations(loc))) AddConflictingParametersOfProperties( - referencedSymbols.Select(Function(s) s.Symbol).Concat(renameSymbol).Where(Function(sym) sym.Kind = SymbolKind.Property), + referencedSymbols.Concat(renameSymbol).Where(Function(sym) sym.Kind = SymbolKind.Property), renamedSymbol.Name, conflicts)