This project is still under development and all contributions are welcome :)
If you encounter bugs/problems while using the debugger or have suggestions for new features, please open an issue on github.
If you want to contribute code but are unsure how/where to integrate your code in the package, please don’t hesitate to ask and I’ll try to clarify the packet structure or write some better documentation (which is naturally on the todo list anyways…).
Current ideas/todos include: * Adding Logpoints, conditional breakpoints * Improve display of variables (e.g. promises, R6 objects). This is rather simple to integrate in defaultVarInfos.R, but might take some time to implement precisely and error-free. * Improve handling of breakpoints in function definitions by .vsc.debugSource
* Improve handling of breakpoints in nested functions * Implement proper user facing functions to add/modify VarInfos
The package follows the normal build and installation process of R packages. It contains some C code, which needs to be compiled, so on Windows it might be necessary to install RTools.
Documentation is written using Roxygen comments, which are converted to .Rd files by the command devtools::document()
. Vignettes are written as .Rmd files which can be built using devtools::build_vignettes()
. The online documentation is built from the normal help pages using pkgdown.
The files build.R
and .vscode/tasks.json
contain some scripts that might be useful to speed up the development workflow, but these are not tested or documented properly at the moment.
Below is a rough grouping and explanation of the R files from this package. In the directory d.ts
are typescript declaration files with matching names for some of the R files. These do not contain any running code, but are used to document the interfaces/classes used in the package.
This file contains the functions that handle communication with the debug client. DAP requests are received (as json/text) on socketConnections by .vsc.listenForDAP
and .vsc.listenForJSON
. These jsons are parsed by .vsc.handleJson
and converted to named lists.
Responses and events are passed as named list to sendToVsc
, where they are converted to json-strings and sent via the corresponding socketConnection.
This file contains most of the “DAP-logic” and is the only file that contains calls to/is called by pretty much all other files. .vsc.dispatchRequest
is called by functions from communications.R with DAP requests represented as named lists. Depending on the command of the request, the corresponding R functions xxxRequest()
are called.
The called R functions return their results by calling sendReponse
. Events (e.g. output, breakpoints, …) are reported by internal R functions to the debug client by calling sendEvent.
Most events are implemented in separates functions sendXxxEvent()
and makeXxxEvent()
.
This file contains the definition of session
, a global variable (an environment) that contains information about the configuration and state of the current debug session. Most of the state of the debug session is represented by an R6 object of class State
, which is updated when e.g. breakpoints are hit or code execution is started.
This file handles the launch sequence of the debug adapter. This includes the requests initialize
, launch
/attach
, and configurationDone
. The launch configuration is interpreted and stored to the session
.
This file handles the commands used to control the flow of a debugged session. This includes the requests continue
, next
, stepIn
, stepOut
, disconnect
, terminate
. Furthermore, the custom request (not specified by the DAP!) showingPrompt
and the error handler .vsc.onError
are defined here.
This file contains functions that are used to keep track of internal stack frames, in order to show the user only “their frames”. Most exported functions from this package call registerEntryFrame
on entry and unregisterEntryFrame
when they finish. When user code is executed (e.g. in eval
requests), registerLaunchFrame
is called to register the new frames as “user frames”.
getTopFrameId
, getSkipFromBottom
, and getExternalFrames
can be used to retrieve the indices of the last/first/all user frames.
This file contains the R6 classes that are used to internally represent the tree of stack frames, scopes, and variables of the current debug session. Each of these objects is represented by an individual node class (StackNode
, FrameNode
, …) which inherit from a common base class Node
. The info stored in a node can be accessed through the functions getChildren
and getContent
. The children of a node are the nodes representing the next items on the next level of the stack tree (e.g. the children of a FrameNode
are the ScopeNodes
, the children of a ScopeNode
are VariableNodes
). The content of a node usually extends the corresponding interface declared in the DAP (e.g. VariableNode$getcontent()
can be used directly as DebugProtocol.Variable
)
A (typescript) declaration of these classes can be found in stackTree.d.ts
.
Information retrieval for variables is done through VarInfos
(see customVarInfo.d.ts). These contain a function doesApply
, which is used to determine if they should be used for a given variable, and a number of functions (or fixed values) that return information about the variable. To retrieve information about a given variable, each VarInfo$doesApply()
is tested and if it returns TRUE
, the items supplied by this VarInfo are used for the variable. This is repeated with the remaining items until all requested information is found.
A VarInfo can contain all information about a specific type of variable (e.g. NULL
is quite easy to represent with a single VarInfo), or add just a single piece of information for a broad range of variables (e.g. the entry R6
only yields a string for the variable type of R6 objects), or anything in between.
Contains setBreakpoints
which is used to set breakpoints in functions that are loaded in the workspace already. This is done by using the functions findLineNum
and trace
to insert calls to browser
in the function body.
Contains code used to set the value of variables in the variables window through setVariable
requests.
Contains the functions .vsc.print
, .vsc...
used to overwrite base::print
etc.