pub struct ResolveError { /* private fields */ }Expand description
A resolution that reported at least one error.
There is no AST to carry, matching hermes_parser::ParseError: on the
compile path there genuinely is none (the resolver returns nothing once it
has failed), and on the parser path the tree is dropped rather than
returned — use resolve_for_parser if you need the partially resolved
tree that reported these errors.
Implementations§
Source§impl ResolveError
impl ResolveError
Sourcepub fn diagnostics(&self) -> &[ResolvedDiagnostic]
pub fn diagnostics(&self) -> &[ResolvedDiagnostic]
Every diagnostic recorded during parsing and resolution, in emission order.
Sourcepub fn error_count(&self) -> u32
pub fn error_count(&self) -> u32
How many of the diagnostics are errors. Greater than zero for every
ResolveError the façade produces.
Sourcepub fn messages(&self) -> Vec<String>
pub fn messages(&self) -> Vec<String>
The diagnostics rendered one string each, LLVM-style (location line, message, source line, caret), without ANSI colors.
Each string already ends with a newline, as
hermes_parser::ParseError::messages does — print them with
print!/eprint!, since println! adds a blank line between
diagnostics.
Examples found in repository?
126fn main() {
127 let (name, source) = match std::env::args().nth(1) {
128 Some(path) => match std::fs::read_to_string(&path) {
129 Ok(s) => (path, s),
130 Err(e) => {
131 eprintln!("print_bindings: cannot read '{path}': {e}");
132 std::process::exit(1);
133 }
134 },
135 None => ("<builtin>".to_string(), SOURCE.to_string()),
136 };
137
138 // Step 1: parse. `ParseFlags::default()` is plain ECMAScript.
139 let parsed = match parse_named(&source, &name, ParseFlags::default()) {
140 Ok(parsed) => parsed,
141 Err(e) => {
142 // `messages()` strings are already newline-terminated.
143 for m in e.messages() {
144 eprint!("{m}");
145 }
146 std::process::exit(2);
147 }
148 };
149
150 // Step 2: resolve. The compile path, so the standard globals exist and an
151 // undeclared `console` comes back as `UndeclaredGlobalProperty` rather
152 // than as nothing at all; `hermes_sema::resolve` is the parser path.
153 let mut resolved =
154 match resolve_for_compile(parsed, &CompileOptions::default()) {
155 Ok(resolved) => resolved,
156 Err(e) => {
157 for m in e.messages() {
158 eprint!("{m}");
159 }
160 std::process::exit(2);
161 }
162 };
163
164 // Step 3: walk. References into the arena die with the lock, so the
165 // visitor collects owned `String`s and hands them back out.
166 let rows = resolved.with_program(|gc, root, sem| {
167 let mut printer = BindingPrinter {
168 gc,
169 sem,
170 rows: Vec::new(),
171 };
172 printer.visit_node(root);
173 printer.rows
174 });
175
176 println!("{}: {} identifiers", name, rows.len());
177 for (name, role, binding) in rows {
178 println!(" {name:<12} {role:<5} {binding}");
179 }
180}More examples
30fn main() -> ExitCode {
31 let mut args = std::env::args().skip(1);
32 let mut summary = false;
33 let mut path = None;
34 for arg in args.by_ref() {
35 match arg.as_str() {
36 "--summary" => summary = true,
37 _ => path = Some(arg),
38 }
39 }
40 let Some(path) = path else {
41 eprintln!("usage: resolve_and_dump [--summary] <file.js>");
42 return ExitCode::from(1);
43 };
44
45 let source = match std::fs::read_to_string(&path) {
46 Ok(s) => s,
47 Err(e) => {
48 eprintln!("resolve_and_dump: cannot read '{path}': {e}");
49 return ExitCode::from(1);
50 }
51 };
52
53 // Step 1: parse. `ParseFlags::default()` is plain ECMAScript; set
54 // `parse_flow`, `parse_ts` or `parse_jsx` for the other dialects.
55 let parsed = match parse_named(&source, &path, ParseFlags::default()) {
56 Ok(parsed) => parsed,
57 Err(e) => {
58 for m in e.messages() {
59 eprint!("{m}");
60 }
61 return ExitCode::from(2);
62 }
63 };
64
65 // Step 2: resolve. The compile path, with the standard globals declared —
66 // what `hermesc -dump-sema` does. `hermes_sema::resolve` is the parser
67 // path instead: no ambient declarations and no AST rewrites.
68 let options = CompileOptions::default();
69 let mut resolved = match resolve_for_compile(parsed, &options) {
70 Ok(resolved) => resolved,
71 Err(e) => {
72 for m in e.messages() {
73 eprint!("{m}");
74 }
75 return ExitCode::from(2);
76 }
77 };
78
79 // Warnings, if any: resolution succeeded, so none of these is an error.
80 for d in resolved.diagnostics() {
81 eprintln!("{}:{}:{}: {}", d.file_name, d.line, d.col, d.message);
82 }
83
84 // Step 3: read the result.
85 if summary {
86 print_summary(&mut resolved);
87 } else {
88 // Bytes, not a `String`: an identifier can be an unpaired surrogate,
89 // which the dumper writes as WTF-8.
90 let dump = resolved.to_sema_dump();
91 std::io::stdout().write_all(&dump).expect("write failed");
92 }
93 ExitCode::SUCCESS
94}Trait Implementations§
Source§impl Clone for ResolveError
impl Clone for ResolveError
Source§fn clone(&self) -> ResolveError
fn clone(&self) -> ResolveError
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ResolveError
impl Debug for ResolveError
Source§impl Display for ResolveError
impl Display for ResolveError
Source§impl Error for ResolveError
impl Error for ResolveError
1.30.0 · Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()