diff --git a/compiler/forget/Cargo.lock b/compiler/forget/Cargo.lock index 55f707deca..145e459e6d 100644 --- a/compiler/forget/Cargo.lock +++ b/compiler/forget/Cargo.lock @@ -461,12 +461,25 @@ version = "0.1.0" dependencies = [ "bumpalo", "elsa", + "estree-codegen", "insta", "serde", "serde_json", "static_assertions", ] +[[package]] +name = "estree-codegen" +version = "0.1.0" +dependencies = [ + "indexmap 2.0.0", + "prettyplease", + "quote", + "serde", + "serde_json", + "syn 2.0.23", +] + [[package]] name = "estree-swc" version = "0.1.0" @@ -683,6 +696,7 @@ checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" dependencies = [ "equivalent", "hashbrown 0.14.0", + "serde", ] [[package]] @@ -1219,6 +1233,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "prettyplease" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92139198957b410250d43fad93e630d956499a625c527eda65175c8680f83387" +dependencies = [ + "proc-macro2", + "syn 2.0.23", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -1460,9 +1484,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.166" +version = "1.0.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8" +checksum = "7daf513456463b42aa1d94cff7e0c24d682b429f020b9afa4f5ba5c40a22b237" dependencies = [ "serde_derive", ] @@ -1480,9 +1504,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.166" +version = "1.0.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6" +checksum = "b69b106b68bc8054f0e974e70d19984040f8a5cf9215ca82626ea4853f82c4b9" dependencies = [ "proc-macro2", "quote", diff --git a/compiler/forget/Cargo.toml b/compiler/forget/Cargo.toml index b20b6328ab..af75d48c7c 100644 --- a/compiler/forget/Cargo.toml +++ b/compiler/forget/Cargo.toml @@ -6,6 +6,7 @@ members = [ "crates/hir", "crates/swc-demo", "crates/estree", + "crates/estree-codegen", "crates/estree-swc", ] diff --git a/compiler/forget/crates/estree-codegen/Cargo.toml b/compiler/forget/crates/estree-codegen/Cargo.toml new file mode 100644 index 0000000000..1044c7ce44 --- /dev/null +++ b/compiler/forget/crates/estree-codegen/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "estree-codegen" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +indexmap = { version = "2.0.0", features = ["serde"] } +prettyplease = "0.2.10" +quote = "1.0.29" +serde = { version = "1.0.167", features = ["serde_derive"] } +serde_json = "1.0.100" +syn = "2.0.23" diff --git a/compiler/forget/crates/estree-codegen/src/codegen.rs b/compiler/forget/crates/estree-codegen/src/codegen.rs new file mode 100644 index 0000000000..330526b6cf --- /dev/null +++ b/compiler/forget/crates/estree-codegen/src/codegen.rs @@ -0,0 +1,416 @@ +use std::collections::HashSet; + +use indexmap::IndexMap; +use quote::{__private::TokenStream, format_ident, quote}; +use serde::{Deserialize, Serialize}; + +/// Returns prettyplease-formatted Rust source for estree +pub fn estree() -> String { + let src = include_str!("./ecmascript.json"); + let grammar: Grammar = serde_json::from_str(src).unwrap(); + let raw = grammar.codegen().to_string(); + + let parsed = syn::parse_file(&raw).unwrap(); + prettyplease::unparse(&parsed) +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Grammar { + pub objects: IndexMap, + pub nodes: IndexMap, + pub enums: IndexMap, + pub operators: IndexMap, +} + +impl Grammar { + pub fn codegen(self) -> TokenStream { + let Self { + objects, + nodes, + enums, + operators, + } = self; + + let nodelike: HashSet = + // nodes.keys().cloned().chain(enums.keys().cloned()).collect(); + Default::default(); + + let enum_names: HashSet = enums.keys().cloned().collect(); + + let mut node_names: Vec<_> = nodes.keys().cloned().collect(); + node_names.sort(); + let node_variants: Vec<_> = node_names + .iter() + .map(|name| { + let name = format_ident!("{}", name); + quote!(#name(Box<#name>)) + }) + .collect(); + + let objects: Vec<_> = objects + .iter() + .map(|(name, object)| object.codegen(name, &nodelike)) + .collect(); + let nodes: Vec<_> = nodes + .iter() + .map(|(name, node)| node.codegen(name, &nodelike)) + .collect(); + let enums: Vec<_> = enums + .iter() + .map(|(name, enum_)| enum_.codegen(name, &enum_names)) + .collect(); + let operators: Vec<_> = operators + .iter() + .map(|(name, operator)| operator.codegen(name)) + .collect(); + + quote! { + use std::num::NonZeroU32; + use serde::{Serialize, Deserialize}; + use crate::{JsValue, Binding, SourceRange}; + + #(#objects)* + + #(#nodes)* + + #(#enums)* + + #(#operators)* + + // #[derive(Serialize, Deserialize, Clone, Debug)] + // #[serde(tag = "type")] + // pub enum Node { + // #(#node_variants),* + // } + } + } +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Object { + #[serde(default)] + pub fields: IndexMap, +} + +impl Object { + pub fn codegen(&self, name: &str, nodes: &HashSet) -> TokenStream { + let name = format_ident!("{}", name); + let fields: Vec<_> = self + .fields + .iter() + .map(|(name, field)| field.codegen(name, nodes)) + .collect(); + + quote! { + #[derive(Serialize, Deserialize, Clone, Debug)] + pub struct #name { + #(#fields),* + } + } + } +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Node { + #[serde(default)] + pub fields: IndexMap, +} + +impl Node { + pub fn codegen(&self, name: &str, nodes: &HashSet) -> TokenStream { + let name = format_ident!("{}", name); + let fields: Vec<_> = self + .fields + .iter() + .map(|(name, field)| field.codegen_node(name, nodes)) + .collect(); + + quote! { + #[derive(Serialize, Deserialize, Clone, Debug)] + pub struct #name { + #(#fields,)* + + #[serde(default)] + pub loc: Option, + + #[serde(default)] + pub range: Option, + } + + // impl #name { + // pub fn from_node(node: Node) -> Option> { + // match node { + // Node::#name(node) => Some(node), + // _ => None + // } + // } + // } + } + } +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Field { + #[serde(rename = "type")] + pub type_: String, + + #[serde(default)] + pub nullable: bool, + + #[serde(default)] + pub optional: bool, + + #[serde(default)] + pub plural: bool, + + #[serde(default)] + pub nullable_item: bool, + + #[serde(default)] + pub flatten: bool, +} + +impl Field { + pub fn codegen(&self, name: &str, nodes: &HashSet) -> TokenStream { + let name = format_ident!("{}", name); + let type_name = format_ident!( + "{}", + if nodes.contains(&self.type_) { + "Node" + } else { + &self.type_ + } + ); + let mut type_ = quote!(#type_name); + if self.plural { + if self.nullable_item { + type_ = quote!(Option<#type_>); + } + type_ = quote! { Vec<#type_> }; + } else { + assert_eq!( + self.nullable_item, false, + "Can only set nullable_item if plural" + ) + } + if self.nullable || self.optional { + assert_eq!( + self.optional, false, + "Expected field to be nullable if optional" + ); + type_ = quote!(Option<#type_>); + } + let mut field = quote!(#name: #type_); + if self.optional { + field = quote! { + #[serde(default)] + #field + } + } + if self.flatten { + field = quote! { + #[serde(flatten)] + #field + } + } + field + } + + pub fn codegen_node(&self, name: &str, nodes: &HashSet) -> TokenStream { + let name = format_ident!("{}", name); + let type_name = format_ident!( + "{}", + if nodes.contains(&self.type_) { + "Node" + } else { + &self.type_ + } + ); + let mut type_ = quote!(#type_name); + if self.plural { + if self.nullable_item { + type_ = quote!(Option<#type_>); + } + type_ = quote! { Vec<#type_> }; + } else { + assert_eq!( + self.nullable_item, false, + "Can only set nullable_item if plural" + ) + } + if self.nullable || self.optional { + assert_eq!( + self.nullable, true, + "Expected field to be nullable if optional" + ); + type_ = quote!(Option<#type_>); + } + let mut field = quote!(#name: #type_); + if self.optional { + field = quote! { + #[serde(default)] + #field + } + } + if self.flatten { + field = quote! { + #[serde(flatten)] + #field + } + } + if nodes.contains(&self.type_) { + let comment = format!(" {}", &self.type_); + field = quote! { + #[doc = #comment] + #field + } + } + field + } +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(transparent)] +pub struct Enum { + pub variants: Vec, +} + +impl Enum { + pub fn codegen(&self, name: &str, enums: &HashSet) -> TokenStream { + let mut sorted_variants: Vec<_> = self.variants.iter().collect(); + sorted_variants.sort(); + + let name = format_ident!("{}", name); + let variants: Vec<_> = sorted_variants + .iter() + .map(|name| { + let variant = format_ident!("{}", name); + if enums.contains(*name) { + quote!(#variant(#variant)) + } else { + quote!(#variant(Box<#variant>)) + } + }) + .collect(); + + let from_node_matches: Vec<_> = sorted_variants + .iter() + .map(|name| { + let variant = format_ident!("{}", name); + if enums.contains(*name) { + quote! { + if let Some(node) = #variant::from_node(node) { + return Some(Self::#variant(node)); + } + } + } else { + quote! { + if let Some(node) = #variant::from_node(node) { + return Some(Self::#variant(node)); + } + } + } + }) + .collect(); + + let enum_ = quote! { + pub enum #name { + #(#variants),* + } + }; + let enum_ = if sorted_variants.iter().any(|name| enums.contains(*name)) { + // contains recursive enum, use untagged serialization + quote! { + #[serde(untagged)] + #enum_ + } + } else { + quote! { + #[serde(tag = "type")] + #enum_ + } + }; + + quote! { + #[derive(Serialize, Deserialize, Clone, Debug)] + #enum_ + + // impl #name { + // pub fn from_node(node: Node) -> Option { + // #(#from_node_matches)* + // None + // } + // } + } + } +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(transparent)] +pub struct Operator { + pub variants: IndexMap, +} + +impl Operator { + pub fn codegen(&self, name: &str) -> TokenStream { + let mut sorted_variants: Vec<_> = self.variants.iter().collect(); + sorted_variants.sort(); + + let name = format_ident!("{}", name); + let variants: Vec<_> = sorted_variants + .iter() + .map(|(name, operator)| { + let name = format_ident!("{}", name); + let comment = format!(" {}", &operator); + quote! { + #[doc = #comment] + #[serde(rename = #operator)] + #name + } + }) + .collect(); + + let display_matches: Vec<_> = sorted_variants + .iter() + .map(|(name, operator)| { + let name = format_ident!("{}", name); + quote!(Self::#name => #operator) + }) + .collect(); + + let fromstr_matches: Vec<_> = sorted_variants + .iter() + .map(|(name, operator)| { + let name = format_ident!("{}", name); + quote!(#operator => Ok(Self::#name)) + }) + .collect(); + + quote! { + #[derive(Serialize, Deserialize, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] + pub enum #name { + #(#variants),* + } + + impl std::fmt::Display for #name { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let name = match self { + #(#display_matches),* + }; + f.write_str(name) + } + } + + impl std::str::FromStr for #name { + type Err = (); + + fn from_str(s: &str) -> Result { + match s { + #(#fromstr_matches,)* + _ => Err(()), + } + } + } + } + } +} diff --git a/compiler/forget/crates/estree-codegen/src/ecmascript.json b/compiler/forget/crates/estree-codegen/src/ecmascript.json new file mode 100644 index 0000000000..79eb4e7408 --- /dev/null +++ b/compiler/forget/crates/estree-codegen/src/ecmascript.json @@ -0,0 +1,596 @@ +{ + "objects": { + "SourceLocation": { + "fields": { + "source": { + "type": "String", + "nullable": true + }, + "start": { + "type": "Position" + }, + "end": { + "type": "Position" + } + } + }, + "Position": { + "fields": { + "line": { + "type": "NonZeroU32" + }, + "column": { + "type": "u32" + } + } + }, + "Function": { + "fields": { + "id": { + "type": "Identifier", + "nullable": true + }, + "params": { + "type": "Pattern", + "plural": true + }, + "body": { + "type": "BlockStatement", + "nullable": true + } + } + }, + "RegExpValue": { + "fields": { + "pattern": { + "type": "String" + }, + "flags": { + "type": "String" + } + } + } + }, + "nodes": { + "Identifier": { + "fields": { + "name": { + "type": "String" + }, + "binding": { + "type": "Binding", + "nullable": true, + "optional": true, + "skip": true + } + } + }, + "Literal": { + "fields": { + "value": { + "type": "JsValue" + }, + "raw": { + "type": "String", + "nullable": true, + "optional": true + }, + "regex": { + "type": "RegExpValue", + "nullable": true, + "optional": true + } + } + }, + "Program": { + "fields": { + "body": { + "type": "Statement", + "plural": true + } + } + }, + "ExpressionStatement": { + "fields": { + "expression": { + "type": "Expression" + } + } + }, + "BlockStatement": { + "fields": { + "body": { + "type": "Statement", + "plural": true + } + } + }, + "EmptyStatement": {}, + "DebuggerStatement": {}, + "WithStatement": { + "fields": { + "object": { + "type": "Expression" + }, + "body": { + "type": "Statement" + } + } + }, + "ReturnStatement": { + "fields": { + "argument": { + "type": "Expression", + "nullable": true + } + } + }, + "LabeledStatement": { + "fields": { + "label": { + "type": "Identifier" + }, + "body": { + "type": "Statement" + } + } + }, + "BreakStatement": { + "fields": { + "label": { + "type": "Identifier", + "nullable": true + } + } + }, + "ContinueStatement": { + "fields": { + "label": { + "type": "Identifier", + "nullable": true + } + } + }, + "IfStatement": { + "fields": { + "test": { + "type": "Expression" + }, + "consequent": { + "type": "Statement" + }, + "alternate": { + "type": "Statement", + "nullable": true + } + } + }, + "SwitchStatement": { + "fields": { + "discriminant": { + "type": "Expression" + }, + "cases": { + "type": "SwitchCase", + "plural": true + } + } + }, + "SwitchCase": { + "fields": { + "test": { + "type": "Expression", + "nullable": true + }, + "consequent": { + "type": "Statement", + "plural": true + } + } + }, + "ThrowStatement": { + "fields": { + "argument": { + "type": "Expression" + } + } + }, + "TryStatement": { + "fields": { + "block": { + "type": "BlockStatement" + }, + "handler": { + "type": "CatchClause", + "nullable": true + }, + "finalizer": { + "type": "BlockStatement", + "nullable": true + } + } + }, + "CatchClause": { + "fields": { + "param": { + "type": "Pattern" + }, + "body": { + "type": "BlockStatement" + } + } + }, + "WhileStatement": { + "fields": { + "test": { + "type": "Expression" + }, + "body": { + "type": "Statement" + } + } + }, + "DoWhileStatement": { + "fields": { + "body": { + "type": "Statement" + }, + "test": { + "type": "Expression" + } + } + }, + "ForStatement": { + "fields": { + "init": { + "type": "ForInit", + "nullable": true + }, + "test": { + "type": "Expression", + "nullable": true + }, + "update": { + "type": "Expression", + "nullable": true + }, + "body": { + "type": "Statement" + } + } + }, + "ForInStatement": { + "fields": { + "left": { + "type": "ForInInit" + }, + "right": { + "type": "Expression" + }, + "body": { + "type": "Statement" + } + } + }, + "FunctionDeclaration": { + "fields": { + "function": { + "type": "Function", + "flatten": true + } + } + }, + "VariableDeclaration": { + "fields": { + "kind": { + "type": "VariableDeclarationKind" + }, + "declarations": { + "type": "VariableDeclarator", + "plural": true + } + } + }, + "VariableDeclarator": { + "fields": { + "id": { + "type": "Pattern" + }, + "init": { + "type": "Expression", + "nullable": true + } + } + }, + "ThisExpression": {}, + "ArrayExpression": { + "fields": { + "elements": { + "type": "Expression", + "plural": true, + "nullable_item": true + } + } + }, + "ObjectExpression": { + "fields": { + "properties": { + "type": "Property", + "plural": true + } + } + }, + "Property": { + "fields": { + "key": { + "type": "PropertyKey" + }, + "value": { + "type": "Expression" + }, + "kind": { + "type": "PropertyKind" + } + } + }, + "FunctionExpression": { + "fields": { + "function": { + "type": "Function", + "flatten": true + } + } + }, + "UnaryExpression": { + "fields": { + "operator": { + "type": "UnaryOperator" + }, + "prefix": { + "type": "bool" + }, + "argument": { + "type": "Expression" + } + } + }, + "UpdateExpression": { + "fields": { + "operator": { + "type": "UpdateOperator" + }, + "argument": { + "type": "Expression" + }, + "prefix": { + "type": "bool" + } + } + }, + "BinaryExpression": { + "fields": { + "left": { + "type": "Expression" + }, + "operator": { + "type": "BinaryOperator" + }, + "right": { + "type": "Expression" + } + } + }, + "AssignmentExpression": { + "fields": { + "operator": { + "type": "AssignmentOperator" + }, + "left": { + "type": "AssignmentTarget" + }, + "right": { + "type": "Expression" + } + } + }, + "LogicalExpression": { + "fields": { + "operator": { + "type": "LogicalOperator" + }, + "left": { + "type": "Expression" + }, + "right": { + "type": "Expression" + } + } + }, + "MemberExpression": { + "fields": { + "object": { + "type": "Expression" + }, + "property": { + "type": "Expression" + }, + "computed": { + "type": "bool" + } + } + }, + "ConditionalExpression": { + "fields": { + "test": { + "type": "Expression" + }, + "alternate": { + "type": "Expression" + }, + "consequent": { + "type": "Expression" + } + } + }, + "CallExpression": { + "type": true, + "fields": { + "callee": { + "type": "Expression" + }, + "arguments": { + "type": "Expression", + "plural": true + } + } + }, + "NewExpression": { + "type": true, + "fields": { + "callee": { + "type": "Expression" + }, + "arguments": { + "type": "Expression", + "plural": true + } + } + }, + "SequenceExpression": { + "type": true, + "fields": { + "expressions": { + "type": "Expression", + "plural": true + } + } + } + }, + "enums": { + "Statement": [ + "BlockStatement", + "BreakStatement", + "ContinueStatement", + "DebuggerStatement", + "DoWhileStatement", + "EmptyStatement", + "ExpressionStatement", + "ForInStatement", + "ForStatement", + "FunctionDeclaration", + "IfStatement", + "LabeledStatement", + "ReturnStatement", + "SwitchStatement", + "ThrowStatement", + "TryStatement", + "VariableDeclaration", + "WhileStatement", + "WithStatement" + ], + "Expression": [ + "ArrayExpression", + "AssignmentExpression", + "BinaryExpression", + "CallExpression", + "ConditionalExpression", + "FunctionExpression", + "Identifier", + "Literal", + "LogicalExpression", + "MemberExpression", + "NewExpression", + "ObjectExpression", + "SequenceExpression", + "ThisExpression", + "UnaryExpression", + "UpdateExpression" + ], + "Pattern": [ + "Identifier" + ], + "ForInit": [ + "Expression", + "VariableDeclaration" + ], + "ForInInit": [ + "Pattern", + "VariableDeclaration" + ], + "PropertyKey": [ + "Identifier", + "Literal" + ], + "AssignmentTarget": [ + "Expression", + "Pattern" + ] + }, + "operators": { + "VariableDeclarationKind": { + "Const": "const", + "Let": "let", + "Var": "var" + }, + "PropertyKind": { + "Get": "get", + "Init": "init", + "Set": "set" + }, + "UnaryOperator": { + "Delete": "delete", + "Minus": "-", + "Negation": "!", + "Plus": "+", + "Tilde": "~", + "Typeof": "typeof", + "Void": "void" + }, + "UpdateOperator": { + "Decrement": "--", + "Increment": "++" + }, + "BinaryOperator": { + "Add": "+", + "BinaryAnd": "&", + "BinaryOr": "|", + "BinaryXor": "^", + "Divide": "/", + "Equals": "==", + "GreaterThan": ">", + "GreaterThanOrEqual": ">=", + "In": "in", + "Instanceof": "instanceof", + "LessThan": "<", + "LessThanOrEqual": "<=", + "Modulo": "%", + "Multiply": "*", + "NotEquals": "!=", + "NotStrictEquals": "!==", + "ShiftLeft": "<<", + "ShiftRight": ">>", + "StrictEquals": "===", + "Subtract": "-", + "UnsignedShiftRight": ">>>" + }, + "AssignmentOperator": { + "BinaryAndEquals": "&=", + "BinaryOrEquals": "|=", + "BinaryXorEquals": "^=", + "DivideEquals": "/=", + "Equals": "=", + "MinusEquals": "-=", + "ModuloEquals": "%=", + "MultiplyEquals": "*=", + "PlusEquals": "+=", + "ShiftLeftEquals": "<<=", + "ShiftRightEquals": ">>=", + "UnsignedShiftRightEquals": ">>>=" + }, + "LogicalOperator": { + "And": "&&", + "NullCoalescing": "??", + "Or": "||" + } + } +} \ No newline at end of file diff --git a/compiler/forget/crates/estree-codegen/src/lib.rs b/compiler/forget/crates/estree-codegen/src/lib.rs new file mode 100644 index 0000000000..47d0ac41ec --- /dev/null +++ b/compiler/forget/crates/estree-codegen/src/lib.rs @@ -0,0 +1,3 @@ +mod codegen; + +pub use codegen::estree; diff --git a/compiler/forget/crates/estree/Cargo.toml b/compiler/forget/crates/estree/Cargo.toml index 08ede92540..ff0a6ca1a2 100644 --- a/compiler/forget/crates/estree/Cargo.toml +++ b/compiler/forget/crates/estree/Cargo.toml @@ -12,3 +12,6 @@ insta = { version = "1.30.0", features = ["glob"] } serde = { version = "1.0.164", features = ["derive"] } serde_json = "1.0.99" static_assertions = "1.1.0" + +[build-dependencies] +estree-codegen = { path = "../estree-codegen" } \ No newline at end of file diff --git a/compiler/forget/crates/estree/build.rs b/compiler/forget/crates/estree/build.rs new file mode 100644 index 0000000000..eef603e9f6 --- /dev/null +++ b/compiler/forget/crates/estree/build.rs @@ -0,0 +1,13 @@ +use estree_codegen::estree; + +// Example custom build script. +fn main() { + // Re-run if the codegen files change + println!("cargo:rerun-if-changed=../estree-codegen/src/codegen.rs"); + println!("cargo:rerun-if-changed=../estree-codegen/src/lib.rs"); + println!("cargo:rerun-if-changed=../estree-codegen/src/ecmascript.json"); + println!("cargo:rerun-if-changed=../estree-codegen"); + + let src = estree(); + std::fs::write("src/generated.rs", src).unwrap(); +} diff --git a/compiler/forget/crates/estree/src/binding.rs b/compiler/forget/crates/estree/src/binding.rs new file mode 100644 index 0000000000..a5fa32814c --- /dev/null +++ b/compiler/forget/crates/estree/src/binding.rs @@ -0,0 +1,4 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct Binding; diff --git a/compiler/forget/crates/estree/src/for-statement.json b/compiler/forget/crates/estree/src/for-statement.json deleted file mode 100644 index e45691e530..0000000000 --- a/compiler/forget/crates/estree/src/for-statement.json +++ /dev/null @@ -1,528 +0,0 @@ -{ - "type": "Program", - "loc": { - "source": null, - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 7, - "column": 1 - } - }, - "body": [ - { - "type": "FunctionDeclaration", - "loc": { - "source": null, - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 7, - "column": 1 - } - }, - "id": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 1, - "column": 9 - }, - "end": { - "line": 1, - "column": 18 - } - }, - "name": "Component", - "typeAnnotation": null, - "optional": false, - "range": [ - 9, - 18 - ] - }, - "params": [ - { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 1, - "column": 19 - }, - "end": { - "line": 1, - "column": 24 - } - }, - "name": "props", - "typeAnnotation": null, - "optional": false, - "range": [ - 19, - 24 - ] - } - ], - "body": { - "type": "BlockStatement", - "loc": { - "source": null, - "start": { - "line": 1, - "column": 26 - }, - "end": { - "line": 7, - "column": 1 - } - }, - "body": [ - { - "type": "VariableDeclaration", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 2 - }, - "end": { - "line": 2, - "column": 12 - } - }, - "kind": "let", - "declarations": [ - { - "type": "VariableDeclarator", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 6 - }, - "end": { - "line": 2, - "column": 11 - } - }, - "init": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 10 - }, - "end": { - "line": 2, - "column": 11 - } - }, - "value": 0, - "range": [ - 38, - 39 - ], - "raw": "0" - }, - "id": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 6 - }, - "end": { - "line": 2, - "column": 7 - } - }, - "name": "x", - "typeAnnotation": null, - "optional": false, - "range": [ - 34, - 35 - ] - }, - "range": [ - 34, - 39 - ] - } - ], - "range": [ - 30, - 40 - ] - }, - { - "type": "ForStatement", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 2 - }, - "end": { - "line": 5, - "column": 3 - } - }, - "init": { - "type": "VariableDeclaration", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 7 - }, - "end": { - "line": 3, - "column": 16 - } - }, - "kind": "let", - "declarations": [ - { - "type": "VariableDeclarator", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 11 - }, - "end": { - "line": 3, - "column": 16 - } - }, - "init": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 15 - }, - "end": { - "line": 3, - "column": 16 - } - }, - "value": 0, - "range": [ - 56, - 57 - ], - "raw": "0" - }, - "id": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 11 - }, - "end": { - "line": 3, - "column": 12 - } - }, - "name": "i", - "typeAnnotation": null, - "optional": false, - "range": [ - 52, - 53 - ] - }, - "range": [ - 52, - 57 - ] - } - ], - "range": [ - 48, - 57 - ] - }, - "test": { - "type": "BinaryExpression", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 18 - }, - "end": { - "line": 3, - "column": 24 - } - }, - "left": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 18 - }, - "end": { - "line": 3, - "column": 19 - } - }, - "name": "i", - "typeAnnotation": null, - "optional": false, - "range": [ - 59, - 60 - ] - }, - "right": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 22 - }, - "end": { - "line": 3, - "column": 24 - } - }, - "value": 10, - "range": [ - 63, - 65 - ], - "raw": "10" - }, - "operator": "<", - "range": [ - 59, - 65 - ] - }, - "update": { - "type": "UpdateExpression", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 26 - }, - "end": { - "line": 3, - "column": 29 - } - }, - "operator": "++", - "argument": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 26 - }, - "end": { - "line": 3, - "column": 27 - } - }, - "name": "i", - "typeAnnotation": null, - "optional": false, - "range": [ - 67, - 68 - ] - }, - "prefix": false, - "range": [ - 67, - 70 - ] - }, - "body": { - "type": "BlockStatement", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 31 - }, - "end": { - "line": 5, - "column": 3 - } - }, - "body": [ - { - "type": "ExpressionStatement", - "loc": { - "source": null, - "start": { - "line": 4, - "column": 4 - }, - "end": { - "line": 4, - "column": 11 - } - }, - "expression": { - "type": "AssignmentExpression", - "loc": { - "source": null, - "start": { - "line": 4, - "column": 4 - }, - "end": { - "line": 4, - "column": 10 - } - }, - "operator": "+=", - "left": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 4, - "column": 4 - }, - "end": { - "line": 4, - "column": 5 - } - }, - "name": "x", - "typeAnnotation": null, - "optional": false, - "range": [ - 78, - 79 - ] - }, - "right": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 4, - "column": 9 - }, - "end": { - "line": 4, - "column": 10 - } - }, - "name": "i", - "typeAnnotation": null, - "optional": false, - "range": [ - 83, - 84 - ] - }, - "range": [ - 78, - 84 - ] - }, - "directive": null, - "range": [ - 78, - 85 - ] - } - ], - "range": [ - 72, - 89 - ] - }, - "range": [ - 43, - 89 - ] - }, - { - "type": "ReturnStatement", - "loc": { - "source": null, - "start": { - "line": 6, - "column": 2 - }, - "end": { - "line": 6, - "column": 11 - } - }, - "argument": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 6, - "column": 9 - }, - "end": { - "line": 6, - "column": 10 - } - }, - "name": "x", - "typeAnnotation": null, - "optional": false, - "range": [ - 99, - 100 - ] - }, - "range": [ - 92, - 101 - ] - } - ], - "range": [ - 26, - 103 - ] - }, - "typeParameters": null, - "returnType": null, - "predicate": null, - "generator": false, - "async": false, - "range": [ - 0, - 103 - ] - } - ], - "comments": [], - "interpreter": null, - "range": [ - 0, - 103 - ], - "sourceType": "script" - } \ No newline at end of file diff --git a/compiler/forget/crates/estree/src/generated.rs b/compiler/forget/crates/estree/src/generated.rs new file mode 100644 index 0000000000..1c2c873eca --- /dev/null +++ b/compiler/forget/crates/estree/src/generated.rs @@ -0,0 +1,916 @@ +use std::num::NonZeroU32; +use serde::{Serialize, Deserialize}; +use crate::{JsValue, Binding, SourceRange}; +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct SourceLocation { + source: Option, + start: Position, + end: Position, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct Position { + line: NonZeroU32, + column: u32, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct Function { + id: Option, + params: Vec, + body: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct RegExpValue { + pattern: String, + flags: String, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct Identifier { + name: String, + #[serde(default)] + binding: Option, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct Literal { + value: JsValue, + #[serde(default)] + raw: Option, + #[serde(default)] + regex: Option, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct Program { + body: Vec, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ExpressionStatement { + expression: Expression, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct BlockStatement { + body: Vec, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct EmptyStatement { + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct DebuggerStatement { + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct WithStatement { + object: Expression, + body: Statement, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ReturnStatement { + argument: Option, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct LabeledStatement { + label: Identifier, + body: Statement, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct BreakStatement { + label: Option, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ContinueStatement { + label: Option, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct IfStatement { + test: Expression, + consequent: Statement, + alternate: Option, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct SwitchStatement { + discriminant: Expression, + cases: Vec, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct SwitchCase { + test: Option, + consequent: Vec, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ThrowStatement { + argument: Expression, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct TryStatement { + block: BlockStatement, + handler: Option, + finalizer: Option, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct CatchClause { + param: Pattern, + body: BlockStatement, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct WhileStatement { + test: Expression, + body: Statement, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct DoWhileStatement { + body: Statement, + test: Expression, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ForStatement { + init: Option, + test: Option, + update: Option, + body: Statement, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ForInStatement { + left: ForInInit, + right: Expression, + body: Statement, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct FunctionDeclaration { + #[serde(flatten)] + function: Function, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct VariableDeclaration { + kind: VariableDeclarationKind, + declarations: Vec, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct VariableDeclarator { + id: Pattern, + init: Option, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ThisExpression { + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArrayExpression { + elements: Vec>, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ObjectExpression { + properties: Vec, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct Property { + key: PropertyKey, + value: Expression, + kind: PropertyKind, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct FunctionExpression { + #[serde(flatten)] + function: Function, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct UnaryExpression { + operator: UnaryOperator, + prefix: bool, + argument: Expression, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct UpdateExpression { + operator: UpdateOperator, + argument: Expression, + prefix: bool, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct BinaryExpression { + left: Expression, + operator: BinaryOperator, + right: Expression, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct AssignmentExpression { + operator: AssignmentOperator, + left: AssignmentTarget, + right: Expression, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct LogicalExpression { + operator: LogicalOperator, + left: Expression, + right: Expression, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct MemberExpression { + object: Expression, + property: Expression, + computed: bool, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ConditionalExpression { + test: Expression, + alternate: Expression, + consequent: Expression, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct CallExpression { + callee: Expression, + arguments: Vec, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct NewExpression { + callee: Expression, + arguments: Vec, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct SequenceExpression { + expressions: Vec, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(tag = "type")] +pub enum Statement { + BlockStatement(Box), + BreakStatement(Box), + ContinueStatement(Box), + DebuggerStatement(Box), + DoWhileStatement(Box), + EmptyStatement(Box), + ExpressionStatement(Box), + ForInStatement(Box), + ForStatement(Box), + FunctionDeclaration(Box), + IfStatement(Box), + LabeledStatement(Box), + ReturnStatement(Box), + SwitchStatement(Box), + ThrowStatement(Box), + TryStatement(Box), + VariableDeclaration(Box), + WhileStatement(Box), + WithStatement(Box), +} +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(tag = "type")] +pub enum Expression { + ArrayExpression(Box), + AssignmentExpression(Box), + BinaryExpression(Box), + CallExpression(Box), + ConditionalExpression(Box), + FunctionExpression(Box), + Identifier(Box), + Literal(Box), + LogicalExpression(Box), + MemberExpression(Box), + NewExpression(Box), + ObjectExpression(Box), + SequenceExpression(Box), + ThisExpression(Box), + UnaryExpression(Box), + UpdateExpression(Box), +} +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(tag = "type")] +pub enum Pattern { + Identifier(Box), +} +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(untagged)] +pub enum ForInit { + Expression(Expression), + VariableDeclaration(Box), +} +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(untagged)] +pub enum ForInInit { + Pattern(Pattern), + VariableDeclaration(Box), +} +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(tag = "type")] +pub enum PropertyKey { + Identifier(Box), + Literal(Box), +} +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(untagged)] +pub enum AssignmentTarget { + Expression(Expression), + Pattern(Pattern), +} +#[derive( + Serialize, + Deserialize, + Clone, + Copy, + Eq, + PartialEq, + Ord, + PartialOrd, + Hash, + Debug +)] +pub enum VariableDeclarationKind { + /// const + #[serde(rename = "const")] + Const, + /// let + #[serde(rename = "let")] + Let, + /// var + #[serde(rename = "var")] + Var, +} +impl std::fmt::Display for VariableDeclarationKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let name = match self { + Self::Const => "const", + Self::Let => "let", + Self::Var => "var", + }; + f.write_str(name) + } +} +impl std::str::FromStr for VariableDeclarationKind { + type Err = (); + fn from_str(s: &str) -> Result { + match s { + "const" => Ok(Self::Const), + "let" => Ok(Self::Let), + "var" => Ok(Self::Var), + _ => Err(()), + } + } +} +#[derive( + Serialize, + Deserialize, + Clone, + Copy, + Eq, + PartialEq, + Ord, + PartialOrd, + Hash, + Debug +)] +pub enum PropertyKind { + /// get + #[serde(rename = "get")] + Get, + /// init + #[serde(rename = "init")] + Init, + /// set + #[serde(rename = "set")] + Set, +} +impl std::fmt::Display for PropertyKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let name = match self { + Self::Get => "get", + Self::Init => "init", + Self::Set => "set", + }; + f.write_str(name) + } +} +impl std::str::FromStr for PropertyKind { + type Err = (); + fn from_str(s: &str) -> Result { + match s { + "get" => Ok(Self::Get), + "init" => Ok(Self::Init), + "set" => Ok(Self::Set), + _ => Err(()), + } + } +} +#[derive( + Serialize, + Deserialize, + Clone, + Copy, + Eq, + PartialEq, + Ord, + PartialOrd, + Hash, + Debug +)] +pub enum UnaryOperator { + /// delete + #[serde(rename = "delete")] + Delete, + /// - + #[serde(rename = "-")] + Minus, + /// ! + #[serde(rename = "!")] + Negation, + /// + + #[serde(rename = "+")] + Plus, + /// ~ + #[serde(rename = "~")] + Tilde, + /// typeof + #[serde(rename = "typeof")] + Typeof, + /// void + #[serde(rename = "void")] + Void, +} +impl std::fmt::Display for UnaryOperator { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let name = match self { + Self::Delete => "delete", + Self::Minus => "-", + Self::Negation => "!", + Self::Plus => "+", + Self::Tilde => "~", + Self::Typeof => "typeof", + Self::Void => "void", + }; + f.write_str(name) + } +} +impl std::str::FromStr for UnaryOperator { + type Err = (); + fn from_str(s: &str) -> Result { + match s { + "delete" => Ok(Self::Delete), + "-" => Ok(Self::Minus), + "!" => Ok(Self::Negation), + "+" => Ok(Self::Plus), + "~" => Ok(Self::Tilde), + "typeof" => Ok(Self::Typeof), + "void" => Ok(Self::Void), + _ => Err(()), + } + } +} +#[derive( + Serialize, + Deserialize, + Clone, + Copy, + Eq, + PartialEq, + Ord, + PartialOrd, + Hash, + Debug +)] +pub enum UpdateOperator { + /// -- + #[serde(rename = "--")] + Decrement, + /// ++ + #[serde(rename = "++")] + Increment, +} +impl std::fmt::Display for UpdateOperator { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let name = match self { + Self::Decrement => "--", + Self::Increment => "++", + }; + f.write_str(name) + } +} +impl std::str::FromStr for UpdateOperator { + type Err = (); + fn from_str(s: &str) -> Result { + match s { + "--" => Ok(Self::Decrement), + "++" => Ok(Self::Increment), + _ => Err(()), + } + } +} +#[derive( + Serialize, + Deserialize, + Clone, + Copy, + Eq, + PartialEq, + Ord, + PartialOrd, + Hash, + Debug +)] +pub enum BinaryOperator { + /// + + #[serde(rename = "+")] + Add, + /// & + #[serde(rename = "&")] + BinaryAnd, + /// | + #[serde(rename = "|")] + BinaryOr, + /// ^ + #[serde(rename = "^")] + BinaryXor, + /// / + #[serde(rename = "/")] + Divide, + /// == + #[serde(rename = "==")] + Equals, + /// > + #[serde(rename = ">")] + GreaterThan, + /// >= + #[serde(rename = ">=")] + GreaterThanOrEqual, + /// in + #[serde(rename = "in")] + In, + /// instanceof + #[serde(rename = "instanceof")] + Instanceof, + /// < + #[serde(rename = "<")] + LessThan, + /// <= + #[serde(rename = "<=")] + LessThanOrEqual, + /// % + #[serde(rename = "%")] + Modulo, + /// * + #[serde(rename = "*")] + Multiply, + /// != + #[serde(rename = "!=")] + NotEquals, + /// !== + #[serde(rename = "!==")] + NotStrictEquals, + /// << + #[serde(rename = "<<")] + ShiftLeft, + /// >> + #[serde(rename = ">>")] + ShiftRight, + /// === + #[serde(rename = "===")] + StrictEquals, + /// - + #[serde(rename = "-")] + Subtract, + /// >>> + #[serde(rename = ">>>")] + UnsignedShiftRight, +} +impl std::fmt::Display for BinaryOperator { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let name = match self { + Self::Add => "+", + Self::BinaryAnd => "&", + Self::BinaryOr => "|", + Self::BinaryXor => "^", + Self::Divide => "/", + Self::Equals => "==", + Self::GreaterThan => ">", + Self::GreaterThanOrEqual => ">=", + Self::In => "in", + Self::Instanceof => "instanceof", + Self::LessThan => "<", + Self::LessThanOrEqual => "<=", + Self::Modulo => "%", + Self::Multiply => "*", + Self::NotEquals => "!=", + Self::NotStrictEquals => "!==", + Self::ShiftLeft => "<<", + Self::ShiftRight => ">>", + Self::StrictEquals => "===", + Self::Subtract => "-", + Self::UnsignedShiftRight => ">>>", + }; + f.write_str(name) + } +} +impl std::str::FromStr for BinaryOperator { + type Err = (); + fn from_str(s: &str) -> Result { + match s { + "+" => Ok(Self::Add), + "&" => Ok(Self::BinaryAnd), + "|" => Ok(Self::BinaryOr), + "^" => Ok(Self::BinaryXor), + "/" => Ok(Self::Divide), + "==" => Ok(Self::Equals), + ">" => Ok(Self::GreaterThan), + ">=" => Ok(Self::GreaterThanOrEqual), + "in" => Ok(Self::In), + "instanceof" => Ok(Self::Instanceof), + "<" => Ok(Self::LessThan), + "<=" => Ok(Self::LessThanOrEqual), + "%" => Ok(Self::Modulo), + "*" => Ok(Self::Multiply), + "!=" => Ok(Self::NotEquals), + "!==" => Ok(Self::NotStrictEquals), + "<<" => Ok(Self::ShiftLeft), + ">>" => Ok(Self::ShiftRight), + "===" => Ok(Self::StrictEquals), + "-" => Ok(Self::Subtract), + ">>>" => Ok(Self::UnsignedShiftRight), + _ => Err(()), + } + } +} +#[derive( + Serialize, + Deserialize, + Clone, + Copy, + Eq, + PartialEq, + Ord, + PartialOrd, + Hash, + Debug +)] +pub enum AssignmentOperator { + /// &= + #[serde(rename = "&=")] + BinaryAndEquals, + /// |= + #[serde(rename = "|=")] + BinaryOrEquals, + /// ^= + #[serde(rename = "^=")] + BinaryXorEquals, + /// /= + #[serde(rename = "/=")] + DivideEquals, + /// = + #[serde(rename = "=")] + Equals, + /// -= + #[serde(rename = "-=")] + MinusEquals, + /// %= + #[serde(rename = "%=")] + ModuloEquals, + /// *= + #[serde(rename = "*=")] + MultiplyEquals, + /// += + #[serde(rename = "+=")] + PlusEquals, + /// <<= + #[serde(rename = "<<=")] + ShiftLeftEquals, + /// >>= + #[serde(rename = ">>=")] + ShiftRightEquals, + /// >>>= + #[serde(rename = ">>>=")] + UnsignedShiftRightEquals, +} +impl std::fmt::Display for AssignmentOperator { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let name = match self { + Self::BinaryAndEquals => "&=", + Self::BinaryOrEquals => "|=", + Self::BinaryXorEquals => "^=", + Self::DivideEquals => "/=", + Self::Equals => "=", + Self::MinusEquals => "-=", + Self::ModuloEquals => "%=", + Self::MultiplyEquals => "*=", + Self::PlusEquals => "+=", + Self::ShiftLeftEquals => "<<=", + Self::ShiftRightEquals => ">>=", + Self::UnsignedShiftRightEquals => ">>>=", + }; + f.write_str(name) + } +} +impl std::str::FromStr for AssignmentOperator { + type Err = (); + fn from_str(s: &str) -> Result { + match s { + "&=" => Ok(Self::BinaryAndEquals), + "|=" => Ok(Self::BinaryOrEquals), + "^=" => Ok(Self::BinaryXorEquals), + "/=" => Ok(Self::DivideEquals), + "=" => Ok(Self::Equals), + "-=" => Ok(Self::MinusEquals), + "%=" => Ok(Self::ModuloEquals), + "*=" => Ok(Self::MultiplyEquals), + "+=" => Ok(Self::PlusEquals), + "<<=" => Ok(Self::ShiftLeftEquals), + ">>=" => Ok(Self::ShiftRightEquals), + ">>>=" => Ok(Self::UnsignedShiftRightEquals), + _ => Err(()), + } + } +} +#[derive( + Serialize, + Deserialize, + Clone, + Copy, + Eq, + PartialEq, + Ord, + PartialOrd, + Hash, + Debug +)] +pub enum LogicalOperator { + /// && + #[serde(rename = "&&")] + And, + /// ?? + #[serde(rename = "??")] + NullCoalescing, + /// || + #[serde(rename = "||")] + Or, +} +impl std::fmt::Display for LogicalOperator { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let name = match self { + Self::And => "&&", + Self::NullCoalescing => "??", + Self::Or => "||", + }; + f.write_str(name) + } +} +impl std::str::FromStr for LogicalOperator { + type Err = (); + fn from_str(s: &str) -> Result { + match s { + "&&" => Ok(Self::And), + "??" => Ok(Self::NullCoalescing), + "||" => Ok(Self::Or), + _ => Err(()), + } + } +} diff --git a/compiler/forget/crates/estree/src/import.json b/compiler/forget/crates/estree/src/import.json deleted file mode 100644 index 78997e87bd..0000000000 --- a/compiler/forget/crates/estree/src/import.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "type": "Program", - "loc": { - "source": null, - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 1, - "column": 26 - } - }, - "body": [ - { - "type": "ImportDeclaration", - "loc": { - "source": null, - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 1, - "column": 26 - } - }, - "specifiers": [ - { - "type": "ImportDefaultSpecifier", - "loc": { - "source": null, - "start": { - "line": 1, - "column": 7 - }, - "end": { - "line": 1, - "column": 12 - } - }, - "local": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 1, - "column": 7 - }, - "end": { - "line": 1, - "column": 12 - } - }, - "name": "React", - "typeAnnotation": null, - "optional": false, - "range": [ - 7, - 12 - ] - }, - "range": [ - 7, - 12 - ] - } - ], - "source": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 1, - "column": 18 - }, - "end": { - "line": 1, - "column": 25 - } - }, - "value": "react", - "range": [ - 18, - 25 - ], - "raw": "'react'" - }, - "attributes": [], - "importKind": "value", - "range": [ - 0, - 26 - ] - } - ], - "comments": [], - "interpreter": null, - "range": [ - 0, - 26 - ], - "sourceType": "module" - } \ No newline at end of file diff --git a/compiler/forget/crates/estree/src/js_value.rs b/compiler/forget/crates/estree/src/js_value.rs new file mode 100644 index 0000000000..3d23352a05 --- /dev/null +++ b/compiler/forget/crates/estree/src/js_value.rs @@ -0,0 +1,112 @@ +use serde::{de::Visitor, Deserialize, Serialize}; + +#[derive(Serialize, Clone, Debug, PartialEq, PartialOrd, Hash)] +pub enum JsValue { + Undefined, + Null, + Bool(bool), + Number(Number), + String(String), +} + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Debug)] +pub struct Number(u64); + +impl From for Number { + fn from(value: u32) -> Self { + Number(value.into()) + } +} + +impl From for Number { + fn from(value: u64) -> Self { + Number(value) + } +} + +impl From for Number { + fn from(value: f64) -> Self { + Number(value.to_bits()) + } +} + +impl From for f64 { + fn from(value: Number) -> Self { + f64::from_bits(value.0) + } +} + +impl<'de> Deserialize<'de> for JsValue { + #[inline] + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct ValueVisitor; + + impl<'de> Visitor<'de> for ValueVisitor { + type Value = JsValue; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("valid primitive JSON value (null, boolean, number, or string") + } + + #[inline] + fn visit_bool(self, value: bool) -> Result { + Ok(JsValue::Bool(value)) + } + + #[inline] + fn visit_i64(self, value: i64) -> Result { + if value < u32::MAX as i64 { + Ok(JsValue::Number((value as u32).into())) + } else { + panic!("Invalid number") + } + } + + #[inline] + fn visit_u64(self, value: u64) -> Result { + Ok(JsValue::Number(value.into())) + } + + #[inline] + fn visit_f64(self, value: f64) -> Result { + Ok(JsValue::Number(value.into())) + } + + #[inline] + fn visit_str(self, value: &str) -> Result + where + E: serde::de::Error, + { + self.visit_string(String::from(value)) + } + + #[inline] + fn visit_string(self, value: String) -> Result { + Ok(JsValue::String(value)) + } + + #[inline] + fn visit_none(self) -> Result { + Ok(JsValue::Null) + } + + #[inline] + fn visit_some(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + Deserialize::deserialize(deserializer) + } + + #[inline] + fn visit_unit(self) -> Result { + Ok(JsValue::Undefined) + } + } + + deserializer.deserialize_any(ValueVisitor) + } +} diff --git a/compiler/forget/crates/estree/src/kitchen-sink.json b/compiler/forget/crates/estree/src/kitchen-sink.json deleted file mode 100644 index eafd48f0bf..0000000000 --- a/compiler/forget/crates/estree/src/kitchen-sink.json +++ /dev/null @@ -1,4069 +0,0 @@ -{ - "type": "Program", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 0 - }, - "end": { - "line": 45, - "column": 1 - } - }, - "body": [ - { - "type": "FunctionDeclaration", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 0 - }, - "end": { - "line": 45, - "column": 1 - } - }, - "id": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 9 - }, - "end": { - "line": 2, - "column": 12 - } - }, - "name": "foo", - "typeAnnotation": null, - "optional": false, - "range": [ - 10, - 13 - ] - }, - "params": [ - { - "type": "ArrayPattern", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 13 - }, - "end": { - "line": 2, - "column": 19 - } - }, - "elements": [ - { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 14 - }, - "end": { - "line": 2, - "column": 15 - } - }, - "name": "a", - "typeAnnotation": null, - "optional": false, - "range": [ - 15, - 16 - ] - }, - { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 17 - }, - "end": { - "line": 2, - "column": 18 - } - }, - "name": "b", - "typeAnnotation": null, - "optional": false, - "range": [ - 18, - 19 - ] - } - ], - "typeAnnotation": null, - "range": [ - 14, - 20 - ] - }, - { - "type": "ObjectPattern", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 21 - }, - "end": { - "line": 2, - "column": 38 - } - }, - "properties": [ - { - "type": "Property", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 23 - }, - "end": { - "line": 2, - "column": 24 - } - }, - "key": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 23 - }, - "end": { - "line": 2, - "column": 24 - } - }, - "name": "c", - "typeAnnotation": null, - "optional": false, - "range": [ - 24, - 25 - ] - }, - "value": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 23 - }, - "end": { - "line": 2, - "column": 24 - } - }, - "name": "c", - "typeAnnotation": null, - "optional": false, - "range": [ - 24, - 25 - ] - }, - "kind": "init", - "computed": false, - "method": false, - "shorthand": true, - "range": [ - 24, - 25 - ] - }, - { - "type": "Property", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 26 - }, - "end": { - "line": 2, - "column": 27 - } - }, - "key": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 26 - }, - "end": { - "line": 2, - "column": 27 - } - }, - "name": "d", - "typeAnnotation": null, - "optional": false, - "range": [ - 27, - 28 - ] - }, - "value": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 26 - }, - "end": { - "line": 2, - "column": 27 - } - }, - "name": "d", - "typeAnnotation": null, - "optional": false, - "range": [ - 27, - 28 - ] - }, - "kind": "init", - "computed": false, - "method": false, - "shorthand": true, - "range": [ - 27, - 28 - ] - }, - { - "type": "Property", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 29 - }, - "end": { - "line": 2, - "column": 36 - } - }, - "key": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 29 - }, - "end": { - "line": 2, - "column": 30 - } - }, - "name": "e", - "typeAnnotation": null, - "optional": false, - "range": [ - 30, - 31 - ] - }, - "value": { - "type": "AssignmentPattern", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 29 - }, - "end": { - "line": 2, - "column": 36 - } - }, - "left": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 29 - }, - "end": { - "line": 2, - "column": 30 - } - }, - "name": "e", - "typeAnnotation": null, - "optional": false, - "range": [ - 30, - 31 - ] - }, - "right": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 33 - }, - "end": { - "line": 2, - "column": 36 - } - }, - "value": "e", - "range": [ - 34, - 37 - ], - "raw": "\"e\"" - }, - "range": [ - 30, - 37 - ] - }, - "kind": "init", - "computed": false, - "method": false, - "shorthand": true, - "range": [ - 30, - 37 - ] - } - ], - "typeAnnotation": null, - "range": [ - 22, - 39 - ] - }, - { - "type": "AssignmentPattern", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 40 - }, - "end": { - "line": 2, - "column": 47 - } - }, - "left": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 40 - }, - "end": { - "line": 2, - "column": 41 - } - }, - "name": "f", - "typeAnnotation": null, - "optional": false, - "range": [ - 41, - 42 - ] - }, - "right": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 44 - }, - "end": { - "line": 2, - "column": 47 - } - }, - "value": "f", - "range": [ - 45, - 48 - ], - "raw": "\"f\"" - }, - "range": [ - 41, - 48 - ] - }, - { - "type": "RestElement", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 49 - }, - "end": { - "line": 2, - "column": 56 - } - }, - "argument": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 52 - }, - "end": { - "line": 2, - "column": 56 - } - }, - "name": "args", - "typeAnnotation": null, - "optional": false, - "range": [ - 53, - 57 - ] - }, - "range": [ - 50, - 57 - ] - } - ], - "body": { - "type": "BlockStatement", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 58 - }, - "end": { - "line": 45, - "column": 1 - } - }, - "body": [ - { - "type": "ExpressionStatement", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 2 - }, - "end": { - "line": 3, - "column": 18 - } - }, - "expression": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 2 - }, - "end": { - "line": 3, - "column": 18 - } - }, - "value": "use P780731197", - "range": [ - 63, - 79 - ], - "raw": "\"use P780731197\"" - }, - "directive": "use P780731197", - "range": [ - 63, - 79 - ] - }, - { - "type": "VariableDeclaration", - "loc": { - "source": null, - "start": { - "line": 4, - "column": 2 - }, - "end": { - "line": 4, - "column": 12 - } - }, - "kind": "let", - "declarations": [ - { - "type": "VariableDeclarator", - "loc": { - "source": null, - "start": { - "line": 4, - "column": 6 - }, - "end": { - "line": 4, - "column": 11 - } - }, - "init": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 4, - "column": 10 - }, - "end": { - "line": 4, - "column": 11 - } - }, - "value": 0, - "range": [ - 90, - 91 - ], - "raw": "0" - }, - "id": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 4, - "column": 6 - }, - "end": { - "line": 4, - "column": 7 - } - }, - "name": "i", - "typeAnnotation": null, - "optional": false, - "range": [ - 86, - 87 - ] - }, - "range": [ - 86, - 91 - ] - } - ], - "range": [ - 82, - 92 - ] - }, - { - "type": "VariableDeclaration", - "loc": { - "source": null, - "start": { - "line": 5, - "column": 2 - }, - "end": { - "line": 5, - "column": 13 - } - }, - "kind": "var", - "declarations": [ - { - "type": "VariableDeclarator", - "loc": { - "source": null, - "start": { - "line": 5, - "column": 6 - }, - "end": { - "line": 5, - "column": 12 - } - }, - "init": { - "type": "ArrayExpression", - "loc": { - "source": null, - "start": { - "line": 5, - "column": 10 - }, - "end": { - "line": 5, - "column": 12 - } - }, - "elements": [], - "trailingComma": false, - "range": [ - 103, - 105 - ] - }, - "id": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 5, - "column": 6 - }, - "end": { - "line": 5, - "column": 7 - } - }, - "name": "x", - "typeAnnotation": null, - "optional": false, - "range": [ - 99, - 100 - ] - }, - "range": [ - 99, - 105 - ] - } - ], - "range": [ - 95, - 106 - ] - }, - { - "type": "ClassDeclaration", - "loc": { - "source": null, - "start": { - "line": 7, - "column": 2 - }, - "end": { - "line": 12, - "column": 3 - } - }, - "id": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 7, - "column": 8 - }, - "end": { - "line": 7, - "column": 11 - } - }, - "name": "Bar", - "typeAnnotation": null, - "optional": false, - "range": [ - 116, - 119 - ] - }, - "typeParameters": null, - "superClass": null, - "superTypeParameters": null, - "implements": [], - "decorators": [], - "body": { - "type": "ClassBody", - "loc": { - "source": null, - "start": { - "line": 7, - "column": 12 - }, - "end": { - "line": 12, - "column": 3 - } - }, - "body": [ - { - "type": "ClassProperty", - "loc": { - "source": null, - "start": { - "line": 8, - "column": 4 - }, - "end": { - "line": 8, - "column": 21 - } - }, - "key": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 8, - "column": 4 - }, - "end": { - "line": 8, - "column": 15 - } - }, - "name": "secretSauce", - "typeAnnotation": null, - "optional": false, - "range": [ - 126, - 137 - ] - }, - "value": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 8, - "column": 18 - }, - "end": { - "line": 8, - "column": 20 - } - }, - "value": 42, - "range": [ - 140, - 142 - ], - "raw": "42" - }, - "computed": false, - "static": false, - "declare": false, - "optional": false, - "variance": null, - "typeAnnotation": null, - "range": [ - 126, - 143 - ] - }, - { - "type": "MethodDefinition", - "loc": { - "source": null, - "start": { - "line": 9, - "column": 4 - }, - "end": { - "line": 11, - "column": 5 - } - }, - "key": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 9, - "column": 4 - }, - "end": { - "line": 9, - "column": 15 - } - }, - "name": "constructor", - "typeAnnotation": null, - "optional": false, - "range": [ - 148, - 159 - ] - }, - "value": { - "type": "FunctionExpression", - "loc": { - "source": null, - "start": { - "line": 9, - "column": 15 - }, - "end": { - "line": 11, - "column": 5 - } - }, - "id": null, - "params": [], - "body": { - "type": "BlockStatement", - "loc": { - "source": null, - "start": { - "line": 9, - "column": 18 - }, - "end": { - "line": 11, - "column": 5 - } - }, - "body": [ - { - "type": "ExpressionStatement", - "loc": { - "source": null, - "start": { - "line": 10, - "column": 6 - }, - "end": { - "line": 10, - "column": 36 - } - }, - "expression": { - "type": "CallExpression", - "loc": { - "source": null, - "start": { - "line": 10, - "column": 6 - }, - "end": { - "line": 10, - "column": 35 - } - }, - "callee": { - "type": "MemberExpression", - "loc": { - "source": null, - "start": { - "line": 10, - "column": 6 - }, - "end": { - "line": 10, - "column": 17 - } - }, - "object": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 10, - "column": 6 - }, - "end": { - "line": 10, - "column": 13 - } - }, - "name": "console", - "typeAnnotation": null, - "optional": false, - "range": [ - 170, - 177 - ] - }, - "property": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 10, - "column": 14 - }, - "end": { - "line": 10, - "column": 17 - } - }, - "name": "log", - "typeAnnotation": null, - "optional": false, - "range": [ - 178, - 181 - ] - }, - "computed": false, - "range": [ - 170, - 181 - ] - }, - "typeArguments": null, - "arguments": [ - { - "type": "MemberExpression", - "loc": { - "source": null, - "start": { - "line": 10, - "column": 18 - }, - "end": { - "line": 10, - "column": 34 - } - }, - "object": { - "type": "ThisExpression", - "loc": { - "source": null, - "start": { - "line": 10, - "column": 18 - }, - "end": { - "line": 10, - "column": 22 - } - }, - "range": [ - 182, - 186 - ] - }, - "property": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 10, - "column": 23 - }, - "end": { - "line": 10, - "column": 34 - } - }, - "name": "secretSauce", - "typeAnnotation": null, - "optional": false, - "range": [ - 187, - 198 - ] - }, - "computed": false, - "range": [ - 182, - 198 - ] - } - ], - "range": [ - 170, - 199 - ] - }, - "directive": null, - "range": [ - 170, - 200 - ] - } - ], - "range": [ - 162, - 206 - ] - }, - "typeParameters": null, - "returnType": null, - "predicate": null, - "generator": false, - "async": false, - "range": [ - 159, - 206 - ] - }, - "kind": "constructor", - "computed": false, - "static": false, - "range": [ - 148, - 206 - ] - } - ], - "range": [ - 120, - 210 - ] - }, - "range": [ - 110, - 210 - ] - }, - { - "type": "VariableDeclaration", - "loc": { - "source": null, - "start": { - "line": 14, - "column": 2 - }, - "end": { - "line": 14, - "column": 42 - } - }, - "kind": "const", - "declarations": [ - { - "type": "VariableDeclarator", - "loc": { - "source": null, - "start": { - "line": 14, - "column": 8 - }, - "end": { - "line": 14, - "column": 41 - } - }, - "init": { - "type": "ObjectExpression", - "loc": { - "source": null, - "start": { - "line": 14, - "column": 12 - }, - "end": { - "line": 14, - "column": 41 - } - }, - "properties": [ - { - "type": "SpreadElement", - "loc": { - "source": null, - "start": { - "line": 14, - "column": 14 - }, - "end": { - "line": 14, - "column": 18 - } - }, - "argument": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 14, - "column": 17 - }, - "end": { - "line": 14, - "column": 18 - } - }, - "name": "a", - "typeAnnotation": null, - "optional": false, - "range": [ - 229, - 230 - ] - }, - "range": [ - 226, - 230 - ] - }, - { - "type": "Property", - "loc": { - "source": null, - "start": { - "line": 14, - "column": 20 - }, - "end": { - "line": 14, - "column": 26 - } - }, - "key": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 14, - "column": 20 - }, - "end": { - "line": 14, - "column": 21 - } - }, - "name": "b", - "typeAnnotation": null, - "optional": false, - "range": [ - 232, - 233 - ] - }, - "value": { - "type": "FunctionExpression", - "loc": { - "source": null, - "start": { - "line": 14, - "column": 20 - }, - "end": { - "line": 14, - "column": 26 - } - }, - "id": null, - "params": [], - "body": { - "type": "BlockStatement", - "loc": { - "source": null, - "start": { - "line": 14, - "column": 24 - }, - "end": { - "line": 14, - "column": 26 - } - }, - "body": [], - "range": [ - 236, - 238 - ] - }, - "typeParameters": null, - "returnType": null, - "predicate": null, - "generator": false, - "async": false, - "range": [ - 232, - 238 - ] - }, - "kind": "init", - "computed": false, - "method": true, - "shorthand": false, - "range": [ - 232, - 238 - ] - }, - { - "type": "Property", - "loc": { - "source": null, - "start": { - "line": 14, - "column": 28 - }, - "end": { - "line": 14, - "column": 39 - } - }, - "key": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 14, - "column": 28 - }, - "end": { - "line": 14, - "column": 29 - } - }, - "name": "c", - "typeAnnotation": null, - "optional": false, - "range": [ - 240, - 241 - ] - }, - "value": { - "type": "ArrowFunctionExpression", - "loc": { - "source": null, - "start": { - "line": 14, - "column": 31 - }, - "end": { - "line": 14, - "column": 39 - } - }, - "id": null, - "params": [], - "body": { - "type": "BlockStatement", - "loc": { - "source": null, - "start": { - "line": 14, - "column": 37 - }, - "end": { - "line": 14, - "column": 39 - } - }, - "body": [], - "range": [ - 249, - 251 - ] - }, - "typeParameters": null, - "returnType": null, - "predicate": null, - "expression": false, - "async": false, - "range": [ - 243, - 251 - ] - }, - "kind": "init", - "computed": false, - "method": false, - "shorthand": false, - "range": [ - 240, - 251 - ] - } - ], - "range": [ - 224, - 253 - ] - }, - "id": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 14, - "column": 8 - }, - "end": { - "line": 14, - "column": 9 - } - }, - "name": "g", - "typeAnnotation": null, - "optional": false, - "range": [ - 220, - 221 - ] - }, - "range": [ - 220, - 253 - ] - } - ], - "range": [ - 214, - 254 - ] - }, - { - "type": "VariableDeclaration", - "loc": { - "source": null, - "start": { - "line": 15, - "column": 2 - }, - "end": { - "line": 15, - "column": 19 - } - }, - "kind": "const", - "declarations": [ - { - "type": "VariableDeclarator", - "loc": { - "source": null, - "start": { - "line": 15, - "column": 8 - }, - "end": { - "line": 15, - "column": 18 - } - }, - "init": { - "type": "ArrayExpression", - "loc": { - "source": null, - "start": { - "line": 15, - "column": 12 - }, - "end": { - "line": 15, - "column": 18 - } - }, - "elements": [ - { - "type": "SpreadElement", - "loc": { - "source": null, - "start": { - "line": 15, - "column": 13 - }, - "end": { - "line": 15, - "column": 17 - } - }, - "argument": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 15, - "column": 16 - }, - "end": { - "line": 15, - "column": 17 - } - }, - "name": "b", - "typeAnnotation": null, - "optional": false, - "range": [ - 271, - 272 - ] - }, - "range": [ - 268, - 272 - ] - } - ], - "trailingComma": false, - "range": [ - 267, - 273 - ] - }, - "id": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 15, - "column": 8 - }, - "end": { - "line": 15, - "column": 9 - } - }, - "name": "h", - "typeAnnotation": null, - "optional": false, - "range": [ - 263, - 264 - ] - }, - "range": [ - 263, - 273 - ] - } - ], - "range": [ - 257, - 274 - ] - }, - { - "type": "ExpressionStatement", - "loc": { - "source": null, - "start": { - "line": 16, - "column": 2 - }, - "end": { - "line": 16, - "column": 17 - } - }, - "expression": { - "type": "NewExpression", - "loc": { - "source": null, - "start": { - "line": 16, - "column": 2 - }, - "end": { - "line": 16, - "column": 16 - } - }, - "callee": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 16, - "column": 6 - }, - "end": { - "line": 16, - "column": 7 - } - }, - "name": "c", - "typeAnnotation": null, - "optional": false, - "range": [ - 281, - 282 - ] - }, - "typeArguments": null, - "arguments": [ - { - "type": "SpreadElement", - "loc": { - "source": null, - "start": { - "line": 16, - "column": 8 - }, - "end": { - "line": 16, - "column": 15 - } - }, - "argument": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 16, - "column": 11 - }, - "end": { - "line": 16, - "column": 15 - } - }, - "name": "args", - "typeAnnotation": null, - "optional": false, - "range": [ - 286, - 290 - ] - }, - "range": [ - 283, - 290 - ] - } - ], - "range": [ - 277, - 291 - ] - }, - "directive": null, - "range": [ - 277, - 292 - ] - }, - { - "type": "ExpressionStatement", - "loc": { - "source": null, - "start": { - "line": 17, - "column": 2 - }, - "end": { - "line": 17, - "column": 13 - } - }, - "expression": { - "type": "CallExpression", - "loc": { - "source": null, - "start": { - "line": 17, - "column": 2 - }, - "end": { - "line": 17, - "column": 12 - } - }, - "callee": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 17, - "column": 2 - }, - "end": { - "line": 17, - "column": 3 - } - }, - "name": "c", - "typeAnnotation": null, - "optional": false, - "range": [ - 295, - 296 - ] - }, - "typeArguments": null, - "arguments": [ - { - "type": "SpreadElement", - "loc": { - "source": null, - "start": { - "line": 17, - "column": 4 - }, - "end": { - "line": 17, - "column": 11 - } - }, - "argument": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 17, - "column": 7 - }, - "end": { - "line": 17, - "column": 11 - } - }, - "name": "args", - "typeAnnotation": null, - "optional": false, - "range": [ - 300, - 304 - ] - }, - "range": [ - 297, - 304 - ] - } - ], - "range": [ - 295, - 305 - ] - }, - "directive": null, - "range": [ - 295, - 306 - ] - }, - { - "type": "ExpressionStatement", - "loc": { - "source": null, - "start": { - "line": 18, - "column": 2 - }, - "end": { - "line": 18, - "column": 14 - } - }, - "expression": { - "type": "AssignmentExpression", - "loc": { - "source": null, - "start": { - "line": 18, - "column": 2 - }, - "end": { - "line": 18, - "column": 13 - } - }, - "operator": "+=", - "left": { - "type": "MemberExpression", - "loc": { - "source": null, - "start": { - "line": 18, - "column": 2 - }, - "end": { - "line": 18, - "column": 8 - } - }, - "object": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 18, - "column": 2 - }, - "end": { - "line": 18, - "column": 3 - } - }, - "name": "g", - "typeAnnotation": null, - "optional": false, - "range": [ - 309, - 310 - ] - }, - "property": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 18, - "column": 4 - }, - "end": { - "line": 18, - "column": 7 - } - }, - "value": "e", - "range": [ - 311, - 314 - ], - "raw": "\"e\"" - }, - "computed": true, - "range": [ - 309, - 315 - ] - }, - "right": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 18, - "column": 12 - }, - "end": { - "line": 18, - "column": 13 - } - }, - "value": 1, - "range": [ - 319, - 320 - ], - "raw": "1" - }, - "range": [ - 309, - 320 - ] - }, - "directive": null, - "range": [ - 309, - 321 - ] - }, - { - "type": "VariableDeclaration", - "loc": { - "source": null, - "start": { - "line": 19, - "column": 2 - }, - "end": { - "line": 19, - "column": 33 - } - }, - "kind": "const", - "declarations": [ - { - "type": "VariableDeclarator", - "loc": { - "source": null, - "start": { - "line": 19, - "column": 8 - }, - "end": { - "line": 19, - "column": 32 - } - }, - "init": { - "type": "CallExpression", - "loc": { - "source": null, - "start": { - "line": 19, - "column": 21 - }, - "end": { - "line": 19, - "column": 32 - } - }, - "callee": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 19, - "column": 21 - }, - "end": { - "line": 19, - "column": 29 - } - }, - "name": "useState", - "typeAnnotation": null, - "optional": false, - "range": [ - 343, - 351 - ] - }, - "typeArguments": null, - "arguments": [ - { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 19, - "column": 30 - }, - "end": { - "line": 19, - "column": 31 - } - }, - "value": 0, - "range": [ - 352, - 353 - ], - "raw": "0" - } - ], - "range": [ - 343, - 354 - ] - }, - "id": { - "type": "ArrayPattern", - "loc": { - "source": null, - "start": { - "line": 19, - "column": 8 - }, - "end": { - "line": 19, - "column": 18 - } - }, - "elements": [ - { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 19, - "column": 9 - }, - "end": { - "line": 19, - "column": 10 - } - }, - "name": "y", - "typeAnnotation": null, - "optional": false, - "range": [ - 331, - 332 - ] - }, - { - "type": "RestElement", - "loc": { - "source": null, - "start": { - "line": 19, - "column": 12 - }, - "end": { - "line": 19, - "column": 17 - } - }, - "argument": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 19, - "column": 15 - }, - "end": { - "line": 19, - "column": 17 - } - }, - "name": "yy", - "typeAnnotation": null, - "optional": false, - "range": [ - 337, - 339 - ] - }, - "range": [ - 334, - 339 - ] - } - ], - "typeAnnotation": null, - "range": [ - 330, - 340 - ] - }, - "range": [ - 330, - 354 - ] - } - ], - "range": [ - 324, - 355 - ] - }, - { - "type": "VariableDeclaration", - "loc": { - "source": null, - "start": { - "line": 20, - "column": 2 - }, - "end": { - "line": 20, - "column": 46 - } - }, - "kind": "const", - "declarations": [ - { - "type": "VariableDeclarator", - "loc": { - "source": null, - "start": { - "line": 20, - "column": 8 - }, - "end": { - "line": 20, - "column": 45 - } - }, - "init": { - "type": "CallExpression", - "loc": { - "source": null, - "start": { - "line": 20, - "column": 34 - }, - "end": { - "line": 20, - "column": 45 - } - }, - "callee": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 20, - "column": 34 - }, - "end": { - "line": 20, - "column": 43 - } - }, - "name": "useCustom", - "typeAnnotation": null, - "optional": false, - "range": [ - 390, - 399 - ] - }, - "typeArguments": null, - "arguments": [], - "range": [ - 390, - 401 - ] - }, - "id": { - "type": "ObjectPattern", - "loc": { - "source": null, - "start": { - "line": 20, - "column": 8 - }, - "end": { - "line": 20, - "column": 31 - } - }, - "properties": [ - { - "type": "Property", - "loc": { - "source": null, - "start": { - "line": 20, - "column": 10 - }, - "end": { - "line": 20, - "column": 11 - } - }, - "key": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 20, - "column": 10 - }, - "end": { - "line": 20, - "column": 11 - } - }, - "name": "z", - "typeAnnotation": null, - "optional": false, - "range": [ - 366, - 367 - ] - }, - "value": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 20, - "column": 10 - }, - "end": { - "line": 20, - "column": 11 - } - }, - "name": "z", - "typeAnnotation": null, - "optional": false, - "range": [ - 366, - 367 - ] - }, - "kind": "init", - "computed": false, - "method": false, - "shorthand": true, - "range": [ - 366, - 367 - ] - }, - { - "type": "Property", - "loc": { - "source": null, - "start": { - "line": 20, - "column": 13 - }, - "end": { - "line": 20, - "column": 22 - } - }, - "key": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 20, - "column": 13 - }, - "end": { - "line": 20, - "column": 15 - } - }, - "name": "aa", - "typeAnnotation": null, - "optional": false, - "range": [ - 369, - 371 - ] - }, - "value": { - "type": "AssignmentPattern", - "loc": { - "source": null, - "start": { - "line": 20, - "column": 13 - }, - "end": { - "line": 20, - "column": 22 - } - }, - "left": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 20, - "column": 13 - }, - "end": { - "line": 20, - "column": 15 - } - }, - "name": "aa", - "typeAnnotation": null, - "optional": false, - "range": [ - 369, - 371 - ] - }, - "right": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 20, - "column": 18 - }, - "end": { - "line": 20, - "column": 22 - } - }, - "value": "aa", - "range": [ - 374, - 378 - ], - "raw": "\"aa\"" - }, - "range": [ - 369, - 378 - ] - }, - "kind": "init", - "computed": false, - "method": false, - "shorthand": true, - "range": [ - 369, - 378 - ] - }, - { - "type": "RestElement", - "loc": { - "source": null, - "start": { - "line": 20, - "column": 24 - }, - "end": { - "line": 20, - "column": 29 - } - }, - "argument": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 20, - "column": 27 - }, - "end": { - "line": 20, - "column": 29 - } - }, - "name": "zz", - "typeAnnotation": null, - "optional": false, - "range": [ - 383, - 385 - ] - }, - "range": [ - 380, - 385 - ] - } - ], - "typeAnnotation": null, - "range": [ - 364, - 387 - ] - }, - "range": [ - 364, - 401 - ] - } - ], - "range": [ - 358, - 402 - ] - }, - { - "type": "ExpressionStatement", - "loc": { - "source": null, - "start": { - "line": 22, - "column": 2 - }, - "end": { - "line": 22, - "column": 30 - } - }, - "expression": { - "type": "JSXElement", - "loc": { - "source": null, - "start": { - "line": 22, - "column": 2 - }, - "end": { - "line": 22, - "column": 29 - } - }, - "openingElement": { - "type": "JSXOpeningElement", - "loc": { - "source": null, - "start": { - "line": 22, - "column": 2 - }, - "end": { - "line": 22, - "column": 20 - } - }, - "name": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 22, - "column": 3 - }, - "end": { - "line": 22, - "column": 9 - } - }, - "name": "Button", - "range": [ - 407, - 413 - ] - }, - "attributes": [ - { - "type": "JSXSpreadAttribute", - "loc": { - "source": null, - "start": { - "line": 22, - "column": 10 - }, - "end": { - "line": 22, - "column": 19 - } - }, - "argument": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 22, - "column": 14 - }, - "end": { - "line": 22, - "column": 18 - } - }, - "name": "args", - "typeAnnotation": null, - "optional": false, - "range": [ - 418, - 422 - ] - }, - "range": [ - 414, - 423 - ] - } - ], - "selfClosing": false, - "range": [ - 406, - 424 - ] - }, - "children": [], - "closingElement": { - "type": "JSXClosingElement", - "loc": { - "source": null, - "start": { - "line": 22, - "column": 20 - }, - "end": { - "line": 22, - "column": 29 - } - }, - "name": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 22, - "column": 22 - }, - "end": { - "line": 22, - "column": 28 - } - }, - "name": "Button", - "range": [ - 426, - 432 - ] - }, - "range": [ - 424, - 433 - ] - }, - "range": [ - 406, - 433 - ] - }, - "directive": null, - "range": [ - 406, - 434 - ] - }, - { - "type": "ExpressionStatement", - "loc": { - "source": null, - "start": { - "line": 23, - "column": 2 - }, - "end": { - "line": 23, - "column": 48 - } - }, - "expression": { - "type": "JSXElement", - "loc": { - "source": null, - "start": { - "line": 23, - "column": 2 - }, - "end": { - "line": 23, - "column": 47 - } - }, - "openingElement": { - "type": "JSXOpeningElement", - "loc": { - "source": null, - "start": { - "line": 23, - "column": 2 - }, - "end": { - "line": 23, - "column": 38 - } - }, - "name": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 23, - "column": 3 - }, - "end": { - "line": 23, - "column": 9 - } - }, - "name": "Button", - "range": [ - 438, - 444 - ] - }, - "attributes": [ - { - "type": "JSXAttribute", - "loc": { - "source": null, - "start": { - "line": 23, - "column": 10 - }, - "end": { - "line": 23, - "column": 37 - } - }, - "name": { - "type": "JSXNamespacedName", - "loc": { - "source": null, - "start": { - "line": 23, - "column": 10 - }, - "end": { - "line": 23, - "column": 20 - } - }, - "namespace": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 23, - "column": 10 - }, - "end": { - "line": 23, - "column": 15 - } - }, - "name": "xlink", - "range": [ - 445, - 450 - ] - }, - "name": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 23, - "column": 16 - }, - "end": { - "line": 23, - "column": 20 - } - }, - "name": "href", - "range": [ - 451, - 455 - ] - }, - "range": [ - 445, - 455 - ] - }, - "value": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 23, - "column": 21 - }, - "end": { - "line": 23, - "column": 37 - } - }, - "value": "localhost:3000", - "range": [ - 456, - 472 - ], - "raw": "\"localhost:3000\"" - }, - "range": [ - 445, - 472 - ] - } - ], - "selfClosing": false, - "range": [ - 437, - 473 - ] - }, - "children": [], - "closingElement": { - "type": "JSXClosingElement", - "loc": { - "source": null, - "start": { - "line": 23, - "column": 38 - }, - "end": { - "line": 23, - "column": 47 - } - }, - "name": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 23, - "column": 40 - }, - "end": { - "line": 23, - "column": 46 - } - }, - "name": "Button", - "range": [ - 475, - 481 - ] - }, - "range": [ - 473, - 482 - ] - }, - "range": [ - 437, - 482 - ] - }, - "directive": null, - "range": [ - 437, - 483 - ] - }, - { - "type": "ExpressionStatement", - "loc": { - "source": null, - "start": { - "line": 24, - "column": 2 - }, - "end": { - "line": 24, - "column": 29 - } - }, - "expression": { - "type": "JSXElement", - "loc": { - "source": null, - "start": { - "line": 24, - "column": 2 - }, - "end": { - "line": 24, - "column": 28 - } - }, - "openingElement": { - "type": "JSXOpeningElement", - "loc": { - "source": null, - "start": { - "line": 24, - "column": 2 - }, - "end": { - "line": 24, - "column": 19 - } - }, - "name": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 24, - "column": 3 - }, - "end": { - "line": 24, - "column": 9 - } - }, - "name": "Button", - "range": [ - 487, - 493 - ] - }, - "attributes": [ - { - "type": "JSXAttribute", - "loc": { - "source": null, - "start": { - "line": 24, - "column": 10 - }, - "end": { - "line": 24, - "column": 18 - } - }, - "name": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 24, - "column": 10 - }, - "end": { - "line": 24, - "column": 14 - } - }, - "name": "haha", - "range": [ - 494, - 498 - ] - }, - "value": { - "type": "JSXExpressionContainer", - "loc": { - "source": null, - "start": { - "line": 24, - "column": 15 - }, - "end": { - "line": 24, - "column": 18 - } - }, - "expression": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 24, - "column": 16 - }, - "end": { - "line": 24, - "column": 17 - } - }, - "value": 1, - "range": [ - 500, - 501 - ], - "raw": "1" - }, - "range": [ - 499, - 502 - ] - }, - "range": [ - 494, - 502 - ] - } - ], - "selfClosing": false, - "range": [ - 486, - 503 - ] - }, - "children": [], - "closingElement": { - "type": "JSXClosingElement", - "loc": { - "source": null, - "start": { - "line": 24, - "column": 19 - }, - "end": { - "line": 24, - "column": 28 - } - }, - "name": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 24, - "column": 21 - }, - "end": { - "line": 24, - "column": 27 - } - }, - "name": "Button", - "range": [ - 505, - 511 - ] - }, - "range": [ - 503, - 512 - ] - }, - "range": [ - 486, - 512 - ] - }, - "directive": null, - "range": [ - 486, - 513 - ] - }, - { - "type": "ExpressionStatement", - "loc": { - "source": null, - "start": { - "line": 25, - "column": 2 - }, - "end": { - "line": 25, - "column": 34 - } - }, - "expression": { - "type": "JSXElement", - "loc": { - "source": null, - "start": { - "line": 25, - "column": 2 - }, - "end": { - "line": 25, - "column": 33 - } - }, - "openingElement": { - "type": "JSXOpeningElement", - "loc": { - "source": null, - "start": { - "line": 25, - "column": 2 - }, - "end": { - "line": 25, - "column": 10 - } - }, - "name": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 25, - "column": 3 - }, - "end": { - "line": 25, - "column": 9 - } - }, - "name": "Button", - "range": [ - 517, - 523 - ] - }, - "attributes": [], - "selfClosing": false, - "range": [ - 516, - 524 - ] - }, - "children": [ - { - "type": "JSXExpressionContainer", - "loc": { - "source": null, - "start": { - "line": 25, - "column": 10 - }, - "end": { - "line": 25, - "column": 24 - } - }, - "expression": { - "type": "JSXEmptyExpression", - "loc": { - "source": null, - "start": { - "line": 25, - "column": 11 - }, - "end": { - "line": 25, - "column": 23 - } - }, - "range": [ - 525, - 537 - ] - }, - "range": [ - 524, - 538 - ] - } - ], - "closingElement": { - "type": "JSXClosingElement", - "loc": { - "source": null, - "start": { - "line": 25, - "column": 24 - }, - "end": { - "line": 25, - "column": 33 - } - }, - "name": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 25, - "column": 26 - }, - "end": { - "line": 25, - "column": 32 - } - }, - "name": "Button", - "range": [ - 540, - 546 - ] - }, - "range": [ - 538, - 547 - ] - }, - "range": [ - 516, - 547 - ] - }, - "directive": null, - "range": [ - 516, - 548 - ] - }, - { - "type": "ExpressionStatement", - "loc": { - "source": null, - "start": { - "line": 26, - "column": 2 - }, - "end": { - "line": 26, - "column": 26 - } - }, - "expression": { - "type": "JSXElement", - "loc": { - "source": null, - "start": { - "line": 26, - "column": 2 - }, - "end": { - "line": 26, - "column": 25 - } - }, - "openingElement": { - "type": "JSXOpeningElement", - "loc": { - "source": null, - "start": { - "line": 26, - "column": 2 - }, - "end": { - "line": 26, - "column": 25 - } - }, - "name": { - "type": "JSXMemberExpression", - "loc": { - "source": null, - "start": { - "line": 26, - "column": 3 - }, - "end": { - "line": 26, - "column": 22 - } - }, - "object": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 26, - "column": 3 - }, - "end": { - "line": 26, - "column": 15 - } - }, - "name": "DesignSystem", - "range": [ - 552, - 564 - ] - }, - "property": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 26, - "column": 16 - }, - "end": { - "line": 26, - "column": 22 - } - }, - "name": "Button", - "range": [ - 565, - 571 - ] - }, - "range": [ - 552, - 571 - ] - }, - "attributes": [], - "selfClosing": true, - "range": [ - 551, - 574 - ] - }, - "children": [], - "closingElement": null, - "range": [ - 551, - 574 - ] - }, - "directive": null, - "range": [ - 551, - 575 - ] - }, - { - "type": "VariableDeclaration", - "loc": { - "source": null, - "start": { - "line": 28, - "column": 2 - }, - "end": { - "line": 28, - "column": 49 - } - }, - "kind": "const", - "declarations": [ - { - "type": "VariableDeclarator", - "loc": { - "source": null, - "start": { - "line": 28, - "column": 8 - }, - "end": { - "line": 28, - "column": 48 - } - }, - "init": { - "type": "FunctionExpression", - "loc": { - "source": null, - "start": { - "line": 28, - "column": 12 - }, - "end": { - "line": 28, - "column": 48 - } - }, - "id": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 28, - "column": 21 - }, - "end": { - "line": 28, - "column": 24 - } - }, - "name": "bar", - "typeAnnotation": null, - "optional": false, - "range": [ - 598, - 601 - ] - }, - "params": [ - { - "type": "ArrayPattern", - "loc": { - "source": null, - "start": { - "line": 28, - "column": 25 - }, - "end": { - "line": 28, - "column": 35 - } - }, - "elements": [ - { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 28, - "column": 26 - }, - "end": { - "line": 28, - "column": 29 - } - }, - "name": "quz", - "typeAnnotation": null, - "optional": false, - "range": [ - 603, - 606 - ] - }, - { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 28, - "column": 31 - }, - "end": { - "line": 28, - "column": 34 - } - }, - "name": "qux", - "typeAnnotation": null, - "optional": false, - "range": [ - 608, - 611 - ] - } - ], - "typeAnnotation": null, - "range": [ - 602, - 612 - ] - }, - { - "type": "RestElement", - "loc": { - "source": null, - "start": { - "line": 28, - "column": 37 - }, - "end": { - "line": 28, - "column": 44 - } - }, - "argument": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 28, - "column": 40 - }, - "end": { - "line": 28, - "column": 44 - } - }, - "name": "args", - "typeAnnotation": null, - "optional": false, - "range": [ - 617, - 621 - ] - }, - "range": [ - 614, - 621 - ] - } - ], - "body": { - "type": "BlockStatement", - "loc": { - "source": null, - "start": { - "line": 28, - "column": 46 - }, - "end": { - "line": 28, - "column": 48 - } - }, - "body": [], - "range": [ - 623, - 625 - ] - }, - "typeParameters": null, - "returnType": null, - "predicate": null, - "generator": false, - "async": false, - "range": [ - 589, - 625 - ] - }, - "id": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 28, - "column": 8 - }, - "end": { - "line": 28, - "column": 9 - } - }, - "name": "j", - "typeAnnotation": null, - "optional": false, - "range": [ - 585, - 586 - ] - }, - "range": [ - 585, - 625 - ] - } - ], - "range": [ - 579, - 626 - ] - }, - { - "type": "ForStatement", - "loc": { - "source": null, - "start": { - "line": 30, - "column": 2 - }, - "end": { - "line": 32, - "column": 3 - } - }, - "init": null, - "test": { - "type": "BinaryExpression", - "loc": { - "source": null, - "start": { - "line": 30, - "column": 9 - }, - "end": { - "line": 30, - "column": 14 - } - }, - "left": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 30, - "column": 9 - }, - "end": { - "line": 30, - "column": 10 - } - }, - "name": "i", - "typeAnnotation": null, - "optional": false, - "range": [ - 637, - 638 - ] - }, - "right": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 30, - "column": 13 - }, - "end": { - "line": 30, - "column": 14 - } - }, - "value": 3, - "range": [ - 641, - 642 - ], - "raw": "3" - }, - "operator": "<", - "range": [ - 637, - 642 - ] - }, - "update": { - "type": "AssignmentExpression", - "loc": { - "source": null, - "start": { - "line": 30, - "column": 16 - }, - "end": { - "line": 30, - "column": 22 - } - }, - "operator": "+=", - "left": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 30, - "column": 16 - }, - "end": { - "line": 30, - "column": 17 - } - }, - "name": "i", - "typeAnnotation": null, - "optional": false, - "range": [ - 644, - 645 - ] - }, - "right": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 30, - "column": 21 - }, - "end": { - "line": 30, - "column": 22 - } - }, - "value": 1, - "range": [ - 649, - 650 - ], - "raw": "1" - }, - "range": [ - 644, - 650 - ] - }, - "body": { - "type": "BlockStatement", - "loc": { - "source": null, - "start": { - "line": 30, - "column": 24 - }, - "end": { - "line": 32, - "column": 3 - } - }, - "body": [ - { - "type": "ExpressionStatement", - "loc": { - "source": null, - "start": { - "line": 31, - "column": 4 - }, - "end": { - "line": 31, - "column": 14 - } - }, - "expression": { - "type": "CallExpression", - "loc": { - "source": null, - "start": { - "line": 31, - "column": 4 - }, - "end": { - "line": 31, - "column": 13 - } - }, - "callee": { - "type": "MemberExpression", - "loc": { - "source": null, - "start": { - "line": 31, - "column": 4 - }, - "end": { - "line": 31, - "column": 10 - } - }, - "object": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 31, - "column": 4 - }, - "end": { - "line": 31, - "column": 5 - } - }, - "name": "x", - "typeAnnotation": null, - "optional": false, - "range": [ - 658, - 659 - ] - }, - "property": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 31, - "column": 6 - }, - "end": { - "line": 31, - "column": 10 - } - }, - "name": "push", - "typeAnnotation": null, - "optional": false, - "range": [ - 660, - 664 - ] - }, - "computed": false, - "range": [ - 658, - 664 - ] - }, - "typeArguments": null, - "arguments": [ - { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 31, - "column": 11 - }, - "end": { - "line": 31, - "column": 12 - } - }, - "name": "i", - "typeAnnotation": null, - "optional": false, - "range": [ - 665, - 666 - ] - } - ], - "range": [ - 658, - 667 - ] - }, - "directive": null, - "range": [ - 658, - 668 - ] - } - ], - "range": [ - 652, - 672 - ] - }, - "range": [ - 630, - 672 - ] - }, - { - "type": "ForStatement", - "loc": { - "source": null, - "start": { - "line": 33, - "column": 2 - }, - "end": { - "line": 35, - "column": 3 - } - }, - "init": null, - "test": { - "type": "BinaryExpression", - "loc": { - "source": null, - "start": { - "line": 33, - "column": 9 - }, - "end": { - "line": 33, - "column": 14 - } - }, - "left": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 33, - "column": 9 - }, - "end": { - "line": 33, - "column": 10 - } - }, - "name": "i", - "typeAnnotation": null, - "optional": false, - "range": [ - 682, - 683 - ] - }, - "right": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 33, - "column": 13 - }, - "end": { - "line": 33, - "column": 14 - } - }, - "value": 3, - "range": [ - 686, - 687 - ], - "raw": "3" - }, - "operator": "<", - "range": [ - 682, - 687 - ] - }, - "update": null, - "body": { - "type": "BlockStatement", - "loc": { - "source": null, - "start": { - "line": 33, - "column": 18 - }, - "end": { - "line": 35, - "column": 3 - } - }, - "body": [ - { - "type": "BreakStatement", - "loc": { - "source": null, - "start": { - "line": 34, - "column": 4 - }, - "end": { - "line": 34, - "column": 10 - } - }, - "label": null, - "range": [ - 697, - 703 - ] - } - ], - "range": [ - 691, - 707 - ] - }, - "range": [ - 675, - 707 - ] - }, - { - "type": "ForStatement", - "loc": { - "source": null, - "start": { - "line": 36, - "column": 2 - }, - "end": { - "line": 38, - "column": 3 - } - }, - "init": null, - "test": null, - "update": null, - "body": { - "type": "BlockStatement", - "loc": { - "source": null, - "start": { - "line": 36, - "column": 11 - }, - "end": { - "line": 38, - "column": 3 - } - }, - "body": [ - { - "type": "BreakStatement", - "loc": { - "source": null, - "start": { - "line": 37, - "column": 4 - }, - "end": { - "line": 37, - "column": 10 - } - }, - "label": null, - "range": [ - 725, - 731 - ] - } - ], - "range": [ - 719, - 735 - ] - }, - "range": [ - 710, - 735 - ] - }, - { - "type": "ExpressionStatement", - "loc": { - "source": null, - "start": { - "line": 40, - "column": 2 - }, - "end": { - "line": 42, - "column": 4 - } - }, - "expression": { - "type": "TaggedTemplateExpression", - "loc": { - "source": null, - "start": { - "line": 40, - "column": 2 - }, - "end": { - "line": 42, - "column": 3 - } - }, - "tag": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 40, - "column": 2 - }, - "end": { - "line": 40, - "column": 9 - } - }, - "name": "graphql", - "typeAnnotation": null, - "optional": false, - "range": [ - 739, - 746 - ] - }, - "quasi": { - "type": "TemplateLiteral", - "loc": { - "source": null, - "start": { - "line": 40, - "column": 9 - }, - "end": { - "line": 42, - "column": 3 - } - }, - "quasis": [ - { - "type": "TemplateElement", - "loc": { - "source": null, - "start": { - "line": 40, - "column": 9 - }, - "end": { - "line": 41, - "column": 6 - } - }, - "range": [ - 746, - 754 - ], - "tail": false, - "value": { - "cooked": "\n ", - "raw": "\n " - } - }, - { - "type": "TemplateElement", - "loc": { - "source": null, - "start": { - "line": 41, - "column": 7 - }, - "end": { - "line": 42, - "column": 3 - } - }, - "range": [ - 755, - 760 - ], - "tail": true, - "value": { - "cooked": "\n ", - "raw": "\n " - } - } - ], - "expressions": [ - { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 41, - "column": 6 - }, - "end": { - "line": 41, - "column": 7 - } - }, - "name": "g", - "typeAnnotation": null, - "optional": false, - "range": [ - 754, - 755 - ] - } - ], - "range": [ - 746, - 760 - ] - }, - "range": [ - 739, - 760 - ] - }, - "directive": null, - "range": [ - 739, - 761 - ] - }, - { - "type": "ExpressionStatement", - "loc": { - "source": null, - "start": { - "line": 44, - "column": 2 - }, - "end": { - "line": 44, - "column": 17 - } - }, - "expression": { - "type": "TaggedTemplateExpression", - "loc": { - "source": null, - "start": { - "line": 44, - "column": 2 - }, - "end": { - "line": 44, - "column": 16 - } - }, - "tag": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 44, - "column": 2 - }, - "end": { - "line": 44, - "column": 9 - } - }, - "name": "graphql", - "typeAnnotation": null, - "optional": false, - "range": [ - 765, - 772 - ] - }, - "quasi": { - "type": "TemplateLiteral", - "loc": { - "source": null, - "start": { - "line": 44, - "column": 9 - }, - "end": { - "line": 44, - "column": 16 - } - }, - "quasis": [ - { - "type": "TemplateElement", - "loc": { - "source": null, - "start": { - "line": 44, - "column": 9 - }, - "end": { - "line": 44, - "column": 16 - } - }, - "range": [ - 772, - 779 - ], - "tail": true, - "value": { - "cooked": "\\t\n", - "raw": "\\\\t\\n" - } - } - ], - "expressions": [], - "range": [ - 772, - 779 - ] - }, - "range": [ - 765, - 779 - ] - }, - "directive": null, - "range": [ - 765, - 780 - ] - } - ], - "range": [ - 59, - 782 - ] - }, - "typeParameters": null, - "returnType": null, - "predicate": null, - "generator": false, - "async": false, - "range": [ - 1, - 782 - ] - } - ], - "comments": [ - { - "type": "Block", - "loc": { - "source": null, - "start": { - "line": 25, - "column": 11 - }, - "end": { - "line": 25, - "column": 23 - } - }, - "value": "* empty ", - "range": [ - 525, - 537 - ] - } - ], - "interpreter": null, - "range": [ - 1, - 782 - ], - "sourceType": "script" - } \ No newline at end of file diff --git a/compiler/forget/crates/estree/src/lib.rs b/compiler/forget/crates/estree/src/lib.rs index 89b6b789d0..9d5cfce15d 100644 --- a/compiler/forget/crates/estree/src/lib.rs +++ b/compiler/forget/crates/estree/src/lib.rs @@ -1,1284 +1,12 @@ -use serde::{Deserialize, Serialize}; -use static_assertions::assert_eq_size; -use std::{fmt::Display, num::NonZeroU32}; - -#[derive(Serialize, Deserialize, Debug)] -pub struct SourceLocation { - pub source: Option, - - pub start: Position, - - pub end: Position, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct Position { - /// >= 1 - pub line: NonZeroU32, - /// >= 0 - pub column: u32, -} -assert_eq_size!(Option, u64); - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct SourceRange { - pub start: u32, - // end is exclusive so it can always be non-zero. This allows - // Option to not take any additional bytes. - pub end: NonZeroU32, -} -assert_eq_size!(Option, u64); - -#[derive(Serialize, Deserialize, Debug)] -pub struct Program { - /// sourceType - #[serde(rename = "sourceType")] - #[serde(default)] - pub source_type: SourceType, - - pub body: Vec, - - #[serde(default)] - pub comments: Option>, - - pub loc: Option, - - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub enum SourceType { - /// "module" - #[serde(rename = "module")] - Module, - /// "script" - #[serde(rename = "script")] - Script, -} - -impl Default for SourceType { - fn default() -> Self { - Self::Module - } -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct Comment { - pub type_: CommentType, - pub value: String, -} - -#[derive(Serialize, Deserialize, Debug)] -pub enum CommentType { - /// "Line" - Line, - /// "Block" - Block, -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(untagged)] -pub enum ModuleItem { - Statement(Box), - ImportDeclaration(Box), -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(tag = "type")] -pub enum ImportExportDeclaration { - ImportDeclaration(Box), - // TODO: - // ExportNamedDeclaration(Box), - // ExportDefaultDeclaration(Box), - // ExportAllDeclaration(Box), -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ImportDeclaration { - pub specifiers: Vec, - pub source: Literal, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(tag = "type")] -pub enum ImportSpecifiers { - ImportSpecifier(Box), - ImportDefaultSpecifier(Box), -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ImportSpecifier { - pub imported: Identifier, - - pub local: Identifier, - - pub loc: Option, - - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ImportDefaultSpecifier { - pub local: Identifier, - - pub loc: Option, - - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(tag = "type")] -pub enum Statement { - BlockStatement(Box), - BreakStatement(Box), - ClassDeclaration(Box), - ContinueStatement(Box), - DebuggerStatement(Box), - DoWhileStatement(Box), - EmptyStatement(Box), - ExpressionStatement(Box), - ForInStatement(Box), - ForOfStatement(Box), - ForStatement(Box), - FunctionDeclaration(Box), - IfStatement(Box), - LabeledStatement(Box), - ReturnStatement(Box), - StaticBlock(Box), - SwitchStatement(Box), - ThrowStatement(Box), - TryStatement(Box), - VariableDeclaration(Box), - WhileStatement(Box), - WithStatement(Box), -} -// Prevent unboxed variants from increasing the size -assert_eq_size!(Statement, u128); - -#[derive(Serialize, Deserialize, Debug)] -pub struct BlockStatement { - pub body: Vec, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct BreakStatement { - #[serde(default)] - pub label: Option, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ClassDeclaration { - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ContinueStatement { - #[serde(default)] - pub label: Option, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct DebuggerStatement { - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct DoWhileStatement { - pub body: Statement, - pub test: ExpressionLike, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct EmptyStatement { - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct FunctionDeclaration { - pub id: Option, - - pub params: Vec, - - #[serde(rename = "generator")] - #[serde(default)] - pub is_generator: bool, - - #[serde(rename = "async")] - #[serde(default)] - pub is_async: bool, - - // TODO: BlockStatement - pub body: Option, - - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct StaticBlock { - pub body: Vec, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ExpressionStatement { - pub expression: ExpressionLike, - - #[serde(default)] - pub directive: Option, - - pub loc: Option, - - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ForInStatement { - pub left: ForPattern, - pub right: ExpressionLike, - pub body: Statement, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ForOfStatement { - #[serde(rename = "await")] - #[serde(default)] - pub is_await: bool, - - pub left: ForPattern, - - pub right: ExpressionLike, - - pub body: Statement, - - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(tag = "type")] -pub enum ForPattern { - VariableDeclaration(Box), - Expression(Box), -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ForStatement { - pub init: Option, - pub test: Option, - pub update: Option, - pub body: Statement, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(tag = "type")] -pub enum ForInit { - VariableDeclaration(Box), - Expression(Box), -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct IfStatement { - pub test: ExpressionLike, - pub consequent: Statement, - pub alternate: Option, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct LabeledStatement { - pub label: Identifier, - pub body: Statement, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ReturnStatement { - pub argument: Option, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct SwitchStatement { - pub discriminant: ExpressionLike, - pub cases: Vec, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct SwitchCase { - pub test: Option, - pub consequent: Vec, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ThrowStatement { - pub argument: ExpressionLike, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct TryStatement { - // TODO: block: BlockStatement - pub block: Statement, - pub handler: Option, - // TODO: finalizer: BlockStatement - pub finalizer: Option, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct CatchClause { - pub param: Option, - pub body: Statement, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct VariableDeclaration { - pub declarations: Vec, - pub kind: VariableDeclarationKind, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct VariableDeclarator { - pub id: Pattern, - pub init: Option, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub enum VariableDeclarationKind { - #[serde(rename = "const")] - Const, - #[serde(rename = "let")] - Let, - #[serde(rename = "var")] - Var, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WhileStatement { - pub test: ExpressionLike, - pub body: Statement, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct WithStatement { - pub object: ExpressionLike, - pub body: Statement, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -/// Expressions and expression-like nodes -/// we flatten these into a single enum to work around limits -/// of serde enum format with handling arbitrary unions -#[derive(Serialize, Deserialize, Debug)] -#[serde(tag = "type")] -pub enum ExpressionLike { - ArrayExpression(Box), - ArrowFunctionExpression(Box), - AssignmentExpression(Box), - AwaitExpression(Box), - BinaryExpression(Box), - CallExpression(Box), - ChainExpression(Box), - ClassExpression(Box), - ConditionalExpression(Box), - FunctionExpression(Box), - Identifier(Box), - ImportExpression(Box), - Literal(Box), - LogicalExpression(Box), - MemberExpression(Box), - MetaProperty(Box), - NewExpression(Box), - ObjectExpression(Box), - SequenceExpression(Box), - TaggedTemplateExpression(Box), - TemplateLiteral(Box), - ThisExpression(Box), - UnaryExpression(Box), - UpdateExpression(Box), - YieldExpression(Box), - - // pseudo-expressions to work with serde - Super(Box), - - // patterns to work with serde - ArrayPattern(Box), - AssignmentPattern(Box), - ObjectPattern(Box), - Property(Box), - RestElement(Box), - SpreadElement(Box), - - // jsx expression-ish types to work with serde - JSXClosingElement(Box), - JSXElement(Box), - JSXExpressionContainer(Box), - JSXIdentifier(Box), - JSXMemberExpression(Box), - JSXNamedspacedName(Box), - JSXOpeningElement(Box), - JSXText(Box), -} -// Prevent unboxed variants from increasing the size -assert_eq_size!(ExpressionLike, u128); - -#[derive(Serialize, Deserialize, Debug)] -pub struct ArrayExpression { - pub elements: Vec, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ArrowFunctionExpression { - pub params: Vec, - - #[serde(rename = "generator")] - #[serde(default)] - pub is_generator: bool, - - #[serde(rename = "async")] - #[serde(default)] - pub is_async: bool, - - #[serde(rename = "expression")] - #[serde(default)] - pub is_expression: bool, - - pub body: BlockOrExpression, - - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(tag = "type")] -pub enum BlockOrExpression { - BlockStatement(Box), - Expression(Box), -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct AssignmentExpression { - pub operator: AssignmentOperator, - pub left: AssignmentTarget, - pub right: ExpressionLike, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub enum AssignmentOperator { - /// = - #[serde(rename = "=")] - Equals, - /// += - #[serde(rename = "+=")] - PlusEquals, - // -= - #[serde(rename = "-=")] - MinusEquals, - /// *= - #[serde(rename = "*=")] - AsteriskEquals, - /// /= - #[serde(rename = "/=")] - SlashEquals, - /// %= - #[serde(rename = "%=")] - PercentEquals, - /// **= - #[serde(rename = "**=")] - AsteriskAsteriskEquals, - /// <<= - #[serde(rename = "<<=")] - LtLtEquals, - /// >>= - #[serde(rename = ">>=")] - GtGtEquals, - /// >>>= - #[serde(rename = ">>>=")] - GtGtGtEquals, - /// |= - #[serde(rename = "|=")] - PipeEquals, - /// ^= - #[serde(rename = "^=")] - CaretEquals, - /// &= - #[serde(rename = "&&=")] - AmpersandEquals, - /// ||= - #[serde(rename = "||=")] - PipePipeEquals, - /// &&= - #[serde(rename = "&&=")] - AmpersandAmpersandEquals, - // ??= - #[serde(rename = "??=")] - QuestionQuestionEquals, -} - -impl AssignmentOperator { - pub fn is_simple_equals(&self) -> bool { - matches!(self, AssignmentOperator::Equals) - } -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(untagged)] -pub enum AssignmentTarget { - Pattern(Box), - MemberExpression(Box), -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct AwaitExpression { - pub argument: ExpressionLike, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct BinaryExpression { - pub operator: BinaryOperator, - pub left: ExpressionLike, - pub right: ExpressionLike, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub enum BinaryOperator { - /// == - #[serde(rename = "==")] - EqualsEquals, - /// != - #[serde(rename = "!=")] - NotEquals, - /// === - #[serde(rename = "===")] - TripleEquals, - /// !== - #[serde(rename = "!==")] - NotTripleEquals, - /// < - #[serde(rename = "<")] - LessThan, - /// <= - #[serde(rename = "<=")] - LessThanEquals, - /// > - #[serde(rename = ">")] - GreaterThan, - /// >= - #[serde(rename = ">=")] - GreaterThanEquals, - /// << - #[serde(rename = "<<")] - LtLt, - /// >> - #[serde(rename = ">>")] - GtGt, - /// >>> - #[serde(rename = ">>>")] - GtGtGt, - /// + - #[serde(rename = "+")] - Plus, - /// - - #[serde(rename = "-")] - Minus, - /// * - #[serde(rename = "*")] - Asterisk, - /// / - #[serde(rename = "/")] - Slash, - /// % - #[serde(rename = "%")] - Percent, - /// ** - #[serde(rename = "**")] - AsteriskAsterisk, - /// | - #[serde(rename = "|")] - Pipe, - /// ^ - #[serde(rename = "^")] - Caret, - /// & - #[serde(rename = "&")] - Ampersand, - /// in - #[serde(rename = "in")] - In, - /// instanceof - #[serde(rename = "instanceof")] - Instanceof, -} - -impl Display for BinaryOperator { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let name = match self { - Self::Plus => "+", - Self::LessThan => "<", - _ => todo!("display for operator: {:#?}", self), - }; - f.write_str(name) - } -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct CallExpression { - #[serde(rename = "optional")] - #[serde(default)] - pub is_optional: bool, - - pub callee: ExpressionLike, - - pub arguments: Vec, - - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ChainExpression { - pub expression: ChainElement, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(tag = "type")] -pub enum ChainElement { - CallExpression(Box), - MemberExpression(Box), -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ClassExpression { - // TODO - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ConditionalExpression { - pub test: ExpressionLike, - pub alternate: ExpressionLike, - pub consequent: ExpressionLike, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct FunctionExpression { - // TODO - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ImportExpression { - // TODO - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct Literal { - pub value: LiteralValue, - - #[serde(default)] - pub raw: Option, - - pub loc: Option, - - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(untagged)] -pub enum LiteralValue { - BigInt(String), - Boolean(bool), - Null, - Number(Number), - RegExp(RegExp), - String(String), -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct Number(u64); - -impl From for Number { - fn from(value: u64) -> Self { - Number(value) - } -} - -impl From for Number { - fn from(value: f64) -> Self { - Number(value.to_bits()) - } -} - -impl From for f64 { - fn from(value: Number) -> Self { - f64::from_bits(value.0) - } -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct RegExp { - pub raw: Option, - pub regex: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct RegExpValue { - pub pattern: String, - pub flags: String, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct LogicalExpression { - pub operator: LogicalOperator, - pub left: ExpressionLike, - pub right: ExpressionLike, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub enum LogicalOperator { - /// || - #[serde(rename = "||")] - PipePipe, - /// && - #[serde(rename = "&&")] - AmpersandAmpersand, - /// ?? - #[serde(rename = "??")] - QuestionQuestion, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct MetaProperty { - // TODO - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct NewExpression { - pub callee: ExpressionLike, - pub arguments: Vec, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ObjectExpression { - pub properties: Vec, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct SequenceExpression { - pub expressions: Vec, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct TaggedTemplateExpression { - pub tag: ExpressionLike, - pub quasi: TemplateLiteral, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct TemplateLiteral { - pub quasis: Vec, - pub expressions: Vec, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct TemplateElement { - #[serde(rename = "tail")] - #[serde(default)] - pub is_tail: bool, - - // TODO: add value: {cooked, raw} wrapper object - pub cooked: Option, - - pub raw: String, - - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ThisExpression { - // TODO - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct UnaryExpression { - pub operator: UnaryOperator, - - #[serde(rename = "prefix")] - #[serde(default)] - pub is_prefix: bool, - - pub argument: ExpressionLike, - - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub enum UnaryOperator { - /// - - #[serde(rename = "+")] - Minus, - /// + - #[serde(rename = "+")] - Plus, - /// ! - #[serde(rename = "!")] - Exclamation, - /// ~ - #[serde(rename = "~")] - Tilde, - /// typeof - #[serde(rename = "typeof")] - Typeof, - /// void - #[serde(rename = "void")] - Void, - /// delete - #[serde(rename = "delete")] - Delete, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct UpdateExpression { - pub operator: UpdateOperator, - - pub argument: ExpressionLike, - - #[serde(rename = "prefix")] - #[serde(default)] - pub is_prefix: bool, - - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub enum UpdateOperator { - /// ++ - #[serde(rename = "++")] - PlusPlus, - /// -- - #[serde(rename = "--")] - MinusMinus, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct YieldExpression { - pub argument: Option, - - #[serde(rename = "delegate")] - #[serde(default)] - pub is_delegate: bool, - - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -// Pattern etc - -#[derive(Serialize, Deserialize, Debug)] -#[serde(tag = "type")] -pub enum Pattern { - ArrayPattern(Box), - AssignmentPattern(Box), - Identifier(Box), - MemberExpression(Box), - ObjectPattern(Box), - RestElement(Box), -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ArrayPattern { - pub elements: Vec, - - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct AssignmentPattern { - pub left: Pattern, - pub right: ExpressionLike, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct Identifier { - pub name: String, - - #[serde(default)] - pub binding: Option, - - pub loc: Option, - - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(tag = "type")] -pub enum Binding { - Local(BindingId), - Module(BindingId), - Global, -} - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, Copy)] -#[serde(transparent)] -pub struct BindingId(NonZeroU32); - -impl BindingId { - pub fn new(id: NonZeroU32) -> Self { - Self(id) - } -} - -impl From for u32 { - fn from(value: BindingId) -> Self { - value.0.into() - } -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct MemberExpression { - pub object: ExpressionLike, - - pub property: ExpressionLike, // ExpressionOrPrivateIdentifier - - #[serde(rename = "computed")] - #[serde(default)] - pub is_computed: bool, - - #[serde(rename = "optional")] - #[serde(default)] - pub is_optional: bool, - - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct Super { - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct PrivateIdentifier { - pub name: String, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ObjectPattern { - pub properties: Vec, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct Property { - pub key: ExpressionLike, - - pub value: PropertyValue, - - pub kind: PropertyKind, - - #[serde(rename = "method")] - #[serde(default)] - pub is_method: bool, - - #[serde(rename = "shorthand")] - #[serde(default)] - pub is_shorthand: bool, - - #[serde(rename = "computed")] - #[serde(default)] - pub is_computed: bool, - - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(untagged)] -pub enum PropertyValue { - Expression(Box), - Pattern(Box), -} - -#[derive(Serialize, Deserialize, Debug)] -pub enum PropertyKind { - #[serde(rename = "init")] - Init, - #[serde(rename = "get")] - Get, - #[serde(rename = "set")] - Set, -} - -impl Default for PropertyKind { - fn default() -> Self { - Self::Init - } -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct RestElement { - pub argument: Pattern, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct SpreadElement { - pub argument: ExpressionLike, - pub loc: Option, - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct JSXElement { - #[serde(rename = "openingElement")] - pub opening_element: ExpressionLike, - - pub children: Vec, - - #[serde(rename = "closingElement")] - pub closing_element: Option, - - pub loc: Option, - - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct JSXOpeningElement { - pub name: ExpressionLike, - - pub attributes: Vec, - - #[serde(rename = "selfClosing")] - #[serde(default)] - pub self_closing: bool, - - pub loc: Option, - - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct JSXClosingElement { - pub name: ExpressionLike, - - pub loc: Option, - - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct JSXMemberExpression { - pub object: ExpressionLike, - - pub property: ExpressionLike, - - pub loc: Option, - - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct JSXIdentifier { - pub name: String, - - pub loc: Option, - - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct JSXNamedspacedName { - pub namespace: ExpressionLike, - - pub name: ExpressionLike, - - pub loc: Option, - - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct JSXAttribute { - pub name: ExpressionLike, - - pub value: ExpressionLike, - - pub loc: Option, - - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct JSXExpressionContainer { - expression: ExpressionLike, - - pub loc: Option, - - #[serde(default)] - pub range: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct JSXText { - value: String, - raw: String, - - pub loc: Option, - - #[serde(default)] - pub range: Option, -} +mod binding; +mod generated; +mod js_value; +mod range; + +pub use binding::Binding; +pub use generated::*; +pub use js_value::JsValue; +pub use range::SourceRange; #[cfg(test)] mod tests { @@ -1286,54 +14,6 @@ mod tests { use insta::{assert_snapshot, glob}; use serde_json; - #[test] - fn for_statement() { - let source = include_str!("for-statement.json"); - let ast: Program = serde_json::from_str(&source).unwrap(); - println!("deserialized:\n{:#?}", ast); - let serialized = serde_json::to_string_pretty(&ast).unwrap(); - println!("serialized:\n{}", serialized); - } - - #[test] - fn simple() { - let source = include_str!("simple.json"); - let ast: Program = serde_json::from_str(&source).unwrap(); - println!("deserialized:\n{:#?}", ast); - let serialized = serde_json::to_string_pretty(&ast).unwrap(); - println!("serialized:\n{}", serialized); - } - - /// TODO: enable once this deserializes - fn _kitchen_sink() { - let source = include_str!("kitchen-sink.json"); - let ast: Program = match serde_json::from_str(&source) { - Ok(ast) => ast, - Err(err) => panic!("{:#?}", err), - }; - println!("deserialized:\n{:#?}", ast); - let serialized = serde_json::to_string_pretty(&ast).unwrap(); - println!("serialized:\n{}", serialized); - } - - #[test] - fn import() { - let source = include_str!("import.json"); - let ast: Program = serde_json::from_str(&source).unwrap(); - println!("deserialized:\n{:#?}", ast); - let serialized = serde_json::to_string_pretty(&ast).unwrap(); - println!("serialized:\n{}", serialized); - } - - #[test] - fn test() { - let source = include_str!("test.json"); - let ast: Program = serde_json::from_str(&source).unwrap(); - println!("deserialized:\n{:#?}", ast); - let serialized = serde_json::to_string_pretty(&ast).unwrap(); - println!("serialized:\n{}", serialized); - } - #[test] fn fixtures() { glob!("fixtures/**.json", |path| { diff --git a/compiler/forget/crates/estree/src/old.lib.rs b/compiler/forget/crates/estree/src/old.lib.rs new file mode 100644 index 0000000000..b7c9188767 --- /dev/null +++ b/compiler/forget/crates/estree/src/old.lib.rs @@ -0,0 +1,1358 @@ +use serde::{Deserialize, Serialize}; +use static_assertions::assert_eq_size; +use std::{fmt::Display, num::NonZeroU32}; + +#[derive(Serialize, Deserialize, Debug)] +pub struct SourceLocation { + pub source: Option, + + pub start: Position, + + pub end: Position, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct Position { + /// >= 1 + pub line: NonZeroU32, + /// >= 0 + pub column: u32, +} +assert_eq_size!(Option, u64); + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct SourceRange { + pub start: u32, + // end is exclusive so it can always be non-zero. This allows + // Option to not take any additional bytes. + pub end: NonZeroU32, +} +assert_eq_size!(Option, u64); + +#[derive(Serialize, Deserialize, Debug)] +pub struct Program { + /// sourceType + #[serde(rename = "sourceType")] + #[serde(default)] + pub source_type: SourceType, + + pub body: Vec, + + #[serde(default)] + pub comments: Option>, + + pub loc: Option, + + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub enum SourceType { + /// "module" + #[serde(rename = "module")] + Module, + /// "script" + #[serde(rename = "script")] + Script, +} + +impl Default for SourceType { + fn default() -> Self { + Self::Module + } +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Comment { + pub type_: CommentType, + pub value: String, +} + +#[derive(Serialize, Deserialize, Debug)] +pub enum CommentType { + /// "Line" + Line, + /// "Block" + Block, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(untagged)] +pub enum ModuleItem { + Statement(Box), + ImportDeclaration(Box), +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "type")] +pub enum ImportExportDeclaration { + ImportDeclaration(Box), + // TODO: + // ExportNamedDeclaration(Box), + // ExportDefaultDeclaration(Box), + // ExportAllDeclaration(Box), +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ImportDeclaration { + pub specifiers: Vec, + pub source: Literal, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "type")] +pub enum ImportSpecifiers { + ImportSpecifier(Box), + ImportDefaultSpecifier(Box), +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ImportSpecifier { + pub imported: Identifier, + + pub local: Identifier, + + pub loc: Option, + + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ImportDefaultSpecifier { + pub local: Identifier, + + pub loc: Option, + + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "type")] +pub enum Statement { + BlockStatement(Box), + BreakStatement(Box), + ClassDeclaration(Box), + ContinueStatement(Box), + DebuggerStatement(Box), + DoWhileStatement(Box), + EmptyStatement(Box), + ExpressionStatement(Box), + ForInStatement(Box), + ForOfStatement(Box), + ForStatement(Box), + FunctionDeclaration(Box), + IfStatement(Box), + LabeledStatement(Box), + ReturnStatement(Box), + StaticBlock(Box), + SwitchStatement(Box), + ThrowStatement(Box), + TryStatement(Box), + VariableDeclaration(Box), + WhileStatement(Box), + WithStatement(Box), +} +// Prevent unboxed variants from increasing the size +assert_eq_size!(Statement, u128); + +#[derive(Serialize, Deserialize, Debug)] +pub struct BlockStatement { + pub body: Vec, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct BreakStatement { + #[serde(default)] + pub label: Option, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ClassDeclaration { + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ContinueStatement { + #[serde(default)] + pub label: Option, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct DebuggerStatement { + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct DoWhileStatement { + pub body: Statement, + pub test: ExpressionLike, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct EmptyStatement { + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct FunctionDeclaration { + pub id: Option, + + pub params: Vec, + + #[serde(rename = "generator")] + #[serde(default)] + pub is_generator: bool, + + #[serde(rename = "async")] + #[serde(default)] + pub is_async: bool, + + // TODO: BlockStatement + pub body: Option, + + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct StaticBlock { + pub body: Vec, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ExpressionStatement { + pub expression: ExpressionLike, + + #[serde(default)] + pub directive: Option, + + pub loc: Option, + + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ForInStatement { + pub left: ForPattern, + pub right: ExpressionLike, + pub body: Statement, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ForOfStatement { + #[serde(rename = "await")] + #[serde(default)] + pub is_await: bool, + + pub left: ForPattern, + + pub right: ExpressionLike, + + pub body: Statement, + + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "type")] +pub enum ForPattern { + VariableDeclaration(Box), + Expression(Box), +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ForStatement { + pub init: Option, + pub test: Option, + pub update: Option, + pub body: Statement, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "type")] +pub enum ForInit { + VariableDeclaration(Box), + Expression(Box), +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct IfStatement { + pub test: ExpressionLike, + pub consequent: Statement, + pub alternate: Option, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct LabeledStatement { + pub label: Identifier, + pub body: Statement, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ReturnStatement { + pub argument: Option, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct SwitchStatement { + pub discriminant: ExpressionLike, + pub cases: Vec, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct SwitchCase { + pub test: Option, + pub consequent: Vec, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ThrowStatement { + pub argument: ExpressionLike, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct TryStatement { + // TODO: block: BlockStatement + pub block: Statement, + pub handler: Option, + // TODO: finalizer: BlockStatement + pub finalizer: Option, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct CatchClause { + pub param: Option, + pub body: Statement, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct VariableDeclaration { + pub declarations: Vec, + pub kind: VariableDeclarationKind, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct VariableDeclarator { + pub id: Pattern, + pub init: Option, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub enum VariableDeclarationKind { + #[serde(rename = "const")] + Const, + #[serde(rename = "let")] + Let, + #[serde(rename = "var")] + Var, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct WhileStatement { + pub test: ExpressionLike, + pub body: Statement, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct WithStatement { + pub object: ExpressionLike, + pub body: Statement, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +/// Expressions and expression-like nodes +/// we flatten these into a single enum to work around limits +/// of serde enum format with handling arbitrary unions +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "type")] +pub enum ExpressionLike { + ArrayExpression(Box), + ArrowFunctionExpression(Box), + AssignmentExpression(Box), + AwaitExpression(Box), + BinaryExpression(Box), + CallExpression(Box), + ChainExpression(Box), + ClassExpression(Box), + ConditionalExpression(Box), + FunctionExpression(Box), + Identifier(Box), + ImportExpression(Box), + Literal(Box), + LogicalExpression(Box), + MemberExpression(Box), + MetaProperty(Box), + NewExpression(Box), + ObjectExpression(Box), + SequenceExpression(Box), + TaggedTemplateExpression(Box), + TemplateLiteral(Box), + ThisExpression(Box), + UnaryExpression(Box), + UpdateExpression(Box), + YieldExpression(Box), + + // pseudo-expressions to work with serde + Super(Box), + + // patterns to work with serde + ArrayPattern(Box), + AssignmentPattern(Box), + ObjectPattern(Box), + Property(Box), + RestElement(Box), + SpreadElement(Box), + + // jsx expression-ish types to work with serde + JSXClosingElement(Box), + JSXElement(Box), + JSXExpressionContainer(Box), + JSXIdentifier(Box), + JSXMemberExpression(Box), + JSXNamedspacedName(Box), + JSXOpeningElement(Box), + JSXText(Box), +} +// Prevent unboxed variants from increasing the size +assert_eq_size!(ExpressionLike, u128); + +#[derive(Serialize, Deserialize, Debug)] +pub struct ArrayExpression { + pub elements: Vec, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ArrowFunctionExpression { + pub params: Vec, + + #[serde(rename = "generator")] + #[serde(default)] + pub is_generator: bool, + + #[serde(rename = "async")] + #[serde(default)] + pub is_async: bool, + + #[serde(rename = "expression")] + #[serde(default)] + pub is_expression: bool, + + pub body: BlockOrExpression, + + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "type")] +pub enum BlockOrExpression { + BlockStatement(Box), + Expression(Box), +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct AssignmentExpression { + pub operator: AssignmentOperator, + pub left: AssignmentTarget, + pub right: ExpressionLike, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub enum AssignmentOperator { + /// = + #[serde(rename = "=")] + Equals, + /// += + #[serde(rename = "+=")] + PlusEquals, + // -= + #[serde(rename = "-=")] + MinusEquals, + /// *= + #[serde(rename = "*=")] + AsteriskEquals, + /// /= + #[serde(rename = "/=")] + SlashEquals, + /// %= + #[serde(rename = "%=")] + PercentEquals, + /// **= + #[serde(rename = "**=")] + AsteriskAsteriskEquals, + /// <<= + #[serde(rename = "<<=")] + LtLtEquals, + /// >>= + #[serde(rename = ">>=")] + GtGtEquals, + /// >>>= + #[serde(rename = ">>>=")] + GtGtGtEquals, + /// |= + #[serde(rename = "|=")] + PipeEquals, + /// ^= + #[serde(rename = "^=")] + CaretEquals, + /// &= + #[serde(rename = "&&=")] + AmpersandEquals, + /// ||= + #[serde(rename = "||=")] + PipePipeEquals, + /// &&= + #[serde(rename = "&&=")] + AmpersandAmpersandEquals, + // ??= + #[serde(rename = "??=")] + QuestionQuestionEquals, +} + +impl AssignmentOperator { + pub fn is_simple_equals(&self) -> bool { + matches!(self, AssignmentOperator::Equals) + } +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(untagged)] +pub enum AssignmentTarget { + Pattern(Box), + MemberExpression(Box), +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct AwaitExpression { + pub argument: ExpressionLike, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct BinaryExpression { + pub operator: BinaryOperator, + pub left: ExpressionLike, + pub right: ExpressionLike, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub enum BinaryOperator { + /// == + #[serde(rename = "==")] + EqualsEquals, + /// != + #[serde(rename = "!=")] + NotEquals, + /// === + #[serde(rename = "===")] + TripleEquals, + /// !== + #[serde(rename = "!==")] + NotTripleEquals, + /// < + #[serde(rename = "<")] + LessThan, + /// <= + #[serde(rename = "<=")] + LessThanEquals, + /// > + #[serde(rename = ">")] + GreaterThan, + /// >= + #[serde(rename = ">=")] + GreaterThanEquals, + /// << + #[serde(rename = "<<")] + LtLt, + /// >> + #[serde(rename = ">>")] + GtGt, + /// >>> + #[serde(rename = ">>>")] + GtGtGt, + /// + + #[serde(rename = "+")] + Plus, + /// - + #[serde(rename = "-")] + Minus, + /// * + #[serde(rename = "*")] + Asterisk, + /// / + #[serde(rename = "/")] + Slash, + /// % + #[serde(rename = "%")] + Percent, + /// ** + #[serde(rename = "**")] + AsteriskAsterisk, + /// | + #[serde(rename = "|")] + Pipe, + /// ^ + #[serde(rename = "^")] + Caret, + /// & + #[serde(rename = "&")] + Ampersand, + /// in + #[serde(rename = "in")] + In, + /// instanceof + #[serde(rename = "instanceof")] + Instanceof, +} + +impl Display for BinaryOperator { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let name = match self { + Self::Plus => "+", + Self::LessThan => "<", + _ => todo!("display for operator: {:#?}", self), + }; + f.write_str(name) + } +} + +impl std::str::FromStr for BinaryOperator { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "+" => Ok(Self::Plus), + "-" => Ok(Self::Minus), + _ => Err(format!("Invalid BinaryOperator: `{}`", s)), + } + } +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct CallExpression { + #[serde(rename = "optional")] + #[serde(default)] + pub is_optional: bool, + + pub callee: ExpressionLike, + + pub arguments: Vec, + + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ChainExpression { + pub expression: ChainElement, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "type")] +pub enum ChainElement { + CallExpression(Box), + MemberExpression(Box), +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ClassExpression { + // TODO + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ConditionalExpression { + pub test: ExpressionLike, + pub alternate: ExpressionLike, + pub consequent: ExpressionLike, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct FunctionExpression { + // TODO + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ImportExpression { + // TODO + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Literal { + pub value: LiteralValue, + + #[serde(default)] + pub raw: Option, + + pub loc: Option, + + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(untagged)] +pub enum LiteralValue { + BigInt(String), + Boolean(bool), + Null, + Number(Number), + RegExp(RegExp), + String(String), +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Number(u64); + +impl From for Number { + fn from(value: u64) -> Self { + Number(value) + } +} + +impl From for Number { + fn from(value: f64) -> Self { + Number(value.to_bits()) + } +} + +impl From for f64 { + fn from(value: Number) -> Self { + f64::from_bits(value.0) + } +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct RegExp { + pub raw: Option, + pub regex: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct RegExpValue { + pub pattern: String, + pub flags: String, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct LogicalExpression { + pub operator: LogicalOperator, + pub left: ExpressionLike, + pub right: ExpressionLike, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub enum LogicalOperator { + /// || + #[serde(rename = "||")] + PipePipe, + /// && + #[serde(rename = "&&")] + AmpersandAmpersand, + /// ?? + #[serde(rename = "??")] + QuestionQuestion, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct MetaProperty { + // TODO + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct NewExpression { + pub callee: ExpressionLike, + pub arguments: Vec, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ObjectExpression { + pub properties: Vec, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct SequenceExpression { + pub expressions: Vec, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct TaggedTemplateExpression { + pub tag: ExpressionLike, + pub quasi: TemplateLiteral, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct TemplateLiteral { + pub quasis: Vec, + pub expressions: Vec, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct TemplateElement { + #[serde(rename = "tail")] + #[serde(default)] + pub is_tail: bool, + + // TODO: add value: {cooked, raw} wrapper object + pub cooked: Option, + + pub raw: String, + + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ThisExpression { + // TODO + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct UnaryExpression { + pub operator: UnaryOperator, + + #[serde(rename = "prefix")] + #[serde(default)] + pub is_prefix: bool, + + pub argument: ExpressionLike, + + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub enum UnaryOperator { + /// - + #[serde(rename = "+")] + Minus, + /// + + #[serde(rename = "+")] + Plus, + /// ! + #[serde(rename = "!")] + Exclamation, + /// ~ + #[serde(rename = "~")] + Tilde, + /// typeof + #[serde(rename = "typeof")] + Typeof, + /// void + #[serde(rename = "void")] + Void, + /// delete + #[serde(rename = "delete")] + Delete, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct UpdateExpression { + pub operator: UpdateOperator, + + pub argument: ExpressionLike, + + #[serde(rename = "prefix")] + #[serde(default)] + pub is_prefix: bool, + + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub enum UpdateOperator { + /// ++ + #[serde(rename = "++")] + PlusPlus, + /// -- + #[serde(rename = "--")] + MinusMinus, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct YieldExpression { + pub argument: Option, + + #[serde(rename = "delegate")] + #[serde(default)] + pub is_delegate: bool, + + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +// Pattern etc + +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "type")] +pub enum Pattern { + ArrayPattern(Box), + AssignmentPattern(Box), + Identifier(Box), + MemberExpression(Box), + ObjectPattern(Box), + RestElement(Box), +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ArrayPattern { + pub elements: Vec, + + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct AssignmentPattern { + pub left: Pattern, + pub right: ExpressionLike, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Identifier { + pub name: String, + + #[serde(default)] + pub binding: Option, + + pub loc: Option, + + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "type")] +pub enum Binding { + Local(BindingId), + Module(BindingId), + Global, +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, Copy)] +#[serde(transparent)] +pub struct BindingId(NonZeroU32); + +impl BindingId { + pub fn new(id: NonZeroU32) -> Self { + Self(id) + } +} + +impl From for u32 { + fn from(value: BindingId) -> Self { + value.0.into() + } +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct MemberExpression { + pub object: ExpressionLike, + + pub property: ExpressionLike, // ExpressionOrPrivateIdentifier + + #[serde(rename = "computed")] + #[serde(default)] + pub is_computed: bool, + + #[serde(rename = "optional")] + #[serde(default)] + pub is_optional: bool, + + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Super { + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct PrivateIdentifier { + pub name: String, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ObjectPattern { + pub properties: Vec, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Property { + pub key: ExpressionLike, + + pub value: PropertyValue, + + pub kind: PropertyKind, + + #[serde(rename = "method")] + #[serde(default)] + pub is_method: bool, + + #[serde(rename = "shorthand")] + #[serde(default)] + pub is_shorthand: bool, + + #[serde(rename = "computed")] + #[serde(default)] + pub is_computed: bool, + + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(untagged)] +pub enum PropertyValue { + Expression(Box), + Pattern(Box), +} + +#[derive(Serialize, Deserialize, Debug)] +pub enum PropertyKind { + #[serde(rename = "init")] + Init, + #[serde(rename = "get")] + Get, + #[serde(rename = "set")] + Set, +} + +impl Default for PropertyKind { + fn default() -> Self { + Self::Init + } +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct RestElement { + pub argument: Pattern, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct SpreadElement { + pub argument: ExpressionLike, + pub loc: Option, + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct JSXElement { + #[serde(rename = "openingElement")] + pub opening_element: ExpressionLike, + + pub children: Vec, + + #[serde(rename = "closingElement")] + pub closing_element: Option, + + pub loc: Option, + + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct JSXOpeningElement { + pub name: ExpressionLike, + + pub attributes: Vec, + + #[serde(rename = "selfClosing")] + #[serde(default)] + pub self_closing: bool, + + pub loc: Option, + + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct JSXClosingElement { + pub name: ExpressionLike, + + pub loc: Option, + + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct JSXMemberExpression { + pub object: ExpressionLike, + + pub property: ExpressionLike, + + pub loc: Option, + + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct JSXIdentifier { + pub name: String, + + pub loc: Option, + + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct JSXNamedspacedName { + pub namespace: ExpressionLike, + + pub name: ExpressionLike, + + pub loc: Option, + + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct JSXAttribute { + pub name: ExpressionLike, + + pub value: ExpressionLike, + + pub loc: Option, + + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct JSXExpressionContainer { + expression: ExpressionLike, + + pub loc: Option, + + #[serde(default)] + pub range: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct JSXText { + value: String, + raw: String, + + pub loc: Option, + + #[serde(default)] + pub range: Option, +} + +#[cfg(test)] +mod tests { + use super::*; + use insta::{assert_snapshot, glob}; + use serde_json; + + #[test] + fn for_statement() { + let source = include_str!("for-statement.json"); + let ast: Program = serde_json::from_str(&source).unwrap(); + println!("deserialized:\n{:#?}", ast); + let serialized = serde_json::to_string_pretty(&ast).unwrap(); + println!("serialized:\n{}", serialized); + } + + #[test] + fn simple() { + let source = include_str!("simple.json"); + let ast: Program = serde_json::from_str(&source).unwrap(); + println!("deserialized:\n{:#?}", ast); + let serialized = serde_json::to_string_pretty(&ast).unwrap(); + println!("serialized:\n{}", serialized); + } + + /// TODO: enable once this deserializes + fn _kitchen_sink() { + let source = include_str!("kitchen-sink.json"); + let ast: Program = match serde_json::from_str(&source) { + Ok(ast) => ast, + Err(err) => panic!("{:#?}", err), + }; + println!("deserialized:\n{:#?}", ast); + let serialized = serde_json::to_string_pretty(&ast).unwrap(); + println!("serialized:\n{}", serialized); + } + + #[test] + fn import() { + let source = include_str!("import.json"); + let ast: Program = serde_json::from_str(&source).unwrap(); + println!("deserialized:\n{:#?}", ast); + let serialized = serde_json::to_string_pretty(&ast).unwrap(); + println!("serialized:\n{}", serialized); + } + + #[test] + fn test() { + let source = include_str!("test.json"); + let ast: Program = serde_json::from_str(&source).unwrap(); + println!("deserialized:\n{:#?}", ast); + let serialized = serde_json::to_string_pretty(&ast).unwrap(); + println!("serialized:\n{}", serialized); + } + + #[test] + fn fixtures() { + glob!("fixtures/**.json", |path| { + let input = std::fs::read_to_string(path).unwrap(); + let ast: Program = serde_json::from_str(&input).unwrap(); + let serialized = serde_json::to_string_pretty(&ast).unwrap(); + assert_snapshot!(format!("Input:\n{input}\n\nOutput:\n{serialized}")); + }); + } +} diff --git a/compiler/forget/crates/estree/src/range.rs b/compiler/forget/crates/estree/src/range.rs new file mode 100644 index 0000000000..e3d06a259b --- /dev/null +++ b/compiler/forget/crates/estree/src/range.rs @@ -0,0 +1,9 @@ +use std::num::NonZeroU32; + +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct SourceRange { + pub start: u32, + pub end: NonZeroU32, +} diff --git a/compiler/forget/crates/estree/src/simple.json b/compiler/forget/crates/estree/src/simple.json deleted file mode 100644 index 4a1de32d5d..0000000000 --- a/compiler/forget/crates/estree/src/simple.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "type": "Program", - "loc": { - "source": null, - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 3, - "column": 1 - } - }, - "range": [ - 0, - 51 - ], - "body": [ - { - "type": "FunctionDeclaration", - "loc": { - "source": null, - "start": { - "line": 1, - "column": 0 - }, - "end": { - "line": 3, - "column": 1 - } - }, - "range": [ - 0, - 51 - ], - "id": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 1, - "column": 9 - }, - "end": { - "line": 1, - "column": 18 - } - }, - "range": [ - 9, - 18 - ], - "name": "Component", - "typeAnnotation": null, - "optional": false - }, - "params": [ - { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 1, - "column": 19 - }, - "end": { - "line": 1, - "column": 24 - } - }, - "range": [ - 19, - 24 - ], - "name": "props", - "typeAnnotation": null, - "optional": false - } - ], - "body": { - "type": "BlockStatement", - "loc": { - "source": null, - "start": { - "line": 1, - "column": 26 - }, - "end": { - "line": 3, - "column": 1 - } - }, - "range": [ - 26, - 51 - ], - "body": [ - { - "type": "ReturnStatement", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 2 - }, - "end": { - "line": 2, - "column": 21 - } - }, - "range": [ - 30, - 49 - ], - "argument": { - "type": "MemberExpression", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 9 - }, - "end": { - "line": 2, - "column": 20 - } - }, - "range": [ - 37, - 48 - ], - "object": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 9 - }, - "end": { - "line": 2, - "column": 14 - } - }, - "range": [ - 37, - 42 - ], - "name": "props", - "typeAnnotation": null, - "optional": false - }, - "property": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 15 - }, - "end": { - "line": 2, - "column": 20 - } - }, - "range": [ - 43, - 48 - ], - "name": "value", - "typeAnnotation": null, - "optional": false - }, - "computed": false - } - } - ] - }, - "async": false, - "generator": false, - "predicate": null, - "expression": false, - "returnType": null, - "typeParameters": null - } - ], - "comments": [], - "errors": [] - } \ No newline at end of file diff --git a/compiler/forget/crates/estree/src/snapshots/estree__tests__fixtures@for-statement.json.snap b/compiler/forget/crates/estree/src/snapshots/estree__tests__fixtures@for-statement.json.snap index 8a7f225260..afffb846b6 100644 --- a/compiler/forget/crates/estree/src/snapshots/estree__tests__fixtures@for-statement.json.snap +++ b/compiler/forget/crates/estree/src/snapshots/estree__tests__fixtures@for-statement.json.snap @@ -535,7 +535,6 @@ Input: Output: { - "sourceType": "script", "body": [ { "type": "FunctionDeclaration", @@ -580,13 +579,11 @@ Output: } } ], - "generator": false, - "async": false, "body": { - "type": "BlockStatement", "body": [ { "type": "VariableDeclaration", + "kind": "let", "declarations": [ { "id": { @@ -611,8 +608,11 @@ Output: }, "init": { "type": "Literal", - "value": 0, + "value": { + "Number": 0 + }, "raw": "0", + "regex": null, "loc": { "source": null, "start": { @@ -646,7 +646,6 @@ Output: } } ], - "kind": "let", "loc": { "source": null, "start": { @@ -666,7 +665,7 @@ Output: { "type": "ForStatement", "init": { - "type": "VariableDeclaration", + "kind": "let", "declarations": [ { "id": { @@ -691,8 +690,11 @@ Output: }, "init": { "type": "Literal", - "value": 0, + "value": { + "Number": 0 + }, "raw": "0", + "regex": null, "loc": { "source": null, "start": { @@ -726,7 +728,6 @@ Output: } } ], - "kind": "let", "loc": { "source": null, "start": { @@ -745,7 +746,6 @@ Output: }, "test": { "type": "BinaryExpression", - "operator": "<", "left": { "type": "Identifier", "name": "i", @@ -766,10 +766,14 @@ Output: "end": 60 } }, + "operator": "<", "right": { "type": "Literal", - "value": 10, + "value": { + "Number": 10 + }, "raw": "10", + "regex": null, "loc": { "source": null, "start": { @@ -906,7 +910,6 @@ Output: "end": 84 } }, - "directive": null, "loc": { "source": null, "start": { @@ -1028,7 +1031,6 @@ Output: } } ], - "comments": [], "loc": { "source": null, "start": { diff --git a/compiler/forget/crates/estree/src/test.json b/compiler/forget/crates/estree/src/test.json deleted file mode 100644 index 8804bc20d9..0000000000 --- a/compiler/forget/crates/estree/src/test.json +++ /dev/null @@ -1,351 +0,0 @@ -{ - "type": "Program", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 0 - }, - "end": { - "line": 4, - "column": 1 - } - }, - "body": [ - { - "type": "FunctionDeclaration", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 0 - }, - "end": { - "line": 4, - "column": 1 - } - }, - "id": { - "type": "Identifier", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 9 - }, - "end": { - "line": 2, - "column": 12 - } - }, - "name": "foo", - "typeAnnotation": null, - "optional": false, - "range": [ - 10, - 13 - ] - }, - "params": [], - "body": { - "type": "BlockStatement", - "loc": { - "source": null, - "start": { - "line": 2, - "column": 15 - }, - "end": { - "line": 4, - "column": 1 - } - }, - "body": [ - { - "type": "ReturnStatement", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 2 - }, - "end": { - "line": 3, - "column": 36 - } - }, - "argument": { - "type": "JSXElement", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 9 - }, - "end": { - "line": 3, - "column": 36 - } - }, - "openingElement": { - "type": "JSXOpeningElement", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 9 - }, - "end": { - "line": 3, - "column": 26 - } - }, - "name": { - "type": "JSXMemberExpression", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 10 - }, - "end": { - "line": 3, - "column": 17 - } - }, - "object": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 10 - }, - "end": { - "line": 3, - "column": 13 - } - }, - "name": "Foo", - "range": [ - 28, - 31 - ] - }, - "property": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 14 - }, - "end": { - "line": 3, - "column": 17 - } - }, - "name": "Bar", - "range": [ - 32, - 35 - ] - }, - "range": [ - 28, - 35 - ] - }, - "attributes": [ - { - "type": "JSXAttribute", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 18 - }, - "end": { - "line": 3, - "column": 24 - } - }, - "name": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 18 - }, - "end": { - "line": 3, - "column": 19 - } - }, - "name": "a", - "range": [ - 36, - 37 - ] - }, - "value": { - "type": "JSXExpressionContainer", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 20 - }, - "end": { - "line": 3, - "column": 24 - } - }, - "expression": { - "type": "Literal", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 21 - }, - "end": { - "line": 3, - "column": 23 - } - }, - "value": 10, - "range": [ - 39, - 41 - ], - "raw": "10" - }, - "range": [ - 38, - 42 - ] - }, - "range": [ - 36, - 42 - ] - } - ], - "selfClosing": false, - "range": [ - 27, - 44 - ] - }, - "children": [], - "closingElement": { - "type": "JSXClosingElement", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 26 - }, - "end": { - "line": 3, - "column": 36 - } - }, - "name": { - "type": "JSXMemberExpression", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 28 - }, - "end": { - "line": 3, - "column": 35 - } - }, - "object": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 28 - }, - "end": { - "line": 3, - "column": 31 - } - }, - "name": "Foo", - "range": [ - 46, - 49 - ] - }, - "property": { - "type": "JSXIdentifier", - "loc": { - "source": null, - "start": { - "line": 3, - "column": 32 - }, - "end": { - "line": 3, - "column": 35 - } - }, - "name": "Bar", - "range": [ - 50, - 53 - ] - }, - "range": [ - 46, - 53 - ] - }, - "range": [ - 44, - 54 - ] - }, - "range": [ - 27, - 54 - ] - }, - "range": [ - 20, - 54 - ] - } - ], - "range": [ - 16, - 56 - ] - }, - "typeParameters": null, - "returnType": null, - "predicate": null, - "generator": false, - "async": false, - "range": [ - 1, - 56 - ] - } - ], - "comments": [], - "interpreter": null, - "range": [ - 1, - 56 - ], - "sourceType": "script" - } \ No newline at end of file