Skip to content

Commit fd39524

Browse files
committed
Improve error messages
Include file path and line number and emit better descriptions
1 parent 47ccc33 commit fd39524

File tree

1 file changed

+60
-11
lines changed

1 file changed

+60
-11
lines changed

extractor/src/extractor.rs

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,33 @@ struct Visitor<'a> {
7676

7777
impl Visitor<'_> {
7878
fn enter_node(&mut self, node: Node) {
79+
if node.is_error() {
80+
println!(
81+
"error: {}:{}: parse error",
82+
&self.path,
83+
node.start_position().row,
84+
);
85+
return;
86+
}
87+
if node.is_missing() {
88+
println!(
89+
"error: {}:{}: parse error: expecting '{}'",
90+
&self.path,
91+
node.start_position().row,
92+
node.kind()
93+
);
94+
return;
95+
}
96+
7997
if node.is_extra() {
8098
return;
8199
}
100+
82101
self.stack.push(Vec::new());
83102
}
84103

85104
fn leave_node(&mut self, field_name: Option<&'static str>, node: Node) {
86-
if node.is_extra() {
105+
if node.is_extra() || node.is_error() || node.is_missing() {
87106
return;
88107
}
89108
let child_nodes = self.stack.pop().expect("Vistor: empty stack");
@@ -103,7 +122,7 @@ impl Visitor<'_> {
103122
if fields.is_empty() {
104123
args = Some(vec![sliced_source_arg(self.source, node)]);
105124
} else {
106-
args = self.complex_node(fields, child_nodes, id);
125+
args = self.complex_node(&node, fields, child_nodes, id);
107126
}
108127
if let Some(args) = args {
109128
self.program
@@ -120,12 +139,17 @@ impl Visitor<'_> {
120139
))
121140
};
122141
} else {
123-
panic!(format!("Unknown table type: '{}'", node.kind()))
142+
println!(
143+
"error: {}:{}: unknown table type: '{}'",
144+
&self.path,
145+
node.start_position().row,
146+
node.kind()
147+
);
124148
}
125149
}
126-
127150
fn complex_node(
128151
&mut self,
152+
node: &Node,
129153
fields: &Vec<Field>,
130154
child_nodes: Vec<(Option<&str>, Id, TypeName)>,
131155
parent_id: Id,
@@ -141,15 +165,26 @@ impl Visitor<'_> {
141165
values.push(child_id);
142166
} else if field.name.is_some() {
143167
println!(
144-
"Type mismatch for field {:?} with type {:?} != {:?}",
145-
child_field, child_type, field.types
168+
"error: {}:{}: type mismatch for field {}::{} with type {:?} != {:?}",
169+
&self.path,
170+
node.start_position().row,
171+
node.kind(),
172+
child_field.unwrap_or("child"),
173+
child_type,
174+
field.types
146175
)
147176
}
148177
} else {
149-
println!(
150-
"Value for unknown field: {:?} and type {:?}",
151-
&child_field, &child_type
152-
);
178+
if child_field.is_some() || child_type.named {
179+
println!(
180+
"error: {}:{}: value for unknown field: {}::{} and type {:?}",
181+
&self.path,
182+
node.start_position().row,
183+
node.kind(),
184+
&child_field.unwrap_or("child"),
185+
&child_type
186+
);
187+
}
153188
}
154189
}
155190
let mut args = Vec::new();
@@ -162,7 +197,21 @@ impl Visitor<'_> {
162197
args.push(Arg::IdArg(*child_ids.first().unwrap()));
163198
} else {
164199
is_valid = false;
165-
println!("Argument count mismatch for field {:?}", field.name);
200+
println!(
201+
"error: {}:{}: {} for field: {}::{}",
202+
&self.path,
203+
node.start_position().row,
204+
if child_ids.is_empty() {
205+
"missing value"
206+
} else {
207+
"too many values"
208+
},
209+
node.kind(),
210+
match field.name.as_ref() {
211+
Some(x) => x,
212+
None => "child",
213+
}
214+
)
166215
}
167216
}
168217
Storage::Table { parent, index } => {

0 commit comments

Comments
 (0)