Commit 2c7c528d authored by Walter Erquinigo's avatar Walter Erquinigo
Browse files

[lldb-vscode] support the completion request

Summary:
The DAP has a completion request that has been unimplemented. It allows showing autocompletion tokens inside the Debug Console.
I implemented it in a very simple fashion mimicking what the user would see when autocompleting an expression inside the CLI.
There are two cases: normal variables and commands. The latter occurs when a text is prepepended with ` in the Debug Console.
These two cases work well and have tests.

Reviewers: clayborg, aadsm

Subscribers: lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D69873
parent 979da9a4
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
CXX_SOURCES := main.cpp

include Makefile.rules
+117 −0
Original line number Diff line number Diff line
"""
Test lldb-vscode completions request
"""

from __future__ import print_function

import lldbvscode_testcase
import unittest2
import vscode
from lldbsuite.test import lldbutil
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *


class TestVSCode_variables(lldbvscode_testcase.VSCodeTestCaseBase):

    mydir = TestBase.compute_mydir(__file__)

    def verify_completions(self, actual_list, expected_list, not_expected_list=[]):
        for expected_item in expected_list:
            self.assertTrue(expected_item in actual_list)

        for not_expected_item in not_expected_list:
            self.assertFalse(not_expected_item in actual_list)

    @skipIfWindows
    @skipIfDarwin # Skip this test for now until we can figure out why tings aren't working on build bots
    @no_debug_info_test
    def test_completions(self):
        """
            Tests the completion request at different breakpoints
        """
        program = self.getBuildArtifact("a.out")
        self.build_and_launch(program)
        source = "main.cpp"
        breakpoint1_line = line_number(source, "// breakpoint 1")
        breakpoint2_line = line_number(source, "// breakpoint 2")
        breakpoint_ids = self.set_source_breakpoints(
            source, [breakpoint1_line, breakpoint2_line]
        )
        self.continue_to_next_stop()

        # shouldn't see variables inside main
        self.verify_completions(
            self.vscode.get_completions("var"),
            [
                {
                    "text": "var",
                    "label": "var -- vector<basic_string<char, char_traits<char>, allocator<char> >, allocator<basic_string<char, char_traits<char>, allocator<char> > > > &",
                }
            ],
            [{"text": "var1", "label": "var1 -- int &"}],
        )

        # should see global keywords but not variables inside main
        self.verify_completions(
            self.vscode.get_completions("str"),
            [{"text": "struct", "label": "struct"}],
            [{"text": "str1", "label": "str1 -- std::string &"}],
        )

        self.continue_to_next_stop()

        # should see variables from main but not from the other function
        self.verify_completions(
            self.vscode.get_completions("var"),
            [
                {"text": "var1", "label": "var1 -- int &"},
                {"text": "var2", "label": "var2 -- int &"},
            ],
            [
                {
                    "text": "var",
                    "label": "var -- vector<basic_string<char, char_traits<char>, allocator<char> >, allocator<basic_string<char, char_traits<char>, allocator<char> > > > &",
                }
            ],
        )

        self.verify_completions(
            self.vscode.get_completions("str"),
            [
                {"text": "struct", "label": "struct"},
                {"text": "str1", "label": "str1 -- string &"},
            ],
        )

        # should complete arbitrary commands including word starts
        self.verify_completions(
            self.vscode.get_completions("`log enable  "),
            [{"text": "gdb-remote", "label": "gdb-remote"}],
        )

        # should complete expressions with quotes inside
        self.verify_completions(
            self.vscode.get_completions('`expr " "; typed'),
            [{"text": "typedef", "label": "typedef"}],
        )

        # should complete an incomplete quoted token
        self.verify_completions(
            self.vscode.get_completions('`setting "se'),
            [
                {
                    "text": "set",
                    "label": "set -- Set the value of the specified debugger setting.",
                }
            ],
        )
        self.verify_completions(
            self.vscode.get_completions("`'comm"),
            [
                {
                    "text": "command",
                    "label": "command -- Commands for managing custom LLDB commands.",
                }
            ],
        )
+16 −0
Original line number Diff line number Diff line
#include <string>
#include <vector>

int fun(std::vector<std::string> var) {
  return var.size(); // breakpoint 1
}

int main(int argc, char const *argv[]) {
  int var1 = 0;
  int var2 = 1;
  std::string str1 = "a";
  std::string str2 = "b";
  std::vector<std::string> vec;
  fun(vec);
  return 0; // breakpoint 2
}
+1 −1
Original line number Diff line number Diff line
@@ -254,7 +254,7 @@ class VSCodeTestCaseBase(TestBase):
        '''Sending launch request to vscode
        '''

        # Make sure we disconnet and terminate the VSCode debug adaptor,
        # Make sure we disconnect and terminate the VSCode debug adapter,
        # if we throw an exception during the test case
        def cleanup():
            self.vscode.request_disconnect(terminateDebuggee=True)
+1 −1
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ class TestVSCode_variables(lldbvscode_testcase.VSCodeTestCaseBase):
        source = 'main.cpp'
        breakpoint1_line = line_number(source, '// breakpoint 1')
        lines = [breakpoint1_line]
        # Set breakoint in the thread function so we can step the threads
        # Set breakpoint in the thread function so we can step the threads
        breakpoint_ids = self.set_source_breakpoints(source, lines)
        self.assertTrue(len(breakpoint_ids) == len(lines),
                        "expect correct number of breakpoints")
Loading