public void UpdateBufferFindsProjectBasedOnNearestPath()
        {
            var workspace = new OmnisharpWorkspace();


            TestHelpers.AddProjectToWorkspace(workspace, Path.Combine("src", "root", "foo.csproj"),
                new[] { "" },
                new Dictionary<string, string>() { { Path.Combine("src", "root", "foo.cs"), "class C1 {}" } });

            TestHelpers.AddProjectToWorkspace(workspace, Path.Combine("src", "root", "foo", "bar", "insane.csproj"),
                new[] { "" },
                new Dictionary<string, string>() { { Path.Combine("src", "root", "foo", "bar", "nested", "code.cs"), "class C2 {}" } });

            workspace.BufferManager.UpdateBuffer(new Request() { FileName = Path.Combine("src", "root", "bar.cs"), Buffer = "enum E {}" });
            var documents = workspace.GetDocuments(Path.Combine("src", "root", "bar.cs"));
            Assert.Equal(1, documents.Count());
            Assert.Equal(Path.Combine("src", "root", "foo.csproj"), documents.ElementAt(0).Project.FilePath);
            Assert.Equal(2, documents.ElementAt(0).Project.Documents.Count());

            workspace.BufferManager.UpdateBuffer(new Request() { FileName = Path.Combine("src", "root", "foo", "bar", "nested", "paths", "dance.cs"), Buffer = "enum E {}" });
            documents = workspace.GetDocuments(Path.Combine("src", "root", "foo", "bar", "nested", "paths", "dance.cs"));
            Assert.Equal(1, documents.Count());
            Assert.Equal(Path.Combine("src", "root", "foo", "bar", "insane.csproj"), documents.ElementAt(0).Project.FilePath);
            Assert.Equal(2, documents.ElementAt(0).Project.Documents.Count());
        }
        public async Task UpdateBufferFindsProjectBasedOnNearestPath()
        {
            var workspace = new OmnisharpWorkspace(
                new HostServicesAggregator(
                    Enumerable.Empty <IHostServicesProvider>()));

            await TestHelpers.AddProjectToWorkspace(workspace, Path.Combine("src", "root", "foo.csproj"),
                                                    new[] { "" },
                                                    new Dictionary <string, string>() { { Path.Combine("src", "root", "foo.cs"), "class C1 {}" } });

            await TestHelpers.AddProjectToWorkspace(workspace, Path.Combine("src", "root", "foo", "bar", "insane.csproj"),
                                                    new[] { "" },
                                                    new Dictionary <string, string>() { { Path.Combine("src", "root", "foo", "bar", "nested", "code.cs"), "class C2 {}" } });

            await workspace.BufferManager.UpdateBuffer(new Request()
            {
                FileName = Path.Combine("src", "root", "bar.cs"), Buffer = "enum E {}"
            });

            var documents = workspace.GetDocuments(Path.Combine("src", "root", "bar.cs"));

            Assert.Equal(1, documents.Count());
            Assert.Equal(Path.Combine("src", "root", "foo.csproj"), documents.ElementAt(0).Project.FilePath);
            Assert.Equal(2, documents.ElementAt(0).Project.Documents.Count());

            await workspace.BufferManager.UpdateBuffer(new Request()
            {
                FileName = Path.Combine("src", "root", "foo", "bar", "nested", "paths", "dance.cs"), Buffer = "enum E {}"
            });

            documents = workspace.GetDocuments(Path.Combine("src", "root", "foo", "bar", "nested", "paths", "dance.cs"));
            Assert.Equal(1, documents.Count());
            Assert.Equal(Path.Combine("src", "root", "foo", "bar", "insane.csproj"), documents.ElementAt(0).Project.FilePath);
            Assert.Equal(2, documents.ElementAt(0).Project.Documents.Count());
        }
