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); }
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); }