private static CompletionItem CreateCompletionItem(XamlCompletionItem xamlCompletion, DocumentId documentId, SourceText text, Position position)
        {
            var item = new VSCompletionItem
            {
                Label            = xamlCompletion.DisplayText,
                CommitCharacters = xamlCompletion.CommitCharacters,
                Detail           = xamlCompletion.Detail,
                InsertText       = xamlCompletion.InsertText,
                Preselect        = xamlCompletion.Preselect.GetValueOrDefault(),
                SortText         = xamlCompletion.SortText,
                FilterText       = xamlCompletion.FilterText,
                Kind             = GetItemKind(xamlCompletion.Kind),
                Description      = xamlCompletion.Description,
                Icon             = xamlCompletion.Icon,
                Data             = new CompletionResolveData {
                    ProjectGuid = documentId.ProjectId.Id, DocumentGuid = documentId.Id, Position = position, DisplayText = xamlCompletion.DisplayText
                }
            };

            if (xamlCompletion.Span.HasValue)
            {
                item.TextEdit = new TextEdit
                {
                    NewText = xamlCompletion.InsertText,
                    Range   = ProtocolConversions.LinePositionToRange(text.Lines.GetLinePositionSpan(xamlCompletion.Span.Value))
                };
            }

            return(item);
        }
        public async Task <object> HandleAsync(LSP.TextDocumentPositionParams request, RequestContext <Solution> requestContext, CancellationToken cancellationToken)
        {
            var document = _solutionProvider.GetDocument(request.TextDocument);

            if (document == null)
            {
                return(Array.Empty <LSP.Location>());
            }

            var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);

            var locations = await GetDefinitionsWithFindUsagesServiceAsync(document, position, cancellationToken).ConfigureAwait(false);

            // No definition found - see if we can get metadata as source but that's only applicable for C#\VB.
            if ((locations.Length == 0) && document.SupportsSemanticModel && this._metadataAsSourceService != null)
            {
                var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position, cancellationToken).ConfigureAwait(false);

                if (symbol?.Locations.FirstOrDefault().IsInMetadata == true)
                {
                    var declarationFile = await this._metadataAsSourceService.GetGeneratedFileAsync(document.Project, symbol, false, cancellationToken).ConfigureAwait(false);

                    var linePosSpan = declarationFile.IdentifierLocation.GetLineSpan().Span;
                    return(new LSP.Location[]
                    {
                        new LSP.Location {
                            Uri = new Uri(declarationFile.FilePath), Range = ProtocolConversions.LinePositionToRange(linePosSpan)
                        }
                    });
                }
            }

            return(locations.ToArray());
        }
        protected async Task <LSP.Location[]> GetDefinitionAsync(Solution solution, LSP.TextDocumentPositionParams request, bool typeOnly, CancellationToken cancellationToken)
        {
            var locations = ArrayBuilder <LSP.Location> .GetInstance();

            var document = solution.GetDocumentFromURI(request.TextDocument.Uri);

            if (document == null)
            {
                return(locations.ToArrayAndFree());
            }

            var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);

            var definitionService = document.Project.LanguageServices.GetService <IGoToDefinitionService>();
            var definitions       = await definitionService.FindDefinitionsAsync(document, position, cancellationToken).ConfigureAwait(false);

            if (definitions != null && definitions.Count() > 0)
            {
                foreach (var definition in definitions)
                {
                    if (!ShouldInclude(definition, typeOnly))
                    {
                        continue;
                    }

                    var definitionText = await definition.Document.GetTextAsync(cancellationToken).ConfigureAwait(false);

                    locations.Add(new LSP.Location
                    {
                        Uri   = definition.Document.GetURI(),
                        Range = ProtocolConversions.TextSpanToRange(definition.SourceSpan, definitionText),
                    });
                }
            }
            else if (document.SupportsSemanticModel && _metadataAsSourceFileService != null)
            {
                // No definition found - see if we can get metadata as source but that's only applicable for C#\VB.
                var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position, cancellationToken).ConfigureAwait(false);

                if (symbol != null && symbol.Locations != null && !symbol.Locations.IsEmpty && symbol.Locations.First().IsInMetadata)
                {
                    if (!typeOnly || symbol is ITypeSymbol)
                    {
                        var declarationFile = await _metadataAsSourceFileService.GetGeneratedFileAsync(document.Project, symbol, false, cancellationToken).ConfigureAwait(false);

                        var linePosSpan = declarationFile.IdentifierLocation.GetLineSpan().Span;
                        locations.Add(new LSP.Location
                        {
                            Uri   = new Uri(declarationFile.FilePath),
                            Range = ProtocolConversions.LinePositionToRange(linePosSpan),
                        });
                    }
                }
            }

            return(locations.ToArrayAndFree());
        protected async Task <LSP.Location[]?> GetDefinitionAsync(LSP.TextDocumentPositionParams request, bool typeOnly, RequestContext context, CancellationToken cancellationToken)
        {
            var document = context.Document;

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

            var locations = ArrayBuilder <LSP.Location> .GetInstance();

            var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);

            var findDefinitionService = document.GetRequiredLanguageService <IFindDefinitionService>();

            var definitions = await findDefinitionService.FindDefinitionsAsync(document, position, cancellationToken).ConfigureAwait(false);

            if (definitions.Any())
            {
                foreach (var definition in definitions)
                {
                    if (!ShouldInclude(definition, typeOnly))
                    {
                        continue;
                    }

                    var location = await ProtocolConversions.TextSpanToLocationAsync(
                        definition.Document, definition.SourceSpan, definition.IsStale, cancellationToken).ConfigureAwait(false);

                    locations.AddIfNotNull(location);
                }
            }
            else if (document.SupportsSemanticModel && _metadataAsSourceFileService != null)
            {
                // No definition found - see if we can get metadata as source but that's only applicable for C#\VB.
                var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position, cancellationToken).ConfigureAwait(false);

                if (symbol != null && _metadataAsSourceFileService.IsNavigableMetadataSymbol(symbol))
                {
                    if (!typeOnly || symbol is ITypeSymbol)
                    {
                        var options         = _globalOptions.GetMetadataAsSourceOptions(document.Project.LanguageServices);
                        var declarationFile = await _metadataAsSourceFileService.GetGeneratedFileAsync(document.Project, symbol, signaturesOnly : false, options, cancellationToken).ConfigureAwait(false);

                        var linePosSpan = declarationFile.IdentifierLocation.GetLineSpan().Span;
                        locations.Add(new LSP.Location
                        {
                            Uri   = new Uri(declarationFile.FilePath),
                            Range = ProtocolConversions.LinePositionToRange(linePosSpan),
                        });
                    }
                }
            }

            return(locations.ToArrayAndFree());
