mirror of
https://github.com/SpaceManiac/SpacemanDMM.git
synced 2025-12-23 05:36:47 +00:00
Add initial structure and types for debugger
This commit is contained in:
parent
174e7c0c50
commit
ddbb3e9b39
3 changed files with 194 additions and 0 deletions
49
src/langserver/debugger/mod.rs
Normal file
49
src/langserver/debugger/mod.rs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
//! Debug adapter protocol implementation for DreamSeeker.
|
||||
//!
|
||||
//! * https://microsoft.github.io/debug-adapter-protocol/
|
||||
|
||||
mod types;
|
||||
|
||||
use std::error::Error;
|
||||
use io;
|
||||
use self::types::*;
|
||||
|
||||
pub fn debugger_main<I: Iterator<Item=String>>(mut args: I) {
|
||||
let mut dreamseeker_exe = None;
|
||||
|
||||
while let Some(arg) = args.next() {
|
||||
if arg == "--dreamseeker-exe" {
|
||||
dreamseeker_exe = Some(args.next().expect("must specify a value for --dreamseeker-exe"));
|
||||
} else {
|
||||
panic!("unknown argument {:?}", arg);
|
||||
}
|
||||
}
|
||||
|
||||
let mut debugger = Debugger {
|
||||
dreamseeker_exe: dreamseeker_exe.expect("must provide argument `--dreamseeker-exe path/to/dreamseeker.exe`"),
|
||||
};
|
||||
io::run_forever(|message| debugger.handle_input(message));
|
||||
}
|
||||
|
||||
struct Debugger {
|
||||
dreamseeker_exe: String,
|
||||
}
|
||||
|
||||
impl Debugger {
|
||||
fn handle_input(&mut self, message: &str) {
|
||||
// TODO: error handling
|
||||
self.dispatch_input(message).expect("error in dispatch_input");
|
||||
}
|
||||
|
||||
fn dispatch_input(&mut self, message: &str) -> Result<(), Box<dyn Error>> {
|
||||
let protocol_message = serde_json::from_str::<ProtocolMessage>(message)?;
|
||||
match protocol_message.type_.as_str() {
|
||||
"request" => {
|
||||
let request = serde_json::from_str::<Request>(message)?;
|
||||
eprintln!("{:?}", request);
|
||||
}
|
||||
other => return Err(format!("unknown `type` field {:?}", other).into())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
133
src/langserver/debugger/types.rs
Normal file
133
src/langserver/debugger/types.rs
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
//! Serde types for the Debug Adapter Protocol.
|
||||
//!
|
||||
//! * https://microsoft.github.io/debug-adapter-protocol/specification
|
||||
|
||||
use std::collections::HashMap;
|
||||
use serde_json::Value;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Base Protocol
|
||||
|
||||
/// Base class of requests, responses, and events.
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ProtocolMessage {
|
||||
/// Sequence number (also known as message ID). For protocol messages of type 'request' this ID can be used to cancel the request.
|
||||
pub seq: i64,
|
||||
#[serde(rename = "type")]
|
||||
/// Message type.
|
||||
/// Values: 'request', 'response', 'event', etc.
|
||||
pub type_: String,
|
||||
}
|
||||
|
||||
/// A client or debug adapter initiated request.
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Request {
|
||||
#[serde(flatten)]
|
||||
pub protocol_message: ProtocolMessage,
|
||||
/// The command to execute.
|
||||
pub command: String,
|
||||
/// Object containing arguments for the command.
|
||||
pub arguments: Option<Value>,
|
||||
}
|
||||
|
||||
/// A debug adapter initiated event.
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Event {
|
||||
#[serde(flatten)]
|
||||
pub protocol_message: ProtocolMessage,
|
||||
/// Type of event.
|
||||
pub event: String,
|
||||
/// Event-specific information.
|
||||
pub body: Option<Value>,
|
||||
}
|
||||
|
||||
/// Response for a request.
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Response {
|
||||
#[serde(flatten)]
|
||||
pub protocol_message: ProtocolMessage,
|
||||
|
||||
/**
|
||||
* Sequence number of the corresponding request.
|
||||
*/
|
||||
pub request_seq: i64,
|
||||
|
||||
/**
|
||||
* Outcome of the request.
|
||||
* If true, the request was successful and the 'body' attribute may contain the result of the request.
|
||||
* If the value is false, the attribute 'message' contains the error in short form and the 'body' may contain additional information (see 'ErrorResponse.body.error').
|
||||
*/
|
||||
pub success: bool,
|
||||
|
||||
/**
|
||||
* The command requested.
|
||||
*/
|
||||
pub command: String,
|
||||
|
||||
/**
|
||||
* Contains the raw error in short form if 'success' is false.
|
||||
* This raw error might be interpreted by the frontend and is not shown in the UI.
|
||||
* Some predefined values exist.
|
||||
* Values:
|
||||
* 'cancelled': request was cancelled.
|
||||
* etc.
|
||||
*/
|
||||
pub message: Option<String>,
|
||||
|
||||
/**
|
||||
* Contains request result if success is true and optional error details if success is false.
|
||||
*/
|
||||
pub body: Option<Value>,
|
||||
}
|
||||
|
||||
/// On error (whenever ‘success’ is false), the body can provide more details.
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ErrorResponseBody {
|
||||
/// An optional, structured error message.
|
||||
pub error: Option<Message>,
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Types
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Message {
|
||||
/**
|
||||
* Unique identifier for the message.
|
||||
*/
|
||||
pub id: i64,
|
||||
|
||||
/**
|
||||
* A format string for the message. Embedded variables have the form '{name}'.
|
||||
* If variable name starts with an underscore character, the variable does not contain user data (PII) and can be safely used for telemetry purposes.
|
||||
*/
|
||||
pub format: String,
|
||||
|
||||
/**
|
||||
* An object used as a dictionary for looking up the variables in the format string.
|
||||
*/
|
||||
pub variables: Option<HashMap<String, String>>,
|
||||
|
||||
/**
|
||||
* If true send to telemetry.
|
||||
*/
|
||||
#[serde(rename = "sendTelemetry")]
|
||||
pub send_telemetry: Option<bool>,
|
||||
|
||||
/**
|
||||
* If true show user.
|
||||
*/
|
||||
#[serde(rename = "showUser")]
|
||||
pub show_user: Option<bool>,
|
||||
|
||||
/**
|
||||
* An optional url where additional information about this message can be found.
|
||||
*/
|
||||
pub url: Option<String>,
|
||||
|
||||
/**
|
||||
* An optional label that is presented to the user as the UI for opening the url.
|
||||
*/
|
||||
#[serde(rename = "urlLabel")]
|
||||
pub url_label: Option<String>,
|
||||
}
|
||||
|
|
@ -27,6 +27,8 @@ mod find_references;
|
|||
mod extras;
|
||||
mod completion;
|
||||
|
||||
mod debugger;
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
use std::collections::hash_map::Entry;
|
||||
|
|
@ -62,6 +64,16 @@ fn main() {
|
|||
Err(e) => eprintln!("dir check failure: {}", e),
|
||||
}
|
||||
|
||||
let mut args = std::env::args();
|
||||
let _ = args.next(); // skip executable name
|
||||
if let Some(arg) = args.next() {
|
||||
if arg == "--debugger" {
|
||||
return debugger::debugger_main(args);
|
||||
} else {
|
||||
panic!("unknown argument {:?}", arg);
|
||||
}
|
||||
}
|
||||
|
||||
let context = dm::Context::default();
|
||||
let mut engine = Engine::new(&context);
|
||||
io::run_forever(|message| engine.handle_input(message));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue