@samitouri / QOS-React-1 / commits / ce2725eda5

[rust] Very rough sketch of consuming Hermes parser results

Joe Savona committed Jul 28, 2023 at 16:12 UTC ce2725eda5858a642f21390d0fe5ae3d40ba4060
5 files changed +189
compiler/forget/Cargo.lock
+49
@@ -266,6 +266,15 @@ dependencies = [
266 "winapi",
267 ]
268
269 +[[package]]
270 +name = "cmake"
271 +version = "0.1.50"
272 +source = "registry+https://github.com/rust-lang/crates.io-index"
273 +checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130"
274 +dependencies = [
275 + "cc",
276 +]
277 +
278 [[package]]
279 name = "console"
280 version = "0.15.7"
@@ -513,6 +522,16 @@ dependencies = [
522 "miette 5.9.0",
523 ]
524
525 +[[package]]
526 +name = "forget_hermes_parser"
527 +version = "0.1.0"
528 +dependencies = [
529 + "forget_diagnostics",
530 + "forget_estree",
531 + "hermes",
532 + "juno_support",
533 +]
534 +
535 [[package]]
536 name = "forget_hir"
537 version = "0.1.0"
@@ -658,6 +677,18 @@ version = "0.14.0"
677 source = "registry+https://github.com/rust-lang/crates.io-index"
678 checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
679
680 +[[package]]
681 +name = "hermes"
682 +version = "0.1.0"
683 +source = "git+https://github.com/facebook/hermes.git#b2618410b4093e780a04228a2ce87a3626983506"
684 +dependencies = [
685 + "cmake",
686 + "juno_support",
687 + "libc",
688 + "libcplusplus",
689 + "thiserror",
690 +]
691 +
692 [[package]]
693 name = "hermit-abi"
694 version = "0.1.19"
@@ -824,6 +855,19 @@ dependencies = [
855 "serde_json",
856 ]
857
858 +[[package]]
859 +name = "juno_support"
860 +version = "0.1.0"
861 +source = "git+https://github.com/facebook/hermes.git#b2618410b4093e780a04228a2ce87a3626983506"
862 +dependencies = [
863 + "anyhow",
864 + "base64",
865 + "cmake",
866 + "libcplusplus",
867 + "thiserror",
868 + "url",
869 +]
870 +
871 [[package]]
872 name = "lazy_static"
873 version = "1.4.0"
@@ -909,6 +953,11 @@ version = "0.2.147"
953 source = "registry+https://github.com/rust-lang/crates.io-index"
954 checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
955
956 +[[package]]
957 +name = "libcplusplus"
958 +version = "0.1.0"
959 +source = "git+https://github.com/facebook/hermes.git#b2618410b4093e780a04228a2ce87a3626983506"
960 +
961 [[package]]
962 name = "linked-hash-map"
963 version = "0.5.6"
compiler/forget/Cargo.toml
+3
@@ -19,6 +19,7 @@ forget_estree = { path = "crates/forget_estree" }
19 forget_estree_codegen = { path = "crates/forget_estree_codegen" }
20 forget_estree_swc = { path = "crates/forget_estree_swc" }
21 forget_fixtures = { path = "crates/forget_fixtures" }
22 +forget_hermes_parser = { path = "crates/forget_hermes_parser" }
23 forget_hir = { path = "crates/forget_hir" }
24 forget_optimization = { path = "crates/forget_optimization" }
25 forget_ssa = { path = "crates/forget_ssa" }
@@ -39,6 +40,8 @@ swc = "0.264.8"
40 swc_core = { version = "0.79.9", features = ["swc_ecma_visit", "__ecma_transforms", "swc_ecma_ast", "swc_common", "swc", "swc_ecma_parser", "__ecma", "__common", "ecma_ast", "__visit", "__parser"] }
41 syn = "2.0.23"
42 thiserror = "1.0.41"
43 +hermes = { git = "https://github.com/facebook/hermes.git" }
44 +juno_support = { git = "https://github.com/facebook/hermes.git" }
45
46 [profile.release]
47 # configuration adapted from oxc
compiler/forget/crates/forget_hermes_parser/Cargo.toml new
+18
@@ -0,0 +1,18 @@
1 +[package]
2 +name = "forget_hermes_parser"
3 +version = "0.1.0"
4 +authors.workspace = true
5 +description.workspace = true
6 +edition.workspace = true
7 +homepage.workspace = true
8 +keywords.workspace = true
9 +license.workspace = true
10 +repository.workspace = true
11 +
12 +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
13 +
14 +[dependencies]
15 +forget_diagnostics = { workspace = true }
16 +forget_estree = { workspace = true }
17 +hermes = { workspace = true }
18 +juno_support = { workspace = true }
\ No newline at end of file
compiler/forget/crates/forget_hermes_parser/README.md new
+3
@@ -0,0 +1,3 @@
1 +# forget_hermes_parser
2 +
3 +Wrapper around the Hermes parser that exposes parse results as a `forget_estree` AST.
\ No newline at end of file
compiler/forget/crates/forget_hermes_parser/src/lib.rs new
+116
@@ -0,0 +1,116 @@
1 +use forget_diagnostics::Diagnostic;
2 +use hermes::parser::{
3 + hermes_get_BlockStatement_body, hermes_get_DeclareFunction_id,
4 + hermes_get_FunctionDeclaration_async, hermes_get_FunctionDeclaration_body,
5 + hermes_get_FunctionDeclaration_generator, hermes_get_Program_body, HermesParser, NodeKind,
6 + NodePtr, ParserDialect, ParserFlags,
7 +};
8 +use juno_support::source_manager::SourceRange;
9 +use juno_support::NullTerminatedBuf;
10 +
11 +pub fn parse(source: &str, file: &str) -> Result<forget_estree::Program, Vec<Diagnostic>> {
12 + let buf = NullTerminatedBuf::from_str_check(source);
13 + let result = HermesParser::parse(
14 + ParserFlags {
15 + dialect: ParserDialect::TypeScript,
16 + enable_jsx: true,
17 + store_doc_block: true,
18 + strict_mode: true,
19 + },
20 + &buf,
21 + );
22 + if result.has_errors() {
23 + let error_messages = result.messages();
24 + return Err(todo!("construct diagnostics"));
25 + }
26 +
27 + Ok(unsafe { convert_program(result.root().unwrap()) })
28 +}
29 +
30 +unsafe fn convert_program(node: NodePtr) -> forget_estree::Program {
31 + let node_ref = node.as_ref();
32 + let body = hermes_get_Program_body(node);
33 + let body: Vec<_> = body
34 + .iter()
35 + .map(|node| convert_module_item(NodePtr::new(node)))
36 + .collect();
37 + forget_estree::Program {
38 + body,
39 + source_type: forget_estree::SourceType::Module,
40 + loc: None,
41 + range: None,
42 + }
43 +}
44 +
45 +unsafe fn convert_module_item(node: NodePtr) -> forget_estree::ModuleItem {
46 + let node_ref = node.as_ref();
47 + match node_ref.kind {
48 + NodeKind::FunctionDeclaration => {
49 + forget_estree::ModuleItem::Statement(forget_estree::Statement::FunctionDeclaration(
50 + Box::new(convert_function_declaration(node)),
51 + ))
52 + }
53 + _ => todo!(),
54 + }
55 +}
56 +
57 +unsafe fn convert_function_declaration(node: NodePtr) -> forget_estree::FunctionDeclaration {
58 + let id = None; //hermes_get_DeclareFunction_id(node);
59 + let params = Vec::new();
60 + let body = forget_estree::FunctionBody::BlockStatement(Box::new(convert_block_statement(
61 + hermes_get_FunctionDeclaration_body(node),
62 + )));
63 + let is_generator = hermes_get_FunctionDeclaration_generator(node);
64 + let is_async = hermes_get_FunctionDeclaration_async(node);
65 + forget_estree::FunctionDeclaration {
66 + function: forget_estree::Function {
67 + id,
68 + params,
69 + body: Some(body),
70 + is_generator,
71 + is_async,
72 + loc: None,
73 + range: None,
74 + },
75 + loc: None,
76 + range: None,
77 + }
78 +}
79 +
80 +unsafe fn convert_block_statement(node: NodePtr) -> forget_estree::BlockStatement {
81 + let body = hermes_get_BlockStatement_body(node);
82 + let body: Vec<_> = body
83 + .iter()
84 + .map(|node| convert_statement(NodePtr::new(node)))
85 + .collect();
86 + forget_estree::BlockStatement {
87 + body,
88 + loc: None,
89 + range: None,
90 + }
91 +}
92 +
93 +unsafe fn convert_statement(node: NodePtr) -> forget_estree::Statement {
94 + let node_ref = node.as_ref();
95 + match node_ref.kind {
96 + NodeKind::ReturnStatement => {
97 + forget_estree::Statement::ReturnStatement(Box::new(forget_estree::ReturnStatement {
98 + argument: None,
99 + loc: None,
100 + range: None,
101 + }))
102 + }
103 + _ => todo!(),
104 + }
105 +}
106 +
107 +#[cfg(test)]
108 +mod tests {
109 + use super::*;
110 +
111 + #[test]
112 + fn fixtures() {
113 + let res = parse("function foo() { return }", "hello.js");
114 + println!("{:#?}", res);
115 + }
116 +}