public async Task FindImplementationsAsync(Document document, int position, IFindUsagesContext context)
        {
            var tuple = await FindUsagesHelpers.FindImplementationsAsync(
                document, position, context.CancellationToken).ConfigureAwait(false);
            if (tuple == null)
            {
                context.ReportMessage(EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret);
                return;
            }

            var message = tuple.Value.message;

            if (message != null)
            {
                context.ReportMessage(message);
                return;
            }

            context.SetSearchTitle(string.Format(EditorFeaturesResources._0_implementations,
                FindUsagesHelpers.GetDisplayName(tuple.Value.symbol)));

            var project = tuple.Value.project;
            foreach (var implementation in tuple.Value.implementations)
            {
                var definitionItem = implementation.ToDefinitionItem(
                    project.Solution, includeHiddenLocations: false);
                await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false);
            }
        }
Example #2
0
        private static async Task InspectInterfaceAsync(
            IFindUsagesContext context,
            INamedTypeSymbol interfaceSymbol,
            INamedTypeSymbol namedTypeSymbol,
            Project project
            )
        {
            foreach (var interfaceMember in interfaceSymbol.GetMembers())
            {
                if (context.CancellationToken.IsCancellationRequested)
                {
                    return;
                }

                var impl = namedTypeSymbol.FindImplementationForInterfaceMember(interfaceMember);
                if (impl == null)
                {
                    continue;
                }

                var definitionItem = impl.ToNonClassifiedDefinitionItem(project.Solution, true);
#pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task
                await context.OnDefinitionFoundAsync(definitionItem);

#pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task
            }
        }
Example #3
0
        public async Task FindBasesAsync(Document document, int position, IFindUsagesContext context)
        {
            var cancellationToken   = context.CancellationToken;
            var symbolAndProjectOpt = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(
                document, position, cancellationToken).ConfigureAwait(false);

            if (symbolAndProjectOpt == null)
            {
                await context.ReportMessageAsync(
                    EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret).ConfigureAwait(false);

                return;
            }

            var(symbol, project) = symbolAndProjectOpt.Value;

            var bases = FindBaseHelpers.FindBases(
                symbol, project, cancellationToken);

            await context.SetSearchTitleAsync(
                string.Format(EditorFeaturesResources._0_bases,
                              FindUsagesHelpers.GetDisplayName(symbol))).ConfigureAwait(false);

            var found = false;

            // For each potential base, try to find its definition in sources.
            // If found, add it's definitionItem to the context.
            // If not found but the symbol is from metadata, create it's definition item from metadata and add to the context.
            foreach (var baseSymbol in bases)
            {
                var sourceDefinition = await SymbolFinder.FindSourceDefinitionAsync(
                    SymbolAndProjectId.Create(baseSymbol, project.Id), project.Solution, cancellationToken).ConfigureAwait(false);

                if (sourceDefinition.Symbol != null)
                {
                    var definitionItem = await sourceDefinition.Symbol.ToClassifiedDefinitionItemAsync(
                        project.Solution.GetProject(sourceDefinition.ProjectId), 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);
                    await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false);

                    found = true;
                }
            }

            if (!found)
            {
                await context.ReportMessageAsync(EditorFeaturesResources.The_symbol_has_no_base)
                .ConfigureAwait(false);
            }
        }
        public static async Task FindImplementationsAsync(
            ISymbol symbol, Project project, IFindUsagesContext context)
        {
            var cancellationToken = context.CancellationToken;
            var solution          = project.Solution;
            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 FindUsagesServerCallback(solution, context);

                var success = await client.TryRunRemoteAsync(
                    WellKnownServiceHubServices.CodeAnalysisService,
                    nameof(IRemoteFindUsagesService.FindImplementationsAsync),
                    solution,
                    new object[]
                {
                    SerializableSymbolAndProjectId.Create(symbol, project, cancellationToken),
                },
                    serverCallback,
                    cancellationToken).ConfigureAwait(false);

                if (success)
                {
                    return;
                }
            }

            // Couldn't effectively search in OOP. Perform the search in-process.
            await FindImplementationsInCurrentProcessAsync(
                symbol, project, context).ConfigureAwait(false);
        }
