mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[rust][wip] Codegen conversion from HermesParser (C++)
This commit is contained in:
Generated
+1
@@ -528,6 +528,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"forget_diagnostics",
|
||||
"forget_estree",
|
||||
"forget_estree_codegen",
|
||||
"hermes",
|
||||
"juno_support",
|
||||
]
|
||||
|
||||
@@ -65,4 +65,8 @@ impl<'ast> Visitor<'ast> for ContextVisitor<'ast> {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_literal(&mut self, _literal: &'ast forget_estree::Literal) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use std::num::NonZeroU32;
|
||||
use serde::ser::{Serializer, SerializeMap};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use crate::{JsValue, Binding, SourceRange};
|
||||
use crate::{JsValue, Binding, SourceRange, Number};
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct SourceLocation {
|
||||
@@ -19,6 +19,14 @@ pub struct Position {
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Class {
|
||||
pub id: Option<Identifier>,
|
||||
#[serde(rename = "superClass")]
|
||||
pub super_class: Option<Expression>,
|
||||
pub body: ClassBody,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Function {
|
||||
pub id: Option<Identifier>,
|
||||
pub params: Vec<Pattern>,
|
||||
@@ -101,6 +109,88 @@ impl Serialize for Literal {
|
||||
}
|
||||
}
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
pub struct NumericLiteral {
|
||||
pub value: Number,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
impl Serialize for NumericLiteral {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut state = serializer.serialize_map(None)?;
|
||||
state.serialize_entry("type", "NumericLiteral")?;
|
||||
state.serialize_entry("value", &self.value)?;
|
||||
state.serialize_entry("loc", &self.loc)?;
|
||||
state.serialize_entry("range", &self.range)?;
|
||||
state.end()
|
||||
}
|
||||
}
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
pub struct BooleanLiteral {
|
||||
pub value: bool,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
impl Serialize for BooleanLiteral {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut state = serializer.serialize_map(None)?;
|
||||
state.serialize_entry("type", "BooleanLiteral")?;
|
||||
state.serialize_entry("value", &self.value)?;
|
||||
state.serialize_entry("loc", &self.loc)?;
|
||||
state.serialize_entry("range", &self.range)?;
|
||||
state.end()
|
||||
}
|
||||
}
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
pub struct NullLiteral {
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
impl Serialize for NullLiteral {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut state = serializer.serialize_map(None)?;
|
||||
state.serialize_entry("type", "NullLiteral")?;
|
||||
state.serialize_entry("loc", &self.loc)?;
|
||||
state.serialize_entry("range", &self.range)?;
|
||||
state.end()
|
||||
}
|
||||
}
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
pub struct StringLiteral {
|
||||
pub value: String,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
impl Serialize for StringLiteral {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut state = serializer.serialize_map(None)?;
|
||||
state.serialize_entry("type", "StringLiteral")?;
|
||||
state.serialize_entry("value", &self.value)?;
|
||||
state.serialize_entry("loc", &self.loc)?;
|
||||
state.serialize_entry("range", &self.range)?;
|
||||
state.end()
|
||||
}
|
||||
}
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
pub struct Program {
|
||||
pub body: Vec<ModuleItem>,
|
||||
#[serde(rename = "sourceType")]
|
||||
@@ -610,32 +700,6 @@ impl Serialize for FunctionDeclaration {
|
||||
}
|
||||
}
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
pub struct Class {
|
||||
pub id: Option<Identifier>,
|
||||
#[serde(rename = "superClass")]
|
||||
pub super_class: Option<Expression>,
|
||||
pub body: ClassBody,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
impl Serialize for Class {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut state = serializer.serialize_map(None)?;
|
||||
state.serialize_entry("type", "Class")?;
|
||||
state.serialize_entry("id", &self.id)?;
|
||||
state.serialize_entry("superClass", &self.super_class)?;
|
||||
state.serialize_entry("body", &self.body)?;
|
||||
state.serialize_entry("loc", &self.loc)?;
|
||||
state.serialize_entry("range", &self.range)?;
|
||||
state.end()
|
||||
}
|
||||
}
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
pub struct ClassDeclaration {
|
||||
#[serde(flatten)]
|
||||
pub class: Class,
|
||||
@@ -1062,9 +1126,6 @@ pub struct MemberExpression {
|
||||
pub property: Expression,
|
||||
#[serde(rename = "computed")]
|
||||
pub is_computed: bool,
|
||||
#[serde(rename = "optional")]
|
||||
#[serde(default)]
|
||||
pub is_optional: bool,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
@@ -1080,7 +1141,6 @@ impl Serialize for MemberExpression {
|
||||
state.serialize_entry("object", &self.object)?;
|
||||
state.serialize_entry("property", &self.property)?;
|
||||
state.serialize_entry("computed", &self.is_computed)?;
|
||||
state.serialize_entry("optional", &self.is_optional)?;
|
||||
state.serialize_entry("loc", &self.loc)?;
|
||||
state.serialize_entry("range", &self.range)?;
|
||||
state.end()
|
||||
@@ -1115,9 +1175,6 @@ impl Serialize for ConditionalExpression {
|
||||
pub struct CallExpression {
|
||||
pub callee: ExpressionOrSuper,
|
||||
pub arguments: Vec<ExpressionOrSpread>,
|
||||
#[serde(rename = "optional")]
|
||||
#[serde(default)]
|
||||
pub is_optional: bool,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
@@ -1132,7 +1189,6 @@ impl Serialize for CallExpression {
|
||||
state.serialize_entry("type", "CallExpression")?;
|
||||
state.serialize_entry("callee", &self.callee)?;
|
||||
state.serialize_entry("arguments", &self.arguments)?;
|
||||
state.serialize_entry("optional", &self.is_optional)?;
|
||||
state.serialize_entry("loc", &self.loc)?;
|
||||
state.serialize_entry("range", &self.range)?;
|
||||
state.end()
|
||||
@@ -1250,7 +1306,7 @@ impl Serialize for YieldExpression {
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
pub struct ImportDeclaration {
|
||||
pub specifiers: Vec<ImportDeclarationSpecifier>,
|
||||
pub source: Literal,
|
||||
pub source: _Literal,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
@@ -1339,7 +1395,7 @@ impl Serialize for ImportNamespaceSpecifier {
|
||||
pub struct ExportNamedDeclaration {
|
||||
pub declaration: Option<Declaration>,
|
||||
pub specifiers: Vec<ExportSpecifier>,
|
||||
pub source: Option<Literal>,
|
||||
pub source: Option<_Literal>,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
@@ -1404,7 +1460,7 @@ impl Serialize for ExportDefaultDeclaration {
|
||||
}
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
pub struct ExportAllDeclaration {
|
||||
pub source: Literal,
|
||||
pub source: _Literal,
|
||||
#[serde(default)]
|
||||
pub exported: Option<Identifier>,
|
||||
#[serde(default)]
|
||||
@@ -1704,7 +1760,7 @@ pub struct JSXFragment {
|
||||
pub opening_fragment: JSXOpeningFragment,
|
||||
pub children: Vec<JSXChildItem>,
|
||||
#[serde(rename = "closingFragment")]
|
||||
pub closing_fragment: Option<JSXClosingFragment>,
|
||||
pub closing_fragment: JSXClosingFragment,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
@@ -2013,7 +2069,7 @@ impl Serialize for ChainExpression {
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
pub struct OptionalMemberExpression {
|
||||
pub object: Expression,
|
||||
pub property: Identifier,
|
||||
pub property: Expression,
|
||||
#[serde(rename = "computed")]
|
||||
pub is_computed: bool,
|
||||
#[serde(rename = "optional")]
|
||||
@@ -2328,6 +2384,7 @@ pub enum Expression {
|
||||
AssignmentExpression(Box<AssignmentExpression>),
|
||||
AwaitExpression(Box<AwaitExpression>),
|
||||
BinaryExpression(Box<BinaryExpression>),
|
||||
BooleanLiteral(Box<BooleanLiteral>),
|
||||
CallExpression(Box<CallExpression>),
|
||||
ChainExpression(Box<ChainExpression>),
|
||||
ClassExpression(Box<ClassExpression>),
|
||||
@@ -2341,10 +2398,13 @@ pub enum Expression {
|
||||
MemberExpression(Box<MemberExpression>),
|
||||
MetaProperty(Box<MetaProperty>),
|
||||
NewExpression(Box<NewExpression>),
|
||||
NullLiteral(Box<NullLiteral>),
|
||||
NumericLiteral(Box<NumericLiteral>),
|
||||
ObjectExpression(Box<ObjectExpression>),
|
||||
OptionalCallExpression(Box<OptionalCallExpression>),
|
||||
OptionalMemberExpression(Box<OptionalMemberExpression>),
|
||||
SequenceExpression(Box<SequenceExpression>),
|
||||
StringLiteral(Box<StringLiteral>),
|
||||
TaggedTemplateExpression(Box<TaggedTemplateExpression>),
|
||||
TemplateLiteral(Box<TemplateLiteral>),
|
||||
ThisExpression(Box<ThisExpression>),
|
||||
@@ -2359,6 +2419,7 @@ enum __ExpressionTag {
|
||||
AssignmentExpression,
|
||||
AwaitExpression,
|
||||
BinaryExpression,
|
||||
BooleanLiteral,
|
||||
CallExpression,
|
||||
ChainExpression,
|
||||
ClassExpression,
|
||||
@@ -2372,10 +2433,13 @@ enum __ExpressionTag {
|
||||
MemberExpression,
|
||||
MetaProperty,
|
||||
NewExpression,
|
||||
NullLiteral,
|
||||
NumericLiteral,
|
||||
ObjectExpression,
|
||||
OptionalCallExpression,
|
||||
OptionalMemberExpression,
|
||||
SequenceExpression,
|
||||
StringLiteral,
|
||||
TaggedTemplateExpression,
|
||||
TemplateLiteral,
|
||||
ThisExpression,
|
||||
@@ -2435,6 +2499,14 @@ impl<'de> serde::Deserialize<'de> for Expression {
|
||||
)?;
|
||||
Ok(Expression::BinaryExpression(node))
|
||||
}
|
||||
__ExpressionTag::BooleanLiteral => {
|
||||
let node: Box<BooleanLiteral> = <Box<
|
||||
BooleanLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(Expression::BooleanLiteral(node))
|
||||
}
|
||||
__ExpressionTag::CallExpression => {
|
||||
let node: Box<CallExpression> = <Box<
|
||||
CallExpression,
|
||||
@@ -2539,6 +2611,22 @@ impl<'de> serde::Deserialize<'de> for Expression {
|
||||
)?;
|
||||
Ok(Expression::NewExpression(node))
|
||||
}
|
||||
__ExpressionTag::NullLiteral => {
|
||||
let node: Box<NullLiteral> = <Box<
|
||||
NullLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(Expression::NullLiteral(node))
|
||||
}
|
||||
__ExpressionTag::NumericLiteral => {
|
||||
let node: Box<NumericLiteral> = <Box<
|
||||
NumericLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(Expression::NumericLiteral(node))
|
||||
}
|
||||
__ExpressionTag::ObjectExpression => {
|
||||
let node: Box<ObjectExpression> = <Box<
|
||||
ObjectExpression,
|
||||
@@ -2571,6 +2659,14 @@ impl<'de> serde::Deserialize<'de> for Expression {
|
||||
)?;
|
||||
Ok(Expression::SequenceExpression(node))
|
||||
}
|
||||
__ExpressionTag::StringLiteral => {
|
||||
let node: Box<StringLiteral> = <Box<
|
||||
StringLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(Expression::StringLiteral(node))
|
||||
}
|
||||
__ExpressionTag::TaggedTemplateExpression => {
|
||||
let node: Box<TaggedTemplateExpression> = <Box<
|
||||
TaggedTemplateExpression,
|
||||
@@ -2624,6 +2720,78 @@ impl<'de> serde::Deserialize<'de> for Expression {
|
||||
}
|
||||
#[derive(Serialize, Clone, Debug)]
|
||||
#[serde(untagged)]
|
||||
pub enum _Literal {
|
||||
BooleanLiteral(Box<BooleanLiteral>),
|
||||
Literal(Box<Literal>),
|
||||
NullLiteral(Box<NullLiteral>),
|
||||
NumericLiteral(Box<NumericLiteral>),
|
||||
StringLiteral(Box<StringLiteral>),
|
||||
}
|
||||
#[derive(Deserialize, Debug)]
|
||||
enum ___LiteralTag {
|
||||
Literal,
|
||||
BooleanLiteral,
|
||||
NullLiteral,
|
||||
StringLiteral,
|
||||
NumericLiteral,
|
||||
}
|
||||
impl<'de> serde::Deserialize<'de> for _Literal {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let tagged = serde::Deserializer::deserialize_any(
|
||||
deserializer,
|
||||
serde::__private::de::TaggedContentVisitor::<
|
||||
___LiteralTag,
|
||||
>::new("type", "_Literal"),
|
||||
)?;
|
||||
match tagged.0 {
|
||||
___LiteralTag::Literal => {
|
||||
let node: Box<Literal> = <Box<
|
||||
Literal,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(_Literal::Literal(node))
|
||||
}
|
||||
___LiteralTag::BooleanLiteral => {
|
||||
let node: Box<BooleanLiteral> = <Box<
|
||||
BooleanLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(_Literal::BooleanLiteral(node))
|
||||
}
|
||||
___LiteralTag::NullLiteral => {
|
||||
let node: Box<NullLiteral> = <Box<
|
||||
NullLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(_Literal::NullLiteral(node))
|
||||
}
|
||||
___LiteralTag::StringLiteral => {
|
||||
let node: Box<StringLiteral> = <Box<
|
||||
StringLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(_Literal::StringLiteral(node))
|
||||
}
|
||||
___LiteralTag::NumericLiteral => {
|
||||
let node: Box<NumericLiteral> = <Box<
|
||||
NumericLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(_Literal::NumericLiteral(node))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Serialize, Clone, Debug)]
|
||||
#[serde(untagged)]
|
||||
pub enum Declaration {
|
||||
ClassDeclaration(Box<ClassDeclaration>),
|
||||
FunctionDeclaration(Box<FunctionDeclaration>),
|
||||
@@ -3066,6 +3234,7 @@ enum __ExpressionOrSuperTag {
|
||||
AssignmentExpression,
|
||||
AwaitExpression,
|
||||
BinaryExpression,
|
||||
BooleanLiteral,
|
||||
CallExpression,
|
||||
ChainExpression,
|
||||
ClassExpression,
|
||||
@@ -3079,10 +3248,13 @@ enum __ExpressionOrSuperTag {
|
||||
MemberExpression,
|
||||
MetaProperty,
|
||||
NewExpression,
|
||||
NullLiteral,
|
||||
NumericLiteral,
|
||||
ObjectExpression,
|
||||
OptionalCallExpression,
|
||||
OptionalMemberExpression,
|
||||
SequenceExpression,
|
||||
StringLiteral,
|
||||
TaggedTemplateExpression,
|
||||
TemplateLiteral,
|
||||
ThisExpression,
|
||||
@@ -3147,6 +3319,14 @@ impl<'de> serde::Deserialize<'de> for ExpressionOrSuper {
|
||||
)?;
|
||||
Ok(ExpressionOrSuper::Expression(Expression::BinaryExpression(node)))
|
||||
}
|
||||
__ExpressionOrSuperTag::BooleanLiteral => {
|
||||
let node: Box<BooleanLiteral> = <Box<
|
||||
BooleanLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(ExpressionOrSuper::Expression(Expression::BooleanLiteral(node)))
|
||||
}
|
||||
__ExpressionOrSuperTag::CallExpression => {
|
||||
let node: Box<CallExpression> = <Box<
|
||||
CallExpression,
|
||||
@@ -3255,6 +3435,22 @@ impl<'de> serde::Deserialize<'de> for ExpressionOrSuper {
|
||||
)?;
|
||||
Ok(ExpressionOrSuper::Expression(Expression::NewExpression(node)))
|
||||
}
|
||||
__ExpressionOrSuperTag::NullLiteral => {
|
||||
let node: Box<NullLiteral> = <Box<
|
||||
NullLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(ExpressionOrSuper::Expression(Expression::NullLiteral(node)))
|
||||
}
|
||||
__ExpressionOrSuperTag::NumericLiteral => {
|
||||
let node: Box<NumericLiteral> = <Box<
|
||||
NumericLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(ExpressionOrSuper::Expression(Expression::NumericLiteral(node)))
|
||||
}
|
||||
__ExpressionOrSuperTag::ObjectExpression => {
|
||||
let node: Box<ObjectExpression> = <Box<
|
||||
ObjectExpression,
|
||||
@@ -3295,6 +3491,14 @@ impl<'de> serde::Deserialize<'de> for ExpressionOrSuper {
|
||||
)?;
|
||||
Ok(ExpressionOrSuper::Expression(Expression::SequenceExpression(node)))
|
||||
}
|
||||
__ExpressionOrSuperTag::StringLiteral => {
|
||||
let node: Box<StringLiteral> = <Box<
|
||||
StringLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(ExpressionOrSuper::Expression(Expression::StringLiteral(node)))
|
||||
}
|
||||
__ExpressionOrSuperTag::TaggedTemplateExpression => {
|
||||
let node: Box<TaggedTemplateExpression> = <Box<
|
||||
TaggedTemplateExpression,
|
||||
@@ -3371,6 +3575,7 @@ enum __ExpressionOrSpreadTag {
|
||||
AssignmentExpression,
|
||||
AwaitExpression,
|
||||
BinaryExpression,
|
||||
BooleanLiteral,
|
||||
CallExpression,
|
||||
ChainExpression,
|
||||
ClassExpression,
|
||||
@@ -3384,10 +3589,13 @@ enum __ExpressionOrSpreadTag {
|
||||
MemberExpression,
|
||||
MetaProperty,
|
||||
NewExpression,
|
||||
NullLiteral,
|
||||
NumericLiteral,
|
||||
ObjectExpression,
|
||||
OptionalCallExpression,
|
||||
OptionalMemberExpression,
|
||||
SequenceExpression,
|
||||
StringLiteral,
|
||||
TaggedTemplateExpression,
|
||||
TemplateLiteral,
|
||||
ThisExpression,
|
||||
@@ -3456,6 +3664,14 @@ impl<'de> serde::Deserialize<'de> for ExpressionOrSpread {
|
||||
)?;
|
||||
Ok(ExpressionOrSpread::Expression(Expression::BinaryExpression(node)))
|
||||
}
|
||||
__ExpressionOrSpreadTag::BooleanLiteral => {
|
||||
let node: Box<BooleanLiteral> = <Box<
|
||||
BooleanLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(ExpressionOrSpread::Expression(Expression::BooleanLiteral(node)))
|
||||
}
|
||||
__ExpressionOrSpreadTag::CallExpression => {
|
||||
let node: Box<CallExpression> = <Box<
|
||||
CallExpression,
|
||||
@@ -3564,6 +3780,22 @@ impl<'de> serde::Deserialize<'de> for ExpressionOrSpread {
|
||||
)?;
|
||||
Ok(ExpressionOrSpread::Expression(Expression::NewExpression(node)))
|
||||
}
|
||||
__ExpressionOrSpreadTag::NullLiteral => {
|
||||
let node: Box<NullLiteral> = <Box<
|
||||
NullLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(ExpressionOrSpread::Expression(Expression::NullLiteral(node)))
|
||||
}
|
||||
__ExpressionOrSpreadTag::NumericLiteral => {
|
||||
let node: Box<NumericLiteral> = <Box<
|
||||
NumericLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(ExpressionOrSpread::Expression(Expression::NumericLiteral(node)))
|
||||
}
|
||||
__ExpressionOrSpreadTag::ObjectExpression => {
|
||||
let node: Box<ObjectExpression> = <Box<
|
||||
ObjectExpression,
|
||||
@@ -3604,6 +3836,14 @@ impl<'de> serde::Deserialize<'de> for ExpressionOrSpread {
|
||||
)?;
|
||||
Ok(ExpressionOrSpread::Expression(Expression::SequenceExpression(node)))
|
||||
}
|
||||
__ExpressionOrSpreadTag::StringLiteral => {
|
||||
let node: Box<StringLiteral> = <Box<
|
||||
StringLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(ExpressionOrSpread::Expression(Expression::StringLiteral(node)))
|
||||
}
|
||||
__ExpressionOrSpreadTag::TaggedTemplateExpression => {
|
||||
let node: Box<TaggedTemplateExpression> = <Box<
|
||||
TaggedTemplateExpression,
|
||||
@@ -3681,6 +3921,7 @@ enum __FunctionBodyTag {
|
||||
AssignmentExpression,
|
||||
AwaitExpression,
|
||||
BinaryExpression,
|
||||
BooleanLiteral,
|
||||
CallExpression,
|
||||
ChainExpression,
|
||||
ClassExpression,
|
||||
@@ -3694,10 +3935,13 @@ enum __FunctionBodyTag {
|
||||
MemberExpression,
|
||||
MetaProperty,
|
||||
NewExpression,
|
||||
NullLiteral,
|
||||
NumericLiteral,
|
||||
ObjectExpression,
|
||||
OptionalCallExpression,
|
||||
OptionalMemberExpression,
|
||||
SequenceExpression,
|
||||
StringLiteral,
|
||||
TaggedTemplateExpression,
|
||||
TemplateLiteral,
|
||||
ThisExpression,
|
||||
@@ -3765,6 +4009,14 @@ impl<'de> serde::Deserialize<'de> for FunctionBody {
|
||||
)?;
|
||||
Ok(FunctionBody::Expression(Expression::BinaryExpression(node)))
|
||||
}
|
||||
__FunctionBodyTag::BooleanLiteral => {
|
||||
let node: Box<BooleanLiteral> = <Box<
|
||||
BooleanLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(FunctionBody::Expression(Expression::BooleanLiteral(node)))
|
||||
}
|
||||
__FunctionBodyTag::CallExpression => {
|
||||
let node: Box<CallExpression> = <Box<
|
||||
CallExpression,
|
||||
@@ -3869,6 +4121,22 @@ impl<'de> serde::Deserialize<'de> for FunctionBody {
|
||||
)?;
|
||||
Ok(FunctionBody::Expression(Expression::NewExpression(node)))
|
||||
}
|
||||
__FunctionBodyTag::NullLiteral => {
|
||||
let node: Box<NullLiteral> = <Box<
|
||||
NullLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(FunctionBody::Expression(Expression::NullLiteral(node)))
|
||||
}
|
||||
__FunctionBodyTag::NumericLiteral => {
|
||||
let node: Box<NumericLiteral> = <Box<
|
||||
NumericLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(FunctionBody::Expression(Expression::NumericLiteral(node)))
|
||||
}
|
||||
__FunctionBodyTag::ObjectExpression => {
|
||||
let node: Box<ObjectExpression> = <Box<
|
||||
ObjectExpression,
|
||||
@@ -3901,6 +4169,14 @@ impl<'de> serde::Deserialize<'de> for FunctionBody {
|
||||
)?;
|
||||
Ok(FunctionBody::Expression(Expression::SequenceExpression(node)))
|
||||
}
|
||||
__FunctionBodyTag::StringLiteral => {
|
||||
let node: Box<StringLiteral> = <Box<
|
||||
StringLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(FunctionBody::Expression(Expression::StringLiteral(node)))
|
||||
}
|
||||
__FunctionBodyTag::TaggedTemplateExpression => {
|
||||
let node: Box<TaggedTemplateExpression> = <Box<
|
||||
TaggedTemplateExpression,
|
||||
@@ -4037,6 +4313,7 @@ enum __ForInitTag {
|
||||
AssignmentExpression,
|
||||
AwaitExpression,
|
||||
BinaryExpression,
|
||||
BooleanLiteral,
|
||||
CallExpression,
|
||||
ChainExpression,
|
||||
ClassExpression,
|
||||
@@ -4050,10 +4327,13 @@ enum __ForInitTag {
|
||||
MemberExpression,
|
||||
MetaProperty,
|
||||
NewExpression,
|
||||
NullLiteral,
|
||||
NumericLiteral,
|
||||
ObjectExpression,
|
||||
OptionalCallExpression,
|
||||
OptionalMemberExpression,
|
||||
SequenceExpression,
|
||||
StringLiteral,
|
||||
TaggedTemplateExpression,
|
||||
TemplateLiteral,
|
||||
ThisExpression,
|
||||
@@ -4114,6 +4394,14 @@ impl<'de> serde::Deserialize<'de> for ForInit {
|
||||
)?;
|
||||
Ok(ForInit::Expression(Expression::BinaryExpression(node)))
|
||||
}
|
||||
__ForInitTag::BooleanLiteral => {
|
||||
let node: Box<BooleanLiteral> = <Box<
|
||||
BooleanLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(ForInit::Expression(Expression::BooleanLiteral(node)))
|
||||
}
|
||||
__ForInitTag::CallExpression => {
|
||||
let node: Box<CallExpression> = <Box<
|
||||
CallExpression,
|
||||
@@ -4218,6 +4506,22 @@ impl<'de> serde::Deserialize<'de> for ForInit {
|
||||
)?;
|
||||
Ok(ForInit::Expression(Expression::NewExpression(node)))
|
||||
}
|
||||
__ForInitTag::NullLiteral => {
|
||||
let node: Box<NullLiteral> = <Box<
|
||||
NullLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(ForInit::Expression(Expression::NullLiteral(node)))
|
||||
}
|
||||
__ForInitTag::NumericLiteral => {
|
||||
let node: Box<NumericLiteral> = <Box<
|
||||
NumericLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(ForInit::Expression(Expression::NumericLiteral(node)))
|
||||
}
|
||||
__ForInitTag::ObjectExpression => {
|
||||
let node: Box<ObjectExpression> = <Box<
|
||||
ObjectExpression,
|
||||
@@ -4250,6 +4554,14 @@ impl<'de> serde::Deserialize<'de> for ForInit {
|
||||
)?;
|
||||
Ok(ForInit::Expression(Expression::SequenceExpression(node)))
|
||||
}
|
||||
__ForInitTag::StringLiteral => {
|
||||
let node: Box<StringLiteral> = <Box<
|
||||
StringLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(ForInit::Expression(Expression::StringLiteral(node)))
|
||||
}
|
||||
__ForInitTag::TaggedTemplateExpression => {
|
||||
let node: Box<TaggedTemplateExpression> = <Box<
|
||||
TaggedTemplateExpression,
|
||||
@@ -4526,6 +4838,7 @@ enum __AssignmentTargetTag {
|
||||
AssignmentExpression,
|
||||
AwaitExpression,
|
||||
BinaryExpression,
|
||||
BooleanLiteral,
|
||||
CallExpression,
|
||||
ChainExpression,
|
||||
ClassExpression,
|
||||
@@ -4539,10 +4852,13 @@ enum __AssignmentTargetTag {
|
||||
MemberExpression,
|
||||
MetaProperty,
|
||||
NewExpression,
|
||||
NullLiteral,
|
||||
NumericLiteral,
|
||||
ObjectExpression,
|
||||
OptionalCallExpression,
|
||||
OptionalMemberExpression,
|
||||
SequenceExpression,
|
||||
StringLiteral,
|
||||
TaggedTemplateExpression,
|
||||
TemplateLiteral,
|
||||
ThisExpression,
|
||||
@@ -4610,6 +4926,14 @@ impl<'de> serde::Deserialize<'de> for AssignmentTarget {
|
||||
)?;
|
||||
Ok(AssignmentTarget::Expression(Expression::BinaryExpression(node)))
|
||||
}
|
||||
__AssignmentTargetTag::BooleanLiteral => {
|
||||
let node: Box<BooleanLiteral> = <Box<
|
||||
BooleanLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(AssignmentTarget::Expression(Expression::BooleanLiteral(node)))
|
||||
}
|
||||
__AssignmentTargetTag::CallExpression => {
|
||||
let node: Box<CallExpression> = <Box<
|
||||
CallExpression,
|
||||
@@ -4714,6 +5038,22 @@ impl<'de> serde::Deserialize<'de> for AssignmentTarget {
|
||||
)?;
|
||||
Ok(AssignmentTarget::Expression(Expression::NewExpression(node)))
|
||||
}
|
||||
__AssignmentTargetTag::NullLiteral => {
|
||||
let node: Box<NullLiteral> = <Box<
|
||||
NullLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(AssignmentTarget::Expression(Expression::NullLiteral(node)))
|
||||
}
|
||||
__AssignmentTargetTag::NumericLiteral => {
|
||||
let node: Box<NumericLiteral> = <Box<
|
||||
NumericLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(AssignmentTarget::Expression(Expression::NumericLiteral(node)))
|
||||
}
|
||||
__AssignmentTargetTag::ObjectExpression => {
|
||||
let node: Box<ObjectExpression> = <Box<
|
||||
ObjectExpression,
|
||||
@@ -4754,6 +5094,14 @@ impl<'de> serde::Deserialize<'de> for AssignmentTarget {
|
||||
)?;
|
||||
Ok(AssignmentTarget::Expression(Expression::SequenceExpression(node)))
|
||||
}
|
||||
__AssignmentTargetTag::StringLiteral => {
|
||||
let node: Box<StringLiteral> = <Box<
|
||||
StringLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(AssignmentTarget::Expression(Expression::StringLiteral(node)))
|
||||
}
|
||||
__AssignmentTargetTag::TaggedTemplateExpression => {
|
||||
let node: Box<TaggedTemplateExpression> = <Box<
|
||||
TaggedTemplateExpression,
|
||||
@@ -4938,6 +5286,7 @@ enum __JSXExpressionOrEmptyTag {
|
||||
AssignmentExpression,
|
||||
AwaitExpression,
|
||||
BinaryExpression,
|
||||
BooleanLiteral,
|
||||
CallExpression,
|
||||
ChainExpression,
|
||||
ClassExpression,
|
||||
@@ -4951,10 +5300,13 @@ enum __JSXExpressionOrEmptyTag {
|
||||
MemberExpression,
|
||||
MetaProperty,
|
||||
NewExpression,
|
||||
NullLiteral,
|
||||
NumericLiteral,
|
||||
ObjectExpression,
|
||||
OptionalCallExpression,
|
||||
OptionalMemberExpression,
|
||||
SequenceExpression,
|
||||
StringLiteral,
|
||||
TaggedTemplateExpression,
|
||||
TemplateLiteral,
|
||||
ThisExpression,
|
||||
@@ -5023,6 +5375,14 @@ impl<'de> serde::Deserialize<'de> for JSXExpressionOrEmpty {
|
||||
)?;
|
||||
Ok(JSXExpressionOrEmpty::Expression(Expression::BinaryExpression(node)))
|
||||
}
|
||||
__JSXExpressionOrEmptyTag::BooleanLiteral => {
|
||||
let node: Box<BooleanLiteral> = <Box<
|
||||
BooleanLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(JSXExpressionOrEmpty::Expression(Expression::BooleanLiteral(node)))
|
||||
}
|
||||
__JSXExpressionOrEmptyTag::CallExpression => {
|
||||
let node: Box<CallExpression> = <Box<
|
||||
CallExpression,
|
||||
@@ -5135,6 +5495,22 @@ impl<'de> serde::Deserialize<'de> for JSXExpressionOrEmpty {
|
||||
)?;
|
||||
Ok(JSXExpressionOrEmpty::Expression(Expression::NewExpression(node)))
|
||||
}
|
||||
__JSXExpressionOrEmptyTag::NullLiteral => {
|
||||
let node: Box<NullLiteral> = <Box<
|
||||
NullLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(JSXExpressionOrEmpty::Expression(Expression::NullLiteral(node)))
|
||||
}
|
||||
__JSXExpressionOrEmptyTag::NumericLiteral => {
|
||||
let node: Box<NumericLiteral> = <Box<
|
||||
NumericLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(JSXExpressionOrEmpty::Expression(Expression::NumericLiteral(node)))
|
||||
}
|
||||
__JSXExpressionOrEmptyTag::ObjectExpression => {
|
||||
let node: Box<ObjectExpression> = <Box<
|
||||
ObjectExpression,
|
||||
@@ -5179,6 +5555,14 @@ impl<'de> serde::Deserialize<'de> for JSXExpressionOrEmpty {
|
||||
),
|
||||
)
|
||||
}
|
||||
__JSXExpressionOrEmptyTag::StringLiteral => {
|
||||
let node: Box<StringLiteral> = <Box<
|
||||
StringLiteral,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(JSXExpressionOrEmpty::Expression(Expression::StringLiteral(node)))
|
||||
}
|
||||
__JSXExpressionOrEmptyTag::TaggedTemplateExpression => {
|
||||
let node: Box<TaggedTemplateExpression> = <Box<
|
||||
TaggedTemplateExpression,
|
||||
|
||||
@@ -7,7 +7,7 @@ mod visit;
|
||||
|
||||
pub use binding::{Binding, BindingId};
|
||||
pub use generated::*;
|
||||
pub use js_value::JsValue;
|
||||
pub use js_value::{JsValue, Number};
|
||||
pub use range::SourceRange;
|
||||
pub use visit::*;
|
||||
|
||||
|
||||
-1
@@ -286,7 +286,6 @@ Output:
|
||||
}
|
||||
},
|
||||
"computed": false,
|
||||
"optional": false,
|
||||
"loc": {
|
||||
"source": null,
|
||||
"start": {
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::{
|
||||
ExportDefaultDeclaration, ExportNamedDeclaration, Expression, ExpressionOrSpread,
|
||||
ExpressionOrSuper, ForInInit, ForInit, Function, FunctionBody, Identifier, ImportDeclaration,
|
||||
ImportDeclarationSpecifier, ImportOrExportDeclaration, Literal, MethodDefinition, ModuleItem,
|
||||
Pattern, Program, Statement, SwitchCase, VariableDeclarator,
|
||||
Pattern, Program, Statement, SwitchCase, VariableDeclarator, _Literal,
|
||||
};
|
||||
|
||||
/// Trait for visiting an estree
|
||||
@@ -97,7 +97,7 @@ pub trait Visitor<'ast> {
|
||||
fn visit_import_declaration_specifier(
|
||||
&mut self,
|
||||
specifier: &'ast ImportDeclarationSpecifier,
|
||||
_source: &'ast Literal,
|
||||
_source: &'ast _Literal,
|
||||
) {
|
||||
match specifier {
|
||||
ImportDeclarationSpecifier::ImportSpecifier(specifier) => {
|
||||
@@ -406,17 +406,22 @@ pub trait Visitor<'ast> {
|
||||
|
||||
fn visit_identifier(&mut self, _identifier: &'ast Identifier) {
|
||||
// nothing to do unless overridden
|
||||
todo!("Implement visit_identifier()")
|
||||
}
|
||||
|
||||
fn visit_import_source(&mut self, literal: &'ast Literal) {
|
||||
self.visit_literal(literal);
|
||||
fn visit_import_source(&mut self, literal: &'ast _Literal) {
|
||||
self.visit_any_literal(literal);
|
||||
}
|
||||
|
||||
fn visit_export_source(&mut self, literal: &'ast Literal) {
|
||||
self.visit_literal(literal);
|
||||
fn visit_export_source(&mut self, literal: &'ast _Literal) {
|
||||
self.visit_any_literal(literal);
|
||||
}
|
||||
|
||||
fn visit_any_literal(&mut self, _literal: &'ast _Literal) {
|
||||
todo!("Implement visit_any_literal()")
|
||||
}
|
||||
|
||||
fn visit_literal(&mut self, _literal: &'ast Literal) {
|
||||
// nothing to do unless overridden
|
||||
todo!("Implement visit_literal()")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,21 @@ pub fn estree() -> String {
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns prettyplease-formatted Rust source for converting HermesParser results
|
||||
/// into estree
|
||||
pub fn estree_hermes() -> String {
|
||||
let src = include_str!("./ecmascript.json");
|
||||
let grammar: Grammar = serde_json::from_str(src).unwrap();
|
||||
let raw = grammar.codegen_hermes().to_string();
|
||||
|
||||
let parsed = syn::parse_file(&raw).unwrap();
|
||||
format!(
|
||||
"// {}generated\n#![cfg_attr(rustfmt, rustfmt_skip)]\n{}",
|
||||
'\u{0040}',
|
||||
prettyplease::unparse(&parsed)
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Grammar {
|
||||
@@ -59,7 +74,7 @@ impl Grammar {
|
||||
use std::num::NonZeroU32;
|
||||
use serde::ser::{Serializer, SerializeMap};
|
||||
use serde::{Serialize,Deserialize};
|
||||
use crate::{JsValue, Binding, SourceRange};
|
||||
use crate::{JsValue, Binding, SourceRange, Number};
|
||||
|
||||
#(#objects)*
|
||||
|
||||
@@ -70,6 +85,42 @@ impl Grammar {
|
||||
#(#operators)*
|
||||
}
|
||||
}
|
||||
|
||||
pub fn codegen_hermes(self) -> TokenStream {
|
||||
let nodes: Vec<_> = self
|
||||
.nodes
|
||||
.iter()
|
||||
.filter(|(_, node)| !node.skip_hermes_codegen)
|
||||
.map(|(name, node)| node.codegen_hermes(name))
|
||||
.collect();
|
||||
let enums: Vec<_> = self
|
||||
.enums
|
||||
.iter()
|
||||
.map(|(name, enum_)| enum_.codegen_hermes(name, &self))
|
||||
.collect();
|
||||
let operators: Vec<_> = self
|
||||
.operators
|
||||
.iter()
|
||||
.map(|(name, operator)| operator.codegen_hermes(name))
|
||||
.collect();
|
||||
|
||||
quote! {
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_variables)]
|
||||
|
||||
use forget_estree::*;
|
||||
use hermes;
|
||||
use hermes::parser::{NodePtr, NodeKind, NodeLabel };
|
||||
use hermes::utf::{utf8_with_surrogates_to_string};
|
||||
use crate::generated_extension::*;
|
||||
|
||||
#(#nodes)*
|
||||
|
||||
#(#enums)*
|
||||
|
||||
#(#operators)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
@@ -107,6 +158,12 @@ pub struct Node {
|
||||
|
||||
#[serde(default)]
|
||||
pub fields: IndexMap<String, Field>,
|
||||
|
||||
#[serde(default)]
|
||||
pub skip_hermes_codegen: bool,
|
||||
|
||||
#[serde(default)]
|
||||
pub skip_hermes_enum_variant: bool,
|
||||
}
|
||||
|
||||
impl Node {
|
||||
@@ -175,11 +232,108 @@ impl Node {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn codegen_hermes(&self, name: &str) -> TokenStream {
|
||||
let name_str = name;
|
||||
let name = format_ident!("{}", name);
|
||||
let field_names: Vec<_> = self
|
||||
.fields
|
||||
.iter()
|
||||
.map(|(name, _field)| format_ident!("{}", name))
|
||||
.collect();
|
||||
let fields: Vec<_> = self
|
||||
.fields
|
||||
.iter()
|
||||
.map(|(name, field)| {
|
||||
let (type_name_str, type_kind) = parse_type(&field.type_).unwrap();
|
||||
let camelcase_name = field.rename.as_ref().unwrap_or(name);
|
||||
let field_name = format_ident!("{}", name);
|
||||
let helper = format_ident!("hermes_get_{}_{}", name_str, camelcase_name);
|
||||
let type_name = format_ident!("{}", type_name_str);
|
||||
if field.skip || field.hermes_default {
|
||||
return quote! {
|
||||
let #field_name = Default::default();
|
||||
};
|
||||
}
|
||||
if let Some(convert_with) = &field.hermes_convert_with {
|
||||
let convert_with = format_ident!("{}", convert_with);
|
||||
return quote! {
|
||||
let #field_name = #convert_with(cx, unsafe { hermes::parser::#helper(node) } );
|
||||
}
|
||||
}
|
||||
match type_kind {
|
||||
TypeKind::Named => {
|
||||
match type_name_str.as_ref() {
|
||||
"bool" => {
|
||||
quote! {
|
||||
let #field_name = unsafe { hermes::parser::#helper(node) };
|
||||
}
|
||||
}
|
||||
"Number" => {
|
||||
quote! {
|
||||
let #field_name = convert_number(unsafe { hermes::parser::#helper(node) });
|
||||
}
|
||||
}
|
||||
"String" => {
|
||||
quote! {
|
||||
let #field_name = convert_string(cx, unsafe { hermes::parser::#helper(node) });
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
quote! {
|
||||
let #field_name = #type_name::convert(cx, unsafe { hermes::parser::#helper(node) });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TypeKind::Option => {
|
||||
match type_name_str.as_ref() {
|
||||
"String" => {
|
||||
quote! {
|
||||
let #field_name = convert_option_string(cx, unsafe { hermes::parser::#helper(node) });
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
quote! {
|
||||
let #field_name = convert_option(unsafe { hermes::parser::#helper(node) }, |node| #type_name::convert(cx, node));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TypeKind::Vec => {
|
||||
quote! {
|
||||
let #field_name = convert_vec(unsafe { hermes::parser::#helper(node) }, |node| #type_name::convert(cx, node));
|
||||
}
|
||||
}
|
||||
TypeKind::VecOfOption => {
|
||||
quote! {
|
||||
let #field_name = convert_vec_of_option(unsafe { hermes::parser::#helper(node) }, |node| #type_name::convert(cx, node));
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
quote! {
|
||||
impl FromHermes for #name {
|
||||
fn convert(cx: &mut Context, node: NodePtr) -> Self {
|
||||
let range = convert_range(node);
|
||||
#(#fields)*
|
||||
Self {
|
||||
#(#field_names,)*
|
||||
loc: None,
|
||||
range: Some(range),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Field {
|
||||
// TODO: deserialize with `parse_type` into a custom type
|
||||
#[serde(rename = "type")]
|
||||
pub type_: String,
|
||||
|
||||
@@ -198,11 +352,18 @@ pub struct Field {
|
||||
#[serde(default)]
|
||||
#[serde(rename = "TODO")]
|
||||
pub todo: Option<String>,
|
||||
|
||||
#[serde(default)]
|
||||
pub hermes_convert_with: Option<String>,
|
||||
|
||||
#[serde(default)]
|
||||
pub hermes_default: bool,
|
||||
}
|
||||
|
||||
impl Field {
|
||||
pub fn codegen(&self, name: &str) -> TokenStream {
|
||||
let name = format_ident!("{}", name);
|
||||
parse_type(&self.type_).unwrap();
|
||||
let type_name: Type = syn::parse_str(&self.type_)
|
||||
.unwrap_or_else(|_| panic!("Expected a type name, got `{}`", &self.type_));
|
||||
|
||||
@@ -237,6 +398,7 @@ impl Field {
|
||||
|
||||
pub fn codegen_node(&self, name: &str) -> TokenStream {
|
||||
let name = format_ident!("{}", name);
|
||||
parse_type(&self.type_).unwrap();
|
||||
let type_name: Type = syn::parse_str(&self.type_)
|
||||
.unwrap_or_else(|_| panic!("Expected a type name, got `{}`", &self.type_));
|
||||
let type_ = quote!(#type_name);
|
||||
@@ -386,6 +548,86 @@ impl Enum {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn codegen_hermes(&self, name: &str, grammar: &Grammar) -> TokenStream {
|
||||
let name = format_ident!("{}", name);
|
||||
|
||||
let mut tag_matches = Vec::new();
|
||||
let mut seen = HashSet::new();
|
||||
|
||||
// Imagine a case like:
|
||||
// enum ModuleItem {
|
||||
// ImportDeclaration, // struct
|
||||
// Statement // another enum
|
||||
// }
|
||||
// We need to generate matches for all the possible *concrete* `type` values, which means
|
||||
// we have to expand nested enums such as `Statement`
|
||||
for variant in self.variants.iter() {
|
||||
if let Some(nested_enum) = grammar.enums.get(variant) {
|
||||
let outer_variant = format_ident!("{}", variant);
|
||||
for variant in nested_enum.variants.iter() {
|
||||
// Skip variants that appear in multiple nested enums, we deserialize
|
||||
// as the first listed outer variant
|
||||
if !seen.insert(variant.to_string()) {
|
||||
continue;
|
||||
}
|
||||
// Modeling ESTree only requires a single level of nested enums,
|
||||
// so that's all we support. Though in theory we could support arbitrary nesting,
|
||||
// since ultimately we're matching based on the final concrete types.
|
||||
assert!(!grammar.enums.contains_key(variant));
|
||||
let node = grammar.nodes.get(variant).unwrap();
|
||||
if node.skip_hermes_enum_variant {
|
||||
continue;
|
||||
}
|
||||
|
||||
let inner_variant = format_ident!("{}", variant);
|
||||
let node_variant_name = node.type_.as_ref().unwrap_or(variant);
|
||||
let node_variant = format_ident!("{}", node_variant_name);
|
||||
|
||||
tag_matches.push(quote! {
|
||||
NodeKind::#node_variant => {
|
||||
let node = #inner_variant::convert(cx, node);
|
||||
#name::#outer_variant(#outer_variant::#inner_variant(Box::new(node)))
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if !seen.insert(variant.to_string()) {
|
||||
panic!(
|
||||
"Concrete variant {} was already added by a nested enum",
|
||||
variant
|
||||
);
|
||||
}
|
||||
let variant_name = format_ident!("{}", variant);
|
||||
let node = grammar.nodes.get(variant).unwrap();
|
||||
if node.skip_hermes_enum_variant {
|
||||
continue;
|
||||
}
|
||||
|
||||
let node_variant_name = node.type_.as_ref().unwrap_or(variant);
|
||||
let node_variant = format_ident!("{}", node_variant_name);
|
||||
|
||||
tag_matches.push(quote! {
|
||||
NodeKind::#node_variant => {
|
||||
let node = #variant_name::convert(cx, node);
|
||||
#name::#variant_name(Box::new(node))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
quote! {
|
||||
impl FromHermes for #name {
|
||||
fn convert(cx: &mut Context, node: NodePtr) -> Self {
|
||||
let node_ref = node.as_ref();
|
||||
match node_ref.kind {
|
||||
#(#tag_matches),*
|
||||
_ => panic!("Unexpected node")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
@@ -457,4 +699,67 @@ impl Operator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn codegen_hermes(&self, name: &str) -> TokenStream {
|
||||
let mut sorted_variants: Vec<_> = self.variants.iter().collect();
|
||||
sorted_variants.sort();
|
||||
|
||||
let name = format_ident!("{}", name);
|
||||
|
||||
quote! {
|
||||
impl FromHermesLabel for #name {
|
||||
fn convert(cx: &mut Context, label: NodeLabel) -> Self {
|
||||
let utf_str = utf8_with_surrogates_to_string(label.as_slice()).unwrap();
|
||||
utf_str.parse().unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum TypeKind {
|
||||
/// T
|
||||
Named,
|
||||
|
||||
/// Option<T>
|
||||
Option,
|
||||
|
||||
/// Vec<T>
|
||||
Vec,
|
||||
|
||||
/// Vec<Option<T>>
|
||||
VecOfOption,
|
||||
}
|
||||
|
||||
/// Parses a given type into the underlying type name plus a descriptor of the
|
||||
/// kind of type. Only a subset of Rust types are supported:
|
||||
/// - T
|
||||
/// - Option<T>
|
||||
/// - Vec<T>
|
||||
/// - Vec<Option<T>>
|
||||
fn parse_type(type_: &str) -> Result<(String, TypeKind), String> {
|
||||
let mut current = type_;
|
||||
let mut is_list = false;
|
||||
let mut is_option = false;
|
||||
if current.starts_with("Vec<") {
|
||||
current = ¤t[4..current.len() - 1];
|
||||
is_list = true;
|
||||
}
|
||||
if current.starts_with("Option<") {
|
||||
current = ¤t[7..current.len() - 1];
|
||||
is_option = true;
|
||||
}
|
||||
if current.contains("<") {
|
||||
Err(format!(
|
||||
"Unsupported type `{current}` expected named type (`Identifier`), optional type (`Option<Identifier>`), list type (`Vec<Identifier>`), or optional list (`Vec<Option<Identifier>>`)"
|
||||
))
|
||||
} else {
|
||||
let kind = match (is_list, is_option) {
|
||||
(true, true) => TypeKind::VecOfOption,
|
||||
(true, false) => TypeKind::Vec,
|
||||
(false, true) => TypeKind::Option,
|
||||
(false, false) => TypeKind::Named,
|
||||
};
|
||||
Ok((current.to_string(), kind))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,20 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Class": {
|
||||
"fields": {
|
||||
"id": {
|
||||
"type": "Option<Identifier>"
|
||||
},
|
||||
"super_class": {
|
||||
"type": "Option<Expression>",
|
||||
"rename": "superClass"
|
||||
},
|
||||
"body": {
|
||||
"type": "ClassBody"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Function": {
|
||||
"fields": {
|
||||
"id": {
|
||||
@@ -89,6 +103,8 @@
|
||||
}
|
||||
},
|
||||
"Literal": {
|
||||
"skip_hermes_codegen": true,
|
||||
"skip_hermes_enum_variant": true,
|
||||
"fields": {
|
||||
"value": {
|
||||
"type": "JsValue"
|
||||
@@ -107,6 +123,29 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"NumericLiteral": {
|
||||
"fields": {
|
||||
"value": {
|
||||
"type": "Number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"BooleanLiteral": {
|
||||
"fields": {
|
||||
"value": {
|
||||
"type": "bool"
|
||||
}
|
||||
}
|
||||
},
|
||||
"NullLiteral": {},
|
||||
"StringLiteral": {
|
||||
"fields": {
|
||||
"value": {
|
||||
"type": "String",
|
||||
"hermes_convert_with": "convert_string_value"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Program": {
|
||||
"fields": {
|
||||
"body": {
|
||||
@@ -115,7 +154,8 @@
|
||||
"source_type": {
|
||||
"type": "SourceType",
|
||||
"optional": true,
|
||||
"rename": "sourceType"
|
||||
"rename": "sourceType",
|
||||
"hermes_default": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -126,7 +166,8 @@
|
||||
},
|
||||
"directive": {
|
||||
"type": "Option<String>",
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"hermes_default": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -311,6 +352,7 @@
|
||||
}
|
||||
},
|
||||
"FunctionDeclaration": {
|
||||
"skip_hermes_codegen": true,
|
||||
"fields": {
|
||||
"function": {
|
||||
"type": "Function",
|
||||
@@ -318,21 +360,8 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Class": {
|
||||
"fields": {
|
||||
"id": {
|
||||
"type": "Option<Identifier>"
|
||||
},
|
||||
"super_class": {
|
||||
"type": "Option<Expression>",
|
||||
"rename": "superClass"
|
||||
},
|
||||
"body": {
|
||||
"type": "ClassBody"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ClassDeclaration": {
|
||||
"skip_hermes_codegen": true,
|
||||
"fields": {
|
||||
"class": {
|
||||
"type": "Class",
|
||||
@@ -341,6 +370,7 @@
|
||||
}
|
||||
},
|
||||
"ClassExpression": {
|
||||
"skip_hermes_codegen": true,
|
||||
"fields": {
|
||||
"class": {
|
||||
"type": "Class",
|
||||
@@ -400,7 +430,8 @@
|
||||
"ArrayExpression": {
|
||||
"fields": {
|
||||
"elements": {
|
||||
"type": "Vec<Option<ExpressionOrSpread>>"
|
||||
"type": "Vec<Option<ExpressionOrSpread>>",
|
||||
"hermes_convert_with": "convert_array_expression_elements"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -437,6 +468,7 @@
|
||||
}
|
||||
},
|
||||
"FunctionExpression": {
|
||||
"skip_hermes_codegen": true,
|
||||
"fields": {
|
||||
"function": {
|
||||
"type": "Function",
|
||||
@@ -445,6 +477,7 @@
|
||||
}
|
||||
},
|
||||
"ArrowFunctionExpression": {
|
||||
"skip_hermes_codegen": true,
|
||||
"fields": {
|
||||
"function": {
|
||||
"type": "Function",
|
||||
@@ -532,11 +565,6 @@
|
||||
"is_computed": {
|
||||
"type": "bool",
|
||||
"rename": "computed"
|
||||
},
|
||||
"is_optional": {
|
||||
"type": "bool",
|
||||
"optional": true,
|
||||
"rename": "optional"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -560,11 +588,6 @@
|
||||
},
|
||||
"arguments": {
|
||||
"type": "Vec<ExpressionOrSpread>"
|
||||
},
|
||||
"is_optional": {
|
||||
"type": "bool",
|
||||
"optional": true,
|
||||
"rename": "optional"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -611,7 +634,7 @@
|
||||
"type": "Vec<ImportDeclarationSpecifier>"
|
||||
},
|
||||
"source": {
|
||||
"type": "Literal"
|
||||
"type": "_Literal"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -648,7 +671,7 @@
|
||||
"type": "Vec<ExportSpecifier>"
|
||||
},
|
||||
"source": {
|
||||
"type": "Option<Literal>"
|
||||
"type": "Option<_Literal>"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -669,11 +692,12 @@
|
||||
"ExportAllDeclaration": {
|
||||
"fields": {
|
||||
"source": {
|
||||
"type": "Literal"
|
||||
"type": "_Literal"
|
||||
},
|
||||
"exported": {
|
||||
"type": "Option<Identifier>",
|
||||
"optional": true
|
||||
"optional": true,
|
||||
"hermes_default": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -765,7 +789,8 @@
|
||||
"JSXText": {
|
||||
"fields": {
|
||||
"value": {
|
||||
"type": "String"
|
||||
"type": "String",
|
||||
"hermes_convert_with": "convert_string_value"
|
||||
},
|
||||
"raw": {
|
||||
"type": "String"
|
||||
@@ -797,7 +822,7 @@
|
||||
"type": "Vec<JSXChildItem>"
|
||||
},
|
||||
"closing_fragment": {
|
||||
"type": "Option<JSXClosingFragment>",
|
||||
"type": "JSXClosingFragment",
|
||||
"rename": "closingFragment"
|
||||
}
|
||||
}
|
||||
@@ -819,6 +844,7 @@
|
||||
}
|
||||
},
|
||||
"AssignmentProperty": {
|
||||
"skip_hermes_codegen": true,
|
||||
"type": "Property",
|
||||
"fields": {
|
||||
"key": {
|
||||
@@ -865,6 +891,7 @@
|
||||
}
|
||||
},
|
||||
"TemplateElement": {
|
||||
"skip_hermes_codegen": true,
|
||||
"fields": {
|
||||
"tail": {
|
||||
"type": "bool"
|
||||
@@ -902,6 +929,8 @@
|
||||
}
|
||||
},
|
||||
"ChainExpression": {
|
||||
"skip_hermes_codegen": true,
|
||||
"skip_hermes_enum_variant": true,
|
||||
"fields": {
|
||||
"expression": {
|
||||
"type": "ChainElement"
|
||||
@@ -914,7 +943,7 @@
|
||||
"type": "Expression"
|
||||
},
|
||||
"property": {
|
||||
"type": "Identifier"
|
||||
"type": "Expression"
|
||||
},
|
||||
"is_computed": {
|
||||
"type": "bool",
|
||||
@@ -980,6 +1009,7 @@
|
||||
"AssignmentExpression",
|
||||
"AwaitExpression",
|
||||
"BinaryExpression",
|
||||
"BooleanLiteral",
|
||||
"CallExpression",
|
||||
"ChainExpression",
|
||||
"ClassExpression",
|
||||
@@ -993,10 +1023,13 @@
|
||||
"MemberExpression",
|
||||
"MetaProperty",
|
||||
"NewExpression",
|
||||
"NullLiteral",
|
||||
"NumericLiteral",
|
||||
"ObjectExpression",
|
||||
"OptionalCallExpression",
|
||||
"OptionalMemberExpression",
|
||||
"SequenceExpression",
|
||||
"StringLiteral",
|
||||
"TaggedTemplateExpression",
|
||||
"TemplateLiteral",
|
||||
"ThisExpression",
|
||||
@@ -1004,6 +1037,13 @@
|
||||
"UpdateExpression",
|
||||
"YieldExpression"
|
||||
],
|
||||
"_Literal": [
|
||||
"Literal",
|
||||
"BooleanLiteral",
|
||||
"NullLiteral",
|
||||
"StringLiteral",
|
||||
"NumericLiteral"
|
||||
],
|
||||
"Declaration": [
|
||||
"ClassDeclaration",
|
||||
"FunctionDeclaration",
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
mod codegen;
|
||||
|
||||
pub use codegen::estree;
|
||||
pub use codegen::{estree, estree_hermes};
|
||||
|
||||
@@ -340,7 +340,6 @@ fn convert_expression(cx: &Context, expr: &Expr) -> forget_estree::Expression {
|
||||
_ => todo!(),
|
||||
},
|
||||
arguments: convert_arguments(cx, &expr.args),
|
||||
is_optional: false,
|
||||
loc: None,
|
||||
range: convert_span(&expr.span),
|
||||
}))
|
||||
@@ -452,9 +451,9 @@ fn convert_expression(cx: &Context, expr: &Expr) -> forget_estree::Expression {
|
||||
}),
|
||||
),
|
||||
OptChainBase::Member(base) => {
|
||||
let mut member = convert_member_expression(cx, base);
|
||||
let mut member = convert_optional_member_expression(cx, base);
|
||||
member.is_optional = expr.optional;
|
||||
forget_estree::Expression::MemberExpression(Box::new(member))
|
||||
forget_estree::Expression::OptionalMemberExpression(Box::new(member))
|
||||
}
|
||||
},
|
||||
Expr::JSXElement(expr) => {
|
||||
@@ -779,6 +778,29 @@ fn convert_member_expression(cx: &Context, expr: &MemberExpr) -> forget_estree::
|
||||
object: forget_estree::ExpressionOrSuper::Expression(convert_expression(cx, &expr.obj)),
|
||||
property,
|
||||
is_computed,
|
||||
loc: None,
|
||||
range: convert_span(&expr.span),
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_optional_member_expression(
|
||||
cx: &Context,
|
||||
expr: &MemberExpr,
|
||||
) -> forget_estree::OptionalMemberExpression {
|
||||
let (is_computed, property) = match &expr.prop {
|
||||
MemberProp::Ident(prop) => (
|
||||
false,
|
||||
forget_estree::Expression::Identifier(Box::new(convert_identifier(cx, prop))),
|
||||
),
|
||||
MemberProp::Computed(prop) => (true, convert_expression(cx, &prop.expr)),
|
||||
_ => {
|
||||
panic!("PrivateName member expression properties are not supported")
|
||||
}
|
||||
};
|
||||
forget_estree::OptionalMemberExpression {
|
||||
object: convert_expression(cx, &expr.obj),
|
||||
property,
|
||||
is_computed,
|
||||
is_optional: false,
|
||||
loc: None,
|
||||
range: convert_span(&expr.span),
|
||||
|
||||
@@ -15,4 +15,7 @@ repository.workspace = true
|
||||
forget_diagnostics = { workspace = true }
|
||||
forget_estree = { workspace = true }
|
||||
hermes = { workspace = true }
|
||||
juno_support = { workspace = true }
|
||||
juno_support = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
forget_estree_codegen = { workspace = true }
|
||||
@@ -0,0 +1,13 @@
|
||||
use forget_estree_codegen::estree_hermes;
|
||||
|
||||
// Example custom build script.
|
||||
fn main() {
|
||||
// Re-run if the codegen files change
|
||||
println!("cargo:rerun-if-changed=../forget_estree_codegen/src/codegen.rs");
|
||||
println!("cargo:rerun-if-changed=../forget_estree_codegen/src/lib.rs");
|
||||
println!("cargo:rerun-if-changed=../forget_estree_codegen/src/ecmascript.json");
|
||||
println!("cargo:rerun-if-changed=../forget_estree_codegen");
|
||||
|
||||
let src = estree_hermes();
|
||||
std::fs::write("src/generated.rs", src).unwrap();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,288 @@
|
||||
use forget_estree::{
|
||||
ArrowFunctionExpression, AssignmentProperty, Class, ClassBody, ClassDeclaration,
|
||||
ClassExpression, Expression, ExpressionOrSpread, Function, FunctionBody, FunctionDeclaration,
|
||||
FunctionExpression, Identifier, Number, Pattern, SourceRange, TemplateElement,
|
||||
TemplateElementValue,
|
||||
};
|
||||
use hermes::parser::{
|
||||
hermes_get_ArrowFunctionExpression_async, hermes_get_ArrowFunctionExpression_body,
|
||||
hermes_get_ArrowFunctionExpression_expression, hermes_get_ArrowFunctionExpression_id,
|
||||
hermes_get_ArrowFunctionExpression_params, hermes_get_ClassDeclaration_body,
|
||||
hermes_get_ClassDeclaration_id, hermes_get_ClassDeclaration_superClass,
|
||||
hermes_get_ClassExpression_body, hermes_get_ClassExpression_id,
|
||||
hermes_get_ClassExpression_superClass, hermes_get_FunctionDeclaration_async,
|
||||
hermes_get_FunctionDeclaration_body, hermes_get_FunctionDeclaration_generator,
|
||||
hermes_get_FunctionDeclaration_id, hermes_get_FunctionDeclaration_params,
|
||||
hermes_get_FunctionExpression_async, hermes_get_FunctionExpression_body,
|
||||
hermes_get_FunctionExpression_generator, hermes_get_FunctionExpression_id,
|
||||
hermes_get_FunctionExpression_params, hermes_get_Property_key, hermes_get_Property_kind,
|
||||
hermes_get_Property_method, hermes_get_Property_value, NodeKind, NodeLabel, NodeLabelOpt,
|
||||
NodeListRef, NodePtr, NodePtrOpt, NodeString, NodeStringOpt, SMRange,
|
||||
};
|
||||
use hermes::utf::utf8_with_surrogates_to_string;
|
||||
|
||||
pub struct Context;
|
||||
|
||||
impl Context {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FromHermes {
|
||||
fn convert(cx: &mut Context, node: NodePtr) -> Self;
|
||||
}
|
||||
pub trait FromHermesLabel {
|
||||
fn convert(cx: &mut Context, label: NodeLabel) -> Self;
|
||||
}
|
||||
|
||||
pub fn convert_option<F, T>(node: NodePtrOpt, mut f: F) -> Option<T>
|
||||
where
|
||||
F: FnMut(NodePtr) -> T,
|
||||
{
|
||||
node.as_node_ptr().map(|node| f(node))
|
||||
}
|
||||
|
||||
pub fn convert_vec<F, T>(node: NodeListRef, mut f: F) -> Vec<T>
|
||||
where
|
||||
F: FnMut(NodePtr) -> T,
|
||||
{
|
||||
node.iter().map(|node| f(NodePtr::new(node))).collect()
|
||||
}
|
||||
|
||||
pub fn convert_vec_of_option<F, T>(node: NodeListRef, mut f: F) -> Vec<Option<T>>
|
||||
where
|
||||
F: FnMut(NodePtr) -> T,
|
||||
{
|
||||
node.iter()
|
||||
.map(|node| {
|
||||
let node = NodePtr::new(node);
|
||||
let node_ref = node.as_ref();
|
||||
match node_ref.kind {
|
||||
NodeKind::Empty => None,
|
||||
_ => Some(f(node)),
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn convert_range(node: NodePtr) -> SourceRange {
|
||||
let _range = node.as_ref().source_range;
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn convert_smrange(_range: SMRange) -> SourceRange {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn convert_string(_cx: &mut Context, label: NodeLabel) -> String {
|
||||
utf8_with_surrogates_to_string(label.as_slice()).unwrap()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn convert_option_string(cx: &mut Context, label: NodeLabelOpt) -> Option<String> {
|
||||
label.as_node_label().map(|label| convert_string(cx, label))
|
||||
}
|
||||
|
||||
pub fn convert_string_value(_cx: &mut Context, label: NodeString) -> String {
|
||||
utf8_with_surrogates_to_string(label.as_slice()).unwrap()
|
||||
}
|
||||
|
||||
pub fn convert_option_string_value(_cx: &mut Context, label: NodeStringOpt) -> Option<String> {
|
||||
label
|
||||
.as_node_string()
|
||||
.map(|label| utf8_with_surrogates_to_string(label.as_slice()).unwrap())
|
||||
}
|
||||
|
||||
pub fn convert_number(value: f64) -> Number {
|
||||
value.into()
|
||||
}
|
||||
|
||||
pub fn convert_array_expression_elements(
|
||||
cx: &mut Context,
|
||||
node: NodeListRef,
|
||||
) -> Vec<Option<ExpressionOrSpread>> {
|
||||
convert_vec_of_option(node, |node| ExpressionOrSpread::convert(cx, node))
|
||||
}
|
||||
|
||||
impl FromHermes for TemplateElement {
|
||||
fn convert(cx: &mut Context, node: NodePtr) -> Self {
|
||||
let range = convert_range(node);
|
||||
let tail = unsafe { hermes::parser::hermes_get_TemplateElement_tail(node) };
|
||||
let value = TemplateElementValue {
|
||||
cooked: convert_option_string_value(cx, unsafe {
|
||||
hermes::parser::hermes_get_TemplateElement_cooked(node)
|
||||
}),
|
||||
raw: convert_string(cx, unsafe {
|
||||
hermes::parser::hermes_get_TemplateElement_raw(node)
|
||||
}),
|
||||
};
|
||||
Self {
|
||||
tail,
|
||||
value,
|
||||
loc: None,
|
||||
range: Some(range),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromHermes for AssignmentProperty {
|
||||
fn convert(cx: &mut Context, node: NodePtr) -> Self {
|
||||
let key = FromHermes::convert(cx, unsafe { hermes_get_Property_key(node) });
|
||||
let value = FromHermes::convert(cx, unsafe { hermes_get_Property_value(node) });
|
||||
let kind = FromHermesLabel::convert(cx, unsafe { hermes_get_Property_kind(node) });
|
||||
let method = unsafe { hermes_get_Property_method(node) };
|
||||
let loc = None;
|
||||
let range = convert_range(node);
|
||||
AssignmentProperty {
|
||||
key,
|
||||
value,
|
||||
kind,
|
||||
method,
|
||||
loc,
|
||||
range: Some(range),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromHermes for FunctionDeclaration {
|
||||
fn convert(cx: &mut Context, node: NodePtr) -> Self {
|
||||
let id = convert_option(unsafe { hermes_get_FunctionDeclaration_id(node) }, |node| {
|
||||
Identifier::convert(cx, node)
|
||||
});
|
||||
let params = convert_vec(
|
||||
unsafe { hermes_get_FunctionDeclaration_params(node) },
|
||||
|node| Pattern::convert(cx, node),
|
||||
);
|
||||
let body = FunctionBody::convert(cx, unsafe { hermes_get_FunctionDeclaration_body(node) });
|
||||
let is_generator = unsafe { hermes_get_FunctionDeclaration_generator(node) };
|
||||
let is_async = unsafe { hermes_get_FunctionDeclaration_async(node) };
|
||||
let loc = None;
|
||||
let range = convert_range(node);
|
||||
FunctionDeclaration {
|
||||
function: Function {
|
||||
id,
|
||||
params,
|
||||
body: Some(body),
|
||||
is_generator,
|
||||
is_async,
|
||||
loc: loc.clone(),
|
||||
range: Some(range),
|
||||
},
|
||||
loc,
|
||||
range: Some(range),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromHermes for FunctionExpression {
|
||||
fn convert(cx: &mut Context, node: NodePtr) -> Self {
|
||||
let id = convert_option(unsafe { hermes_get_FunctionExpression_id(node) }, |node| {
|
||||
Identifier::convert(cx, node)
|
||||
});
|
||||
let params = convert_vec(
|
||||
unsafe { hermes_get_FunctionExpression_params(node) },
|
||||
|node| Pattern::convert(cx, node),
|
||||
);
|
||||
let body = FunctionBody::convert(cx, unsafe { hermes_get_FunctionExpression_body(node) });
|
||||
let is_generator = unsafe { hermes_get_FunctionExpression_generator(node) };
|
||||
let is_async = unsafe { hermes_get_FunctionExpression_async(node) };
|
||||
let loc = None;
|
||||
let range = convert_range(node);
|
||||
FunctionExpression {
|
||||
function: Function {
|
||||
id,
|
||||
params,
|
||||
body: Some(body),
|
||||
is_generator,
|
||||
is_async,
|
||||
loc: loc.clone(),
|
||||
range: Some(range),
|
||||
},
|
||||
loc,
|
||||
range: Some(range),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromHermes for ArrowFunctionExpression {
|
||||
fn convert(cx: &mut Context, node: NodePtr) -> Self {
|
||||
let id = convert_option(
|
||||
unsafe { hermes_get_ArrowFunctionExpression_id(node) },
|
||||
|node| Identifier::convert(cx, node),
|
||||
);
|
||||
let params = convert_vec(
|
||||
unsafe { hermes_get_ArrowFunctionExpression_params(node) },
|
||||
|node| Pattern::convert(cx, node),
|
||||
);
|
||||
let body =
|
||||
FunctionBody::convert(cx, unsafe { hermes_get_ArrowFunctionExpression_body(node) });
|
||||
let is_generator = unsafe { hermes_get_FunctionExpression_generator(node) };
|
||||
let is_async = unsafe { hermes_get_ArrowFunctionExpression_async(node) };
|
||||
let is_expression = unsafe { hermes_get_ArrowFunctionExpression_expression(node) };
|
||||
let loc = None;
|
||||
let range = convert_range(node);
|
||||
ArrowFunctionExpression {
|
||||
function: Function {
|
||||
id,
|
||||
params,
|
||||
body: Some(body),
|
||||
is_generator,
|
||||
is_async,
|
||||
loc: loc.clone(),
|
||||
range: Some(range),
|
||||
},
|
||||
is_expression,
|
||||
loc,
|
||||
range: Some(range),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromHermes for ClassDeclaration {
|
||||
fn convert(cx: &mut Context, node: NodePtr) -> Self {
|
||||
let id = convert_option(unsafe { hermes_get_ClassDeclaration_id(node) }, |node| {
|
||||
Identifier::convert(cx, node)
|
||||
});
|
||||
let super_class = convert_option(
|
||||
unsafe { hermes_get_ClassDeclaration_superClass(node) },
|
||||
|node| Expression::convert(cx, node),
|
||||
);
|
||||
let body = ClassBody::convert(cx, unsafe { hermes_get_ClassDeclaration_body(node) });
|
||||
let loc = None;
|
||||
let range = convert_range(node);
|
||||
ClassDeclaration {
|
||||
class: Class {
|
||||
id,
|
||||
super_class,
|
||||
body,
|
||||
},
|
||||
loc,
|
||||
range: Some(range),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl FromHermes for ClassExpression {
|
||||
fn convert(cx: &mut Context, node: NodePtr) -> Self {
|
||||
let id = convert_option(unsafe { hermes_get_ClassExpression_id(node) }, |node| {
|
||||
Identifier::convert(cx, node)
|
||||
});
|
||||
let super_class = convert_option(
|
||||
unsafe { hermes_get_ClassExpression_superClass(node) },
|
||||
|node| Expression::convert(cx, node),
|
||||
);
|
||||
let body = ClassBody::convert(cx, unsafe { hermes_get_ClassExpression_body(node) });
|
||||
let loc = None;
|
||||
let range = convert_range(node);
|
||||
ClassExpression {
|
||||
class: Class {
|
||||
id,
|
||||
super_class,
|
||||
body,
|
||||
},
|
||||
loc,
|
||||
range: Some(range),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
mod generated;
|
||||
mod generated_extension;
|
||||
|
||||
use forget_diagnostics::Diagnostic;
|
||||
use hermes::parser::{
|
||||
hermes_get_BlockStatement_body, hermes_get_DeclareFunction_id,
|
||||
hermes_get_FunctionDeclaration_async, hermes_get_FunctionDeclaration_body,
|
||||
hermes_get_FunctionDeclaration_generator, hermes_get_Program_body, HermesParser, NodeKind,
|
||||
NodePtr, ParserDialect, ParserFlags,
|
||||
};
|
||||
use juno_support::source_manager::SourceRange;
|
||||
use forget_estree::Program;
|
||||
use generated_extension::{Context, FromHermes};
|
||||
use hermes::parser::{HermesParser, ParserDialect, ParserFlags};
|
||||
use hermes::utf::utf8_with_surrogates_to_string;
|
||||
use juno_support::NullTerminatedBuf;
|
||||
|
||||
pub fn parse(source: &str, file: &str) -> Result<forget_estree::Program, Vec<Diagnostic>> {
|
||||
pub fn parse(source: &str, _file: &str) -> Result<Program, Vec<Diagnostic>> {
|
||||
let buf = NullTerminatedBuf::from_str_check(source);
|
||||
let result = HermesParser::parse(
|
||||
ParserFlags {
|
||||
@@ -19,98 +19,17 @@ pub fn parse(source: &str, file: &str) -> Result<forget_estree::Program, Vec<Dia
|
||||
},
|
||||
&buf,
|
||||
);
|
||||
let mut cx = Context::new();
|
||||
if result.has_errors() {
|
||||
let error_messages = result.messages();
|
||||
return Err(todo!("construct diagnostics"));
|
||||
return Err(error_messages
|
||||
.into_iter()
|
||||
.map(|diag| {
|
||||
let message = utf8_with_surrogates_to_string(diag.message.as_slice()).unwrap();
|
||||
Diagnostic::invalid_syntax(message, None)
|
||||
})
|
||||
.collect());
|
||||
}
|
||||
|
||||
Ok(unsafe { convert_program(result.root().unwrap()) })
|
||||
}
|
||||
|
||||
unsafe fn convert_program(node: NodePtr) -> forget_estree::Program {
|
||||
let node_ref = node.as_ref();
|
||||
let body = hermes_get_Program_body(node);
|
||||
let body: Vec<_> = body
|
||||
.iter()
|
||||
.map(|node| convert_module_item(NodePtr::new(node)))
|
||||
.collect();
|
||||
forget_estree::Program {
|
||||
body,
|
||||
source_type: forget_estree::SourceType::Module,
|
||||
loc: None,
|
||||
range: None,
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn convert_module_item(node: NodePtr) -> forget_estree::ModuleItem {
|
||||
let node_ref = node.as_ref();
|
||||
match node_ref.kind {
|
||||
NodeKind::FunctionDeclaration => {
|
||||
forget_estree::ModuleItem::Statement(forget_estree::Statement::FunctionDeclaration(
|
||||
Box::new(convert_function_declaration(node)),
|
||||
))
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn convert_function_declaration(node: NodePtr) -> forget_estree::FunctionDeclaration {
|
||||
let id = None; //hermes_get_DeclareFunction_id(node);
|
||||
let params = Vec::new();
|
||||
let body = forget_estree::FunctionBody::BlockStatement(Box::new(convert_block_statement(
|
||||
hermes_get_FunctionDeclaration_body(node),
|
||||
)));
|
||||
let is_generator = hermes_get_FunctionDeclaration_generator(node);
|
||||
let is_async = hermes_get_FunctionDeclaration_async(node);
|
||||
forget_estree::FunctionDeclaration {
|
||||
function: forget_estree::Function {
|
||||
id,
|
||||
params,
|
||||
body: Some(body),
|
||||
is_generator,
|
||||
is_async,
|
||||
loc: None,
|
||||
range: None,
|
||||
},
|
||||
loc: None,
|
||||
range: None,
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn convert_block_statement(node: NodePtr) -> forget_estree::BlockStatement {
|
||||
let body = hermes_get_BlockStatement_body(node);
|
||||
let body: Vec<_> = body
|
||||
.iter()
|
||||
.map(|node| convert_statement(NodePtr::new(node)))
|
||||
.collect();
|
||||
forget_estree::BlockStatement {
|
||||
body,
|
||||
loc: None,
|
||||
range: None,
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn convert_statement(node: NodePtr) -> forget_estree::Statement {
|
||||
let node_ref = node.as_ref();
|
||||
match node_ref.kind {
|
||||
NodeKind::ReturnStatement => {
|
||||
forget_estree::Statement::ReturnStatement(Box::new(forget_estree::ReturnStatement {
|
||||
argument: None,
|
||||
loc: None,
|
||||
range: None,
|
||||
}))
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn fixtures() {
|
||||
let res = parse("function foo() { return }", "hello.js");
|
||||
println!("{:#?}", res);
|
||||
}
|
||||
Ok(FromHermes::convert(&mut cx, result.root().unwrap()))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user