| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 | 
							- /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 
-    file LICENSE.rst or https://cmake.org/licensing for details.  */
 
- #include "cmDebuggerBreakpointManager.h"
 
- #include <algorithm>
 
- #include <cstddef>
 
- #include <cstdint>
 
- #include <utility>
 
- #include <cm3p/cppdap/optional.h>
 
- #include <cm3p/cppdap/session.h>
 
- #include <cm3p/cppdap/types.h>
 
- #include "cmDebuggerSourceBreakpoint.h"
 
- #include "cmListFileCache.h"
 
- #include "cmSystemTools.h"
 
- namespace cmDebugger {
 
- cmDebuggerBreakpointManager::cmDebuggerBreakpointManager(
 
-   dap::Session* dapSession)
 
-   : DapSession(dapSession)
 
- {
 
-   // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_SetBreakpoints
 
-   DapSession->registerHandler([&](dap::SetBreakpointsRequest const& request) {
 
-     return HandleSetBreakpointsRequest(request);
 
-   });
 
- }
 
- int64_t cmDebuggerBreakpointManager::FindFunctionStartLine(
 
-   std::string const& sourcePath, int64_t line)
 
- {
 
-   auto location =
 
-     find_if(ListFileFunctionLines[sourcePath].begin(),
 
-             ListFileFunctionLines[sourcePath].end(),
 
-             [=](cmDebuggerFunctionLocation loc) {
 
-               return loc.StartLine <= line && loc.EndLine >= line;
 
-             });
 
-   if (location != ListFileFunctionLines[sourcePath].end()) {
 
-     return location->StartLine;
 
-   }
 
-   return 0;
 
- }
 
- int64_t cmDebuggerBreakpointManager::CalibrateBreakpointLine(
 
-   std::string const& sourcePath, int64_t line)
 
- {
 
-   auto location = find_if(
 
-     ListFileFunctionLines[sourcePath].begin(),
 
-     ListFileFunctionLines[sourcePath].end(),
 
-     [=](cmDebuggerFunctionLocation loc) { return loc.StartLine >= line; });
 
-   if (location != ListFileFunctionLines[sourcePath].end()) {
 
-     return location->StartLine;
 
-   }
 
-   if (!ListFileFunctionLines[sourcePath].empty() &&
 
-       ListFileFunctionLines[sourcePath].back().EndLine <= line) {
 
-     // return last function start line for any breakpoints after.
 
-     return ListFileFunctionLines[sourcePath].back().StartLine;
 
-   }
 
-   return 0;
 
- }
 
- dap::SetBreakpointsResponse
 
- cmDebuggerBreakpointManager::HandleSetBreakpointsRequest(
 
-   dap::SetBreakpointsRequest const& request)
 
- {
 
-   std::unique_lock<std::mutex> lock(Mutex);
 
-   dap::SetBreakpointsResponse response;
 
-   auto sourcePath =
 
-     cmSystemTools::GetActualCaseForPath(request.source.path.value());
 
-   dap::array<dap::SourceBreakpoint> const defaultValue{};
 
-   auto const& breakpoints = request.breakpoints.value(defaultValue);
 
-   if (Breakpoints.find(sourcePath) != Breakpoints.end()) {
 
-     Breakpoints[sourcePath].clear();
 
-   }
 
-   response.breakpoints.resize(breakpoints.size());
 
-   if (ListFileFunctionLines.find(sourcePath) != ListFileFunctionLines.end()) {
 
-     // The file has loaded, we can validate breakpoints.
 
-     for (size_t i = 0; i < breakpoints.size(); i++) {
 
-       int64_t correctedLine =
 
-         CalibrateBreakpointLine(sourcePath, breakpoints[i].line);
 
-       if (correctedLine > 0) {
 
-         Breakpoints[sourcePath].emplace_back(NextBreakpointId++,
 
-                                              correctedLine);
 
-         response.breakpoints[i].id = Breakpoints[sourcePath].back().GetId();
 
-         response.breakpoints[i].line =
 
-           Breakpoints[sourcePath].back().GetLine();
 
-         response.breakpoints[i].verified = true;
 
-       } else {
 
-         response.breakpoints[i].verified = false;
 
-         response.breakpoints[i].line = breakpoints[i].line;
 
-       }
 
-       dap::Source dapSrc;
 
-       dapSrc.path = sourcePath;
 
-       response.breakpoints[i].source = dapSrc;
 
-     }
 
-   } else {
 
-     // The file has not loaded, validate breakpoints later.
 
-     ListFilePendingValidations.emplace(sourcePath);
 
-     for (size_t i = 0; i < breakpoints.size(); i++) {
 
-       Breakpoints[sourcePath].emplace_back(NextBreakpointId++,
 
-                                            breakpoints[i].line);
 
-       response.breakpoints[i].id = Breakpoints[sourcePath].back().GetId();
 
-       response.breakpoints[i].line = Breakpoints[sourcePath].back().GetLine();
 
-       response.breakpoints[i].verified = false;
 
-       dap::Source dapSrc;
 
-       dapSrc.path = sourcePath;
 
-       response.breakpoints[i].source = dapSrc;
 
-     }
 
-   }
 
-   return response;
 
- }
 
- void cmDebuggerBreakpointManager::SourceFileLoaded(
 
-   std::string const& sourcePath,
 
-   std::vector<cmListFileFunction> const& functions)
 
- {
 
-   std::unique_lock<std::mutex> lock(Mutex);
 
-   if (ListFileFunctionLines.find(sourcePath) != ListFileFunctionLines.end()) {
 
-     // this is not expected.
 
-     return;
 
-   }
 
-   for (cmListFileFunction const& func : functions) {
 
-     ListFileFunctionLines[sourcePath].emplace_back(
 
-       cmDebuggerFunctionLocation{ func.Line(), func.LineEnd() });
 
-   }
 
-   if (ListFilePendingValidations.find(sourcePath) ==
 
-       ListFilePendingValidations.end()) {
 
-     return;
 
-   }
 
-   ListFilePendingValidations.erase(sourcePath);
 
-   for (size_t i = 0; i < Breakpoints[sourcePath].size(); i++) {
 
-     dap::BreakpointEvent breakpointEvent;
 
-     breakpointEvent.breakpoint.id = Breakpoints[sourcePath][i].GetId();
 
-     breakpointEvent.breakpoint.line = Breakpoints[sourcePath][i].GetLine();
 
-     auto source = dap::Source();
 
-     source.path = sourcePath;
 
-     breakpointEvent.breakpoint.source = source;
 
-     int64_t correctedLine = CalibrateBreakpointLine(
 
-       sourcePath, Breakpoints[sourcePath][i].GetLine());
 
-     if (correctedLine != Breakpoints[sourcePath][i].GetLine()) {
 
-       Breakpoints[sourcePath][i].ChangeLine(correctedLine);
 
-     }
 
-     breakpointEvent.reason = "changed";
 
-     breakpointEvent.breakpoint.verified = (correctedLine > 0);
 
-     if (breakpointEvent.breakpoint.verified) {
 
-       breakpointEvent.breakpoint.line = correctedLine;
 
-     } else {
 
-       Breakpoints[sourcePath][i].Invalid();
 
-     }
 
-     DapSession->send(breakpointEvent);
 
-   }
 
- }
 
- std::vector<int64_t> cmDebuggerBreakpointManager::GetBreakpoints(
 
-   std::string const& sourcePath, int64_t line)
 
- {
 
-   std::unique_lock<std::mutex> lock(Mutex);
 
-   auto const& all = Breakpoints[sourcePath];
 
-   std::vector<int64_t> breakpoints;
 
-   if (all.empty()) {
 
-     return breakpoints;
 
-   }
 
-   auto it = all.begin();
 
-   while ((it = std::find_if(
 
-             it, all.end(), [&](cmDebuggerSourceBreakpoint const& breakpoint) {
 
-               return (breakpoint.GetIsValid() && breakpoint.GetLine() == line);
 
-             })) != all.end()) {
 
-     breakpoints.emplace_back(it->GetId());
 
-     ++it;
 
-   }
 
-   return breakpoints;
 
- }
 
- size_t cmDebuggerBreakpointManager::GetBreakpointCount() const
 
- {
 
-   size_t count = 0;
 
-   for (auto const& pair : Breakpoints) {
 
-     count += pair.second.size();
 
-   }
 
-   return count;
 
- }
 
- void cmDebuggerBreakpointManager::ClearAll()
 
- {
 
-   std::unique_lock<std::mutex> lock(Mutex);
 
-   Breakpoints.clear();
 
- }
 
- } // namespace cmDebugger
 
 
  |