[Lldb-commits] [PATCH] D155248: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-19 Thread David Goldman via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG3d1f89c2e37c: [lldb-vscode] Creating a new flag for 
adjusting the behavior of evaluation repl… (authored by ashgti, committed by 
dgoldman).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155248/new/

https://reviews.llvm.org/D155248

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/completions/TestVSCode_completions.py
  lldb/test/API/tools/lldb-vscode/console/TestVSCode_console.py
  lldb/test/API/tools/lldb-vscode/module/TestVSCode_module.py
  lldb/test/API/tools/lldb-vscode/startDebugging/TestVSCode_startDebugging.py
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
-  std::string text = std::string(GetString(arguments, "text"));
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
+  std::string text = GetString(arguments, "text").str();
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::SmallVector<::llvm::StringRef, 2> lines;
+llvm::StringRef(text).split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
+
+  if (g_vsc.DetectExpressionContext(frame, text) ==
+  ExpressionContext::Variable) {
 char command[] = "expression -- ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches so ignore the
+// first result.
+targets.reserve(matches.GetSize() - 1);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  llvm::json::Object item;
+  llvm::StringRef match_ref = match;
+  for (llvm::StringRef commit_point : {".", "->"}) {
+if (match_ref.contains(commit_point)) {
+  match_ref = match_ref.rsplit(commit_point).second;
+}
   }
-}
-EmplaceSafeString(item, "text", match_ref);
+  EmplaceSafeString(item, "text", match_ref);
 
-if (description.empty())
-  EmplaceSafeString(item, "label", match);
-else
-  EmplaceSafeString(item, "label", match + " -- " + description);
+  if (description.empty())
+EmplaceSafeString(item, "label", match);
+  else
+EmplaceSafeString(item, "label", match + " -- " + description);
 
-targets.emplace_back(std::move(item));
+  targets.emplace_back(std::move(item));
+}
   }
 
   body.try_emplace("targets", std::move(targets));
@@ -1223,12 +1235,17 @@
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
   lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
-  const auto 

[Lldb-commits] [PATCH] D155248: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-18 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 541728.
ashgti added a comment.

Updating patch.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155248/new/

https://reviews.llvm.org/D155248

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/completions/TestVSCode_completions.py
  lldb/test/API/tools/lldb-vscode/console/TestVSCode_console.py
  lldb/test/API/tools/lldb-vscode/module/TestVSCode_module.py
  lldb/test/API/tools/lldb-vscode/startDebugging/TestVSCode_startDebugging.py
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
-  std::string text = std::string(GetString(arguments, "text"));
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
+  std::string text = GetString(arguments, "text").str();
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::SmallVector<::llvm::StringRef, 2> lines;
+llvm::StringRef(text).split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
+
+  if (g_vsc.DetectExpressionContext(frame, text) ==
+  ExpressionContext::Variable) {
 char command[] = "expression -- ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches so ignore the
+// first result.
+targets.reserve(matches.GetSize() - 1);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  llvm::json::Object item;
+  llvm::StringRef match_ref = match;
+  for (llvm::StringRef commit_point : {".", "->"}) {
+if (match_ref.contains(commit_point)) {
+  match_ref = match_ref.rsplit(commit_point).second;
+}
   }
-}
-EmplaceSafeString(item, "text", match_ref);
+  EmplaceSafeString(item, "text", match_ref);
 
-if (description.empty())
-  EmplaceSafeString(item, "label", match);
-else
-  EmplaceSafeString(item, "label", match + " -- " + description);
+  if (description.empty())
+EmplaceSafeString(item, "label", match);
+  else
+EmplaceSafeString(item, "label", match + " -- " + description);
 
-targets.emplace_back(std::move(item));
+  targets.emplace_back(std::move(item));
+}
   }
 
   body.try_emplace("targets", std::move(targets));
@@ -1223,12 +1235,17 @@
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
   lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
-  const auto expression = GetString(arguments, "expression");
+  std::string expression = GetString(arguments, "expression").str();
   llvm::StringRef context = 

[Lldb-commits] [PATCH] D155248: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-15 Thread walter erquinigo via Phabricator via lldb-commits
wallace accepted this revision.
wallace added a comment.
This revision is now accepted and ready to land.