Example #5
0
 public FindReferencesProgressAdapter(
     Solution solution, IFindUsagesContext context, FindReferencesSearchOptions options)
 {
     _solution = solution;
     _context  = context;
     _options  = options;
 }
        private async Task<ProgressAdapter> FindReferencesWorkerAsync(
            Document document, int position, IFindUsagesContext context)
        {
            var cancellationToken = context.CancellationToken;
            cancellationToken.ThrowIfCancellationRequested();

            // Find the symbol we want to search and the solution we want to search in.
            var symbolAndProject = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(
                document, position, cancellationToken).ConfigureAwait(false);
            if (symbolAndProject == null)
            {
                return null;
            }

            var symbol = symbolAndProject?.symbol;
            var project = symbolAndProject?.project;

            context.SetSearchTitle(string.Format(EditorFeaturesResources._0_references,
                FindUsagesHelpers.GetDisplayName(symbol)));

            var progressAdapter = new ProgressAdapter(project.Solution, context);

            // Now call into the underlying FAR engine to find reference.  The FAR
            // 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.
            await SymbolFinder.FindReferencesAsync(
                SymbolAndProjectId.Create(symbol, project.Id),
                project.Solution,
                progressAdapter,
                documents: null,
                cancellationToken: cancellationToken).ConfigureAwait(false);

            return progressAdapter;
        }
Example #7
0
        async Task IFindUsagesService.FindReferencesAsync(
            Document document, int position, IFindUsagesContext context)
        {
            var definitionTrackingContext = new DefinitionTrackingContext(context);

            // Need ConfigureAwait(true) here so we get back to the UI thread before calling
            // GetThirdPartyDefinitions.  We need to call that on the UI thread to match behavior
            // of how the language service always worked in the past.
            //
            // Any async calls before GetThirdPartyDefinitions must be ConfigureAwait(true).
            await FindLiteralOrSymbolReferencesAsync(
                document, position, definitionTrackingContext).ConfigureAwait(true);

            // After the FAR engine is done call into any third party extensions to see
            // if they want to add results.
            var thirdPartyDefinitions = GetThirdPartyDefinitions(
                document.Project.Solution, definitionTrackingContext.GetDefinitions(), context.CancellationToken);

            // From this point on we can do ConfigureAwait(false) as we're not calling back
            // into third parties anymore.

            foreach (var definition in thirdPartyDefinitions)
            {
                // Don't need ConfigureAwait(true) here
                await context.OnDefinitionFoundAsync(definition).ConfigureAwait(false);
            }
        }
        public async Task FindImplementationsAsync(Document document, int position, IFindUsagesContext context)
        {
            var tuple = await FindUsagesHelpers.FindImplementationsAsync(
                document, position, context.CancellationToken).ConfigureAwait(false);

            if (tuple == null)
            {
                context.ReportMessage(EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret);
                return;
            }

            var message = tuple.Value.message;

            if (message != null)
            {
                context.ReportMessage(message);
                return;
            }

            var project = tuple.Value.project;

            foreach (var implementation in tuple.Value.implementations)
            {
                var definitionItem = implementation.ToDefinitionItem(
                    project.Solution, includeHiddenLocations: false);
                await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false);
            }
        }
