@ -1,3 +1,5 @@
//! This module implements the `Node` structure, which composes the AST.
use crate ::syntax ::ast ::{
constant ::Const ,
op ::{ BinOp , Operator , UnaryOp } ,
@ -12,85 +14,482 @@ use serde::{Deserialize, Serialize};
#[ cfg_attr(feature = " serde-ast " , derive(Serialize, Deserialize)) ]
#[ derive(Clone, Debug, Trace, Finalize, PartialEq) ]
pub enum Node {
/// Create an array with items inside.
/// An array is an ordered collection of data (either primitive or object depending upon the language).
///
/// Arrays are used to store multiple values in a single variable.
/// This is compared to a variable that can store only one value.
///
/// Each item in an array has a number attached to it, called a numeric index, that allows you to access it.
/// In JavaScript, arrays start at index zero and can be manipulated with various methods.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-ArrayLiteral
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
ArrayDecl ( Vec < Node > ) ,
/// Create an arrow function with the given arguments and internal AST node.
/// An arrow function expression is a syntactically compact alternative to a regular function expression.
///
/// Arrow function expressions are ill suited as methods, and they cannot be used as constructors.
/// Arrow functions cannot be used as constructors and will throw an error when used with new.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-ArrowFunction
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
ArrowFunctionDecl ( Vec < FormalParameter > , Box < Node > ) ,
/// Assign an AST node result to an AST node.
/// An assignment operator assigns a value to its left operand based on the value of its right operand.
///
/// Assignment operator (`=`), assigns the value of its right operand to its left operand.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-AssignmentExpression
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators
Assign ( Box < Node > , Box < Node > ) ,
/// Run an operation between 2 AST nodes.
/// Binary operators requires two operands, one before the operator and one after the operator.
///
/// More information:
/// - [MDN documentation][mdn]
///
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Operators
BinOp ( BinOp , Box < Node > , Box < Node > ) ,
/// Run several AST nodes from top-to-bottom.
/// A `block` statement (or compound statement in other languages) is used to group zero or more statements.
///
/// The block statement is often called compound statement in other languages.
/// It allows you to use multiple statements where JavaScript expects only one statement.
/// Combining statements into blocks is a common practice in JavaScript. The opposite behavior is possible using an empty statement,
/// where you provide no statement, although one is required.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-BlockStatement
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block
Block ( Vec < Node > ) ,
/// Break statement with an optional label.
/// The `break` statement terminates the current loop, switch, or label statement and transfers program control to the statement following the terminated statement.
///
/// The break statement includes an optional label that allows the program to break out of a labeled statement.
/// The break statement needs to be nested within the referenced label. The labeled statement can be any block statement;
/// it does not have to be preceded by a loop statement.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-BreakStatement
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/break
Break ( Option < String > ) ,
/// Call a function with some values.
/// Calling the function actually performs the specified actions with the indicated parameters.
///
/// Defining a function does not execute it. Defining it simply names the function and specifies what to do when the function is called.
/// Functions must be in scope when they are called, but the function declaration can be hoisted
/// The scope of a function is the function in which it is declared (or the entire program, if it is declared at the top level).
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-CallExpression
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#Calling_functions
Call ( Box < Node > , Vec < Node > ) ,
/// Conditional Operator (`{condition} ? {if true} : {if false}`).
/// The `conditional` (ternary) operator is the only JavaScript operator that takes three operands.
///
/// This operator is the only JavaScript operator that takes three operands: a condition followed by a question mark (`?`),
/// then an expression to execute `if` the condition is truthy followed by a colon (`:`), and finally the expression to execute if the condition is `falsy`.
/// This operator is frequently used as a shortcut for the `if` statement.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-ConditionalExpression
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Literals
ConditionalOp ( Box < Node > , Box < Node > , Box < Node > ) ,
/// Make a constant value.
/// Literals represent values in JavaScript.
///
/// These are fixed values not variables that you literally provide in your script.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#sec-primary-expression-literals
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Literals
Const ( Const ) ,
/// Const declaration.
/// The `const` statements are block-scoped, much like variables defined using the `let` keyword.
///
/// This declaration creates a constant whose scope can be either global or local to the block in which it is declared.
/// Global constants do not become properties of the window object, unlike var variables.
///
/// An initializer for a constant is required. You must specify its value in the same statement in which it's declared.
/// (This makes sense, given that it can't be changed later.)
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#sec-let-and-const-declarations
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
/// [identifier]: https://developer.mozilla.org/en-US/docs/Glossary/identifier
/// [expression]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Expressions
ConstDecl ( Vec < ( String , Node ) > ) ,
/// Continue with an optional label.
/// The `continue` statement terminates execution of the statements in the current iteration of the current or labeled loop,
/// and continues execution of the loop with the next iteration.
///
/// The continue statement can include an optional label that allows the program to jump to the next iteration of a labeled
/// loop statement instead of the current loop. In this case, the continue statement needs to be nested within this labeled statement.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-ContinueStatement
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/continue
Continue ( Option < String > ) ,
/// do [body] while [cond]
/// The `do...while` statement creates a loop that executes a specified statement until the test condition evaluates to false.
///
/// The condition is evaluated after executing the statement, resulting in the specified statement executing at least once.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#sec-do-while-statement
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/do...while
DoWhileLoop ( Box < Node > , Box < Node > ) ,
/// Create a function with the given name, arguments, and internal AST node.
/// The `function` declaration (function statement) defines a function with the specified parameters.
///
/// A function created with a function declaration is a `Function` object and has all the properties, methods and behavior of `Function`.
///
/// A function can also be created using an expression (see function expression).
///
/// By default, functions return undefined. To return any other value, the function must have a return statement that specifies the value to return.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#sec-terms-and-definitions-function
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function
FunctionDecl ( Option < String > , Vec < FormalParameter > , Box < Node > ) ,
/// Gets the constant field of a value.
/// This property accessor provides access to an object's properties by using the [dot notation][mdn].
///
/// In the object.property syntax, the property must be a valid JavaScript identifier.
/// (In the ECMAScript standard, the names of properties are technically "IdentifierNames", not "Identifiers",
/// so reserved words can be used but are not recommended).
///
/// One can think of an object as an associative array (a.k.a. map, dictionary, hash, lookup table).
/// The keys in this array are the names of the object's properties.
///
/// It's typical when speaking of an object's properties to make a distinction between properties and methods. However,
/// the property/method distinction is little more than a convention. A method is simply a property that can be called (for example,
/// if it has a reference to a Function instance as its value).
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#sec-property-accessors
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors#Dot_notation
GetConstField ( Box < Node > , String ) ,
/// Gets the [field] of a value.
/// This property accessor provides access to an object's properties by using the [bracket notation][mdn].
///
/// In the object[property_name] syntax, the property_name is just a string or [Symbol][symbol]. So, it can be any string, including '1foo', '!bar!', or even ' ' (a space).
///
/// One can think of an object as an associative array (a.k.a. map, dictionary, hash, lookup table).
/// The keys in this array are the names of the object's properties.
///
/// It's typical when speaking of an object's properties to make a distinction between properties and methods. However,
/// the property/method distinction is little more than a convention. A method is simply a property that can be called (for example,
/// if it has a reference to a Function instance as its value).
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#sec-property-accessors
/// [symbol]: https://developer.mozilla.org/en-US/docs/Glossary/Symbol
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors#Bracket_notation
GetField ( Box < Node > , Box < Node > ) ,
/// [init], [cond], [step], body
/// The `for` statement creates a loop that consists of three optional expressions.
///
/// A `for` loop repeats until a specified condition evaluates to `false`.
/// The JavaScript for loop is similar to the Java and C for loop.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-ForDeclaration
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for
ForLoop (
Option < Box < Node > > ,
Option < Box < Node > > ,
Option < Box < Node > > ,
Box < Node > ,
) ,
/// Check if a conditional expression is true and run an expression if it is and another expression if it isn't
/// The `if` statement executes a statement if a specified condition is [`truthy`][truthy]. If the condition is [`falsy`][falsy], another statement can be executed.
///
/// Multiple `if...else` statements can be nested to create an else if clause.
///
/// Note that there is no elseif (in one word) keyword in JavaScript.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-IfStatement
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else
/// [truthy]: https://developer.mozilla.org/en-US/docs/Glossary/truthy
/// [falsy]: https://developer.mozilla.org/en-US/docs/Glossary/falsy
/// [expression]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Expressions
If ( Box < Node > , Box < Node > , Option < Box < Node > > ) ,
/// Let declaraton
/// The `let` statement declares a block scope local variable, optionally initializing it to a value.
///
///
/// `let` allows you to declare variables that are limited to a scope of a block statement, or expression on which
/// it is used, unlike the `var` keyword, which defines a variable globally, or locally to an entire function regardless of block scope.
///
/// Just like const the `let` does not create properties of the window object when declared globally (in the top-most scope).
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#sec-let-and-const-declarations
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
LetDecl ( Vec < ( String , Option < Node > ) > ) ,
/// Load a reference to a value, or a function argument
/// An `identifier` is a sequence of characters in the code that identifies a variable, function, or property.
///
/// In JavaScript, identifiers are case-sensitive and can contain Unicode letters, $, _, and digits (0-9), but may not start with a digit.
///
/// An identifier differs from a string in that a string is data, while an identifier is part of the code. In JavaScript, there is no way
/// to convert identifiers to strings, but sometimes it is possible to parse strings into identifiers.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-Identifier
/// [mdn]: https://developer.mozilla.org/en-US/docs/Glossary/Identifier
Local ( String ) ,
/// New
/// The `new` operator lets developers create an instance of a user-defined object type or of one of the built-in object types that has a constructor function.
///
/// The new keyword does the following things:
/// - Creates a blank, plain JavaScript object;
/// - Links (sets the constructor of) this object to another object;
/// - Passes the newly created object from Step 1 as the this context;
/// - Returns this if the function doesn't return its own object.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-NewExpression
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new
New ( Box < Node > ) ,
/// Object Declaration
/// Objects in JavaScript may be defined as an unordered collection of related data, of primitive or reference types, in the form of “key: value” pairs.
///
/// Objects can be initialized using `new Object()`, `Object.create()`, or using the literal notation.
///
/// An object initializer is an expression that describes the initialization of an [`Object`][object].
/// Objects consist of properties, which are used to describe an object. Values of object properties can either
/// contain [`primitive`][primitive] data types or other objects.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-ObjectLiteral
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer
/// [object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
/// [primitive]: https://developer.mozilla.org/en-US/docs/Glossary/primitive
Object ( Vec < PropertyDefinition > ) ,
/// Return the expression from a function
/// The `return` statement ends function execution and specifies a value to be returned to the function caller.
///
/// Syntax: `return [expression];`
///
/// `expression`:
/// > The expression whose value is to be returned. If omitted, `undefined` is returned instead.
///
/// When a `return` statement is used in a function body, the execution of the function is stopped.
/// If specified, a given value is returned to the function caller.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-ReturnStatement
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return
Return ( Option < Box < Node > > ) ,
/// Run blocks whose cases match the expression
/// The `switch` statement evaluates an expression, matching the expression's value to a case clause,
/// and executes statements associated with that case, as well as statements in cases that follow the matching case.
///
/// A `switch` statement first evaluates its expression. It then looks for the first case clause whose expression evaluates
/// to the same value as the result of the input expression (using the strict comparison, `===`) and transfers control to that clause,
/// executing the associated statements. (If multiple cases match the provided value, the first case that matches is selected, even if
/// the cases are not equal to each other.)
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-SwitchStatement
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch
Switch ( Box < Node > , Vec < ( Node , Vec < Node > ) > , Option < Box < Node > > ) ,
/// `...a` - spread an iterable value
/// The `spread` operator allows an iterable such as an array expression or string to be expanded.
///
/// Syntax: `...x`
///
/// It expands array expressions or strings in places where zero or more arguments (for function calls) or elements (for array literals)
/// are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-SpreadElement
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
Spread ( Box < Node > ) ,
// Similar to Block but without the braces
/// Similar to `Node::Block` but without the braces
///
/// More information:
/// - [ECMAScript reference][spec]
///
/// [spec]: https://tc39.es/ecma262/#prod-StatementList
StatementList ( Vec < Node > ) ,
/// Throw a value
/// The `throw` statement throws a user-defined exception.
///
/// Syntax: `throw expression;`
///
/// Execution of the current function will stop (the statements after throw won't be executed),
/// and control will be passed to the first catch block in the call stack. If no catch block exists among
/// caller functions, the program will terminate.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-ThrowStatement
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw
Throw ( Box < Node > ) ,
/// Return a string representing the type of the given expression
/// The `typeof` operator returns a string indicating the type of the unevaluated operand.
///
/// Syntax: `typeof operand`
///
/// Returns a string indicating the type of the unevaluated operand.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#sec-typeof-operator
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof
TypeOf ( Box < Node > ) ,
/// Try / Catch
/// The `try...catch` statement marks a block of statements to try and specifies a response should an exception be thrown.
///
/// The `try` statement consists of a `try`-block, which contains one or more statements. `{}` must always be used,
/// even for single statements. At least one `catch`-block, or a `finally`-block, must be present.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-TryStatement
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch
Try (
Box < Node > ,
Option < Box < Node > > ,
Option < Box < Node > > ,
Option < Box < Node > > ,
) ,
/// The JavaScript `this` keyword refers to the object it belongs to.
///
/// A property of an execution context (global, function or eval) that,
/// in non–strict mode, is always a reference to an object and in strict
/// mode can be any value.
///
/// For more information, please check: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this>
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#sec-this-keyword
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
This ,
/// Run an operation on a value
/// A unary operation is an operation with only one operand.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-UnaryExpression
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Unary_operators
UnaryOp ( UnaryOp , Box < Node > ) ,
/// A variable declaration
/// The `var` statement declares a variable, optionally initializing it to a value.
///
/// var declarations, wherever they occur, are processed before any code is executed. This is called hoisting, and is discussed further below.
///
/// The scope of a variable declared with var is its current execution context, which is either the enclosing function or,
/// for variables declared outside any function, global. If you re-declare a JavaScript variable, it will not lose its value.
///
/// Assigning a value to an undeclared variable implicitly creates it as a global variable
/// (it becomes a property of the global object) when the assignment is executed.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-VariableStatement
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var
VarDecl ( Vec < ( String , Option < Node > ) > ) ,
/// Repeatedly run an expression while the conditional expression resolves to true
/// The `while` statement creates a loop that executes a specified statement as long as the test condition evaluates to `true`.
///
/// The condition is evaluated before executing the statement.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-grammar-notation-WhileStatement
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while
WhileLoop ( Box < Node > , Box < Node > ) ,
}
@ -101,6 +500,7 @@ impl Operator for Node {
_ = > true ,
}
}
fn get_precedence ( & self ) -> u64 {
match self {
Node ::GetField ( _ , _ ) | Node ::GetConstField ( _ , _ ) = > 1 ,
@ -335,11 +735,17 @@ fn join_nodes(f: &mut fmt::Formatter<'_>, nodes: &[Node]) -> fmt::Result {
///
/// In the declaration of a function, the parameters must be identifiers,
/// not any value like numbers, strings, or objects.
///```javascrip t
///```tex t
///function foo(formalParametar1, formalParametar2) {
///}
///```
/// For more information, please check <https://tc39.es/ecma262/#prod-FormalParameter>
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-FormalParameter
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Missing_formal_parameter
#[ cfg_attr(feature = " serde-ast " , derive(Serialize, Deserialize)) ]
#[ derive(Clone, Debug, PartialEq, Trace, Finalize) ]
pub struct FormalParameter {
@ -348,6 +754,13 @@ pub struct FormalParameter {
pub is_rest_param : bool ,
}
/// A sequence of `FormalParameter`.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-FormalParameters
pub type FormalParameters = Vec < FormalParameter > ;
impl FormalParameter {
@ -360,20 +773,119 @@ impl FormalParameter {
}
}
/// A JavaScript property is a characteristic of an object, often describing attributes associated with a data structure.
///
/// A property has a name (a string) and a value (primitive, method, or object reference).
/// Note that when we say that "a property holds an object", that is shorthand for "a property holds an object reference".
/// This distinction matters because the original referenced object remains unchanged when you change the property's value.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-PropertyDefinition
/// [mdn]: https://developer.mozilla.org/en-US/docs/Glossary/property/JavaScript
// TODO: Support all features: https://tc39.es/ecma262/#prod-PropertyDefinition
#[ cfg_attr(feature = " serde-ast " , derive(Serialize, Deserialize)) ]
#[ derive(Clone, Debug, PartialEq, Trace, Finalize) ]
pub enum PropertyDefinition {
/// Puts a variable into an object.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-IdentifierReference
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Property_definitions
IdentifierReference ( String ) ,
/// Binds a property name to a JavaScript value.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-PropertyDefinition
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Property_definitions
Property ( String , Node ) ,
/// A property of an object can also refer to a function or a getter or setter method.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-MethodDefinition
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Method_definitions
MethodDefinition ( MethodDefinitionKind , String , Node ) ,
/// The Rest/Spread Properties for ECMAScript proposal (stage 4) adds spread properties to object literals.
/// It copies own enumerable properties from a provided object onto a new object.
///
/// Shallow-cloning (excluding `prototype`) or merging objects is now possible using a shorter syntax than `Object.assign()`.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-PropertyDefinition
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Spread_properties
SpreadObject ( Node ) ,
}
/// Method definition kinds.
///
/// Starting with ECMAScript 2015, a shorter syntax for method definitions on objects initializers is introduced.
/// It is a shorthand for a function assigned to the method's name.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-MethodDefinition
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions
#[ cfg_attr(feature = " serde-ast " , derive(Serialize, Deserialize)) ]
#[ derive(Clone, Debug, PartialEq, Trace, Finalize) ]
pub enum MethodDefinitionKind {
/// The `get` syntax binds an object property to a function that will be called when that property is looked up.
///
/// Sometimes it is desirable to allow access to a property that returns a dynamically computed value,
/// or you may want to reflect the status of an internal variable without requiring the use of explicit method calls.
/// In JavaScript, this can be accomplished with the use of a getter.
///
/// It is not possible to simultaneously have a getter bound to a property and have that property actually hold a value,
/// although it is possible to use a getter and a setter in conjunction to create a type of pseudo-property.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-MethodDefinition
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get
Get ,
/// The `set` syntax binds an object property to a function to be called when there is an attempt to set that property.
///
/// In JavaScript, a setter can be used to execute a function whenever a specified property is attempted to be changed.
/// Setters are most often used in conjunction with getters to create a type of pseudo-property.
/// It is not possible to simultaneously have a setter on a property that holds an actual value.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-MethodDefinition
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set
Set ,
/// Starting with ECMAScript 2015, you are able to define own methods in a shorter syntax, similar to the getters and setters.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#prod-MethodDefinition
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#Method_definition_syntax
Ordinary ,
// TODO: support other method definition kinds, like `Generator`.
}