Add property breakpoints.
This commit is contained in:
parent
cc64ae3939
commit
b4f679d35f
@ -12,7 +12,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Pretty-print source line.
|
/// Pretty-print source line.
|
||||||
fn print_source(lines: &[String], pos: Position) {
|
fn print_source(lines: &[String], pos: Position, offset: usize) {
|
||||||
let line_no = if lines.len() > 1 {
|
let line_no = if lines.len() > 1 {
|
||||||
if pos.is_none() {
|
if pos.is_none() {
|
||||||
"".to_string()
|
"".to_string()
|
||||||
@ -32,7 +32,9 @@ fn print_source(lines: &[String], pos: Position) {
|
|||||||
println!("{}{}", line_no, lines[pos.line().unwrap() - 1]);
|
println!("{}{}", line_no, lines[pos.line().unwrap() - 1]);
|
||||||
|
|
||||||
// Display position marker
|
// Display position marker
|
||||||
println!("{0:>1$}", "^", line_no.len() + pos.position().unwrap(),);
|
if let Some(pos) = pos.position() {
|
||||||
|
println!("{0:>1$}", "^", line_no.len() + pos + offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,6 +85,7 @@ fn print_debug_help() {
|
|||||||
println!("clear => delete all break-points");
|
println!("clear => delete all break-points");
|
||||||
println!("break => set a new break-point at the current position");
|
println!("break => set a new break-point at the current position");
|
||||||
println!("break <line#> => set a new break-point at a line number");
|
println!("break <line#> => set a new break-point at a line number");
|
||||||
|
println!("break .<prop> => set a new break-point for a property access");
|
||||||
println!("break <func> => set a new break-point for a function call");
|
println!("break <func> => set a new break-point for a function call");
|
||||||
println!(
|
println!(
|
||||||
"break <func> <#args> => set a new break-point for a function call with #args arguments"
|
"break <func> <#args> => set a new break-point for a function call with #args arguments"
|
||||||
@ -198,7 +201,7 @@ fn main() {
|
|||||||
let lines: Vec<_> = script.trim().split('\n').map(|s| s.to_string()).collect();
|
let lines: Vec<_> = script.trim().split('\n').map(|s| s.to_string()).collect();
|
||||||
|
|
||||||
engine.on_debugger(move |context, node, source, pos| {
|
engine.on_debugger(move |context, node, source, pos| {
|
||||||
print_source(&lines, pos);
|
print_source(&lines, pos, 0);
|
||||||
|
|
||||||
let mut input = String::new();
|
let mut input = String::new();
|
||||||
|
|
||||||
@ -210,7 +213,12 @@ fn main() {
|
|||||||
|
|
||||||
match stdin().read_line(&mut input) {
|
match stdin().read_line(&mut input) {
|
||||||
Ok(0) => break DebuggerCommand::Continue,
|
Ok(0) => break DebuggerCommand::Continue,
|
||||||
Ok(_) => match input.trim_end().split(' ').collect::<Vec<_>>().as_slice() {
|
Ok(_) => match input
|
||||||
|
.trim_end()
|
||||||
|
.split_whitespace()
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.as_slice()
|
||||||
|
{
|
||||||
["help", ..] => print_debug_help(),
|
["help", ..] => print_debug_help(),
|
||||||
["exit", ..] | ["quit", ..] | ["kill", ..] => {
|
["exit", ..] | ["quit", ..] | ["kill", ..] => {
|
||||||
println!("Script terminated. Bye!");
|
println!("Script terminated. Bye!");
|
||||||
@ -221,7 +229,7 @@ fn main() {
|
|||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
["continue", ..] => break DebuggerCommand::Continue,
|
["continue", ..] => break DebuggerCommand::Continue,
|
||||||
[""] | ["step", ..] => break DebuggerCommand::StepInto,
|
[] | ["step", ..] => break DebuggerCommand::StepInto,
|
||||||
["next", ..] => break DebuggerCommand::StepOver,
|
["next", ..] => break DebuggerCommand::StepOver,
|
||||||
["scope", ..] => print_scope(context.scope()),
|
["scope", ..] => print_scope(context.scope()),
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
@ -250,10 +258,11 @@ fn main() {
|
|||||||
.enumerate()
|
.enumerate()
|
||||||
.for_each(|(i, bp)| match bp {
|
.for_each(|(i, bp)| match bp {
|
||||||
BreakPoint::AtPosition { pos, .. } => {
|
BreakPoint::AtPosition { pos, .. } => {
|
||||||
println!("[{}]", i + 1);
|
let line_num = format!("[{}] line ", i + 1);
|
||||||
print_source(&lines, *pos);
|
print!("{}", line_num);
|
||||||
|
print_source(&lines, *pos, line_num.len());
|
||||||
}
|
}
|
||||||
_ => println!("[{}]\n{}", i + 1, bp),
|
_ => println!("[{}] {}", i + 1, bp),
|
||||||
}),
|
}),
|
||||||
["enable", n, ..] => {
|
["enable", n, ..] => {
|
||||||
if let Ok(n) = n.parse::<usize>() {
|
if let Ok(n) = n.parse::<usize>() {
|
||||||
@ -340,7 +349,19 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
["break", param] => {
|
["break", param] => {
|
||||||
if let Ok(n) = param.parse::<usize>() {
|
if param.starts_with('.') && param.len() > 1 {
|
||||||
|
// Property name
|
||||||
|
let bp = rhai::debugger::BreakPoint::AtProperty {
|
||||||
|
name: param[1..].into(),
|
||||||
|
enabled: true,
|
||||||
|
};
|
||||||
|
println!("Break-point added for {}", bp);
|
||||||
|
context
|
||||||
|
.global_runtime_state_mut()
|
||||||
|
.debugger
|
||||||
|
.break_points_mut()
|
||||||
|
.push(bp);
|
||||||
|
} else if let Ok(n) = param.parse::<usize>() {
|
||||||
// Numeric parameter
|
// Numeric parameter
|
||||||
let range = 1..=lines.len();
|
let range = 1..=lines.len();
|
||||||
if range.contains(&n) {
|
if range.contains(&n) {
|
||||||
@ -385,7 +406,7 @@ fn main() {
|
|||||||
.break_points_mut()
|
.break_points_mut()
|
||||||
.push(bp);
|
.push(bp);
|
||||||
}
|
}
|
||||||
cmd => eprintln!("Invalid debugger command: '{}'", cmd[0]),
|
[cmd, ..] => eprintln!("Invalid debugger command: '{}'", cmd),
|
||||||
},
|
},
|
||||||
Err(err) => panic!("input error: {}", err),
|
Err(err) => panic!("input error: {}", err),
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,8 @@ pub enum BreakPoint {
|
|||||||
args: usize,
|
args: usize,
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
},
|
},
|
||||||
|
/// Break at a particular property .
|
||||||
|
AtProperty { name: Identifier, enabled: bool },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for BreakPoint {
|
impl fmt::Display for BreakPoint {
|
||||||
@ -102,6 +104,16 @@ impl fmt::Display for BreakPoint {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Self::AtProperty {
|
||||||
|
name: prop,
|
||||||
|
enabled,
|
||||||
|
} => {
|
||||||
|
write!(f, ".{}", prop)?;
|
||||||
|
if !*enabled {
|
||||||
|
f.write_str(" (disabled)")?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,7 +125,9 @@ impl BreakPoint {
|
|||||||
match self {
|
match self {
|
||||||
#[cfg(not(feature = "no_position"))]
|
#[cfg(not(feature = "no_position"))]
|
||||||
Self::AtPosition { enabled, .. } => *enabled,
|
Self::AtPosition { enabled, .. } => *enabled,
|
||||||
Self::AtFunctionName { enabled, .. } | Self::AtFunctionCall { enabled, .. } => *enabled,
|
Self::AtFunctionName { enabled, .. }
|
||||||
|
| Self::AtFunctionCall { enabled, .. }
|
||||||
|
| Self::AtProperty { enabled, .. } => *enabled,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Enable/disable this [`BreakPoint`].
|
/// Enable/disable this [`BreakPoint`].
|
||||||
@ -122,9 +136,9 @@ impl BreakPoint {
|
|||||||
match self {
|
match self {
|
||||||
#[cfg(not(feature = "no_position"))]
|
#[cfg(not(feature = "no_position"))]
|
||||||
Self::AtPosition { enabled, .. } => *enabled = value,
|
Self::AtPosition { enabled, .. } => *enabled = value,
|
||||||
Self::AtFunctionName { enabled, .. } | Self::AtFunctionCall { enabled, .. } => {
|
Self::AtFunctionName { enabled, .. }
|
||||||
*enabled = value
|
| Self::AtFunctionCall { enabled, .. }
|
||||||
}
|
| Self::AtProperty { enabled, .. } => *enabled = value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -272,6 +286,10 @@ impl Debugger {
|
|||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
|
BreakPoint::AtProperty { name, .. } => match node {
|
||||||
|
ASTNode::Expr(Expr::Property(x)) => (x.2).0 == *name,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/// Get a slice of all [`BreakPoint`]'s.
|
/// Get a slice of all [`BreakPoint`]'s.
|
||||||
|
Loading…
Reference in New Issue
Block a user