Example #9
0
        public static async Task FindImplementationsAsync(
            ISymbol symbol, Project project, IFindUsagesContext context)
        {
            var cancellationToken = context.CancellationToken;
            var solution          = project.Solution;
            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 FindUsagesServerCallback(solution, context);
                var symbolAndProjectId = SerializableSymbolAndProjectId.Create(symbol, project, cancellationToken);

                await client.TryInvokeAsync <IRemoteFindUsagesService>(
                    solution,
                    (service, solutionInfo, cancellationToken) => service.FindImplementationsAsync(solutionInfo, symbolAndProjectId, cancellationToken),
                    serverCallback,
                    cancellationToken).ConfigureAwait(false);
            }
            else
            {
                // Couldn't effectively search in OOP. Perform the search in-process.
                await FindImplementationsInCurrentProcessAsync(
                    symbol, project, context).ConfigureAwait(false);
            }
        }
 public FindLiteralsProgressAdapter(
     IFindUsagesContext context, DefinitionItem definition, ClassificationOptions classificationOptions)
 {
     _context               = context;
     _definition            = definition;
     _classificationOptions = classificationOptions;
 }
        public async Task FindImplementationsAsync(
            Document document,
            int position,
            IFindUsagesContext context
            )
        {
            var cancellationToken = context.CancellationToken;

            // If this is a symbol from a metadata-as-source project, then map that symbol back to a symbol in the primary workspace.
            var symbolAndProjectOpt = await FindUsagesHelpers
                                      .GetRelevantSymbolAndProjectAtPositionAsync(document, position, cancellationToken)
                                      .ConfigureAwait(false);

            if (symbolAndProjectOpt == null)
            {
                await context
                .ReportMessageAsync(
                    EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret
                    )
                .ConfigureAwait(false);

                return;
            }

            var symbolAndProject = symbolAndProjectOpt.Value;

            await FindImplementationsAsync(
                symbolAndProject.symbol,
                symbolAndProject.project,
                context
                )
            .ConfigureAwait(false);
        }
Example #12
0
        public async Task FindReferencesAsync(
            Document document, int position, IFindUsagesContext context)
        {
            // NOTE: All ConFigureAwaits in this method need to pass 'true' so that
            // we return to the caller's context.  that's so the call to
            // CallThirdPartyExtensionsAsync will happen on the UI thread.  We need
            // this to maintain the threading guarantee we had around that method
            // from pre-Roslyn days.
            var cancellationToken = context.CancellationToken;

            cancellationToken.ThrowIfCancellationRequested();

            // First, see if we're on a literal.  If so search for literals in the solution with
            // the same value.
            var found = await TryFindLiteralReferencesAsync(document, position, context).ConfigureAwait(true);

            if (found)
            {
                return;
            }

            var findReferencesProgress = await FindSymbolReferencesAsync(
                document, position, context).ConfigureAwait(true);

            if (findReferencesProgress == null)
            {
                return;
            }

            // After the FAR engine is done call into any third party extensions to see
            // if they want to add results.
            await findReferencesProgress.CallThirdPartyExtensionsAsync(
                context.CancellationToken).ConfigureAwait(true);
        }
Example #13
0
        private static async Task FindImplementationsInCurrentProcessAsync(
            ISymbol symbol, Project project, IFindUsagesContext context)
        {
            var cancellationToken = context.CancellationToken;

            var solution = project.Solution;

            var(implementations, message) = await FindSourceImplementationsAsync(
                solution, symbol, cancellationToken).ConfigureAwait(false);

            if (message != null)
            {
                await context.ReportMessageAsync(message).ConfigureAwait(false);

                return;
            }

            await context.SetSearchTitleAsync(
                string.Format(EditorFeaturesResources._0_implementations,
                              FindUsagesHelpers.GetDisplayName(symbol))).ConfigureAwait(false);

            foreach (var implementation in implementations)
            {
                var definitionItem = await implementation.ToClassifiedDefinitionItemAsync(
                    solution, isPrimary : true, includeHiddenLocations : false, FindReferencesSearchOptions.Default, cancellationToken).ConfigureAwait(false);

                await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false);
            }
        }
 public FindLiteralsProgressAdapter(
     IFindUsagesContext context,
     DefinitionItem definition
     )
 {
     _context    = context;
     _definition = definition;
 }
Example #15
0
 public Task FindReferencesAsync(Document document, int position, IFindUsagesContext context)
 {
     return(_service.FindReferencesAsync(
                document,
                position,
                new FSharpFindUsagesContext(context)
                ));
 }
