herb 0.7.5 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Makefile +8 -5
- data/config.yml +26 -6
- data/ext/herb/error_helpers.c +57 -3
- data/ext/herb/error_helpers.h +1 -1
- data/ext/herb/extconf.rb +1 -0
- data/ext/herb/extension.c +10 -24
- data/ext/herb/extension_helpers.c +3 -3
- data/ext/herb/extension_helpers.h +1 -1
- data/ext/herb/nodes.c +72 -37
- data/herb.gemspec +0 -2
- data/lib/herb/ast/helpers.rb +11 -0
- data/lib/herb/ast/node.rb +15 -6
- data/lib/herb/ast/nodes.rb +609 -392
- data/lib/herb/cli.rb +31 -0
- data/lib/herb/colors.rb +82 -0
- data/lib/herb/engine/compiler.rb +140 -14
- data/lib/herb/engine/debug_visitor.rb +1 -5
- data/lib/herb/engine/parser_error_overlay.rb +1 -1
- data/lib/herb/engine.rb +8 -14
- data/lib/herb/errors.rb +166 -56
- data/lib/herb/location.rb +2 -2
- data/lib/herb/project.rb +86 -21
- data/lib/herb/token.rb +14 -2
- data/lib/herb/version.rb +1 -1
- data/lib/herb.rb +1 -0
- data/sig/herb/ast/helpers.rbs +3 -0
- data/sig/herb/ast/node.rbs +12 -5
- data/sig/herb/ast/nodes.rbs +124 -62
- data/sig/herb/colors.rbs +35 -0
- data/sig/herb/engine/compiler.rbs +23 -1
- data/sig/herb/errors.rbs +74 -20
- data/sig/herb/token.rbs +8 -0
- data/sig/herb_c_extension.rbs +1 -1
- data/sig/serialized_ast_errors.rbs +8 -0
- data/src/analyze.c +420 -171
- data/src/analyze_helpers.c +5 -0
- data/src/analyze_missing_end.c +147 -0
- data/src/analyze_transform.c +196 -0
- data/src/analyzed_ruby.c +23 -2
- data/src/ast_node.c +5 -5
- data/src/ast_nodes.c +179 -179
- data/src/ast_pretty_print.c +232 -232
- data/src/element_source.c +7 -6
- data/src/errors.c +246 -126
- data/src/extract.c +92 -34
- data/src/herb.c +37 -49
- data/src/html_util.c +34 -96
- data/src/include/analyze.h +10 -2
- data/src/include/analyze_helpers.h +3 -0
- data/src/include/analyzed_ruby.h +4 -2
- data/src/include/ast_node.h +2 -2
- data/src/include/ast_nodes.h +67 -66
- data/src/include/ast_pretty_print.h +2 -2
- data/src/include/element_source.h +3 -1
- data/src/include/errors.h +30 -14
- data/src/include/extract.h +4 -4
- data/src/include/herb.h +6 -7
- data/src/include/html_util.h +4 -5
- data/src/include/lexer.h +1 -3
- data/src/include/lexer_peek_helpers.h +14 -14
- data/src/include/lexer_struct.h +3 -2
- data/src/include/macros.h +4 -0
- data/src/include/parser.h +12 -6
- data/src/include/parser_helpers.h +25 -15
- data/src/include/pretty_print.h +38 -28
- data/src/include/token.h +5 -8
- data/src/include/utf8.h +3 -2
- data/src/include/util/hb_arena.h +31 -0
- data/src/include/util/hb_arena_debug.h +8 -0
- data/src/include/util/hb_array.h +33 -0
- data/src/include/util/hb_buffer.h +34 -0
- data/src/include/util/hb_string.h +29 -0
- data/src/include/util/hb_system.h +9 -0
- data/src/include/util.h +3 -14
- data/src/include/version.h +1 -1
- data/src/include/visitor.h +1 -1
- data/src/io.c +7 -4
- data/src/lexer.c +61 -88
- data/src/lexer_peek_helpers.c +35 -37
- data/src/main.c +19 -23
- data/src/parser.c +282 -201
- data/src/parser_helpers.c +46 -40
- data/src/parser_match_tags.c +316 -0
- data/src/pretty_print.c +82 -106
- data/src/token.c +18 -65
- data/src/utf8.c +4 -4
- data/src/util/hb_arena.c +179 -0
- data/src/util/hb_arena_debug.c +237 -0
- data/src/{array.c → util/hb_array.c} +26 -27
- data/src/util/hb_buffer.c +203 -0
- data/src/util/hb_string.c +85 -0
- data/src/util/hb_system.c +30 -0
- data/src/util.c +29 -99
- data/src/visitor.c +54 -54
- data/templates/ext/herb/error_helpers.c.erb +3 -3
- data/templates/ext/herb/error_helpers.h.erb +1 -1
- data/templates/ext/herb/nodes.c.erb +11 -6
- data/templates/java/error_helpers.c.erb +75 -0
- data/templates/java/error_helpers.h.erb +20 -0
- data/templates/java/nodes.c.erb +97 -0
- data/templates/java/nodes.h.erb +23 -0
- data/templates/java/org/herb/ast/Errors.java.erb +121 -0
- data/templates/java/org/herb/ast/NodeVisitor.java.erb +14 -0
- data/templates/java/org/herb/ast/Nodes.java.erb +220 -0
- data/templates/java/org/herb/ast/Visitor.java.erb +56 -0
- data/templates/javascript/packages/node/extension/error_helpers.cpp.erb +8 -8
- data/templates/javascript/packages/node/extension/error_helpers.h.erb +1 -1
- data/templates/javascript/packages/node/extension/nodes.cpp.erb +9 -9
- data/templates/javascript/packages/node/extension/nodes.h.erb +1 -1
- data/templates/lib/herb/ast/nodes.rb.erb +28 -16
- data/templates/lib/herb/errors.rb.erb +17 -12
- data/templates/rust/src/ast/nodes.rs.erb +220 -0
- data/templates/rust/src/errors.rs.erb +216 -0
- data/templates/rust/src/nodes.rs.erb +374 -0
- data/templates/src/analyze_missing_end.c.erb +36 -0
- data/templates/src/analyze_transform.c.erb +24 -0
- data/templates/src/ast_nodes.c.erb +14 -14
- data/templates/src/ast_pretty_print.c.erb +36 -36
- data/templates/src/errors.c.erb +31 -31
- data/templates/src/include/ast_nodes.h.erb +10 -9
- data/templates/src/include/ast_pretty_print.h.erb +2 -2
- data/templates/src/include/errors.h.erb +6 -6
- data/templates/src/parser_match_tags.c.erb +38 -0
- data/templates/src/visitor.c.erb +4 -4
- data/templates/template.rb +22 -3
- data/templates/wasm/error_helpers.cpp.erb +9 -9
- data/templates/wasm/error_helpers.h.erb +1 -1
- data/templates/wasm/nodes.cpp.erb +9 -9
- data/templates/wasm/nodes.h.erb +1 -1
- data/vendor/prism/Rakefile +4 -1
- data/vendor/prism/config.yml +2 -1
- data/vendor/prism/include/prism/ast.h +31 -1
- data/vendor/prism/include/prism/diagnostic.h +1 -0
- data/vendor/prism/include/prism/version.h +3 -3
- data/vendor/prism/src/diagnostic.c +3 -1
- data/vendor/prism/src/prism.c +130 -71
- data/vendor/prism/src/util/pm_string.c +6 -8
- data/vendor/prism/templates/include/prism/ast.h.erb +2 -0
- data/vendor/prism/templates/java/org/prism/Loader.java.erb +2 -2
- data/vendor/prism/templates/javascript/src/deserialize.js.erb +2 -2
- data/vendor/prism/templates/lib/prism/serialize.rb.erb +2 -2
- data/vendor/prism/templates/sig/prism.rbs.erb +4 -0
- data/vendor/prism/templates/src/diagnostic.c.erb +1 -0
- metadata +34 -20
- data/lib/herb/libherb/array.rb +0 -51
- data/lib/herb/libherb/ast_node.rb +0 -50
- data/lib/herb/libherb/buffer.rb +0 -56
- data/lib/herb/libherb/extract_result.rb +0 -20
- data/lib/herb/libherb/lex_result.rb +0 -32
- data/lib/herb/libherb/libherb.rb +0 -52
- data/lib/herb/libherb/parse_result.rb +0 -20
- data/lib/herb/libherb/token.rb +0 -46
- data/lib/herb/libherb.rb +0 -35
- data/src/buffer.c +0 -241
- data/src/include/array.h +0 -33
- data/src/include/buffer.h +0 -39
- data/src/include/json.h +0 -28
- data/src/include/memory.h +0 -12
- data/src/json.c +0 -205
- data/src/memory.c +0 -53
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
use crate::bindings::*;
|
|
2
|
+
use crate::convert::token_from_c;
|
|
3
|
+
use crate::errors::*;
|
|
4
|
+
use crate::nodes::*;
|
|
5
|
+
use crate::{Location, Position};
|
|
6
|
+
use std::ffi::CStr;
|
|
7
|
+
use std::os::raw::{c_char, c_void};
|
|
8
|
+
|
|
9
|
+
unsafe fn convert_location(c_location: location_T) -> Location {
|
|
10
|
+
Location::new(
|
|
11
|
+
Position::new(c_location.start.line, c_location.start.column),
|
|
12
|
+
Position::new(c_location.end.line, c_location.end.column),
|
|
13
|
+
)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
<%- errors.each do |error| -%>
|
|
17
|
+
<%- snake_name = error.name.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase -%>
|
|
18
|
+
unsafe fn convert_<%= snake_name %>(error_ptr: *const <%= error.c_type %>) -> <%= error.name %> {
|
|
19
|
+
let error_ref = &*error_ptr;
|
|
20
|
+
let message = if error_ref.base.message.is_null() {
|
|
21
|
+
String::new()
|
|
22
|
+
} else {
|
|
23
|
+
CStr::from_ptr(error_ref.base.message).to_string_lossy().into_owned()
|
|
24
|
+
};
|
|
25
|
+
let location = convert_location(error_ref.base.location);
|
|
26
|
+
|
|
27
|
+
<%= error.name %>::new(
|
|
28
|
+
message,
|
|
29
|
+
location,
|
|
30
|
+
<%- error.fields.each do |field| -%>
|
|
31
|
+
<%- case field -%>
|
|
32
|
+
<%- when Herb::Template::StringField -%>
|
|
33
|
+
get_string_field(error_ref.<%= field.name %>),
|
|
34
|
+
<%- when Herb::Template::TokenField -%>
|
|
35
|
+
convert_token_field(error_ref.<%= field.name %>),
|
|
36
|
+
<%- when Herb::Template::TokenTypeField -%>
|
|
37
|
+
if error_ref.<%= field.name %> == u32::MAX {
|
|
38
|
+
None
|
|
39
|
+
} else {
|
|
40
|
+
Some(CStr::from_ptr(crate::ffi::token_type_to_string(error_ref.<%= field.name %>)).to_string_lossy().into_owned())
|
|
41
|
+
},
|
|
42
|
+
<%- end -%>
|
|
43
|
+
<%- end -%>
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
<%- end -%>
|
|
48
|
+
|
|
49
|
+
unsafe fn convert_errors(errors_array: *mut hb_array_T) -> Vec<AnyError> {
|
|
50
|
+
if errors_array.is_null() {
|
|
51
|
+
return Vec::new();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let count = hb_array_size(errors_array);
|
|
55
|
+
let mut errors = Vec::with_capacity(count);
|
|
56
|
+
|
|
57
|
+
for index in 0..count {
|
|
58
|
+
let error_base_ptr = hb_array_get(errors_array, index) as *const ERROR_T;
|
|
59
|
+
if error_base_ptr.is_null() {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let error_base = &*error_base_ptr;
|
|
64
|
+
|
|
65
|
+
let error = match error_base.type_ {
|
|
66
|
+
<%- errors.each do |error| -%>
|
|
67
|
+
<%- snake_name = error.name.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase -%>
|
|
68
|
+
<%= error.type %> => {
|
|
69
|
+
let error_ptr = error_base_ptr as *const <%= error.c_type %>;
|
|
70
|
+
AnyError::<%= error.name %>(convert_<%= snake_name %>(error_ptr))
|
|
71
|
+
}
|
|
72
|
+
<%- end -%>
|
|
73
|
+
_ => continue,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
errors.push(error);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
errors
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
unsafe fn get_string_field(string_ptr: *const c_char) -> String {
|
|
83
|
+
if string_ptr.is_null() {
|
|
84
|
+
String::new()
|
|
85
|
+
} else {
|
|
86
|
+
CStr::from_ptr(string_ptr).to_string_lossy().into_owned()
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
unsafe fn convert_element_source(source: u32) -> String {
|
|
91
|
+
let hb_string = crate::ffi::element_source_to_string(source);
|
|
92
|
+
if hb_string.data.is_null() {
|
|
93
|
+
String::new()
|
|
94
|
+
} else {
|
|
95
|
+
let slice = std::slice::from_raw_parts(hb_string.data as *const u8, hb_string.length as usize);
|
|
96
|
+
String::from_utf8_lossy(slice).into_owned()
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
unsafe fn convert_token_field(token_ptr: *mut token_T) -> Option<crate::Token> {
|
|
101
|
+
if token_ptr.is_null() {
|
|
102
|
+
None
|
|
103
|
+
} else {
|
|
104
|
+
Some(token_from_c(token_ptr))
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
unsafe fn convert_children(children_array: *mut hb_array_T) -> Vec<AnyNode> {
|
|
109
|
+
if children_array.is_null() {
|
|
110
|
+
return Vec::new();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
let count = hb_array_size(children_array);
|
|
114
|
+
let mut children = Vec::with_capacity(count);
|
|
115
|
+
|
|
116
|
+
for index in 0..count {
|
|
117
|
+
let child_ptr = hb_array_get(children_array, index);
|
|
118
|
+
if !child_ptr.is_null() {
|
|
119
|
+
if let Some(node) = convert_node(child_ptr as *const c_void) {
|
|
120
|
+
children.push(node);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
children
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
unsafe fn convert_node_field(node_ptr: *mut c_void) -> Option<Box<AnyNode>> {
|
|
129
|
+
if node_ptr.is_null() {
|
|
130
|
+
None
|
|
131
|
+
} else {
|
|
132
|
+
convert_node(node_ptr).map(Box::new)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
macro_rules! convert_specific_node_field {
|
|
137
|
+
($node_ptr:expr, $expected_type:expr, $convert_fn:ident, $node_type:ty) => {
|
|
138
|
+
if $node_ptr.is_null() {
|
|
139
|
+
None
|
|
140
|
+
} else {
|
|
141
|
+
let ast_base_ptr = $node_ptr as *const AST_NODE_T;
|
|
142
|
+
let ast_base_ref = &*ast_base_ptr;
|
|
143
|
+
let node_type = ast_base_ref.type_;
|
|
144
|
+
|
|
145
|
+
if node_type != $expected_type {
|
|
146
|
+
eprintln!("Warning: Expected node type {} but got {}", $expected_type, node_type);
|
|
147
|
+
None
|
|
148
|
+
} else {
|
|
149
|
+
$convert_fn($node_ptr as *const c_void).map(Box::new)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
unsafe fn convert_node(node_ptr: *const c_void) -> Option<AnyNode> {
|
|
156
|
+
if node_ptr.is_null() {
|
|
157
|
+
return None;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
let ast_base_ptr = node_ptr as *const AST_NODE_T;
|
|
161
|
+
let ast_base_ref = &*ast_base_ptr;
|
|
162
|
+
let node_type = ast_base_ref.type_;
|
|
163
|
+
|
|
164
|
+
match node_type {
|
|
165
|
+
<%- nodes.each do |node| -%>
|
|
166
|
+
<%= node.type %> => convert_<%= node.human %>(node_ptr).map(AnyNode::<%= node.name %>),
|
|
167
|
+
<%- end -%>
|
|
168
|
+
_ => {
|
|
169
|
+
eprintln!("Warning: Unknown node type {}", node_type);
|
|
170
|
+
None
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
<%- nodes.each do |node| -%>
|
|
176
|
+
<%- if node.name == "DocumentNode" -%>
|
|
177
|
+
/// Converts a C document node pointer to a Rust DocumentNode.
|
|
178
|
+
///
|
|
179
|
+
/// # Safety
|
|
180
|
+
///
|
|
181
|
+
/// The caller must ensure that `node_ptr` is a valid pointer to a C document node
|
|
182
|
+
/// structure with properly initialized fields.
|
|
183
|
+
<%- end -%>
|
|
184
|
+
<%= node.name == "DocumentNode" ? "pub " : "" %>unsafe fn convert_<%= node.human %>(node_ptr: *const c_void) -> Option<<%= node.name %>> {
|
|
185
|
+
if node_ptr.is_null() {
|
|
186
|
+
return None;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
let c_node_ptr = node_ptr as *const <%= node.c_type %>;
|
|
190
|
+
let node_base_ref = &(*c_node_ptr).base;
|
|
191
|
+
|
|
192
|
+
Some(<%= node.name %> {
|
|
193
|
+
node_type: "<%= node.name %>".to_string(),
|
|
194
|
+
location: convert_location(node_base_ref.location),
|
|
195
|
+
errors: convert_errors(node_base_ref.errors),
|
|
196
|
+
<%- node.fields.each do |field| -%>
|
|
197
|
+
<%- case field -%>
|
|
198
|
+
<%- when Herb::Template::StringField -%>
|
|
199
|
+
<%= field.name %>: get_string_field((*c_node_ptr).<%= field.name %>),
|
|
200
|
+
<%- when Herb::Template::ElementSourceField -%>
|
|
201
|
+
<%= field.name %>: convert_element_source((*c_node_ptr).<%= field.name %>),
|
|
202
|
+
<%- when Herb::Template::TokenField -%>
|
|
203
|
+
<%= field.name %>: convert_token_field((*c_node_ptr).<%= field.name %>),
|
|
204
|
+
<%- when Herb::Template::BooleanField -%>
|
|
205
|
+
<%= field.name %>: (*c_node_ptr).<%= field.name %>,
|
|
206
|
+
<%- when Herb::Template::ArrayField -%>
|
|
207
|
+
<%= field.name %>: convert_children((*c_node_ptr).<%= field.name %>),
|
|
208
|
+
<%- when Herb::Template::NodeField -%>
|
|
209
|
+
<%- if field.specific_kind && field.specific_kind != "Node" -%>
|
|
210
|
+
<%- specific_node = nodes.find { |n| n.name == field.specific_kind } -%>
|
|
211
|
+
<%= field.name %>: convert_specific_node_field!((*c_node_ptr).<%= field.name %>, <%= specific_node.type %>, convert_<%= specific_node.human %>, <%= field.specific_kind %>),
|
|
212
|
+
<%- else -%>
|
|
213
|
+
<%= field.name %>: convert_node_field((*c_node_ptr).<%= field.name %> as *mut c_void),
|
|
214
|
+
<%- end -%>
|
|
215
|
+
<%- end -%>
|
|
216
|
+
<%- end -%>
|
|
217
|
+
})
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
<%- end -%>
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
use crate::{Location, Token};
|
|
2
|
+
use colored::*;
|
|
3
|
+
|
|
4
|
+
fn escape_string(s: &str) -> String {
|
|
5
|
+
s.replace('\\', "\\\\")
|
|
6
|
+
.replace('\n', "\\n")
|
|
7
|
+
.replace('\r', "\\r")
|
|
8
|
+
.replace('\t', "\\t")
|
|
9
|
+
.replace('"', "\\\"")
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
fn format_string_value(value: &str) -> String {
|
|
13
|
+
format!("\"{}\"", escape_string(value)).green().to_string()
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
fn format_token_value(token: &Option<Token>) -> String {
|
|
17
|
+
token.as_ref().map(|t| t.tree_inspect()).unwrap_or_else(|| "∅".magenta().to_string())
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
fn format_token_type_value(token_type: &Option<String>) -> String {
|
|
21
|
+
token_type.as_ref().map(|t| format!("\"{}\"", t).green().to_string()).unwrap_or_else(|| "∅".magenta().to_string())
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
#[allow(dead_code)]
|
|
25
|
+
fn format_position_value(position: &Option<crate::Position>) -> String {
|
|
26
|
+
position.as_ref().map(|p| p.to_string()).unwrap_or_else(|| "∅".magenta().to_string())
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
#[allow(dead_code)]
|
|
30
|
+
fn format_size_value(value: usize) -> String {
|
|
31
|
+
value.to_string().magenta().bold().to_string()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#[derive(Debug, Clone, PartialEq)]
|
|
35
|
+
pub enum ErrorType {
|
|
36
|
+
<%- errors.each do |error| -%>
|
|
37
|
+
<%= error.name %>,
|
|
38
|
+
<%- end -%>
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
impl ErrorType {
|
|
42
|
+
pub fn as_str(&self) -> &str {
|
|
43
|
+
match self {
|
|
44
|
+
<%- errors.each do |error| -%>
|
|
45
|
+
ErrorType::<%= error.name %> => "<%= error.type %>",
|
|
46
|
+
<%- end -%>
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
pub trait ErrorNode {
|
|
52
|
+
fn error_type(&self) -> &str;
|
|
53
|
+
fn message(&self) -> &str;
|
|
54
|
+
fn location(&self) -> &Location;
|
|
55
|
+
fn tree_inspect(&self) -> String;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
#[derive(Debug, Clone)]
|
|
59
|
+
pub enum AnyError {
|
|
60
|
+
<%- errors.each do |error| -%>
|
|
61
|
+
<%= error.name %>(<%= error.name %>),
|
|
62
|
+
<%- end -%>
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
impl AnyError {
|
|
66
|
+
pub fn error_type(&self) -> &str {
|
|
67
|
+
match self {
|
|
68
|
+
<%- errors.each do |error| -%>
|
|
69
|
+
AnyError::<%= error.name %>(e) => &e.error_type,
|
|
70
|
+
<%- end -%>
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
pub fn message(&self) -> &str {
|
|
75
|
+
match self {
|
|
76
|
+
<%- errors.each do |error| -%>
|
|
77
|
+
AnyError::<%= error.name %>(e) => &e.message,
|
|
78
|
+
<%- end -%>
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
pub fn location(&self) -> &Location {
|
|
83
|
+
match self {
|
|
84
|
+
<%- errors.each do |error| -%>
|
|
85
|
+
AnyError::<%= error.name %>(e) => &e.location,
|
|
86
|
+
<%- end -%>
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
pub fn tree_inspect(&self) -> String {
|
|
91
|
+
match self {
|
|
92
|
+
<%- errors.each do |error| -%>
|
|
93
|
+
AnyError::<%= error.name %>(e) => e.tree_inspect(),
|
|
94
|
+
<%- end -%>
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
impl ErrorNode for AnyError {
|
|
100
|
+
fn error_type(&self) -> &str {
|
|
101
|
+
self.error_type()
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
fn message(&self) -> &str {
|
|
105
|
+
self.message()
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
fn location(&self) -> &Location {
|
|
109
|
+
self.location()
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
fn tree_inspect(&self) -> String {
|
|
113
|
+
self.tree_inspect()
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
<%- errors.each do |error| -%>
|
|
118
|
+
#[derive(Debug, Clone)]
|
|
119
|
+
pub struct <%= error.name %> {
|
|
120
|
+
pub error_type: String,
|
|
121
|
+
pub message: String,
|
|
122
|
+
pub location: Location,
|
|
123
|
+
<%- error.fields.each do |field| -%>
|
|
124
|
+
<%- case field -%>
|
|
125
|
+
<%- when Herb::Template::StringField -%>
|
|
126
|
+
pub <%= field.name %>: String,
|
|
127
|
+
<%- when Herb::Template::TokenField -%>
|
|
128
|
+
pub <%= field.name %>: Option<Token>,
|
|
129
|
+
<%- when Herb::Template::TokenTypeField -%>
|
|
130
|
+
pub <%= field.name %>: Option<String>,
|
|
131
|
+
<%- when Herb::Template::PositionField -%>
|
|
132
|
+
pub <%= field.name %>: Option<Position>,
|
|
133
|
+
<%- when Herb::Template::SizeTField -%>
|
|
134
|
+
pub <%= field.name %>: usize,
|
|
135
|
+
<%- end -%>
|
|
136
|
+
<%- end -%>
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
impl <%= error.name %> {
|
|
140
|
+
pub fn new(
|
|
141
|
+
message: String,
|
|
142
|
+
location: Location,
|
|
143
|
+
<%- error.fields.each do |field| -%>
|
|
144
|
+
<%- case field -%>
|
|
145
|
+
<%- when Herb::Template::StringField -%>
|
|
146
|
+
<%= field.name %>: String,
|
|
147
|
+
<%- when Herb::Template::TokenField -%>
|
|
148
|
+
<%= field.name %>: Option<Token>,
|
|
149
|
+
<%- when Herb::Template::TokenTypeField -%>
|
|
150
|
+
<%= field.name %>: Option<String>,
|
|
151
|
+
<%- when Herb::Template::PositionField -%>
|
|
152
|
+
<%= field.name %>: Option<Position>,
|
|
153
|
+
<%- when Herb::Template::SizeTField -%>
|
|
154
|
+
<%= field.name %>: usize,
|
|
155
|
+
<%- end -%>
|
|
156
|
+
<%- end -%>
|
|
157
|
+
) -> Self {
|
|
158
|
+
Self {
|
|
159
|
+
error_type: "<%= error.type %>".to_string(),
|
|
160
|
+
message,
|
|
161
|
+
location,
|
|
162
|
+
<%- error.fields.each do |field| -%>
|
|
163
|
+
<%= field.name %>,
|
|
164
|
+
<%- end -%>
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
pub fn tree_inspect(&self) -> String {
|
|
169
|
+
let mut output = String::new();
|
|
170
|
+
|
|
171
|
+
output.push_str(&format!("{} {} {}\n",
|
|
172
|
+
"@".white(),
|
|
173
|
+
"<%= error.name %>".red().bold(),
|
|
174
|
+
format!("(location: {})", self.location).dimmed()
|
|
175
|
+
));
|
|
176
|
+
<%- symbol = error.fields.any? ? "├──" : "└──" -%>
|
|
177
|
+
output.push_str(&format!("{} {}: {}\n", "<%= symbol %>".white(), "message".white(), format_string_value(&self.message)));
|
|
178
|
+
<%- error.fields.each do |field| -%>
|
|
179
|
+
<%- symbol = error.fields.last == field ? "└──" : "├──" -%>
|
|
180
|
+
<%- case field -%>
|
|
181
|
+
<%- when Herb::Template::StringField -%>
|
|
182
|
+
output.push_str(&format!("{} {}: {}\n", "<%= symbol %>".white(), "<%= field.name %>".white(), format_string_value(&self.<%= field.name %>)));
|
|
183
|
+
<%- when Herb::Template::TokenField -%>
|
|
184
|
+
output.push_str(&format!("{} {}: {}\n", "<%= symbol %>".white(), "<%= field.name %>".white(), format_token_value(&self.<%= field.name %>)));
|
|
185
|
+
<%- when Herb::Template::TokenTypeField -%>
|
|
186
|
+
output.push_str(&format!("{} {}: {}\n", "<%= symbol %>".white(), "<%= field.name %>".white(), format_token_type_value(&self.<%= field.name %>)));
|
|
187
|
+
<%- when Herb::Template::PositionField -%>
|
|
188
|
+
output.push_str(&format!("{} {}: {}\n", "<%= symbol %>".white(), "<%= field.name %>".white(), format_position_value(&self.<%= field.name %>)));
|
|
189
|
+
<%- when Herb::Template::SizeTField -%>
|
|
190
|
+
output.push_str(&format!("{} {}: {}\n", "<%= symbol %>".white(), "<%= field.name %>".white(), format_size_value(self.<%= field.name %>)));
|
|
191
|
+
<%- end -%>
|
|
192
|
+
<%- end -%>
|
|
193
|
+
|
|
194
|
+
output
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
impl ErrorNode for <%= error.name %> {
|
|
199
|
+
fn error_type(&self) -> &str {
|
|
200
|
+
&self.error_type
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
fn message(&self) -> &str {
|
|
204
|
+
&self.message
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
fn location(&self) -> &Location {
|
|
208
|
+
&self.location
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
fn tree_inspect(&self) -> String {
|
|
212
|
+
<%= error.name %>::tree_inspect(self)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
<%- end -%>
|