[Lldb-commits] [PATCH] D154030: [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-11 Thread John Harrison via Phabricator via lldb-commits
ashgti marked an inline comment as done.
ashgti added a comment.

In D154030#4491470 , @rastogishubham 
wrote:

> I am reverting the change for now, I apologize for any inconvenience

Thanks for reverting that, I'll take a look at the tests and double check them 
on linux as well.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

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


[Lldb-commits] [PATCH] D154030: [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-11 Thread Shubham Sandeep Rastogi via Phabricator via lldb-commits
rastogishubham added a comment.

I am reverting the change for now, I apologize for any inconvenience


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

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


[Lldb-commits] [PATCH] D154030: [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-11 Thread Shubham Sandeep Rastogi via Phabricator via lldb-commits
rastogishubham added a comment.

It looks like this change is breaking some lldb tests. 
https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/57586/consoleFull#-1731262255a1ca8a51-895e-46c6-af87-ce24fa4cd561

- TEST 'lldb-api :: tools/lldb-vscode/console/TestVSCode_console.py' FAILED 


Script:
---

/usr/local/Frameworks/Python.framework/Versions/3.10/bin/python3.10 
/Users/buildslave/jenkins/workspace/lldb-cmake/llvm-project/lldb/test/API/dotest.py
 -u CXXFLAGS -u CFLAGS --codesign-identity lldb_codesign --env 
LLVM_LIBS_DIR=/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/./lib 
--env 
LLVM_INCLUDE_DIR=/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/include
 --env 
LLVM_TOOLS_DIR=/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/./bin 
--libcxx-include-dir 
/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/include/c++/v1 
--libcxx-library-dir 
/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/lib --arch x86_64 
--build-dir 
/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/lldb-test-build.noindex
 --lldb-module-cache-dir 
/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/lldb-test-build.noindex/module-cache-lldb/lldb-api
 --clang-module-cache-dir 
/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/lldb-test-build.noindex/module-cache-clang/lldb-api
 --executable 
/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/./bin/lldb --compiler 
/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/./bin/clang 
--dsymutil 
/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/./bin/dsymutil 
--llvm-tools-dir 
/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/./bin --lldb-libs-dir 
/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/./lib --build-dir 
/Users/buildslave/jenkins/workspace/lldb-cmake/lldb-build/lldb-test-build.noindex
 -t --env TERM=vt100 
/Users/buildslave/jenkins/workspace/lldb-cmake/llvm-project/lldb/test/API/tools/lldb-vscode/console
 -p TestVSCode_console.py


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

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


[Lldb-commits] [PATCH] D154030: [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-11 Thread David Goldman via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG16317f1ced77: [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/D154030/new/

https://reviews.llvm.org/D154030

Files:
  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,63 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // 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 = std::string(GetString(arguments, "text"));
   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::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.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 {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(frame, text) ==
+  ExpressionContext::Variable) {
+char command[] = "frame variable ";
 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.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+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 +1236,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 = GetString(arguments, "context");
 
-  if (!expression.empty() && expression[0] == '`') {
-auto result =
-RunLLDBCommands(llvm::StringRef(), 

[Lldb-commits] [PATCH] D154030: [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-11 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.

nice!!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

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


[Lldb-commits] [PATCH] D154030: [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-11 Thread John Harrison via Phabricator via lldb-commits
ashgti marked 2 inline comments as done.
ashgti added inline comments.



Comment at: lldb/tools/lldb-vscode/Options.td:20-38
+def port: S<"port">,
   MetaVarName<"">,
   HelpText<"Communicate with the lldb-vscode tool over the defined port.">;
 def: Separate<["-"], "p">,
   Alias,
   HelpText<"Alias for --port">;
 

wallace wrote:
> +1
Moving this into its own commit.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

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


[Lldb-commits] [PATCH] D154030: [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-11 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 539182.
ashgti marked an inline comment as done.
ashgti added a comment.

Apply clang-format and split out some parts of this into smaller commits.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

Files:
  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,63 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // 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 = std::string(GetString(arguments, "text"));
   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::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.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 {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(frame, text) ==
+  ExpressionContext::Variable) {
+char command[] = "frame variable ";
 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.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+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 +1236,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 = GetString(arguments, "context");
 
-  if (!expression.empty() && expression[0] == '`') {
-auto result =
-RunLLDBCommands(llvm::StringRef(), {std::string(expression.substr(1))});
+  if (context 

[Lldb-commits] [PATCH] D154030: [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-10 Thread walter erquinigo via Phabricator via lldb-commits
wallace added a comment.

Could you split the changes to the selected thread out of this? I'm seeing two 
features being implemented in this patch.
Other than that, it looks pretty good!




Comment at: lldb/tools/lldb-vscode/Options.td:20-38
+def port: S<"port">,
   MetaVarName<"">,
   HelpText<"Communicate with the lldb-vscode tool over the defined port.">;
 def: Separate<["-"], "p">,
   Alias,
   HelpText<"Alias for --port">;
 

+1



Comment at: lldb/tools/lldb-vscode/VSCode.cpp:768
 
+  return true; 
+}

use clang-format please



Comment at: lldb/tools/lldb-vscode/VSCode.h:89
+
+/// A huersitic for determining the context of an evaluation.
+enum class ExpressionContext {

typo


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

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


[Lldb-commits] [PATCH] D154030: [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-05 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 537538.
ashgti added a comment.

Removing a log statement that is not needed.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  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
@@ -191,6 +191,27 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
 }
 
+// Send a "continued" event to indicate the process is in the running state.
+void SendContinuedEvent() {
+  lldb::SBProcess process = g_vsc.target.GetProcess();
+  if (!process.IsValid()) {
+return;
+  }
+
+  // If the focus thread is not set then we haven't reported any thread status
+  // to the client, so nothing to report.
+  if (g_vsc.focus_tid == LLDB_INVALID_THREAD_ID) {
+return;
+  }
+
+  llvm::json::Object event(CreateEventObject("continued"));
+  llvm::json::Object body;
+  body.try_emplace("threadId", (int64_t)g_vsc.focus_tid);  
+  body.try_emplace("allThreadsContinued", true);
+  event.try_emplace("body", std::move(body));
+  g_vsc.SendJSON(llvm::json::Value(std::move(event)));
+}
+
 // Send a "terminated" event to indicate the process is done being
 // debugged.
 void SendTerminatedEvent() {
@@ -252,7 +273,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -468,6 +489,7 @@
 break;
   case lldb::eStateRunning:
 g_vsc.WillContinue();
+SendContinuedEvent();
 break;
   case lldb::eStateExited:
 // When restarting, we can get an "exited" event for the process we
@@ -767,9 +789,10 @@
   FillResponse(request, response);
   lldb::SBProcess process = g_vsc.target.GetProcess();
   auto arguments = request.getObject("arguments");
-  // Remember the thread ID that caused the resume so we can set the
-  // "threadCausedFocus" boolean value in the "stopped" events.
-  g_vsc.focus_tid = GetUnsigned(arguments, "threadId", LLDB_INVALID_THREAD_ID);
+  // Invalidate the focused, continuing the process may land on any thread, not
+  // just the current thread in which case we want the client to update focus to
+  // the new stopped thread.
+  g_vsc.focus_tid = LLDB_INVALID_THREAD_ID;
   lldb::SBError error = process.Continue();
   llvm::json::Object body;
   body.try_emplace("allThreadsContinued", true);
@@ -1065,50 +1088,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // 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 = std::string(GetString(arguments, "text"));
   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::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.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 {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(frame, text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 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 < 

[Lldb-commits] [PATCH] D154030: [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-05 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 537536.
ashgti added a comment.

Uploading latest diff


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  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
@@ -191,6 +191,27 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
 }
 
+// Send a "continued" event to indicate the process is in the running state.
+void SendContinuedEvent() {
+  lldb::SBProcess process = g_vsc.target.GetProcess();
+  if (!process.IsValid()) {
+return;
+  }
+
+  // If the focus thread is not set then we haven't reported any thread status
+  // to the client, so nothing to report.
+  if (g_vsc.focus_tid == LLDB_INVALID_THREAD_ID) {
+return;
+  }
+
+  llvm::json::Object event(CreateEventObject("continued"));
+  llvm::json::Object body;
+  body.try_emplace("threadId", (int64_t)g_vsc.focus_tid);  
+  body.try_emplace("allThreadsContinued", true);
+  event.try_emplace("body", std::move(body));
+  g_vsc.SendJSON(llvm::json::Value(std::move(event)));
+}
+
 // Send a "terminated" event to indicate the process is done being
 // debugged.
 void SendTerminatedEvent() {
@@ -252,7 +273,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -468,6 +489,7 @@
 break;
   case lldb::eStateRunning:
 g_vsc.WillContinue();
+SendContinuedEvent();
 break;
   case lldb::eStateExited:
 // When restarting, we can get an "exited" event for the process we
@@ -767,9 +789,10 @@
   FillResponse(request, response);
   lldb::SBProcess process = g_vsc.target.GetProcess();
   auto arguments = request.getObject("arguments");
-  // Remember the thread ID that caused the resume so we can set the
-  // "threadCausedFocus" boolean value in the "stopped" events.
-  g_vsc.focus_tid = GetUnsigned(arguments, "threadId", LLDB_INVALID_THREAD_ID);
+  // Invalidate the focused, continuing the process may land on any thread, not
+  // just the current thread in which case we want the client to update focus to
+  // the new stopped thread.
+  g_vsc.focus_tid = LLDB_INVALID_THREAD_ID;
   lldb::SBError error = process.Continue();
   llvm::json::Object body;
   body.try_emplace("allThreadsContinued", true);
@@ -1065,50 +1088,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // 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 = std::string(GetString(arguments, "text"));
   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::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.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 {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(frame, text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 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++) {
-

[Lldb-commits] [PATCH] D154030: [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-05 Thread John Harrison via Phabricator via lldb-commits
ashgti added inline comments.



Comment at: lldb/tools/lldb-vscode/JSONUtils.h:239
+/// useful to ensure the same column provided by the setBreakpoints request
+/// are returned to the IDE as a fallback.
 ///

DavidSpickett wrote:
> Appears that this got clang-formatted accidentally. Formatting it is fine but 
> put it in an NFC change if you're gonna do that.
> 
> If you aren't already using it, the clang-format-diff script will help you 
> limit formatting to only what you've edited (with occasional extra bits): 
> https://clang.llvm.org/docs/ClangFormat.html
I had another commit (https://reviews.llvm.org/D154029) that touched this area 
of the code so I think thats how this snuck in. Reverted this change.



Comment at: lldb/tools/lldb-vscode/VSCode.cpp:797
+g_vsc.repl_mode = ReplMode::Variable;
+result.AppendMessage("lldb-vscode repl-mode variable set.");
+  } else if (new_mode == "command") {

DavidSpickett wrote:
> There is AppendMessageWithFormat that you could use to avoid repeating the 
> string here.
Do you mean Printf? Switched to that instead.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

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


[Lldb-commits] [PATCH] D154030: [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-05 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 537496.
ashgti marked 4 inline comments as done.
ashgti added a comment.

Updating the behavior of auto mode to try to evalute local variables over lldb 
commands.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  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
@@ -252,7 +252,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // 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 = std::string(GetString(arguments, "text"));
   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::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.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 {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 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.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+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;
 

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

2023-06-30 Thread David Spickett via Phabricator via lldb-commits
DavidSpickett added a comment.

Some random comments, I'll leave the real review to the VSCode experts.




Comment at: lldb/tools/lldb-vscode/JSONUtils.h:239
+/// useful to ensure the same column provided by the setBreakpoints request
+/// are returned to the IDE as a fallback.
 ///

Appears that this got clang-formatted accidentally. Formatting it is fine but 
put it in an NFC change if you're gonna do that.

If you aren't already using it, the clang-format-diff script will help you 
limit formatting to only what you've edited (with occasional extra bits): 
https://clang.llvm.org/docs/ClangFormat.html



Comment at: lldb/tools/lldb-vscode/VSCode.cpp:797
+g_vsc.repl_mode = ReplMode::Variable;
+result.AppendMessage("lldb-vscode repl-mode variable set.");
+  } else if (new_mode == "command") {

There is AppendMessageWithFormat that you could use to avoid repeating the 
string here.



Comment at: lldb/tools/lldb-vscode/VSCode.cpp:805
+  } else {
+std::string error = "Unknown repl-mode '" + new_mode.str() + "'.";
+result.SetError(error.c_str());

Would be useful if it also said: "repl-mode "foo". Expected one of "auto", 
.".



Comment at: lldb/tools/lldb-vscode/VSCode.cpp:806
+std::string error = "Unknown repl-mode '" + new_mode.str() + "'.";
+result.SetError(error.c_str());
+result.SetStatus(lldb::eReturnStatusFailed);

SetError ends up calling CommandReturnObject::AppendError which will set the 
status to failed for you (I changed this a while back because I kept forgetting 
to set it).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

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


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

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

Hi wallace,

I created to improve the repl behavior of lldb-vscode allowing users to more 
easily run lldb commands. I started 
https://discourse.llvm.org/t/rfc-lldb-vscode-evaluate-repl-behavior-and-improvements/71667
 as well to outline some of behaviors from this patch.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

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


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

2023-06-29 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 536031.
ashgti added a comment.

Pull + Rebase.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/SourceBreakpoint.cpp
  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
@@ -252,7 +252,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // 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 = std::string(GetString(arguments, "text"));
   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::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.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 {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 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.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+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 = 

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

2023-06-29 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 535911.
ashgti added a comment.

Adding ` as an escape hatch in auto mode to ensure lldb commands can always be 
run directly.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/SourceBreakpoint.cpp
  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
@@ -252,7 +252,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // 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 = std::string(GetString(arguments, "text"));
   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::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.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 {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 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.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+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));
@@ 

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

2023-06-28 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 535592.
ashgti added a comment.

Formatting


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/SourceBreakpoint.cpp
  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
@@ -252,7 +252,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // 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 = std::string(GetString(arguments, "text"));
   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::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.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 {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 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.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+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 = 

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

2023-06-28 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 535591.
ashgti added a comment.

Formatting.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/SourceBreakpoint.cpp
  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
@@ -252,7 +252,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // 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 = std::string(GetString(arguments, "text"));
   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::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.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 {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 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.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+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 = 

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

2023-06-28 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 535590.
ashgti added a comment.

Another tweak to the auto mode behavior.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/SourceBreakpoint.cpp
  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
@@ -252,7 +252,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // 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 = std::string(GetString(arguments, "text"));
   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::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.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 {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 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.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+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 

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

2023-06-28 Thread John Harrison via Phabricator via lldb-commits
ashgti updated this revision to Diff 535580.
ashgti added a comment.

Small tweak to the auto expression mode.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/SourceBreakpoint.cpp
  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
@@ -252,7 +252,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // 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 = std::string(GetString(arguments, "text"));
   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::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.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 {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 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.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+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 

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

2023-06-28 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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154030

Files:
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/Options.td
  lldb/tools/lldb-vscode/README.md
  lldb/tools/lldb-vscode/SourceBreakpoint.cpp
  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
@@ -252,7 +252,7 @@
 }
   }
 
-  // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
+  // We will have cleared g_vsc.focus_tid if the focus thread doesn't have
   // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
   // then set the focus thread to the first thread with a stop reason.
   if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
@@ -1065,50 +1065,62 @@
   FillResponse(request, response);
   llvm::json::Object body;
   auto arguments = request.getObject("arguments");
+
+  // 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 = std::string(GetString(arguments, "text"));
   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::StringRef text_ref{text};
+::llvm::SmallVector<::llvm::StringRef, 2> lines;
+text_ref.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 {
-char command[] = "expression -- ";
+
+  if (g_vsc.DetectExpressionContext(text) == ExpressionContext::Variable) {
+char command[] = "frame variable ";
 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.
+targets.reserve(matches.GetSize() - 1);
+std::string common_pattern = matches.GetStringAtIndex(0);
+for (size_t i = 1; i < matches.GetSize(); i++) {
+  std::string match = matches.GetStringAtIndex(i);
+  std::string description = descriptions.GetStringAtIndex(i);
+
+