Example #16
0
 Task IFindUsagesLSPService.FindReferencesAsync(
     Document document, int position, IFindUsagesContext context)
 {
     // We don't need to get third party definitions when finding references in LSP.
     // Currently, 3rd party definitions = XAML definitions, and XAML will provide
     // references via LSP instead of hooking into Roslyn.
     // This also means that we don't need to be on the UI thread.
     return(FindLiteralOrSymbolReferencesAsync(document, position, new DefinitionTrackingContext(context)));
 }
 public FindReferencesProgressAdapter(
     IThreadingContext threadingContext, Solution solution,
     IFindUsagesContext context, FindReferencesSearchOptions options)
     : base(threadingContext)
 {
     _solution = solution;
     _context  = context;
     _options  = options;
 }
Example #18
0
        private static Task FindReferencesInCurrentProcessAsync(
            IFindUsagesContext context,
            ISymbol symbol,
            Project project,
            FindReferencesSearchOptions options)
        {
            var progress = new FindReferencesProgressAdapter(project.Solution, context, options);

            return(SymbolFinder.FindReferencesAsync(
                       symbol, project.Solution, progress, documents: null, options, context.CancellationToken));
        }
        /// <summary>
        /// Public helper that we use from features like ObjectBrowser which start with a symbol
        /// and want to push all the references to it into the Streaming-Find-References window.
        /// </summary>
        public static async Task FindSymbolReferencesAsync(
            IFindUsagesContext context, ISymbol symbol, Project project)
        {
            await context.SetSearchTitleAsync(string.Format(EditorFeaturesResources._0_references,
                                                            FindUsagesHelpers.GetDisplayName(symbol))).ConfigureAwait(false);

            var options = FindReferencesSearchOptions.GetFeatureOptionsForStartingSymbol(symbol);

            // Now call into the underlying FAR engine to find reference.  The FAR
            // 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.
            await FindReferencesAsync(context, symbol, project, options).ConfigureAwait(false);
        }
Example #20
0
        public async Task FindReferencesAsync(Document document, int position, IFindUsagesContext context)
        {
            var text = await document.GetTextAsync().ConfigureAwait(false);

            var lspClient = _roslynLspClientServiceFactory.ActiveLanguageServerClient;

            if (lspClient == null)
            {
                return;
            }

            var referenceParams = new LSP.ReferenceParams
            {
                Context = new LSP.ReferenceContext {
                    IncludeDeclaration = false
                },
                TextDocument = ProtocolConversions.DocumentToTextDocumentIdentifier(document),
                Position     = ProtocolConversions.LinePositionToPosition(text.Lines.GetLinePosition(position))
            };

            var locations = await lspClient.RequestAsync(LSP.Methods.TextDocumentReferences, referenceParams, context.CancellationToken).ConfigureAwait(false);

            if (locations == null)
            {
                return;
            }

            // TODO: Need to get real definition data from the server.
            var dummyDef = DefinitionItem.CreateNonNavigableItem(ImmutableArray <string> .Empty, ImmutableArray <TaggedText> .Empty);
            await context.OnDefinitionFoundAsync(dummyDef).ConfigureAwait(false);

            foreach (var location in locations)
            {
                var documentSpan = await _remoteLanguageServiceWorkspace.GetDocumentSpanFromLocation(location, context.CancellationToken).ConfigureAwait(false);

                if (documentSpan == null)
                {
                    continue;
                }

#pragma warning disable CS0612 // Type or member is obsolete.  TODO.
                await context.OnReferenceFoundAsync(new SourceReferenceItem(dummyDef, documentSpan.Value, isWrittenTo : false)).ConfigureAwait(false);

#pragma warning restore CS0612 // Type or member is obsolete
            }
        }
