diff --git a/compiler/forget/crates/forget_build_hir/src/build.rs b/compiler/forget/crates/forget_build_hir/src/build.rs index eec764ea9c..4401287c55 100644 --- a/compiler/forget/crates/forget_build_hir/src/build.rs +++ b/compiler/forget/crates/forget_build_hir/src/build.rs @@ -56,6 +56,12 @@ pub fn build<'a>( )?; params.push(identifier); } + _ => { + return Err(Diagnostic::todo( + "Support non-identifier params", + param.range(), + )); + } } } @@ -174,27 +180,37 @@ fn lower_statement<'a>( value, )?; } else { - if let Pattern::Identifier(id) = declaration.id { - // TODO: handle unbound variables - let binding = builder.resolve_identifier(&id)?; - let identifier = match binding { - Binding::Local(identifier) => identifier, - _ => { - return Err(Diagnostic::invariant( - BuildHIRError::VariableDeclarationBindingIsNonLocal, - id.range, - )); - } - }; - builder.push(InstructionValue::DeclareLocal(forget_hir::DeclareLocal { - lvalue: LValue { - identifier: IdentifierOperand { - identifier, - effect: None, + match declaration.id { + Pattern::Identifier(id) => { + // TODO: handle unbound variables + let binding = builder.resolve_identifier(&id)?; + let identifier = match binding { + Binding::Local(identifier) => identifier, + _ => { + return Err(Diagnostic::invariant( + BuildHIRError::VariableDeclarationBindingIsNonLocal, + id.range, + )); + } + }; + builder.push(InstructionValue::DeclareLocal( + forget_hir::DeclareLocal { + lvalue: LValue { + identifier: IdentifierOperand { + identifier, + effect: None, + }, + kind, + }, }, - kind, - }, - })); + )); + } + _ => { + return Err(Diagnostic::todo( + "Handle non-identifier variable declarations", + declaration.range, + )); + } } } } diff --git a/compiler/forget/crates/forget_estree/src/generated.rs b/compiler/forget/crates/forget_estree/src/generated.rs index 2df7ba45cd..dc414aa75d 100644 --- a/compiler/forget/crates/forget_estree/src/generated.rs +++ b/compiler/forget/crates/forget_estree/src/generated.rs @@ -257,6 +257,57 @@ pub struct FunctionDeclaration { pub range: Option, } #[derive(Serialize, Deserialize, Clone, Debug)] +pub struct Class { + pub id: Option, + #[serde(rename = "superClass")] + pub super_class: Option, + pub body: ClassBody, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ClassDeclaration { + #[serde(flatten)] + pub class: Class, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ClassExpression { + #[serde(flatten)] + pub class: Class, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ClassBody { + pub body: Vec, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct MethodDefinition { + pub key: Expression, + pub value: FunctionExpression, + pub kind: MethodKind, + #[serde(rename = "computed")] + pub is_computed: bool, + #[serde(rename = "static")] + pub is_static: bool, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] pub struct VariableDeclaration { pub kind: VariableDeclarationKind, pub declarations: Vec, @@ -299,9 +350,15 @@ pub struct ObjectExpression { } #[derive(Serialize, Deserialize, Clone, Debug)] pub struct Property { - pub key: PropertyKey, + pub key: Expression, pub value: Expression, pub kind: PropertyKind, + #[serde(rename = "method")] + pub is_method: bool, + #[serde(rename = "shorthand")] + pub is_shorthand: bool, + #[serde(rename = "computed")] + pub is_computed: bool, #[serde(default)] pub loc: Option, #[serde(default)] @@ -484,6 +541,40 @@ pub struct ImportNamespaceSpecifier { pub range: Option, } #[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ExportNamedDeclaration { + pub declaration: Option, + pub specifiers: Vec, + pub source: Option, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ExportSpecifier { + pub exported: Identifier, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ExportDefaultDeclaration { + pub declaration: Declaration, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ExportAllDeclaration { + pub source: Literal, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] pub struct JSXIdentifier { pub name: String, #[serde(default)] @@ -615,11 +706,56 @@ pub struct JSXClosingFragment { #[serde(default)] pub range: Option, } +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ArrayPattern { + pub elements: Vec>, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct ObjectPattern { + pub properties: Vec, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct AssignmentProperty { + pub key: PropertyKey, + pub value: Pattern, + pub kind: PropertyKind, + pub method: bool, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct RestElement { + pub argument: Pattern, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct AssignmentPattern { + pub left: Pattern, + pub right: Expression, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} #[derive(Serialize, Clone, Debug)] #[serde(tag = "type")] pub enum Statement { BlockStatement(Box), BreakStatement(Box), + ClassDeclaration(Box), ContinueStatement(Box), DebuggerStatement(Box), DoWhileStatement(Box), @@ -643,6 +779,7 @@ pub enum Statement { enum __StatementTag { BlockStatement, BreakStatement, + ClassDeclaration, ContinueStatement, DebuggerStatement, DoWhileStatement, @@ -690,6 +827,14 @@ impl<'de> serde::Deserialize<'de> for Statement { )?; Ok(Statement::BreakStatement(node)) } + __StatementTag::ClassDeclaration => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(Statement::ClassDeclaration(node)) + } __StatementTag::ContinueStatement => { let node: Box = ), BinaryExpression(Box), CallExpression(Box), + ClassExpression(Box), ConditionalExpression(Box), FunctionExpression(Box), Identifier(Box), @@ -867,9 +1013,11 @@ enum __ExpressionTag { AssignmentExpression, BinaryExpression, CallExpression, + ClassExpression, ConditionalExpression, FunctionExpression, Identifier, + JSXElement, Literal, LogicalExpression, MemberExpression, @@ -880,7 +1028,6 @@ enum __ExpressionTag { UnaryExpression, UpdateExpression, YieldExpression, - JSXElement, } impl<'de> serde::Deserialize<'de> for Expression { fn deserialize(deserializer: D) -> Result @@ -934,6 +1081,14 @@ impl<'de> serde::Deserialize<'de> for Expression { )?; Ok(Expression::CallExpression(node)) } + __ExpressionTag::ClassExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(Expression::ClassExpression(node)) + } __ExpressionTag::ConditionalExpression => { let node: Box = serde::Deserialize<'de> for Expression { )?; Ok(Expression::Identifier(node)) } + __ExpressionTag::JSXElement => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(Expression::JSXElement(node)) + } __ExpressionTag::Literal => { let node: Box = serde::Deserialize<'de> for Expression { )?; Ok(Expression::YieldExpression(node)) } - __ExpressionTag::JSXElement => { - let node: Box = ), + FunctionDeclaration(Box), + VariableDeclaration(Box), +} +#[derive(Deserialize, Debug)] +enum __DeclarationTag { + ClassDeclaration, + FunctionDeclaration, + VariableDeclaration, +} +impl<'de> serde::Deserialize<'de> for Declaration { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let tagged = serde::Deserializer::deserialize_any( + deserializer, + serde::__private::de::TaggedContentVisitor::< + __DeclarationTag, + >::new("type", "Pattern"), + )?; + match tagged.0 { + __DeclarationTag::ClassDeclaration => { + let node: Box = as Deserialize>::deserialize( serde::__private::de::ContentDeserializer::::new(tagged.1), )?; - Ok(Expression::JSXElement(node)) + Ok(Declaration::ClassDeclaration(node)) + } + __DeclarationTag::FunctionDeclaration => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(Declaration::FunctionDeclaration(node)) + } + __DeclarationTag::VariableDeclaration => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(Declaration::VariableDeclaration(node)) } } } @@ -1110,8 +1317,12 @@ pub enum ModuleItem { #[derive(Deserialize, Debug)] enum __ModuleItemTag { ImportDeclaration, + ExportNamedDeclaration, + ExportDefaultDeclaration, + ExportAllDeclaration, BlockStatement, BreakStatement, + ClassDeclaration, ContinueStatement, DebuggerStatement, DoWhileStatement, @@ -1155,6 +1366,42 @@ impl<'de> serde::Deserialize<'de> for ModuleItem { ), ) } + __ModuleItemTag::ExportNamedDeclaration => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ModuleItem::ImportOrExportDeclaration( + ImportOrExportDeclaration::ExportNamedDeclaration(node), + ), + ) + } + __ModuleItemTag::ExportDefaultDeclaration => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ModuleItem::ImportOrExportDeclaration( + ImportOrExportDeclaration::ExportDefaultDeclaration(node), + ), + ) + } + __ModuleItemTag::ExportAllDeclaration => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ModuleItem::ImportOrExportDeclaration( + ImportOrExportDeclaration::ExportAllDeclaration(node), + ), + ) + } __ModuleItemTag::BlockStatement => { let node: Box = serde::Deserialize<'de> for ModuleItem { )?; Ok(ModuleItem::Statement(Statement::BreakStatement(node))) } + __ModuleItemTag::ClassDeclaration => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ModuleItem::Statement(Statement::ClassDeclaration(node))) + } __ModuleItemTag::ContinueStatement => { let node: Box = serde::Deserialize<'de> for ModuleItem { #[derive(Serialize, Clone, Debug)] #[serde(tag = "type")] pub enum ImportOrExportDeclaration { + ExportAllDeclaration(Box), + ExportDefaultDeclaration(Box), + ExportNamedDeclaration(Box), ImportDeclaration(Box), } #[derive(Deserialize, Debug)] enum __ImportOrExportDeclarationTag { ImportDeclaration, + ExportNamedDeclaration, + ExportDefaultDeclaration, + ExportAllDeclaration, } impl<'de> serde::Deserialize<'de> for ImportOrExportDeclaration { fn deserialize(deserializer: D) -> Result @@ -1347,6 +1608,30 @@ impl<'de> serde::Deserialize<'de> for ImportOrExportDeclaration { )?; Ok(ImportOrExportDeclaration::ImportDeclaration(node)) } + __ImportOrExportDeclarationTag::ExportNamedDeclaration => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ImportOrExportDeclaration::ExportNamedDeclaration(node)) + } + __ImportOrExportDeclarationTag::ExportDefaultDeclaration => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ImportOrExportDeclaration::ExportDefaultDeclaration(node)) + } + __ImportOrExportDeclarationTag::ExportAllDeclaration => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ImportOrExportDeclaration::ExportAllDeclaration(node)) + } } } } @@ -1363,9 +1648,11 @@ enum __ExpressionOrSuperTag { AssignmentExpression, BinaryExpression, CallExpression, + ClassExpression, ConditionalExpression, FunctionExpression, Identifier, + JSXElement, Literal, LogicalExpression, MemberExpression, @@ -1376,7 +1663,6 @@ enum __ExpressionOrSuperTag { UnaryExpression, UpdateExpression, YieldExpression, - JSXElement, Super, } impl<'de> serde::Deserialize<'de> for ExpressionOrSuper { @@ -1435,6 +1721,14 @@ impl<'de> serde::Deserialize<'de> for ExpressionOrSuper { )?; Ok(ExpressionOrSuper::Expression(Expression::CallExpression(node))) } + __ExpressionOrSuperTag::ClassExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ExpressionOrSuper::Expression(Expression::ClassExpression(node))) + } __ExpressionOrSuperTag::ConditionalExpression => { let node: Box = serde::Deserialize<'de> for ExpressionOrSuper { )?; Ok(ExpressionOrSuper::Expression(Expression::Identifier(node))) } + __ExpressionOrSuperTag::JSXElement => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ExpressionOrSuper::Expression(Expression::JSXElement(node))) + } __ExpressionOrSuperTag::Literal => { let node: Box = serde::Deserialize<'de> for ExpressionOrSuper { )?; Ok(ExpressionOrSuper::Expression(Expression::YieldExpression(node))) } - __ExpressionOrSuperTag::JSXElement => { - let node: Box = as Deserialize>::deserialize( - serde::__private::de::ContentDeserializer::::new(tagged.1), - )?; - Ok(ExpressionOrSuper::Expression(Expression::JSXElement(node))) - } __ExpressionOrSuperTag::Super => { let node: Box = serde::Deserialize<'de> for ExpressionOrSpread { @@ -1651,6 +1946,14 @@ impl<'de> serde::Deserialize<'de> for ExpressionOrSpread { )?; Ok(ExpressionOrSpread::Expression(Expression::CallExpression(node))) } + __ExpressionOrSpreadTag::ClassExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ExpressionOrSpread::Expression(Expression::ClassExpression(node))) + } __ExpressionOrSpreadTag::ConditionalExpression => { let node: Box = serde::Deserialize<'de> for ExpressionOrSpread { )?; Ok(ExpressionOrSpread::Expression(Expression::Identifier(node))) } + __ExpressionOrSpreadTag::JSXElement => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ExpressionOrSpread::Expression(Expression::JSXElement(node))) + } __ExpressionOrSpreadTag::Literal => { let node: Box = serde::Deserialize<'de> for ExpressionOrSpread { )?; Ok(ExpressionOrSpread::Expression(Expression::YieldExpression(node))) } - __ExpressionOrSpreadTag::JSXElement => { - let node: Box = as Deserialize>::deserialize( - serde::__private::de::ContentDeserializer::::new(tagged.1), - )?; - Ok(ExpressionOrSpread::Expression(Expression::JSXElement(node))) - } __ExpressionOrSpreadTag::SpreadElement => { let node: Box = serde::Deserialize<'de> for FunctionBody { fn deserialize(deserializer: D) -> Result @@ -1867,6 +2171,14 @@ impl<'de> serde::Deserialize<'de> for FunctionBody { )?; Ok(FunctionBody::Expression(Expression::CallExpression(node))) } + __FunctionBodyTag::ClassExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(FunctionBody::Expression(Expression::ClassExpression(node))) + } __FunctionBodyTag::ConditionalExpression => { let node: Box = serde::Deserialize<'de> for FunctionBody { )?; Ok(FunctionBody::Expression(Expression::Identifier(node))) } + __FunctionBodyTag::JSXElement => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(FunctionBody::Expression(Expression::JSXElement(node))) + } __FunctionBodyTag::Literal => { let node: Box = serde::Deserialize<'de> for FunctionBody { )?; Ok(FunctionBody::Expression(Expression::YieldExpression(node))) } - __FunctionBodyTag::JSXElement => { - let node: Box = as Deserialize>::deserialize( - serde::__private::de::ContentDeserializer::::new(tagged.1), - )?; - Ok(FunctionBody::Expression(Expression::JSXElement(node))) - } } } } #[derive(Serialize, Clone, Debug)] #[serde(tag = "type")] pub enum Pattern { + ArrayPattern(Box), + AssignmentPattern(Box), Identifier(Box), + ObjectPattern(Box), + RestElement(Box), } #[derive(Deserialize, Debug)] enum __PatternTag { Identifier, + ArrayPattern, + ObjectPattern, + RestElement, + AssignmentPattern, } impl<'de> serde::Deserialize<'de> for Pattern { fn deserialize(deserializer: D) -> Result @@ -2011,6 +2331,38 @@ impl<'de> serde::Deserialize<'de> for Pattern { )?; Ok(Pattern::Identifier(node)) } + __PatternTag::ArrayPattern => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(Pattern::ArrayPattern(node)) + } + __PatternTag::ObjectPattern => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(Pattern::ObjectPattern(node)) + } + __PatternTag::RestElement => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(Pattern::RestElement(node)) + } + __PatternTag::AssignmentPattern => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(Pattern::AssignmentPattern(node)) + } } } } @@ -2027,9 +2379,11 @@ enum __ForInitTag { AssignmentExpression, BinaryExpression, CallExpression, + ClassExpression, ConditionalExpression, FunctionExpression, Identifier, + JSXElement, Literal, LogicalExpression, MemberExpression, @@ -2040,7 +2394,6 @@ enum __ForInitTag { UnaryExpression, UpdateExpression, YieldExpression, - JSXElement, VariableDeclaration, } impl<'de> serde::Deserialize<'de> for ForInit { @@ -2095,6 +2448,14 @@ impl<'de> serde::Deserialize<'de> for ForInit { )?; Ok(ForInit::Expression(Expression::CallExpression(node))) } + __ForInitTag::ClassExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ForInit::Expression(Expression::ClassExpression(node))) + } __ForInitTag::ConditionalExpression => { let node: Box = serde::Deserialize<'de> for ForInit { )?; Ok(ForInit::Expression(Expression::Identifier(node))) } + __ForInitTag::JSXElement => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ForInit::Expression(Expression::JSXElement(node))) + } __ForInitTag::Literal => { let node: Box = serde::Deserialize<'de> for ForInit { )?; Ok(ForInit::Expression(Expression::YieldExpression(node))) } - __ForInitTag::JSXElement => { - let node: Box = as Deserialize>::deserialize( - serde::__private::de::ContentDeserializer::::new(tagged.1), - )?; - Ok(ForInit::Expression(Expression::JSXElement(node))) - } __ForInitTag::VariableDeclaration => { let node: Box = serde::Deserialize<'de> for ForInInit { @@ -2249,6 +2614,38 @@ impl<'de> serde::Deserialize<'de> for ForInInit { )?; Ok(ForInInit::Pattern(Pattern::Identifier(node))) } + __ForInInitTag::ArrayPattern => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ForInInit::Pattern(Pattern::ArrayPattern(node))) + } + __ForInInitTag::ObjectPattern => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ForInInit::Pattern(Pattern::ObjectPattern(node))) + } + __ForInInitTag::RestElement => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ForInInit::Pattern(Pattern::RestElement(node))) + } + __ForInInitTag::AssignmentPattern => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ForInInit::Pattern(Pattern::AssignmentPattern(node))) + } __ForInInitTag::VariableDeclaration => { let node: Box = serde::Deserialize<'de> for AssignmentTarget { fn deserialize(deserializer: D) -> Result @@ -2386,6 +2788,14 @@ impl<'de> serde::Deserialize<'de> for AssignmentTarget { )?; Ok(AssignmentTarget::Expression(Expression::CallExpression(node))) } + __AssignmentTargetTag::ClassExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(AssignmentTarget::Expression(Expression::ClassExpression(node))) + } __AssignmentTargetTag::ConditionalExpression => { let node: Box = serde::Deserialize<'de> for AssignmentTarget { )?; Ok(AssignmentTarget::Expression(Expression::Identifier(node))) } + __AssignmentTargetTag::JSXElement => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(AssignmentTarget::Expression(Expression::JSXElement(node))) + } __AssignmentTargetTag::Literal => { let node: Box = serde::Deserialize<'de> for AssignmentTarget { )?; Ok(AssignmentTarget::Expression(Expression::YieldExpression(node))) } - __AssignmentTargetTag::JSXElement => { - let node: Box = { + let node: Box = as Deserialize>::deserialize( serde::__private::de::ContentDeserializer::::new(tagged.1), )?; - Ok(AssignmentTarget::Expression(Expression::JSXElement(node))) + Ok(AssignmentTarget::Pattern(Pattern::ArrayPattern(node))) + } + __AssignmentTargetTag::ObjectPattern => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(AssignmentTarget::Pattern(Pattern::ObjectPattern(node))) + } + __AssignmentTargetTag::RestElement => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(AssignmentTarget::Pattern(Pattern::RestElement(node))) + } + __AssignmentTargetTag::AssignmentPattern => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(AssignmentTarget::Pattern(Pattern::AssignmentPattern(node))) } } } @@ -2556,9 +2998,11 @@ enum __JSXExpressionOrEmptyTag { AssignmentExpression, BinaryExpression, CallExpression, + ClassExpression, ConditionalExpression, FunctionExpression, Identifier, + JSXElement, Literal, LogicalExpression, MemberExpression, @@ -2569,7 +3013,6 @@ enum __JSXExpressionOrEmptyTag { UnaryExpression, UpdateExpression, YieldExpression, - JSXElement, JSXEmptyExpression, } impl<'de> serde::Deserialize<'de> for JSXExpressionOrEmpty { @@ -2632,6 +3075,14 @@ impl<'de> serde::Deserialize<'de> for JSXExpressionOrEmpty { )?; Ok(JSXExpressionOrEmpty::Expression(Expression::CallExpression(node))) } + __JSXExpressionOrEmptyTag::ClassExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(JSXExpressionOrEmpty::Expression(Expression::ClassExpression(node))) + } __JSXExpressionOrEmptyTag::ConditionalExpression => { let node: Box = serde::Deserialize<'de> for JSXExpressionOrEmpty { )?; Ok(JSXExpressionOrEmpty::Expression(Expression::Identifier(node))) } + __JSXExpressionOrEmptyTag::JSXElement => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(JSXExpressionOrEmpty::Expression(Expression::JSXElement(node))) + } __JSXExpressionOrEmptyTag::Literal => { let node: Box = serde::Deserialize<'de> for JSXExpressionOrEmpty { )?; Ok(JSXExpressionOrEmpty::Expression(Expression::YieldExpression(node))) } - __JSXExpressionOrEmptyTag::JSXElement => { - let node: Box = as Deserialize>::deserialize( - serde::__private::de::ContentDeserializer::::new(tagged.1), - )?; - Ok(JSXExpressionOrEmpty::Expression(Expression::JSXElement(node))) - } __JSXExpressionOrEmptyTag::JSXEmptyExpression => { let node: Box = ) -> std::fmt::Result { + let name = match self { + Self::Constructor => "constructor", + Self::Get => "get", + Self::Method => "method", + Self::Set => "set", + }; + f.write_str(name) + } +} +impl std::str::FromStr for MethodKind { + type Err = (); + fn from_str(s: &str) -> Result { + match s { + "constructor" => Ok(Self::Constructor), + "get" => Ok(Self::Get), + "method" => Ok(Self::Method), + "set" => Ok(Self::Set), + _ => Err(()), + } + } +} diff --git a/compiler/forget/crates/forget_estree/src/generated_extensions.rs b/compiler/forget/crates/forget_estree/src/generated_extensions.rs index 8a6945ccd9..00729a6d50 100644 --- a/compiler/forget/crates/forget_estree/src/generated_extensions.rs +++ b/compiler/forget/crates/forget_estree/src/generated_extensions.rs @@ -1,8 +1,20 @@ // Manual extensions to generated types -use crate::SourceType; +use crate::{Pattern, SourceRange, SourceType}; impl Default for SourceType { fn default() -> Self { Self::Script } } + +impl Pattern { + pub fn range(&self) -> Option { + match self { + Self::ArrayPattern(pattern) => pattern.range, + Self::AssignmentPattern(pattern) => pattern.range, + Self::Identifier(pattern) => pattern.range, + Self::ObjectPattern(pattern) => pattern.range, + Self::RestElement(pattern) => pattern.range, + } + } +} diff --git a/compiler/forget/crates/forget_estree/src/visit.rs b/compiler/forget/crates/forget_estree/src/visit.rs index 6162480096..d99e09b469 100644 --- a/compiler/forget/crates/forget_estree/src/visit.rs +++ b/compiler/forget/crates/forget_estree/src/visit.rs @@ -1,7 +1,9 @@ use crate::{ - AssignmentTarget, Expression, ExpressionOrSpread, ExpressionOrSuper, ForInInit, ForInit, - Function, FunctionBody, Identifier, ImportDeclarationSpecifier, ImportOrExportDeclaration, - Literal, ModuleItem, Pattern, Program, Statement, SwitchCase, VariableDeclarator, + AssignmentTarget, Class, Declaration, ExportAllDeclaration, ExportDefaultDeclaration, + ExportNamedDeclaration, Expression, ExpressionOrSpread, ExpressionOrSuper, ForInInit, ForInit, + Function, FunctionBody, Identifier, ImportDeclaration, ImportDeclarationSpecifier, + ImportOrExportDeclaration, Literal, MethodDefinition, ModuleItem, Pattern, Program, Statement, + SwitchCase, VariableDeclarator, }; /// Trait for visiting an estree @@ -52,13 +54,43 @@ pub trait Visitor<'ast> { fn visit_import_or_export_declaration(&mut self, declaration: &'ast ImportOrExportDeclaration) { match declaration { ImportOrExportDeclaration::ImportDeclaration(declaration) => { - self.visit_lvalue(|visitor| { - for specifier in &declaration.specifiers { - visitor.visit_import_declaration_specifier(specifier, &declaration.source) - } - }); - self.visit_import_source(&declaration.source); + self.visit_import_declaration(declaration); } + ImportOrExportDeclaration::ExportAllDeclaration(declaration) => { + self.visit_export_all_declaration(declaration); + } + ImportOrExportDeclaration::ExportDefaultDeclaration(declaration) => { + self.visit_export_default_declaration(declaration); + } + ImportOrExportDeclaration::ExportNamedDeclaration(declaration) => { + self.visit_export_named_declaration(declaration); + } + } + } + + fn visit_import_declaration(&mut self, declaration: &'ast ImportDeclaration) { + self.visit_lvalue(|visitor| { + for specifier in &declaration.specifiers { + visitor.visit_import_declaration_specifier(specifier, &declaration.source) + } + }); + self.visit_import_source(&declaration.source); + } + + fn visit_export_all_declaration(&mut self, declaration: &'ast ExportAllDeclaration) { + self.visit_export_source(&declaration.source); + } + + fn visit_export_default_declaration(&mut self, declaration: &'ast ExportDefaultDeclaration) { + self.visit_declaration(&declaration.declaration); + } + + fn visit_export_named_declaration(&mut self, declaration: &'ast ExportNamedDeclaration) { + if let Some(declaration) = &declaration.declaration { + self.visit_declaration(declaration) + } + if let Some(source) = &declaration.source { + self.visit_export_source(source); } } @@ -80,6 +112,26 @@ pub trait Visitor<'ast> { } } + fn visit_declaration(&mut self, declaration: &'ast Declaration) { + self.default_visit_declaration(declaration); + } + + fn default_visit_declaration(&mut self, declaration: &'ast Declaration) { + match declaration { + Declaration::ClassDeclaration(declaration) => { + self.visit_class(&declaration.class); + } + Declaration::FunctionDeclaration(declaration) => { + self.visit_function(&declaration.function); + } + Declaration::VariableDeclaration(declaration) => { + for declarator in &declaration.declarations { + self.visit_variable_declarator(declarator) + } + } + } + } + fn visit_statement(&mut self, stmt: &'ast Statement) { self.default_visit_statement(stmt); } @@ -100,6 +152,9 @@ pub trait Visitor<'ast> { Statement::DebuggerStatement(_stmt) => { // todo } + Statement::ClassDeclaration(stmt) => { + self.visit_class(&stmt.class); + } Statement::DoWhileStatement(stmt) => { self.visit_statement(&stmt.body); self.visit_expression(&stmt.test); @@ -191,6 +246,31 @@ pub trait Visitor<'ast> { } } + fn visit_class(&mut self, class: &'ast Class) { + if let Some(id) = &class.id { + self.visit_identifier(id) + } + if let Some(super_class) = &class.super_class { + self.visit_expression(super_class); + } + for method in &class.body.body { + self.visit_method_definition(class, method) + } + } + + fn visit_method_definition(&mut self, class: &'ast Class, method: &'ast MethodDefinition) { + self.default_visit_method_definition(class, method); + } + + fn default_visit_method_definition( + &mut self, + _class: &'ast Class, + method: &'ast MethodDefinition, + ) { + self.visit_expression(&method.key); + self.visit_function(&method.value.function); + } + fn visit_case(&mut self, case_: &'ast SwitchCase) { if let Some(test) = &case_.test { self.visit_expression(test); @@ -229,6 +309,23 @@ pub trait Visitor<'ast> { fn visit_pattern(&mut self, pattern: &'ast Pattern) { match pattern { Pattern::Identifier(pattern) => self.visit_identifier(pattern), + Pattern::ArrayPattern(pattern) => { + for element in &pattern.elements { + if let Some(element) = element { + self.visit_pattern(element); + } + } + } + Pattern::ObjectPattern(pattern) => { + for property in &pattern.properties { + self.visit_pattern(&property.value); + } + } + Pattern::RestElement(pattern) => self.visit_pattern(&pattern.argument), + Pattern::AssignmentPattern(pattern) => { + self.visit_expression(&pattern.right); + self.visit_pattern(&pattern.left); + } } } @@ -280,6 +377,7 @@ pub trait Visitor<'ast> { } Expression::Literal(expr) => self.visit_literal(expr), Expression::FunctionExpression(expr) => self.visit_function(&expr.function), + Expression::ArrowFunctionExpression(expr) => self.visit_function(&expr.function), Expression::MemberExpression(expr) => { match &expr.object { ExpressionOrSuper::Super(_object) => { @@ -305,6 +403,10 @@ pub trait Visitor<'ast> { self.visit_literal(literal); } + fn visit_export_source(&mut self, literal: &'ast Literal) { + self.visit_literal(literal); + } + fn visit_literal(&mut self, _literal: &'ast Literal) { // nothing to do unless overridden } diff --git a/compiler/forget/crates/forget_estree_codegen/src/codegen.rs b/compiler/forget/crates/forget_estree_codegen/src/codegen.rs index dcd5c63bc5..7c78aebd34 100644 --- a/compiler/forget/crates/forget_estree_codegen/src/codegen.rs +++ b/compiler/forget/crates/forget_estree_codegen/src/codegen.rs @@ -21,7 +21,7 @@ pub fn estree() -> String { } #[derive(Serialize, Deserialize, Debug)] -#[serde(deny_unknown_fields)] +// #[serde(deny_unknown_fields)] pub struct Grammar { pub objects: IndexMap, pub nodes: IndexMap, @@ -72,7 +72,7 @@ impl Grammar { } #[derive(Serialize, Deserialize, Debug)] -#[serde(deny_unknown_fields)] +// #[serde(deny_unknown_fields)] pub struct Object { #[serde(default)] pub fields: IndexMap, @@ -97,7 +97,7 @@ impl Object { } #[derive(Serialize, Deserialize, Debug)] -#[serde(deny_unknown_fields)] +// #[serde(deny_unknown_fields)] pub struct Node { #[serde(default)] pub fields: IndexMap, @@ -128,7 +128,7 @@ impl Node { } #[derive(Serialize, Deserialize, Debug)] -#[serde(deny_unknown_fields)] +// #[serde(deny_unknown_fields)] pub struct Field { #[serde(rename = "type")] pub type_: String, @@ -217,7 +217,7 @@ impl Field { #[derive(Serialize, Deserialize, Debug)] #[serde(transparent)] -#[serde(deny_unknown_fields)] +// #[serde(deny_unknown_fields)] pub struct Enum { pub variants: Vec, } @@ -350,7 +350,7 @@ impl Enum { #[derive(Serialize, Deserialize, Debug)] #[serde(transparent)] -#[serde(deny_unknown_fields)] +// #[serde(deny_unknown_fields)] pub struct Operator { pub variants: IndexMap, } diff --git a/compiler/forget/crates/forget_estree_codegen/src/ecmascript.json b/compiler/forget/crates/forget_estree_codegen/src/ecmascript.json index bb21e4ec2a..7eaa364ec4 100644 --- a/compiler/forget/crates/forget_estree_codegen/src/ecmascript.json +++ b/compiler/forget/crates/forget_estree_codegen/src/ecmascript.json @@ -299,6 +299,64 @@ } } }, + "Class": { + "fields": { + "id": { + "type": "Option" + }, + "super_class": { + "type": "Option", + "rename": "superClass" + }, + "body": { + "type": "ClassBody" + } + } + }, + "ClassDeclaration": { + "fields": { + "class": { + "type": "Class", + "flatten": true + } + } + }, + "ClassExpression": { + "fields": { + "class": { + "type": "Class", + "flatten": true + } + } + }, + "ClassBody": { + "fields": { + "body": { + "type": "Vec" + } + } + }, + "MethodDefinition": { + "fields": { + "key": { + "type": "Expression" + }, + "value": { + "type": "FunctionExpression" + }, + "kind": { + "type": "MethodKind" + }, + "is_computed": { + "type": "bool", + "rename": "computed" + }, + "is_static": { + "type": "bool", + "rename": "static" + } + } + }, "VariableDeclaration": { "fields": { "kind": { @@ -337,13 +395,25 @@ "Property": { "fields": { "key": { - "type": "PropertyKey" + "type": "Expression" }, "value": { "type": "Expression" }, "kind": { "type": "PropertyKind" + }, + "is_method": { + "type": "bool", + "rename": "method" + }, + "is_shorthand": { + "type": "bool", + "rename": "shorthand" + }, + "is_computed": { + "type": "bool", + "rename": "computed" } } }, @@ -539,6 +609,40 @@ } } }, + "ExportNamedDeclaration": { + "fields": { + "declaration": { + "type": "Option" + }, + "specifiers": { + "type": "Vec" + }, + "source": { + "type": "Option" + } + } + }, + "ExportSpecifier": { + "fields": { + "exported": { + "type": "Identifier" + } + } + }, + "ExportDefaultDeclaration": { + "fields": { + "declaration": { + "type": "Declaration" + } + } + }, + "ExportAllDeclaration": { + "fields": { + "source": { + "type": "Literal" + } + } + }, "JSXIdentifier": { "fields": { "name": { @@ -660,12 +764,63 @@ } }, "JSXOpeningFragment": {}, - "JSXClosingFragment": {} + "JSXClosingFragment": {}, + "ArrayPattern": { + "fields": { + "elements": { + "type": "Vec>" + } + } + }, + "ObjectPattern": { + "fields": { + "properties": { + "type": "Vec" + } + } + }, + "AssignmentProperty": { + "tag": "Property", + "fields": { + "key": { + "type": "PropertyKey" + }, + "value": { + "type": "Pattern" + }, + "kind": { + "type": "PropertyKind", + "TODO": "fixed value `init`" + }, + "method": { + "type": "bool", + "TODO": "fixed value `false`" + } + } + }, + "RestElement": { + "fields": { + "argument": { + "type": "Pattern" + } + } + }, + "AssignmentPattern": { + "fields": { + "left": { + "type": "Pattern" + }, + "right": { + "type": "Expression" + } + } + } }, "enums": { "Statement": [ "BlockStatement", "BreakStatement", + "ClassDeclaration", "ContinueStatement", "DebuggerStatement", "DoWhileStatement", @@ -691,9 +846,11 @@ "AssignmentExpression", "BinaryExpression", "CallExpression", + "ClassExpression", "ConditionalExpression", "FunctionExpression", "Identifier", + "JSXElement", "Literal", "LogicalExpression", "MemberExpression", @@ -703,8 +860,12 @@ "ThisExpression", "UnaryExpression", "UpdateExpression", - "YieldExpression", - "JSXElement" + "YieldExpression" + ], + "Declaration": [ + "ClassDeclaration", + "FunctionDeclaration", + "VariableDeclaration" ], "ImportDeclarationSpecifier": [ "ImportSpecifier", @@ -716,7 +877,10 @@ "Statement" ], "ImportOrExportDeclaration": [ - "ImportDeclaration" + "ImportDeclaration", + "ExportNamedDeclaration", + "ExportDefaultDeclaration", + "ExportAllDeclaration" ], "ExpressionOrSuper": [ "Expression", @@ -731,7 +895,11 @@ "Expression" ], "Pattern": [ - "Identifier" + "Identifier", + "ArrayPattern", + "ObjectPattern", + "RestElement", + "AssignmentPattern" ], "ForInit": [ "Expression", @@ -853,6 +1021,12 @@ "SourceType": { "Script": "script", "Module": "module" + }, + "MethodKind": { + "Constructor": "constructor", + "Method": "method", + "Get": "get", + "Set": "set" } } } \ No newline at end of file