Пример #1
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);
            }
        }
Пример #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
            }
        }
        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);
            }
        }
Пример #4
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);
            }
        }
Пример #5
0
        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);
            }
        }
Пример #6
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 Task OnDefinitionFoundAsync(DefinitionItem definition)
            {
                lock (_gate)
                {
                    _definitions.Add(definition);
                }

                return(_underlyingContext.OnDefinitionFoundAsync(definition));
            }
Пример #8
0
        public Task OnDefinitionFoundAsync(SerializableDefinitionItem definition)
        {
            var id         = definition.Id;
            var rehydrated = definition.Rehydrate(_solution);

            lock (_idToDefinition)
            {
                _idToDefinition.Add(id, rehydrated);
            }

            return(_context.OnDefinitionFoundAsync(rehydrated).AsTask());
        }
Пример #9
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
            }
        }
        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 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);
            }
        }
Пример #13
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);
            }
        }
Пример #14
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);
            }
        }
Пример #15
0
        private async Task <bool> TryFindLiteralReferencesAsync(
            Document document, int position, IFindUsagesContext context)
        {
            var cancellationToken = context.CancellationToken;

            cancellationToken.ThrowIfCancellationRequested();

            var syntaxTree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            var syntaxFacts = document.GetRequiredLanguageService <ISyntaxFactsService>();

            // Currently we only support FAR for numbers, strings and characters.  We don't
            // bother with true/false/null as those are likely to have way too many results
            // to be useful.
            var token = await syntaxTree.GetTouchingTokenAsync(
                position,
                t => syntaxFacts.IsNumericLiteral(t) ||
                syntaxFacts.IsCharacterLiteral(t) ||
                syntaxFacts.IsStringLiteral(t),
                cancellationToken).ConfigureAwait(false);

            if (token.RawKind == 0)
            {
                return(false);
            }

            // Searching for decimals not supported currently.  Our index can only store 64bits
            // for numeric values, and a decimal won't fit within that.
            var tokenValue = token.Value;

            if (tokenValue == null || tokenValue is decimal)
            {
                return(false);
            }

            if (token.Parent is null)
            {
                return(false);
            }

            var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var symbol = semanticModel.GetSymbolInfo(token.Parent).Symbol ?? semanticModel.GetDeclaredSymbol(token.Parent);

            // Numeric labels are available in VB.  In that case we want the normal FAR engine to
            // do the searching.  For these literals we want to find symbolic results and not
            // numeric matches.
            if (symbol is ILabelSymbol)
            {
                return(false);
            }

            // Use the literal to make the title.  Trim literal if it's too long.
            var title = syntaxFacts.ConvertToSingleLine(token.Parent).ToString();

            if (title.Length >= 10)
            {
                title = title.Substring(0, 10) + "...";
            }

            var searchTitle = string.Format(EditorFeaturesResources._0_references, title);
            await context.SetSearchTitleAsync(searchTitle).ConfigureAwait(false);

            var solution = document.Project.Solution;

            // There will only be one 'definition' that all matching literal reference.
            // So just create it now and report to the context what it is.
            var definition = DefinitionItem.CreateNonNavigableItem(
                ImmutableArray.Create(TextTags.StringLiteral),
                ImmutableArray.Create(new TaggedText(TextTags.Text, searchTitle)));

            await context.OnDefinitionFoundAsync(definition).ConfigureAwait(false);

            var progressAdapter = new FindLiteralsProgressAdapter(context, definition);

            // 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
            // FindUsagesContext instance we were given.
            await SymbolFinder.FindLiteralReferencesAsync(
                tokenValue, Type.GetTypeCode(tokenValue.GetType()), solution, progressAdapter, cancellationToken).ConfigureAwait(false);

            return(true);
        }
Пример #16
0
 public Task OnDefinitionFoundAsync(SymbolAndProjectId definition)
 {
     return(_context.OnDefinitionFoundAsync(GetDefinitionItem(definition)));
 }
Пример #17
0
            public async ValueTask OnDefinitionFoundAsync(ISymbol definition)
            {
                var definitionItem = await GetDefinitionItemAsync(definition).ConfigureAwait(false);

                await _context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false);
            }
            public async Task OnDefinitionFoundAsync(SymbolAndProjectId definition)
            {
                var definitionItem = await GetDefinitionItemAsync(definition).ConfigureAwait(false);

                await _context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false);
            }
 public ValueTask OnDefinitionFoundAsync(VSTypeScriptDefinitionItem definition, CancellationToken cancellationToken)
 => _context.OnDefinitionFoundAsync(definition.UnderlyingObject, cancellationToken);
 public Task OnDefinitionFoundAsync(FSharp.FindUsages.FSharpDefinitionItem definition)
 {
     return(_context.OnDefinitionFoundAsync(definition.RoslynDefinitionItem));
 }
 public Task OnDefinitionFoundAsync(FSharp.FindUsages.FSharpDefinitionItem definition)
 {
     return(_context.OnDefinitionFoundAsync(definition.RoslynDefinitionItem, _cancellationToken).AsTask());
 }