Example #21
0
        private async Task FindLiteralOrSymbolReferencesAsync(
            Document document, int position, IFindUsagesContext context)
        {
            // First, see if we're on a literal.  If so search for literals in the solution with
            // the same value.
            var found = await TryFindLiteralReferencesAsync(
                document, position, context).ConfigureAwait(false);

            if (found)
            {
                return;
            }

            // Wasn't a literal.  Try again as a symbol.
            await FindSymbolReferencesAsync(
                document, position, context).ConfigureAwait(false);
        }
        async Task IFindUsagesService.FindReferencesAsync(
            IFindUsagesContext context, Document document, int position, CancellationToken cancellationToken)
        {
            var definitionTrackingContext = new DefinitionTrackingContext(context);

            await FindLiteralOrSymbolReferencesAsync(
                definitionTrackingContext, document, position, cancellationToken).ConfigureAwait(false);

            // After the FAR engine is done call into any third party extensions to see
            // if they want to add results.
            var thirdPartyDefinitions = await GetThirdPartyDefinitionsAsync(
                document.Project.Solution, definitionTrackingContext.GetDefinitions(), cancellationToken).ConfigureAwait(false);

            foreach (var definition in thirdPartyDefinitions)
            {
                await context.OnDefinitionFoundAsync(definition, cancellationToken).ConfigureAwait(false);
            }
        }
        private static async Task FindSymbolMonikerReferencesAsync(
            IFindSymbolMonikerUsagesService monikerUsagesService,
            ISymbol definition,
            IFindUsagesContext context,
            CancellationToken cancellationToken)
        {
            var moniker = SymbolMoniker.TryCreate(definition);

            if (moniker == null)
            {
                return;
            }

            // Let the find-refs window know we have outstanding work
            await using var _ = await context.ProgressTracker.AddSingleItemAsync().ConfigureAwait(false);

            var displayParts = GetDisplayParts(definition).AddRange(new[]
            {
                new TaggedText(TextTags.Space, " "),
                new TaggedText(TextTags.Text, EditorFeaturesResources.external),
            });

            var definitionItem = DefinitionItem.CreateNonNavigableItem(
                tags: GlyphTags.GetTags(definition.GetGlyph()),
                displayParts,
                originationParts: DefinitionItem.GetOriginationParts(definition));

            var monikers = ImmutableArray.Create(moniker);

            var first = true;

            await foreach (var referenceItem in monikerUsagesService.FindReferencesByMoniker(
                               definitionItem, monikers, context.ProgressTracker, cancellationToken))
            {
                if (first)
                {
                    // found some results.  Add the definition item to the context.
                    first = false;
                    await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false);
                }

                await context.OnExternalReferenceFoundAsync(referenceItem).ConfigureAwait(false);
            }
        }
        private static async Task FindSymbolReferencesAsync(
            IFindUsagesContext context, Document document, int position, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            // If this is a symbol from a metadata-as-source project, then map that symbol back to a symbol in the primary workspace.
            var symbolAndProjectOpt = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(
                document, position, cancellationToken).ConfigureAwait(false);

            if (symbolAndProjectOpt == null)
            {
                return;
            }

            var(symbol, project) = symbolAndProjectOpt.Value;

            await FindSymbolReferencesAsync(
                context, symbol, project, cancellationToken).ConfigureAwait(false);
        }
        /// <summary>
        /// Public helper that we use from features like ObjectBrowser which start with a symbol
        /// and want to push all the references to it into the Streaming-Find-References window.
        /// </summary>
        public static async Task FindSymbolReferencesAsync(
            IFindUsagesContext context, ISymbol symbol, Project project, CancellationToken cancellationToken)
        {
            await context.SetSearchTitleAsync(string.Format(EditorFeaturesResources._0_references,
                                                            FindUsagesHelpers.GetDisplayName(symbol))).ConfigureAwait(false);

            var progressAdapter = new FindReferencesProgressAdapter(project.Solution, context);

            // Now call into the underlying FAR engine to find reference.  The FAR
            // 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.
            await SymbolFinder.FindReferencesAsync(
                SymbolAndProjectId.Create(symbol, project.Id),
                project.Solution,
                progressAdapter,
                documents : null,
                cancellationToken : cancellationToken).ConfigureAwait(false);
        }
        private async Task FindSymbolReferencesAsync(
            Document document, int position, IFindUsagesContext context)
        {
            var cancellationToken = context.CancellationToken;

            cancellationToken.ThrowIfCancellationRequested();

            // Find the symbol we want to search and the solution we want to search in.
            var symbolAndProject = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(
                document, position, cancellationToken).ConfigureAwait(false);

            if (symbolAndProject == null)
            {
                return;
            }

            await FindSymbolReferencesAsync(
                context, symbolAndProject?.symbol, symbolAndProject?.project, cancellationToken).ConfigureAwait(false);
        }
        public async Task FindReferencesAsync(
            Document document, int position, IFindUsagesContext context)
        {
            // NOTE: All ConFigureAwaits in this method need to pass 'true' so that
            // we return to the caller's context.  that's so the call to 
            // CallThirdPartyExtensionsAsync will happen on the UI thread.  We need
            // this to maintain the threading guarantee we had around that method
            // from pre-Roslyn days.
            var findReferencesProgress = await FindReferencesWorkerAsync(
                document, position, context).ConfigureAwait(true);
            if (findReferencesProgress == null)
            {
                return;
            }

            // After the FAR engine is done call into any third party extensions to see
            // if they want to add results.
            await findReferencesProgress.CallThirdPartyExtensionsAsync().ConfigureAwait(true);
        }
        public async Task FindReferencesAsync(
            Document document, int position, IFindUsagesContext context)
        {
            // NOTE: All ConFigureAwaits in this method need to pass 'true' so that
            // we return to the caller's context.  that's so the call to
            // CallThirdPartyExtensionsAsync will happen on the UI thread.  We need
            // this to maintain the threading guarantee we had around that method
            // from pre-Roslyn days.
            var findReferencesProgress = await FindReferencesWorkerAsync(
                document, position, context).ConfigureAwait(true);

            if (findReferencesProgress == null)
            {
                return;
            }

            // After the FAR engine is done call into any third party extensions to see
            // if they want to add results.
            await findReferencesProgress.CallThirdPartyExtensionsAsync().ConfigureAwait(true);
        }
        private static async Task InspectInterfaceAsync(
            IFindUsagesContext context, INamedTypeSymbol interfaceSymbol, INamedTypeSymbol namedTypeSymbol, Project project, CancellationToken cancellationToken)
        {
            foreach (var interfaceMember in interfaceSymbol.GetMembers())
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                var impl = namedTypeSymbol.FindImplementationForInterfaceMember(interfaceMember);
                if (impl == null)
                {
                    continue;
                }

                var definitionItem = impl.ToNonClassifiedDefinitionItem(project.Solution, true);
                await context.OnDefinitionFoundAsync(definitionItem, cancellationToken).ConfigureAwait(false);
            }
        }