Exemple #5
0
        private static CompletionItem CreateCompletionItem(
            XamlCompletionItem xamlCompletion,
            DocumentId documentId,
            SourceText text,
            Position position,
            TextDocumentIdentifier textDocument
            )
        {
            var item = new VSCompletionItem
            {
                Label            = xamlCompletion.DisplayText,
                CommitCharacters = xamlCompletion.CommitCharacters,
                Detail           = xamlCompletion.Detail,
                InsertText       = xamlCompletion.InsertText,
                Preselect        = xamlCompletion.Preselect.GetValueOrDefault(),
                SortText         = xamlCompletion.SortText,
                FilterText       = xamlCompletion.FilterText,
                Kind             = GetItemKind(xamlCompletion.Kind),
                Description      = xamlCompletion.Description,
                Icon             = xamlCompletion.Icon,
                Data             = new CompletionResolveData
                {
                    ProjectGuid  = documentId.ProjectId.Id,
                    DocumentGuid = documentId.Id,
                    Position     = position,
                    DisplayText  = xamlCompletion.DisplayText
                }
            };

            if (xamlCompletion.Span.HasValue)
            {
                item.TextEdit = new TextEdit
                {
                    NewText = xamlCompletion.InsertText,
                    Range   = ProtocolConversions.LinePositionToRange(
                        text.Lines.GetLinePositionSpan(xamlCompletion.Span.Value)
                        )
                };
            }

            if (xamlCompletion.EventDescription.HasValue)
            {
                item.Command = new Command()
                {
                    CommandIdentifier = StringConstants.CreateEventHandlerCommand,
                    Arguments         = new object[] { textDocument, xamlCompletion.EventDescription },
                    Title             = CreateEventHandlerCommandTitle
                };
            }

            return(item);
        }