fingers crossed


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155248/new/

https://reviews.llvm.org/D155248

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D155248: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-13 Thread John Harrison via Phabricator via lldb-commits
ashgti added a reviewer: wallace.
ashgti added a comment.

Hi wallace, this is a second attempt at this change set including updates to 
existing tests to check the behavior changes. LMKWYT


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155248/new/

https://reviews.llvm.org/D155248

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D155248: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-13 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 540219.
ashgti added a comment.

Adjusting the startDebugging test.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155248/new/

https://reviews.llvm.org/D155248

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/completions/TestVSCode_completions.py
  lldb/test/API/tools/lldb-vscode/console/TestVSCode_console.py
  lldb/test/API/tools/lldb-vscode/module/TestVSCode_module.py
  lldb/test/API/tools/lldb-vscode/startDebugging/TestVSCode_startDebugging.py
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
-  std::string text = std::string(GetString(arguments, "text"));
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
+  std::string text = GetString(arguments, "text").str();
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::SmallVector<::llvm::StringRef, 2> lines;
+llvm::StringRef(text).split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
+
+  if (g_vsc.DetectExpressionContext(frame, text) ==
+  ExpressionContext::Variable) {
 char command[] = "expression -- ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches so ignore the
+// first result.
+targets.reserve(matches.GetSize() - 1);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  llvm::json::Object item;
+  llvm::StringRef match_ref = match;
+  for (llvm::StringRef commit_point : {".", "->"}) {
+if (match_ref.contains(commit_point)) {
+  match_ref = match_ref.rsplit(commit_point).second;
+}
   }
-}
-EmplaceSafeString(item, "text", match_ref);
+  EmplaceSafeString(item, "text", match_ref);
 
-if (description.empty())
-  EmplaceSafeString(item, "label", match);
-else
-  EmplaceSafeString(item, "label", match + " -- " + description);
+  if (description.empty())
+EmplaceSafeString(item, "label", match);
+  else
+EmplaceSafeString(item, "label", match + " -- " + description);
 
-targets.emplace_back(std::move(item));
+  targets.emplace_back(std::move(item));
+}
   }
 
   body.try_emplace("targets", std::move(targets));
@@ -1223,12 +1235,17 @@
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
   lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
-  const auto expression = GetString(arguments, "expression");
+  std::string expression = GetString(arguments, "expression").str();
   llvm::S

[Lldb-commits] [PATCH] D155248: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-13 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 540216.
ashgti added a comment.

Applying formatting.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155248/new/

https://reviews.llvm.org/D155248

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/completions/TestVSCode_completions.py
  lldb/test/API/tools/lldb-vscode/console/TestVSCode_console.py
  lldb/test/API/tools/lldb-vscode/module/TestVSCode_module.py
  lldb/test/API/tools/lldb-vscode/startDebugging/TestVSCode_startDebugging.py
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
-  std::string text = std::string(GetString(arguments, "text"));
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
+  std::string text = GetString(arguments, "text").str();
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::SmallVector<::llvm::StringRef, 2> lines;
+llvm::StringRef(text).split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
+
+  if (g_vsc.DetectExpressionContext(frame, text) ==
+  ExpressionContext::Variable) {
 char command[] = "expression -- ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches so ignore the
+// first result.
+targets.reserve(matches.GetSize() - 1);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  llvm::json::Object item;
+  llvm::StringRef match_ref = match;
+  for (llvm::StringRef commit_point : {".", "->"}) {
+if (match_ref.contains(commit_point)) {
+  match_ref = match_ref.rsplit(commit_point).second;
+}
   }
-}
-EmplaceSafeString(item, "text", match_ref);
+  EmplaceSafeString(item, "text", match_ref);
 
-if (description.empty())
-  EmplaceSafeString(item, "label", match);
-else
-  EmplaceSafeString(item, "label", match + " -- " + description);
+  if (description.empty())
+EmplaceSafeString(item, "label", match);
+  else
+EmplaceSafeString(item, "label", match + " -- " + description);
 