Example #3
0
        public static async Task <QuickFix> GetQuickFix(OmnisharpWorkspace workspace, Location location)
        {
            if (!location.IsInSource)
            {
                throw new Exception("Location is not in the source tree");
            }

            var lineSpan   = location.GetLineSpan();
            var path       = lineSpan.Path;
            var documents  = workspace.GetDocuments(path);
            var line       = lineSpan.StartLinePosition.Line;
            var syntaxTree = await documents.First().GetSyntaxTreeAsync();

            var text = syntaxTree.GetText().Lines[line].ToString();

            return(new QuickFix
            {
                Text = text.Trim(),
                FileName = path,
                Line = line + 1,
                Column = lineSpan.StartLinePosition.Character + 1,
                EndLine = lineSpan.EndLinePosition.Line + 1,
                EndColumn = lineSpan.EndLinePosition.Character + 1,
                Projects = documents.Select(document => document.Project.Name).ToArray()
            });
        }
 public async Task <FileMemberTree> Handle(MembersTreeRequest request)
 {
     return(new FileMemberTree()
     {
         TopLevelTypeDefinitions = await StructureComputer.Compute(_workspace.GetDocuments(request.FileName), _discovers)
     });
 }
Example #5
0
        private QuickFix ConvertSymbol(ISymbol symbol, Location location)
        {
            var lineSpan  = location.GetLineSpan();
            var path      = lineSpan.Path;
            var documents = _workspace.GetDocuments(path);

            var format = SymbolDisplayFormat.MinimallyQualifiedFormat;

            format = format.WithMemberOptions(format.MemberOptions
                                              ^ SymbolDisplayMemberOptions.IncludeContainingType
                                              ^ SymbolDisplayMemberOptions.IncludeType);

            format = format.WithKindOptions(SymbolDisplayKindOptions.None);

            return(new SymbolLocation
            {
                Text = symbol.ToDisplayString(format),
                Kind = symbol.GetKind(),
                FileName = path,
                Line = lineSpan.StartLinePosition.Line + 1,
                Column = lineSpan.StartLinePosition.Character + 1,
                EndLine = lineSpan.EndLinePosition.Line + 1,
                EndColumn = lineSpan.EndLinePosition.Character + 1,
                Projects = documents.Select(document => document.Project.Name).ToArray()
            });
        }
        public Task <FileCloseResponse> Handle(FileCloseRequest request)
        {
            var documents = _workspace.GetDocuments(request.FileName);

            foreach (var document in documents)
            {
                _workspace.CloseDocument(document.Id);
            }
            return(Task.FromResult(new FileCloseResponse()));
        }
        public async Task <IEnumerable <QuickFix> > Handle(MembersFlatRequest 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);
        }
        private async Task <DiagnosticResult> ProcessNextItem(string filePath)
        {
            var documents = _workspace.GetDocuments(filePath);
            var items     = new List <DiagnosticLocation>();

            if (documents.Any())
            {
                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 = items.FirstOrDefault(q => q.Equals(quickFix));
                        if (existingQuickFix == null)
                        {
                            quickFix.Projects.Add(document.Project.Name);
                            items.Add(quickFix);
                        }
                        else
                        {
                            existingQuickFix.Projects.Add(document.Project.Name);
                        }
                    }
                }
            }

            return(new DiagnosticResult()
            {
                FileName = filePath,
                QuickFixes = items
            });
        }
        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;
        }
Example #10
0
        public async Task <IEnumerable <AutoCompleteResponse> > Handle(AutoCompleteRequest request)
        {
            var documents      = _workspace.GetDocuments(request.FileName);
            var wordToComplete = request.WordToComplete;
            var completions    = new HashSet <AutoCompleteResponse>();

            foreach (var document in documents)
            {
                var sourceText = await document.GetTextAsync();

                var position = sourceText.Lines.GetPosition(new LinePosition(request.Line - 1, request.Column - 1));
                var model    = await document.GetSemanticModelAsync();

                AddKeywords(completions, model, position, request.WantKind, wordToComplete);

                var symbols = Recommender.GetRecommendedSymbolsAtPosition(model, position, _workspace);

                foreach (var symbol in symbols.Where(s => s.Name.IsValidCompletionFor(wordToComplete)))
                {
                    if (request.WantSnippet)
                    {
                        foreach (var completion in MakeSnippetedResponses(request, symbol))
                        {
                            completions.Add(completion);
                        }
                    }
                    else
                    {
                        completions.Add(MakeAutoCompleteResponse(request, symbol));
                    }
                }
            }

            return(completions
                   .OrderByDescending(c => c.CompletionText.IsValidCompletionStartsWithExactCase(wordToComplete))
                   .ThenByDescending(c => c.CompletionText.IsValidCompletionStartsWithIgnoreCase(wordToComplete))
                   .ThenByDescending(c => c.CompletionText.IsCamelCaseMatch(wordToComplete))
                   .ThenByDescending(c => c.CompletionText.IsSubsequenceMatch(wordToComplete))
                   .ThenBy(c => c.CompletionText));
        }