Exemple #6
0
            // Local functions
            static async Task <LSP.Location?> ComputeLocationAsync(
                Document document,
                int position,
                DocumentSpan documentSpan,
                IMetadataAsSourceFileService metadataAsSourceFileService,
                CancellationToken cancellationToken)
            {
                if (documentSpan != default)
                {
                    // We do have a document span, so compute location normally.
                    return(await ProtocolConversions.DocumentSpanToLocationAsync(documentSpan, cancellationToken).ConfigureAwait(false));
                }

                // If we have no document span, our location may be in metadata or may be a namespace.
                var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position, cancellationToken).ConfigureAwait(false);

                if (symbol == null || symbol.Locations.IsEmpty || symbol.Kind == SymbolKind.Namespace)
                {
                    // Either:
                    // (1) We couldn't find the location in metadata and it's not in any of our known documents.
                    // (2) The symbol is a namespace (and therefore has no location).
                    return(null);
                }

                var declarationFile = await metadataAsSourceFileService.GetGeneratedFileAsync(
                    document.Project, symbol, allowDecompilation : false, cancellationToken).ConfigureAwait(false);

                var linePosSpan = declarationFile.IdentifierLocation.GetLineSpan().Span;

                if (string.IsNullOrEmpty(declarationFile.FilePath))
                {
                    return(null);
                }

                try
                {
                    return(new LSP.Location
                    {
                        Uri = ProtocolConversions.GetUriFromFilePath(declarationFile.FilePath),
                        Range = ProtocolConversions.LinePositionToRange(linePosSpan),
                    });
                }
                catch (UriFormatException e) when(FatalError.ReportAndCatch(e))
                {
                    // We might reach this point if the file path is formatted incorrectly.
                    return(null);
                }
            }
Exemple #7
0
        private static CompletionItem CreateCompletionItem(XamlCompletionItem xamlCompletion, DocumentId documentId, SourceText text, Position position, TextDocumentIdentifier textDocument, Dictionary <XamlCompletionKind, ImmutableArray <VSInternalCommitCharacter> > commitCharactersCach)
        {
            var item = new VSInternalCompletionItem
            {
                Label = xamlCompletion.DisplayText,
                VsCommitCharacters = GetCommitCharacters(xamlCompletion, commitCharactersCach),
                Detail             = xamlCompletion.Detail,
                InsertText         = xamlCompletion.InsertText,
                Preselect          = xamlCompletion.Preselect.GetValueOrDefault(),
                SortText           = xamlCompletion.SortText,
                FilterText         = xamlCompletion.FilterText,
                Kind             = GetItemKind(xamlCompletion.Kind),
                Description      = xamlCompletion.Description,
                Icon             = xamlCompletion.Icon,
                InsertTextFormat = xamlCompletion.IsSnippet ? InsertTextFormat.Snippet : InsertTextFormat.Plaintext,
                Data             = new CompletionResolveData {
                    ProjectGuid = documentId.ProjectId.Id, DocumentGuid = documentId.Id, Position = position, DisplayText = xamlCompletion.DisplayText
                }
            };

            if (xamlCompletion.Span.HasValue)
            {
                item.TextEdit = new TextEdit
                {
                    NewText = xamlCompletion.InsertText,
                    Range   = ProtocolConversions.LinePositionToRange(text.Lines.GetLinePositionSpan(xamlCompletion.Span.Value))
                };
            }

            if (xamlCompletion.EventDescription.HasValue)
            {
                item.Command = new Command()
                {
                    CommandIdentifier = StringConstants.CreateEventHandlerCommand,
                    Arguments         = new object[] { textDocument, xamlCompletion.EventDescription },
                    Title             = CreateEventHandlerCommandTitle
                };
            }
            else if (xamlCompletion.RetriggerCompletion)
            {
                // Retriger completion after commit
                item.Command = s_retriggerCompletionCommand;
            }

            return(item);
        }