Example #30
0
        public async Task FindImplementationsAsync(Document document, int position, IFindUsagesContext context)
        {
            var text = await document.GetTextAsync().ConfigureAwait(false);

            var lspClient = _roslynLspClientServiceFactory.ActiveLanguageServerClient;

            if (lspClient == null)
            {
                return;
            }

            var documentPositionParams = ProtocolConversions.PositionToTextDocumentPositionParams(position, text, document);

            var response = await lspClient.RequestAsync(LiveShareProtocol.Methods.TextDocumentImplementations, documentPositionParams, context.CancellationToken).ConfigureAwait(false);

            var locations = ((JToken)response)?.ToObject <LSP.Location[]>();

            if (locations == null)
            {
                return;
            }

            foreach (var location in locations)
            {
                var documentSpan = await _remoteLanguageServiceWorkspace.GetDocumentSpanFromLocation(location, context.CancellationToken).ConfigureAwait(false);

                if (documentSpan == null)
                {
                    continue;
                }

                // Get the text for the line containing the definition to show in the UI.
                var docText = await documentSpan.Value.Document.GetTextAsync(context.CancellationToken).ConfigureAwait(false);

                var lineText = docText.GetSubText(docText.Lines[location.Range.Start.Line].Span).ToString();

                await context.OnDefinitionFoundAsync(DefinitionItem.Create(ImmutableArray <string> .Empty,
                                                                           ImmutableArray.Create(new TaggedText(TextTags.Text, lineText)), documentSpan.Value)).ConfigureAwait(false);
            }
        }