Example #11
0
        public async Task <QuickFixResponse> Handle(CodeCheckRequest 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 async Task<QuickFix> GetQuickFix(OmnisharpWorkspace workspace, Location location)
        {
            if (!location.IsInSource)
                throw new Exception("Location is not in the source tree");

            var lineSpan = location.GetLineSpan();
            var path = lineSpan.Path;
            var documents = workspace.GetDocuments(path);
            var line = lineSpan.StartLinePosition.Line;
            var syntaxTree = await documents.First().GetSyntaxTreeAsync();
            var text = syntaxTree.GetText().Lines[line].ToString();

            return new QuickFix
            {
                Text = text.Trim(),
                FileName = path,
                Line = line + 1,
                Column = lineSpan.StartLinePosition.Character + 1,
                EndLine = lineSpan.EndLinePosition.Line + 1,
                EndColumn = lineSpan.EndLinePosition.Character + 1,
                Projects = documents.Select(document => document.Project.Name).ToArray()
            };
        }
Example #13
0
        public async Task <IEnumerable <AutoCompleteResponse> > Handle(AutoCompleteRequest request)
        {
            var documents      = _workspace.GetDocuments(request.FileName);
            var wordToComplete = request.WordToComplete;
            var completions    = new HashSet <AutoCompleteResponse>();

            foreach (var document in documents)
            {
                var sourceText = await document.GetTextAsync();

                var position = sourceText.Lines.GetPosition(new LinePosition(request.Line, request.Column));

                var service        = CompletionService.GetService(document);
                var completionList = await service.GetCompletionsAsync(document, position);

                // Add keywords from the completion list. We'll use the recommender service to get symbols
                // to create snippets from.

                foreach (var item in completionList.Items)
                {
                    if (item.Tags.Contains(CompletionTags.Keyword))
                    {
                        // Note: For keywords, we'll just assume that the completion text is the same
                        // as the display text.
                        var keyword = item.DisplayText;
                        if (keyword.IsValidCompletionFor(wordToComplete))
                        {
                            var response = new AutoCompleteResponse()
                            {
                                CompletionText = item.DisplayText,
                                DisplayText    = item.DisplayText,
                                Snippet        = item.DisplayText,
                                Kind           = request.WantKind ? "Keyword" : null
                            };

                            completions.Add(response);
                        }
                    }
                }

                var model = await document.GetSemanticModelAsync();

                var symbols = await Recommender.GetRecommendedSymbolsAtPositionAsync(model, position, _workspace);

                foreach (var symbol in symbols.Where(s => s.Name.IsValidCompletionFor(wordToComplete)))
                {
                    if (request.WantSnippet)
                    {
                        foreach (var completion in MakeSnippetedResponses(request, symbol))
                        {
                            completions.Add(completion);
                        }
                    }
                    else
                    {
                        completions.Add(MakeAutoCompleteResponse(request, symbol));
                    }
                }
            }

            return(completions
                   .OrderByDescending(c => c.CompletionText.IsValidCompletionStartsWithExactCase(wordToComplete))
                   .ThenByDescending(c => c.CompletionText.IsValidCompletionStartsWithIgnoreCase(wordToComplete))
                   .ThenByDescending(c => c.CompletionText.IsCamelCaseMatch(wordToComplete))
                   .ThenByDescending(c => c.CompletionText.IsSubsequenceMatch(wordToComplete))
                   .ThenBy(c => c.CompletionText));
        }
        public async Task <SignatureHelp> Handle(SignatureHelpRequest 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);
        }
Example #15
0
        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);
        }