예제 #1
0
        internal static async Task <IEnumerable <Alias> > GetAliasFromMetadataAsync(
            OmniSharpWorkspace workspace,
            string fileName,
            int line,
            int timeout,
            MetadataExternalSourceService metadataExternalSourceService)
        {
            var document  = workspace.GetDocument(fileName);
            var lineIndex = line + MethodLineOffset;
            int column;

            if (document == null)
            {
                return(Enumerable.Empty <Alias>());
            }

            var semanticModel = await document.GetSemanticModelAsync();

            var sourceText = await document.GetTextAsync();

            var sourceLine = sourceText.Lines[lineIndex].ToString();

            if (sourceLine.Contains("(Context"))
            {
                column = sourceLine.IndexOf("(Context", StringComparison.Ordinal);
            }
            else
            {
                lineIndex  = line + PropertyLineOffset;
                sourceLine = sourceText.Lines[lineIndex].ToString();
                if (sourceLine.Contains("(Context"))
                {
                    column = sourceLine.IndexOf("(Context", StringComparison.Ordinal);
                }
                else
                {
                    return(Enumerable.Empty <Alias>());
                }
            }

            if (column > 0 && sourceLine[column - 1] == '>')
            {
                column = sourceLine.LastIndexOf("<", column, StringComparison.Ordinal);
            }

            var position = sourceText.Lines.GetPosition(new LinePosition(lineIndex, column));
            var symbol   = await SymbolFinder.FindSymbolAtPositionAsync(semanticModel, position, workspace);

            if (symbol == null || symbol is INamespaceSymbol)
            {
                return(Enumerable.Empty <Alias>());
            }
            if (symbol is IMethodSymbol method)
            {
                symbol = method.PartialImplementationPart ?? symbol;
            }

            var result = new List <Alias>();

            foreach (var location in symbol.Locations)
            {
                if (!location.IsInMetadata)
                {
                    continue;
                }

                var cancellationSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(timeout));
                var(metadataDocument, _) = await metadataExternalSourceService.GetAndAddExternalSymbolDocument(document.Project, symbol, cancellationSource.Token);

                if (metadataDocument == null)
                {
                    continue;
                }

                cancellationSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(timeout));
                var metadataLocation = await metadataExternalSourceService.GetExternalSymbolLocation(symbol, metadataDocument, cancellationSource.Token);

                var lineSpan = metadataLocation.GetMappedLineSpan();

                result.Add(new Alias
                {
                    Document         = document,
                    MetadataDocument = metadataDocument,
                    Symbol           = symbol,
                    Location         = location,
                    LineSpan         = lineSpan
                });
            }

            return(result);
        }
예제 #2
0
        private async Task <GotoDefinitionResponse> GetAliasFromMetadataAsync(GotoDefinitionRequest request)
        {
            var document  = Workspace.GetDocument(request.FileName);
            var response  = new GotoDefinitionResponse();
            var lineIndex = request.Line + MethodLineOffset;
            var column    = 0;

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

            var semanticModel = await document.GetSemanticModelAsync();

            var sourceText = await document.GetTextAsync();

            var sourceLine = sourceText.Lines[lineIndex].ToString();

            if (sourceLine.Contains("(Context"))
            {
                column = sourceLine.IndexOf("(Context", StringComparison.Ordinal);
            }
            else
            {
                lineIndex  = request.Line + PropertyLineOffset;
                sourceLine = sourceText.Lines[lineIndex].ToString();
                if (sourceLine.Contains("(Context"))
                {
                    column = sourceLine.IndexOf("(Context", StringComparison.Ordinal);
                }
                else
                {
                    return(response);
                }
            }
            var position = sourceText.Lines.GetPosition(new LinePosition(lineIndex, column));
            var symbol   = await SymbolFinder.FindSymbolAtPositionAsync(semanticModel, position, Workspace);

            if (symbol == null || symbol is INamespaceSymbol)
            {
                return(response);
            }
            if (symbol is IMethodSymbol method)
            {
                symbol = method.PartialImplementationPart ?? symbol;
            }

            var location = symbol.Locations.First();

            if (!location.IsInMetadata)
            {
                return(response);
            }
            var cancellationSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(request.Timeout));

            var(metadataDocument, _) = await _metadataExternalSourceService.GetAndAddExternalSymbolDocument(document.Project, symbol, cancellationSource.Token);

            if (metadataDocument == null)
            {
                return(response);
            }

            cancellationSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(request.Timeout));
            var metadataLocation = await _metadataExternalSourceService.GetExternalSymbolLocation(symbol, metadataDocument, cancellationSource.Token);

            var lineSpan = metadataLocation.GetMappedLineSpan();

            response = new GotoDefinitionResponse
            {
                Line           = lineSpan.StartLinePosition.Line,
                Column         = lineSpan.StartLinePosition.Character,
                MetadataSource = new MetadataSource()
                {
                    AssemblyName = symbol.ContainingAssembly.Name,
                    ProjectName  = document.Project.Name,
                    TypeName     = symbol.GetSymbolName()
                },
            };

            return(response);
        }