Example #31
0
        public async Task FindImplementationsAsync(
            Document document, int position, IFindUsagesContext context)
        {
            var cancellationToken = context.CancellationToken;
            var tuple             = await FindUsagesHelpers.FindImplementationsAsync(
                document, position, cancellationToken).ConfigureAwait(false);

            if (tuple == null)
            {
                await context.ReportMessageAsync(
                    EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret).ConfigureAwait(false);

                return;
            }

            var message = tuple.Value.message;

            if (message != null)
            {
                await context.ReportMessageAsync(message).ConfigureAwait(false);

                return;
            }

            await context.SetSearchTitleAsync(
                string.Format(EditorFeaturesResources._0_implementations,
                              FindUsagesHelpers.GetDisplayName(tuple.Value.symbol))).ConfigureAwait(false);

            var project = tuple.Value.project;

            foreach (var implementation in tuple.Value.implementations)
            {
                var definitionItem = await implementation.ToClassifiedDefinitionItemAsync(
                    project, includeHiddenLocations : false,
                    FindReferencesSearchOptions.Default, cancellationToken : cancellationToken).ConfigureAwait(false);

                await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false);
            }
        }
        private async Task <ProgressAdapter> FindReferencesWorkerAsync(
            Document document, int position, IFindUsagesContext context)
        {
            var cancellationToken = context.CancellationToken;

            cancellationToken.ThrowIfCancellationRequested();

            // Find the symbol we want to search and the solution we want to search in.
            var symbolAndProject = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(
                document, position, cancellationToken).ConfigureAwait(false);

            if (symbolAndProject == null)
            {
                return(null);
            }

            var symbol  = symbolAndProject?.symbol;
            var project = symbolAndProject?.project;

            var displayName = AbstractFindReferencesService.GetDisplayName(symbol);

            context.SetSearchLabel(displayName);

            var progressAdapter = new ProgressAdapter(project.Solution, context);

            // Now call into the underlying FAR engine to find reference.  The FAR
            // 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.
            await SymbolFinder.FindReferencesAsync(
                SymbolAndProjectId.Create(symbol, project.Id),
                project.Solution,
                progressAdapter,
                documents : null,
                cancellationToken : cancellationToken).ConfigureAwait(false);

            return(progressAdapter);
        }
Example #33
0
        public static async Task FindSymbolReferencesAsync(
            IFindUsagesContext context, ISymbol symbol, Project project)
        {
            var solution             = project.Solution;
            var monikerUsagesService = solution.Workspace.Services.GetRequiredService <IFindSymbolMonikerUsagesService>();

            await context.SetSearchTitleAsync(string.Format(EditorFeaturesResources._0_references,
                                                            FindUsagesHelpers.GetDisplayName(symbol))).ConfigureAwait(false);

            var options = FindReferencesSearchOptions.GetFeatureOptionsForStartingSymbol(symbol);

            // Now call into the underlying FAR engine to find reference.  The FAR
            // 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.
            //
            // Kick off work to search the online code index system in parallel.
            //
            // Do both in parallel so we can get all the results as soon as possible.

            await Task.WhenAll(
                FindReferencesAsync(context, symbol, project, options),
                FindSymbolMonikerReferencesAsync(monikerUsagesService, symbol, context)).ConfigureAwait(false);
        }
 public ProgressAdapter(Solution solution, IFindUsagesContext context)
 {
     _solution = solution;
     _context = context;
     _definitionFactory = s => s.ToDefinitionItem(solution, includeHiddenLocations: false);
 }