Skip to content

Commit 68e4e16

Browse files
committed
Refactor JSError:
- Replace JSError::ParseError with parse_error_here! macro - Replace JSError::EvaluationError with eval_error_here! macro - Added eval_error_here import in affected files
1 parent c469c4d commit 68e4e16

31 files changed

Lines changed: 625 additions & 1122 deletions

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ categories = ["development-tools", "parsing"]
1313

1414
[dependencies]
1515
chrono = { version = "0.4.42", features = ["serde"] }
16+
function_name = "0.3"
1617
libc = "0.2.178"
1718
log = "0.4.29"
1819
num-bigint = "0.4.6"

examples/js.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ fn main() {
4343
match evaluate_script(script) {
4444
Ok(result) => print_eval_result(&result),
4545
Err(err) => {
46-
eprintln!("Evaluation failed: {:?}", err);
46+
eprintln!("Evaluation failed: {err}");
4747
process::exit(1);
4848
}
4949
}

src/core.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#![allow(non_camel_case_types)]
33

44
use crate::error::JSError;
5+
use crate::eval_error_here;
56
use crate::js_promise::{PromiseState, run_event_loop};
67
use crate::unicode::{utf8_to_utf16, utf16_to_utf8};
78
use std::cell::RefCell;
@@ -102,9 +103,7 @@ pub fn evaluate_script<T: AsRef<str>>(script: T) -> Result<Value, JSError> {
102103
match &promise_borrow.state {
103104
PromiseState::Fulfilled(val) => return Ok(val.clone()),
104105
PromiseState::Rejected(reason) => {
105-
return Err(JSError::EvaluationError {
106-
message: format!("Promise rejected: {}", value_to_string(reason)),
107-
});
106+
return Err(eval_error_here!(format!("Promise rejected: {}", value_to_string(reason))));
108107
}
109108
PromiseState::Pending => {
110109
// Continue running the event loop

src/core/eval.rs

Lines changed: 151 additions & 430 deletions
Large diffs are not rendered by default.

src/core/parser.rs

Lines changed: 102 additions & 101 deletions
Large diffs are not rendered by default.

src/core/statement.rs

Lines changed: 78 additions & 77 deletions
Large diffs are not rendered by default.

src/error.rs

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@ pub enum JSError {
33
#[error("Tokenization failed")]
44
TokenizationError,
55

6-
#[error("Parsing failed")]
7-
ParseError,
6+
#[error("Parsing failed at {method} {file}:{line}")]
7+
ParseError { file: String, line: usize, method: String },
88

9-
#[error("Evaluation failed: {message}")]
10-
EvaluationError { message: String },
9+
#[error("Evaluation failed at {method} {file}:{line}: {message}")]
10+
EvaluationError {
11+
message: String,
12+
file: String,
13+
line: usize,
14+
method: String,
15+
},
1116

1217
#[error("Infinite loop detected (executed {iterations} iterations)")]
1318
InfiniteLoopError { iterations: usize },
@@ -39,3 +44,46 @@ impl From<JSError> for std::io::Error {
3944
}
4045
}
4146
}
47+
48+
// Macro that constructs a ParseError using the compile-time caller
49+
// location. Using a macro (rather than a function) ensures `file!()` and
50+
// `line!()` expand to the site where the macro is invoked.
51+
#[macro_export]
52+
macro_rules! parse_error_here {
53+
() => {
54+
$crate::JSError::ParseError {
55+
file: file!().to_string(),
56+
line: line!() as usize,
57+
method: $crate::function_name!().to_string(),
58+
}
59+
};
60+
}
61+
62+
// Macro that constructs an EvaluationError using the compile-time caller
63+
// location and the provided message. Using a macro (rather than a
64+
// function) ensures `file!()` and `line!()` expand to the site where the
65+
// macro is invoked.
66+
#[macro_export]
67+
macro_rules! eval_error_here {
68+
($msg:expr) => {
69+
$crate::JSError::EvaluationError {
70+
message: $msg.to_string(),
71+
file: file!().to_string(),
72+
line: line!() as usize,
73+
method: $crate::function_name!().to_string(),
74+
}
75+
};
76+
}
77+
78+
#[macro_export]
79+
macro_rules! function_name {
80+
() => {{
81+
fn f() {}
82+
fn type_name_of<T>(_: T) -> &'static str {
83+
std::any::type_name::<T>()
84+
}
85+
let name = type_name_of(f);
86+
// remove the trailing "::f"
87+
&name[..name.len() - 3]
88+
}};
89+
}

0 commit comments

Comments
 (0)