public async Task<IActionResult> GotoDefinition(Request request) { var quickFixes = new List<QuickFix>(); var document = _workspace.GetDocument(request.FileName); var response = new GotoDefinitionResponse(); if (document != null) { var semanticModel = await document.GetSemanticModelAsync(); var syntaxTree = semanticModel.SyntaxTree; var sourceText = await document.GetTextAsync(); var position = sourceText.Lines.GetPosition(new LinePosition(request.Line - 1, request.Column - 1)); var symbol = SymbolFinder.FindSymbolAtPosition(semanticModel, position, _workspace); if (symbol != null) { var lineSpan = symbol.Locations.First().GetMappedLineSpan(); response = new GotoDefinitionResponse { FileName = lineSpan.Path, Line = lineSpan.StartLinePosition.Line + 1, Column = lineSpan.StartLinePosition.Character + 1 }; } } return new ObjectResult(response); }
public async Task<FileMemberTree> MembersAsTree(Request request) { return new FileMemberTree() { TopLevelTypeDefinitions = await StructureComputer.Compute(_workspace.GetDocuments(request.FileName)) }; }
public async Task<QuickFixResponse> FindImplementations(Request request) { var document = _workspace.GetDocument(request.FileName); var response = new QuickFixResponse(); if (document != null) { var semanticModel = await document.GetSemanticModelAsync(); var sourceText = await document.GetTextAsync(); var position = sourceText.Lines.GetPosition(new LinePosition(request.Line - 1, request.Column - 1)); var symbol = SymbolFinder.FindSymbolAtPosition(semanticModel, position, _workspace); var quickFixes = new List<QuickFix>(); var implementations = await SymbolFinder.FindImplementationsAsync(symbol, _workspace.CurrentSolution); await AddQuickFixes(quickFixes, implementations); var overrides = await SymbolFinder.FindOverridesAsync(symbol, _workspace.CurrentSolution); await AddQuickFixes(quickFixes, overrides); var derivedTypes = await GetDerivedTypes(symbol); await AddQuickFixes(quickFixes, derivedTypes); response = new QuickFixResponse(quickFixes.OrderBy(q => q.FileName) .ThenBy(q => q.Line) .ThenBy(q => q.Column)); } return response; }
public ProjectInformationResponse CurrentProject(Request request) { var document = _workspace.GetDocument(request.FileName); var msBuildContextProject = _msbuildContext?.GetProject(document?.Project.FilePath); var dnxContextProject = _dnxContext?.GetProject(document?.Project.FilePath); MSBuildProject msBuildProjectItem = null; DnxProject dnxProjectItem = null; if (msBuildContextProject != null) { msBuildProjectItem = new MSBuildProject(msBuildContextProject); } if (dnxContextProject != null) { dnxProjectItem = new DnxProject(dnxContextProject); } return new ProjectInformationResponse { MsBuildProject = msBuildProjectItem, DnxProject = dnxProjectItem }; }
public async Task<IActionResult> CodeCheck(Request request) { var quickFixes = new List<QuickFix>(); var documents = _workspace.GetDocuments(request.FileName); foreach (var document in documents) { var semanticModel = await document.GetSemanticModelAsync(); foreach (var quickFix in semanticModel.GetDiagnostics().Select(MakeQuickFix)) { var existingQuickFix = quickFixes.FirstOrDefault(q => q.Equals(quickFix)); if (existingQuickFix == null) { quickFix.Projects.Add(document.Project.Name); quickFixes.Add(quickFix); } else { existingQuickFix.Projects.Add(document.Project.Name); } } } return new ObjectResult(new { QuickFixes = quickFixes }); }
public ProjectInformationResponse CurrentProject(Request request) { var document = _workspace.GetDocument(request.FileName); var msBuildContextProject = _msbuildContext?.GetProject(document?.Project.FilePath); var aspNet5ContextProject = _aspnet5Context?.GetProject(document?.Project.FilePath); MSBuildProject msBuildProjectItem = null; AspNet5Project aspNet5ProjectItem = null; if (msBuildContextProject != null) { msBuildProjectItem = new MSBuildProject(msBuildContextProject); } if (aspNet5ContextProject != null) { aspNet5ProjectItem = new AspNet5Project(aspNet5ContextProject); } return new ProjectInformationResponse { MsBuildProject = msBuildProjectItem, AspNet5Project = aspNet5ProjectItem }; }
public async Task<IActionResult> MembersAsTree(Request request) { return new ObjectResult(new { TopLevelTypeDefinitions = await StructureComputer.Compute(_workspace.GetDocuments(request.FileName)) }); }
public async Task<SignatureHelp> GetSignatureHelp(Request request) { var invocations = new List<InvocationContext>(); foreach (var document in _workspace.GetDocuments(request.FileName)) { var invocation = await GetInvocation(document, request); if (invocation != null) { invocations.Add(invocation); } } if (invocations.Count == 0) { return null; } var response = new SignatureHelp(); // define active parameter by position foreach (var comma in invocations.First().ArgumentList.Arguments.GetSeparators()) { if (comma.Span.Start > invocations.First().Position) { break; } response.ActiveParameter += 1; } // process all signatures, define active signature by types var signaturesSet = new HashSet<SignatureHelpItem>(); var bestScore = int.MinValue; SignatureHelpItem bestScoredItem = null; foreach (var invocation in invocations) { var types = invocation.ArgumentList.Arguments .Select(argument => invocation.SemanticModel.GetTypeInfo(argument.Expression)); foreach (var methodOverload in GetMethodOverloads(invocation.SemanticModel, invocation.Receiver)) { var signature = BuildSignature(methodOverload); signaturesSet.Add(signature); var score = InvocationScore(methodOverload, types); if (score > bestScore) { bestScore = score; bestScoredItem = signature; } } } var signaturesList = signaturesSet.ToList(); response.Signatures = signaturesList; response.ActiveSignature = signaturesList.IndexOf(bestScoredItem); return response; }
public QuickFixResponse GoToFile(Request request) { var docs = _workspace.CurrentSolution.Projects.SelectMany(project => project.Documents). GroupBy(x => x.FilePath). //group in case same file is added to multiple projects Select(x => new QuickFix { FileName = x.Key, Text = x.First().Name, Line = 1, Column = 1}); return new QuickFixResponse(docs); }
private DnxProject GetProjectContainingSourceFile(string name) { var controller = new ProjectSystemController(_context, null, null, _workspace); var request = new Request { FileName = name }; var response = controller.CurrentProject(request); return response.DnxProject; }
public async Task UpdateBuffer(Request request) { var buffer = request.Buffer; var changes = request.Changes; var updateRequest = request as UpdateBufferRequest; if (updateRequest != null && updateRequest.FromDisk) { buffer = File.ReadAllText(updateRequest.FileName); } if (request.FileName == null || (buffer == null && changes == null)) { return; } var documentIds = _workspace.CurrentSolution.GetDocumentIdsWithFilePath(request.FileName); if (!documentIds.IsEmpty) { if (changes == null) { var sourceText = SourceText.From(buffer); foreach (var documentId in documentIds) { _workspace.OnDocumentChanged(documentId, sourceText); } } else { foreach (var documentId in documentIds) { var document = _workspace.CurrentSolution.GetDocument(documentId); var sourceText = await document.GetTextAsync(); foreach (var change in request.Changes) { var startOffset = sourceText.Lines.GetPosition(new LinePosition(change.StartLine - 1, change.StartColumn - 1)); var endOffset = sourceText.Lines.GetPosition(new LinePosition(change.EndLine - 1, change.EndColumn - 1)); sourceText = sourceText.WithChanges(new[] { new TextChange(new TextSpan(startOffset, endOffset - startOffset), change.NewText) }); } _workspace.OnDocumentChanged(documentId, sourceText); } } } else if(buffer != null) { TryAddTransientDocument(request.FileName, buffer); } }
public async Task<IEnumerable<QuickFix>> MembersAsFlat(Request request) { var stack = new List<FileMemberElement>(await StructureComputer.Compute(_workspace.GetDocuments(request.FileName))); var ret = new List<QuickFix>(); while (stack.Count > 0) { var node = stack[0]; stack.Remove(node); ret.Add(node.Location); stack.AddRange(node.ChildNodes); } return ret; }
public void EnsureBufferUpdated(Request request) { if(request.Buffer == null || request.FileName == null) { return; } var sourceText = SourceText.From(request.Buffer); foreach (var documentId in CurrentSolution.GetDocumentIdsWithFilePath(request.FileName)) { OnDocumentChanged(documentId, sourceText); } }
public async Task<CodeFormatResponse> FormatDocument(Request request) { var document = _workspace.GetDocument(request.FileName); if (document == null) { return null; } var newText = await Formatting.GetFormattedDocument(_workspace, Options, document); return new CodeFormatResponse() { Buffer = newText }; }
public async Task<QuickFixResponse> GoToRegion(Request request) { var regions = new List<QuickFix>(); var document = _workspace.GetDocument(request.FileName); if (document != null) { var root = await document.GetSyntaxRootAsync(); var regionTrivias = root.DescendantNodesAndTokens() .Where(node => node.HasLeadingTrivia) .SelectMany(node => node.GetLeadingTrivia()) .Where(x => (x.RawKind == (int) SyntaxKind.RegionDirectiveTrivia || x.RawKind == (int) SyntaxKind.EndRegionDirectiveTrivia)); foreach (var regionTrivia in regionTrivias.Distinct()) { regions.Add(await GetQuickFix(regionTrivia.GetLocation())); } } return new QuickFixResponse(regions); }
public void UpdateBuffer(Request request) { if (request.Buffer == null || request.FileName == null) { return; } var documentIds = _workspace.CurrentSolution.GetDocumentIdsWithFilePath(request.FileName); if (!documentIds.IsEmpty) { var sourceText = SourceText.From(request.Buffer); foreach (var documentId in documentIds) { _workspace.OnDocumentChanged(documentId, sourceText); } } else { TryAddTransientDocument(request.FileName, request.Buffer); } }
public static async Task<NavigateResponse> Navigate(OmnisharpWorkspace workspace, Request request, Func<FileMemberElement, FileMemberElement, Request, bool> IsCloserNode) { var stack = new List<FileMemberElement>(await StructureComputer.Compute(workspace.GetDocuments(request.FileName))); var response = new NavigateResponse(); //Retain current line in case we dont need to navigate. response.Line = request.Line; response.Column = request.Column; FileMemberElement closestNode = null; FileMemberElement thisNode = null; while (stack.Count > 0) { var node = stack[0]; stack.Remove(node); var isCloserNode = IsCloserNode(node, closestNode, request); if (isCloserNode) { closestNode = node; } if (node.Location.Line == request.Line) { thisNode = node; } stack.AddRange(node.ChildNodes); } //If there is a closest node, use its line and column. //or if we are on the last node, adjust column. //if we are above the first or below the last node, do nothing. if (closestNode != null) { response.Line = closestNode.Location.Line; response.Column = closestNode.Location.Column; } else if (thisNode != null) { response.Column = thisNode.Location.Column; } return response; }
private async Task<InvocationContext> GetInvocation(Document document, Request request) { var sourceText = await document.GetTextAsync(); var position = sourceText.Lines.GetPosition(new LinePosition(request.Line - 1, request.Column - 1)); var tree = await document.GetSyntaxTreeAsync(); var node = tree.GetRoot().FindToken(position).Parent; while (node != null) { var invocation = node as InvocationExpressionSyntax; if (invocation != null && invocation.ArgumentList.FullSpan.IntersectsWith(position)) { return new InvocationContext() { SemanticModel = await document.GetSemanticModelAsync(), Position = position, Receiver = invocation.Expression, ArgumentList = invocation.ArgumentList }; } var objectCreation = node as ObjectCreationExpressionSyntax; if (objectCreation != null && objectCreation.ArgumentList.FullSpan.IntersectsWith(position)) { return new InvocationContext() { SemanticModel = await document.GetSemanticModelAsync(), Position = position, Receiver = objectCreation, ArgumentList = objectCreation.ArgumentList }; } node = node.Parent; } return null; }
public async Task<QuickFixResponse> CodeCheck(Request request) { var quickFixes = new List<QuickFix>(); var documents = request.FileName != null ? _workspace.GetDocuments(request.FileName) : _workspace.CurrentSolution.Projects.SelectMany(project => project.Documents); foreach (var document in documents) { var semanticModel = await document.GetSemanticModelAsync(); IEnumerable<Diagnostic> diagnostics = semanticModel.GetDiagnostics(); //script files can have custom directives such as #load which will be deemed invalid by Roslyn //we suppress the CS1024 diagnostic for script files for this reason. Roslyn will fix it later too, so this is temporary. if (document.SourceCodeKind != SourceCodeKind.Regular) { diagnostics = diagnostics.Where(diagnostic => diagnostic.Id != "CS1024"); } foreach (var quickFix in diagnostics.Select(MakeQuickFix)) { var existingQuickFix = quickFixes.FirstOrDefault(q => q.Equals(quickFix)); if (existingQuickFix == null) { quickFix.Projects.Add(document.Project.Name); quickFixes.Add(quickFix); } else { existingQuickFix.Projects.Add(document.Project.Name); } } } return new QuickFixResponse(quickFixes); }
public static bool IsCloserNodeDown(FileMemberElement candidateClosestNode, FileMemberElement closestNode, Request request) { return ((candidateClosestNode.Location.Line > request.Line) && (closestNode == null || candidateClosestNode.Location.Line < closestNode.Location.Line)); }
public async Task<NavigateResponse> NavigateDown(Request request) { return await Navigate(request, IsCloserNodeDown); }
private async Task<NavigateResponse> SendRequest(OmnisharpWorkspace workspace, string fileName, string fileContent, NavigateDirection upOrDown) { var initialCursorLineColumn = TestHelpers.GetLineAndColumnFromDollar(TestHelpers.RemovePercentMarker(fileContent)); var fileContentNoDollarMarker = TestHelpers.RemoveDollarMarker(fileContent); var controller = new OmnisharpController(workspace, new FakeOmniSharpOptions()); var request = new Request { Line = initialCursorLineColumn.Line, Column = initialCursorLineColumn.Column, FileName = fileName, Buffer = fileContentNoDollarMarker }; if (upOrDown == NavigateDirection.UP) { return await controller.NavigateUp(request); } else { return await controller.NavigateDown(request); } }
public static ActionExecutingContext CreateActionExecutingContext(Request req, object controller = null) { var actionContext = new ActionContext(null, null, null); var actionExecutingContext = new ActionExecutingContext(actionContext, new List<IFilter>(), new Dictionary<string, object> { { "request", req } }, controller); return actionExecutingContext; }
private async Task<SignatureHelp> GetSignatureHelp(string source) { var lineColumn = TestHelpers.GetLineAndColumnFromDollar(source); source = source.Replace("$", string.Empty); var request = new Request() { FileName = "dummy.cs", Line = lineColumn.Line, Column = lineColumn.Column, Buffer = source }; var workspace = TestHelpers.CreateSimpleWorkspace(source); var controller = new OmnisharpController(workspace, null); return await controller.GetSignatureHelp(request); }
public ObjectResult UpdateBuffer(Request request) { return new ObjectResult(true); }
private bool IsCloserNodeUp(FileMemberElement candidateClosestNode, FileMemberElement closestNode, Request request) { return ((candidateClosestNode.Location.Line < request.Line) && (closestNode == null || candidateClosestNode.Location.Line > closestNode.Location.Line)); }