Skip to main content

parse_to_estree_json/
parse_to_estree_json.rs

1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8//! Parse a file and print its ESTree JSON, using the crate's `parse()` façade.
9//!
10//! ```text
11//! cargo run -p hermes-parser --example parse_to_estree_json -- file.js
12//! ```
13//!
14//! With no argument it parses a built-in snippet. This is the façade version
15//! of what the `ast-dump` bin (in the unpublished `rust/crates/tools`) does
16//! with the low-level API; that bin remains the reference for flag-by-flag
17//! control.
18
19use hermes_parser::{parse_named, ParseFlags};
20
21fn main() {
22    let path = std::env::args().nth(1);
23    let (name, source) = match &path {
24        Some(p) => (
25            p.as_str(),
26            std::fs::read_to_string(p).unwrap_or_else(|e| {
27                eprintln!("cannot read '{p}': {e}");
28                std::process::exit(1);
29            }),
30        ),
31        None => (
32            "<builtin>",
33            "function greet(name) { return 'Hello, ' + name; }".to_string(),
34        ),
35    };
36
37    // Plain ECMAScript. A file extension says nothing about the dialect, so
38    // like `hermesc` this example assumes none; set the flags explicitly for
39    // the others, e.g.:
40    //     ParseFlags { parse_flow: true, ..Default::default() }   // Flow
41    //     ParseFlags { parse_ts: true, ..Default::default() }     // TypeScript
42    //     ParseFlags { parse_jsx: true, ..Default::default() }    // JSX
43    let flags = ParseFlags::default();
44
45    match parse_named(&source, name, flags) {
46        Ok(mut parsed) => print!("{}", parsed.to_estree_json(true)),
47        Err(e) => {
48            // `Display` is the one-line summary; `messages()` is the full
49            // LLVM-style rendering, which is what a CLI wants. Each string is
50            // already newline-terminated, so this is `eprint!`, not
51            // `eprintln!`.
52            for m in e.messages() {
53                eprint!("{m}");
54            }
55            std::process::exit(1);
56        }
57    }
58}