mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[rust] estree codegen for improved serialization
This is meant to replace the initial `estree` crate with a version that is
generated from a JSON description of ESTree. The idea is to make it easy to
experiment with slightly different representations to balance ergonomic usage of
the data at runtime with serialization compatible with ESTree spec. The JSON
schema looks like this (somewhat abbreviated):
```
{
// Objects are struct types that don't have a `type` and can't appear as an enum
variant
objects: {
Position: {
line: {type: "NonZeroU32"},
column: {type: "u32"}
},
...
},
// Nodes are struct types with a `type` and which can appear as enum variants
(statements, expressions, patterns, etc)
nodes: {
ArrayExpression: {
elements: {
type: "Expression",
plural: true,
nullable_item: true,
}
}
...
},
// Categories of nodes with multiple variants, represented as enums.
// Can be recursive, eg ForInit can be VariableDeclaration or Expression,
// where Expression is also an enum
enums: {
Expression: [
"ArrayExpression",
...
]
},
// Simple enums which have a corresponding string value. Used primarily for
operators (binary/unary/logical/etc)
// but also for things like variable declaration kind (var/const/let)
operators: {
BinaryOperator: {
Plus: "+",
Instanceof: "instanceof",
}
}
}
```
The core estree files are now generated using Cargo's build script mechanism.
Right now i only defined the types and fields from ES5, so i'll have to flush
out the rest of the modern JS spec and extensions like JSX, TypeScript, and
Flow. But already the for-statement example works, showing that this approach
can handle complex cases such as unions of types or other unions (ForStatement
initializer is tricky bc it can be a VariableDeclaration or an Expression - that
works now!).
This is still WIP a bit - now that the ESTree definition is more precise i can
go back and clean up some other code (have to, because the swc -> estree
conversion needs some tweaks now).
This commit is contained in:
Generated
+28
-4
@@ -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",
|
||||
|
||||
@@ -6,6 +6,7 @@ members = [
|
||||
"crates/hir",
|
||||
"crates/swc-demo",
|
||||
"crates/estree",
|
||||
"crates/estree-codegen",
|
||||
"crates/estree-swc",
|
||||
]
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -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<String, Object>,
|
||||
pub nodes: IndexMap<String, Node>,
|
||||
pub enums: IndexMap<String, Enum>,
|
||||
pub operators: IndexMap<String, Operator>,
|
||||
}
|
||||
|
||||
impl Grammar {
|
||||
pub fn codegen(self) -> TokenStream {
|
||||
let Self {
|
||||
objects,
|
||||
nodes,
|
||||
enums,
|
||||
operators,
|
||||
} = self;
|
||||
|
||||
let nodelike: HashSet<String> =
|
||||
// nodes.keys().cloned().chain(enums.keys().cloned()).collect();
|
||||
Default::default();
|
||||
|
||||
let enum_names: HashSet<String> = 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<String, Field>,
|
||||
}
|
||||
|
||||
impl Object {
|
||||
pub fn codegen(&self, name: &str, nodes: &HashSet<String>) -> 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<String, Field>,
|
||||
}
|
||||
|
||||
impl Node {
|
||||
pub fn codegen(&self, name: &str, nodes: &HashSet<String>) -> 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<SourceLocation>,
|
||||
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
|
||||
// impl #name {
|
||||
// pub fn from_node(node: Node) -> Option<Box<Self>> {
|
||||
// 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<String>) -> 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<String>) -> 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<String>,
|
||||
}
|
||||
|
||||
impl Enum {
|
||||
pub fn codegen(&self, name: &str, enums: &HashSet<String>) -> 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<Self> {
|
||||
// #(#from_node_matches)*
|
||||
// None
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(transparent)]
|
||||
pub struct Operator {
|
||||
pub variants: IndexMap<String, String>,
|
||||
}
|
||||
|
||||
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<Self, Self::Err> {
|
||||
match s {
|
||||
#(#fromstr_matches,)*
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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": "||"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
mod codegen;
|
||||
|
||||
pub use codegen::estree;
|
||||
@@ -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" }
|
||||
@@ -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();
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Binding;
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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<String>,
|
||||
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<Identifier>,
|
||||
params: Vec<Pattern>,
|
||||
body: Option<BlockStatement>,
|
||||
}
|
||||
#[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<Binding>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Literal {
|
||||
value: JsValue,
|
||||
#[serde(default)]
|
||||
raw: Option<String>,
|
||||
#[serde(default)]
|
||||
regex: Option<RegExpValue>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Program {
|
||||
body: Vec<Statement>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct ExpressionStatement {
|
||||
expression: Expression,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct BlockStatement {
|
||||
body: Vec<Statement>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct EmptyStatement {
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct DebuggerStatement {
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct WithStatement {
|
||||
object: Expression,
|
||||
body: Statement,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct ReturnStatement {
|
||||
argument: Option<Expression>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct LabeledStatement {
|
||||
label: Identifier,
|
||||
body: Statement,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct BreakStatement {
|
||||
label: Option<Identifier>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct ContinueStatement {
|
||||
label: Option<Identifier>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct IfStatement {
|
||||
test: Expression,
|
||||
consequent: Statement,
|
||||
alternate: Option<Statement>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct SwitchStatement {
|
||||
discriminant: Expression,
|
||||
cases: Vec<SwitchCase>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct SwitchCase {
|
||||
test: Option<Expression>,
|
||||
consequent: Vec<Statement>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct ThrowStatement {
|
||||
argument: Expression,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct TryStatement {
|
||||
block: BlockStatement,
|
||||
handler: Option<CatchClause>,
|
||||
finalizer: Option<BlockStatement>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct CatchClause {
|
||||
param: Pattern,
|
||||
body: BlockStatement,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct WhileStatement {
|
||||
test: Expression,
|
||||
body: Statement,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct DoWhileStatement {
|
||||
body: Statement,
|
||||
test: Expression,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct ForStatement {
|
||||
init: Option<ForInit>,
|
||||
test: Option<Expression>,
|
||||
update: Option<Expression>,
|
||||
body: Statement,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct ForInStatement {
|
||||
left: ForInInit,
|
||||
right: Expression,
|
||||
body: Statement,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct FunctionDeclaration {
|
||||
#[serde(flatten)]
|
||||
function: Function,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct VariableDeclaration {
|
||||
kind: VariableDeclarationKind,
|
||||
declarations: Vec<VariableDeclarator>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct VariableDeclarator {
|
||||
id: Pattern,
|
||||
init: Option<Expression>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct ThisExpression {
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct ArrayExpression {
|
||||
elements: Vec<Option<Expression>>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct ObjectExpression {
|
||||
properties: Vec<Property>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Property {
|
||||
key: PropertyKey,
|
||||
value: Expression,
|
||||
kind: PropertyKind,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct FunctionExpression {
|
||||
#[serde(flatten)]
|
||||
function: Function,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct UnaryExpression {
|
||||
operator: UnaryOperator,
|
||||
prefix: bool,
|
||||
argument: Expression,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct UpdateExpression {
|
||||
operator: UpdateOperator,
|
||||
argument: Expression,
|
||||
prefix: bool,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct BinaryExpression {
|
||||
left: Expression,
|
||||
operator: BinaryOperator,
|
||||
right: Expression,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct AssignmentExpression {
|
||||
operator: AssignmentOperator,
|
||||
left: AssignmentTarget,
|
||||
right: Expression,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct LogicalExpression {
|
||||
operator: LogicalOperator,
|
||||
left: Expression,
|
||||
right: Expression,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct MemberExpression {
|
||||
object: Expression,
|
||||
property: Expression,
|
||||
computed: bool,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct ConditionalExpression {
|
||||
test: Expression,
|
||||
alternate: Expression,
|
||||
consequent: Expression,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct CallExpression {
|
||||
callee: Expression,
|
||||
arguments: Vec<Expression>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct NewExpression {
|
||||
callee: Expression,
|
||||
arguments: Vec<Expression>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct SequenceExpression {
|
||||
expressions: Vec<Expression>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum Statement {
|
||||
BlockStatement(Box<BlockStatement>),
|
||||
BreakStatement(Box<BreakStatement>),
|
||||
ContinueStatement(Box<ContinueStatement>),
|
||||
DebuggerStatement(Box<DebuggerStatement>),
|
||||
DoWhileStatement(Box<DoWhileStatement>),
|
||||
EmptyStatement(Box<EmptyStatement>),
|
||||
ExpressionStatement(Box<ExpressionStatement>),
|
||||
ForInStatement(Box<ForInStatement>),
|
||||
ForStatement(Box<ForStatement>),
|
||||
FunctionDeclaration(Box<FunctionDeclaration>),
|
||||
IfStatement(Box<IfStatement>),
|
||||
LabeledStatement(Box<LabeledStatement>),
|
||||
ReturnStatement(Box<ReturnStatement>),
|
||||
SwitchStatement(Box<SwitchStatement>),
|
||||
ThrowStatement(Box<ThrowStatement>),
|
||||
TryStatement(Box<TryStatement>),
|
||||
VariableDeclaration(Box<VariableDeclaration>),
|
||||
WhileStatement(Box<WhileStatement>),
|
||||
WithStatement(Box<WithStatement>),
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum Expression {
|
||||
ArrayExpression(Box<ArrayExpression>),
|
||||
AssignmentExpression(Box<AssignmentExpression>),
|
||||
BinaryExpression(Box<BinaryExpression>),
|
||||
CallExpression(Box<CallExpression>),
|
||||
ConditionalExpression(Box<ConditionalExpression>),
|
||||
FunctionExpression(Box<FunctionExpression>),
|
||||
Identifier(Box<Identifier>),
|
||||
Literal(Box<Literal>),
|
||||
LogicalExpression(Box<LogicalExpression>),
|
||||
MemberExpression(Box<MemberExpression>),
|
||||
NewExpression(Box<NewExpression>),
|
||||
ObjectExpression(Box<ObjectExpression>),
|
||||
SequenceExpression(Box<SequenceExpression>),
|
||||
ThisExpression(Box<ThisExpression>),
|
||||
UnaryExpression(Box<UnaryExpression>),
|
||||
UpdateExpression(Box<UpdateExpression>),
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum Pattern {
|
||||
Identifier(Box<Identifier>),
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(untagged)]
|
||||
pub enum ForInit {
|
||||
Expression(Expression),
|
||||
VariableDeclaration(Box<VariableDeclaration>),
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(untagged)]
|
||||
pub enum ForInInit {
|
||||
Pattern(Pattern),
|
||||
VariableDeclaration(Box<VariableDeclaration>),
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum PropertyKey {
|
||||
Identifier(Box<Identifier>),
|
||||
Literal(Box<Literal>),
|
||||
}
|
||||
#[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<Self, Self::Err> {
|
||||
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<Self, Self::Err> {
|
||||
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<Self, Self::Err> {
|
||||
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<Self, Self::Err> {
|
||||
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<Self, Self::Err> {
|
||||
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<Self, Self::Err> {
|
||||
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<Self, Self::Err> {
|
||||
match s {
|
||||
"&&" => Ok(Self::And),
|
||||
"??" => Ok(Self::NullCoalescing),
|
||||
"||" => Ok(Self::Or),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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<u32> for Number {
|
||||
fn from(value: u32) -> Self {
|
||||
Number(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for Number {
|
||||
fn from(value: u64) -> Self {
|
||||
Number(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f64> for Number {
|
||||
fn from(value: f64) -> Self {
|
||||
Number(value.to_bits())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Number> for f64 {
|
||||
fn from(value: Number) -> Self {
|
||||
f64::from_bits(value.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for JsValue {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: D) -> Result<JsValue, D::Error>
|
||||
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<E>(self, value: bool) -> Result<JsValue, E> {
|
||||
Ok(JsValue::Bool(value))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_i64<E>(self, value: i64) -> Result<JsValue, E> {
|
||||
if value < u32::MAX as i64 {
|
||||
Ok(JsValue::Number((value as u32).into()))
|
||||
} else {
|
||||
panic!("Invalid number")
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_u64<E>(self, value: u64) -> Result<JsValue, E> {
|
||||
Ok(JsValue::Number(value.into()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_f64<E>(self, value: f64) -> Result<JsValue, E> {
|
||||
Ok(JsValue::Number(value.into()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_str<E>(self, value: &str) -> Result<JsValue, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
self.visit_string(String::from(value))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_string<E>(self, value: String) -> Result<JsValue, E> {
|
||||
Ok(JsValue::String(value))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_none<E>(self) -> Result<JsValue, E> {
|
||||
Ok(JsValue::Null)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_some<D>(self, deserializer: D) -> Result<JsValue, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
Deserialize::deserialize(deserializer)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(self) -> Result<JsValue, E> {
|
||||
Ok(JsValue::Undefined)
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_any(ValueVisitor)
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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,
|
||||
}
|
||||
@@ -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": []
|
||||
}
|
||||
+15
-13
@@ -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": {
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
Reference in New Issue
Block a user