-targets.emplace_back(std::move(item));
+  targets.emplace_back(std::move(item));
+}
   }
 
   body.try_emplace("targets", std::move(targets));
@@ -1223,12 +1235,17 @@
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
   lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
-  const auto expression = GetString(arguments, "expression");
+  std::string expression = GetString(arguments, "expression").str();
   llvm::StringRef conte

[Lldb-commits] [PATCH] D155248: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.

2023-07-13 Thread John Harrison via Phabricator via lldb-commits
ashgti created this revision.
Herald added a project: All.
ashgti requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

This adds a new flag and lldb runtime command to allow users to manage the 
behavior of the lldb-vscode evaluate repl request.

When evaluating a repl context this now has runtime managed flag for control 
how the repl behaviors with the follow values:

- `variable` - the existing behavior, with this mode requests are evaluted in 
the current frame context as variable expressions. To trigger a lldb command 
prefix an expression with ` and it will be evaluted as an lldb command.
- `command` - all expressions are evaluated as lldb commands.
- `auto` - An alternative mode that will attempt to determine if the expression 
is an lldb command or a variable expression. Based off the intepreted results 
the expression will be evaluted either as a command or an expression.

Additionally, I enabled completions and ensured they work with the new repl 
expression behavior to provide auto-completes.

This commit includes updates to the tests to verify the new behavior after the 
previous failures from submitting https://reviews.llvm.org/D154030.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D155248

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/completions/TestVSCode_completions.py
  lldb/test/API/tools/lldb-vscode/console/TestVSCode_console.py
  lldb/test/API/tools/lldb-vscode/module/TestVSCode_module.py
  lldb/test/API/tools/lldb-vscode/startDebugging/TestVSCode_startDebugging.py
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/VSCode.cpp
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
-  std::string text = std::string(GetString(arguments, "text"));
+
+  // If we have a frame, try to set the context for variable completions.
+  lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
+  if (frame.IsValid()) {
+frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
+frame.GetThread().SetSelectedFrame(frame.GetFrameID());
+  }
+
+  std::string text = GetString(arguments, "text").str();
   auto original_column = GetSigned(arguments, "column", text.size());
-  auto actual_column = original_column - 1;
+  auto original_line = GetSigned(arguments, "line", 1);
+  auto offset = original_column - 1;
+  if (original_line > 1) {
+llvm::SmallVector<::llvm::StringRef, 2> lines;
+llvm::StringRef(text).split(lines, '\n');
+for (int i = 0; i < original_line - 1; i++) {
+  offset += lines[i].size();
+}
+  }
   llvm::json::Array targets;
-  // NOTE: the 'line' argument is not needed, as multiline expressions
-  // work well already
-  // TODO: support frameID. Currently
-  // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
-  // is frame-unaware.
-
-  if (!text.empty() && text[0] == '`') {
-text = text.substr(1);
-actual_column--;
-  } else {
+
+  if (g_vsc.DetectExpressionContext(frame, text) ==
+  ExpressionContext::Variable) {
 char command[] = "expression -- ";
 text = command + text;
-actual_column += strlen(command);
+offset += strlen(command);
   }
   lldb::SBStringList matches;
   lldb::SBStringList descriptions;
-  g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
-  text.c_str(), actual_column, 0, -1, matches, descriptions);
-  size_t count = std::min((uint32_t)100, matches.GetSize());
-  targets.reserve(count);
-  for (size_t i = 0; i < count; i++) {
-std::string match = matches.GetStringAtIndex(i);
-std::string description = descriptions.GetStringAtIndex(i);
-
-llvm::json::Object item;
-
-llvm::StringRef match_ref = match;
-for (llvm::StringRef commit_point : {".", "->"}) {
-  if (match_ref.contains(commit_point)) {
-match_ref = match_ref.rsplit(commit_point).second;
+
+  if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
+  text.c_str(), offset, 0, 100, matches, descriptions)) {
+// The first element is the common substring after the cursor position for
+// all the matches. The rest of the elements are the matches so ignore the
+// first result.
+targets.reserve(matches.GetSize() - 1);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+  llvm::json::Object item;
+  llvm::StringRef match_ref = match;
+  for (llvm::StringRef commit_p