Exemple #8
0
        private static async Task <LSP.Location[]> GetSymbolDefinitionLocationsAsync(XamlSymbolDefinition symbolDefinition, RequestContext context, IMetadataAsSourceFileService metadataAsSourceFileService, CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(symbolDefinition.Symbol);

            using var _ = ArrayBuilder <LSP.Location> .GetInstance(out var locations);

            var symbol = symbolDefinition.Symbol;

            var items = NavigableItemFactory.GetItemsFromPreferredSourceLocations(context.Solution, symbol, displayTaggedParts: null, cancellationToken);

            if (items.Any())
            {
                foreach (var item in items)
                {
                    var location = await ProtocolConversions.TextSpanToLocationAsync(
                        item.Document, item.SourceSpan, item.IsStale, cancellationToken).ConfigureAwait(false);

                    locations.AddIfNotNull(location);
                }
            }
            else
            {
                var metadataLocation = symbol.Locations.Where(loc => loc.IsInMetadata).FirstOrDefault();
                if (metadataLocation != null && metadataAsSourceFileService.IsNavigableMetadataSymbol(symbol))
                {
                    var project = context.Document?.GetCodeProject();
                    if (project != null)
                    {
                        var declarationFile = await metadataAsSourceFileService.GetGeneratedFileAsync(project, symbol, allowDecompilation : false, cancellationToken).ConfigureAwait(false);

                        var linePosSpan = declarationFile.IdentifierLocation.GetLineSpan().Span;
                        locations.Add(new LSP.Location
                        {
                            Uri   = new Uri(declarationFile.FilePath),
                            Range = ProtocolConversions.LinePositionToRange(linePosSpan),
                        });
                    }
                }
            }

            return(locations.ToArray());
        }
Exemple #9
0
        public async Task <object> HandleAsync(LSP.TextDocumentPositionParams request, RequestContext <Solution> requestContext, CancellationToken cancellationToken)
        {
            // LiveShare doesn't go through Roslyn LSP infrastructure, but creating one of our request contexts here is a convenient way to handle
            // text document lookup
            var lspContext = LSPHandler.RequestContext.Create(requiresLSPSolution: true, request.TextDocument, null, requestContext.GetClientCapabilities(), _workspaceRegistrationService, null, null, out _);
            var document   = lspContext.Document;

            if (document == null)
            {
                return(Array.Empty <LSP.Location>());
            }

            var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);

            var locations = await GetDefinitionsWithFindUsagesServiceAsync(document, position, cancellationToken).ConfigureAwait(false);

            // No definition found - see if we can get metadata as source but that's only applicable for C#\VB.
            if ((locations.Length == 0) && document.SupportsSemanticModel && this._metadataAsSourceService != null)
            {
                var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position, cancellationToken).ConfigureAwait(false);

                if (symbol?.Locations.FirstOrDefault()?.IsInMetadata == true)
                {
                    var declarationFile = await this._metadataAsSourceService.GetGeneratedFileAsync(document.Project, symbol, false, cancellationToken).ConfigureAwait(false);

                    var linePosSpan = declarationFile.IdentifierLocation.GetLineSpan().Span;
                    return(new LSP.Location[]
                    {
                        new LSP.Location {
                            Uri = new Uri(declarationFile.FilePath), Range = ProtocolConversions.LinePositionToRange(linePosSpan)
                        }
                    });
                }
            }

            return(locations.ToArray());
        }