node/tools/eslint/node_modules/espree/lib/ast-node-factory.js

933 lines
30 KiB
JavaScript

/**
* @fileoverview A factory for creating AST nodes
* @author Fred K. Schott
* @copyright 2014 Fred K. Schott. All rights reserved.
* @copyright 2011-2013 Ariya Hidayat <ariya.hidayat@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var astNodeTypes = require("./ast-node-types");
//------------------------------------------------------------------------------
// Public
//------------------------------------------------------------------------------
module.exports = {
/**
* Create an Array Expression ASTNode out of an array of elements
* @param {ASTNode[]} elements An array of ASTNode elements
* @returns {ASTNode} An ASTNode representing the entire array expression
*/
createArrayExpression: function(elements) {
return {
type: astNodeTypes.ArrayExpression,
elements: elements
};
},
/**
* Create an Arrow Function Expression ASTNode
* @param {ASTNode} params The function arguments
* @param {ASTNode} body The function body
* @param {boolean} expression True if the arrow function is created via an expression.
* Always false for declarations, but kept here to be in sync with
* FunctionExpression objects.
* @returns {ASTNode} An ASTNode representing the entire arrow function expression
*/
createArrowFunctionExpression: function (params, body, expression) {
return {
type: astNodeTypes.ArrowFunctionExpression,
id: null,
params: params,
body: body,
generator: false,
expression: expression
};
},
/**
* Create an ASTNode representation of an assignment expression
* @param {ASTNode} operator The assignment operator
* @param {ASTNode} left The left operand
* @param {ASTNode} right The right operand
* @returns {ASTNode} An ASTNode representing the entire assignment expression
*/
createAssignmentExpression: function(operator, left, right) {
return {
type: astNodeTypes.AssignmentExpression,
operator: operator,
left: left,
right: right
};
},
/**
* Create an ASTNode representation of an assignment pattern (default parameters)
* @param {ASTNode} left The left operand
* @param {ASTNode} right The right operand
* @returns {ASTNode} An ASTNode representing the entire assignment pattern
*/
createAssignmentPattern: function(left, right) {
return {
type: astNodeTypes.AssignmentPattern,
left: left,
right: right
};
},
/**
* Create an ASTNode representation of a binary expression
* @param {ASTNode} operator The assignment operator
* @param {ASTNode} left The left operand
* @param {ASTNode} right The right operand
* @returns {ASTNode} An ASTNode representing the entire binary expression
*/
createBinaryExpression: function(operator, left, right) {
var type = (operator === "||" || operator === "&&") ? astNodeTypes.LogicalExpression :
astNodeTypes.BinaryExpression;
return {
type: type,
operator: operator,
left: left,
right: right
};
},
/**
* Create an ASTNode representation of a block statement
* @param {ASTNode} body The block statement body
* @returns {ASTNode} An ASTNode representing the entire block statement
*/
createBlockStatement: function(body) {
return {
type: astNodeTypes.BlockStatement,
body: body
};
},
/**
* Create an ASTNode representation of a break statement
* @param {ASTNode} label The break statement label
* @returns {ASTNode} An ASTNode representing the break statement
*/
createBreakStatement: function(label) {
return {
type: astNodeTypes.BreakStatement,
label: label
};
},
/**
* Create an ASTNode representation of a call expression
* @param {ASTNode} callee The function being called
* @param {ASTNode[]} args An array of ASTNodes representing the function call arguments
* @returns {ASTNode} An ASTNode representing the entire call expression
*/
createCallExpression: function(callee, args) {
return {
type: astNodeTypes.CallExpression,
callee: callee,
"arguments": args
};
},
/**
* Create an ASTNode representation of a catch clause/block
* @param {ASTNode} param Any catch clause exeption/conditional parameter information
* @param {ASTNode} body The catch block body
* @returns {ASTNode} An ASTNode representing the entire catch clause
*/
createCatchClause: function(param, body) {
return {
type: astNodeTypes.CatchClause,
param: param,
body: body
};
},
/**
* Creates an ASTNode representation of a class body.
* @param {ASTNode} body The node representing the body of the class.
* @returns {ASTNode} An ASTNode representing the class body.
*/
createClassBody: function(body) {
return {
type: astNodeTypes.ClassBody,
body: body
};
},
createClassExpression: function(id, superClass, body) {
return {
type: astNodeTypes.ClassExpression,
id: id,
superClass: superClass,
body: body
};
},
createClassDeclaration: function(id, superClass, body) {
return {
type: astNodeTypes.ClassDeclaration,
id: id,
superClass: superClass,
body: body
};
},
createMethodDefinition: function(propertyType, kind, key, value, computed) {
return {
type: astNodeTypes.MethodDefinition,
key: key,
value: value,
kind: kind,
"static": propertyType === "static",
computed: computed
};
},
/**
* Create an ASTNode representation of a conditional expression
* @param {ASTNode} test The conditional to evaluate
* @param {ASTNode} consequent The code to be run if the test returns true
* @param {ASTNode} alternate The code to be run if the test returns false
* @returns {ASTNode} An ASTNode representing the entire conditional expression
*/
createConditionalExpression: function(test, consequent, alternate) {
return {
type: astNodeTypes.ConditionalExpression,
test: test,
consequent: consequent,
alternate: alternate
};
},
/**
* Create an ASTNode representation of a continue statement
* @param {?ASTNode} label The optional continue label (null if not set)
* @returns {ASTNode} An ASTNode representing the continue statement
*/
createContinueStatement: function(label) {
return {
type: astNodeTypes.ContinueStatement,
label: label
};
},
/**
* Create an ASTNode representation of a debugger statement
* @returns {ASTNode} An ASTNode representing the debugger statement
*/
createDebuggerStatement: function() {
return {
type: astNodeTypes.DebuggerStatement
};
},
/**
* Create an ASTNode representation of an empty statement
* @returns {ASTNode} An ASTNode representing an empty statement
*/
createEmptyStatement: function() {
return {
type: astNodeTypes.EmptyStatement
};
},
/**
* Create an ASTNode representation of an expression statement
* @param {ASTNode} expression The expression
* @returns {ASTNode} An ASTNode representing an expression statement
*/
createExpressionStatement: function(expression) {
return {
type: astNodeTypes.ExpressionStatement,
expression: expression
};
},
/**
* Create an ASTNode representation of a while statement
* @param {ASTNode} test The while conditional
* @param {ASTNode} body The while loop body
* @returns {ASTNode} An ASTNode representing a while statement
*/
createWhileStatement: function(test, body) {
return {
type: astNodeTypes.WhileStatement,
test: test,
body: body
};
},
/**
* Create an ASTNode representation of a do..while statement
* @param {ASTNode} test The do..while conditional
* @param {ASTNode} body The do..while loop body
* @returns {ASTNode} An ASTNode representing a do..while statement
*/
createDoWhileStatement: function(test, body) {
return {
type: astNodeTypes.DoWhileStatement,
body: body,
test: test
};
},
/**
* Create an ASTNode representation of a for statement
* @param {ASTNode} init The initialization expression
* @param {ASTNode} test The conditional test expression
* @param {ASTNode} update The update expression
* @param {ASTNode} body The statement body
* @returns {ASTNode} An ASTNode representing a for statement
*/
createForStatement: function(init, test, update, body) {
return {
type: astNodeTypes.ForStatement,
init: init,
test: test,
update: update,
body: body
};
},
/**
* Create an ASTNode representation of a for..in statement
* @param {ASTNode} left The left-side variable for the property name
* @param {ASTNode} right The right-side object
* @param {ASTNode} body The statement body
* @returns {ASTNode} An ASTNode representing a for..in statement
*/
createForInStatement: function(left, right, body) {
return {
type: astNodeTypes.ForInStatement,
left: left,
right: right,
body: body,
each: false
};
},
/**
* Create an ASTNode representation of a for..of statement
* @param {ASTNode} left The left-side variable for the property value
* @param {ASTNode} right The right-side object
* @param {ASTNode} body The statement body
* @returns {ASTNode} An ASTNode representing a for..of statement
*/
createForOfStatement: function(left, right, body) {
return {
type: astNodeTypes.ForOfStatement,
left: left,
right: right,
body: body
};
},
/**
* Create an ASTNode representation of a function declaration
* @param {ASTNode} id The function name
* @param {ASTNode} params The function arguments
* @param {ASTNode} body The function body
* @param {boolean} generator True if the function is a generator, false if not.
* @param {boolean} expression True if the function is created via an expression.
* Always false for declarations, but kept here to be in sync with
* FunctionExpression objects.
* @returns {ASTNode} An ASTNode representing a function declaration
*/
createFunctionDeclaration: function (id, params, body, generator, expression) {
return {
type: astNodeTypes.FunctionDeclaration,
id: id,
params: params || [],
body: body,
generator: !!generator,
expression: !!expression
};
},
/**
* Create an ASTNode representation of a function expression
* @param {ASTNode} id The function name
* @param {ASTNode} params The function arguments
* @param {ASTNode} body The function body
* @param {boolean} generator True if the function is a generator, false if not.
* @param {boolean} expression True if the function is created via an expression.
* @returns {ASTNode} An ASTNode representing a function declaration
*/
createFunctionExpression: function (id, params, body, generator, expression) {
return {
type: astNodeTypes.FunctionExpression,
id: id,
params: params || [],
body: body,
generator: !!generator,
expression: !!expression
};
},
/**
* Create an ASTNode representation of an identifier
* @param {ASTNode} name The identifier name
* @returns {ASTNode} An ASTNode representing an identifier
*/
createIdentifier: function(name) {
return {
type: astNodeTypes.Identifier,
name: name
};
},
/**
* Create an ASTNode representation of an if statement
* @param {ASTNode} test The if conditional expression
* @param {ASTNode} consequent The consequent if statement to run
* @param {ASTNode} alternate the "else" alternate statement
* @returns {ASTNode} An ASTNode representing an if statement
*/
createIfStatement: function(test, consequent, alternate) {
return {
type: astNodeTypes.IfStatement,
test: test,
consequent: consequent,
alternate: alternate
};
},
/**
* Create an ASTNode representation of a labeled statement
* @param {ASTNode} label The statement label
* @param {ASTNode} body The labeled statement body
* @returns {ASTNode} An ASTNode representing a labeled statement
*/
createLabeledStatement: function(label, body) {
return {
type: astNodeTypes.LabeledStatement,
label: label,
body: body
};
},
/**
* Create an ASTNode literal from the source code
* @param {ASTNode} token The ASTNode token
* @param {string} source The source code to get the literal from
* @returns {ASTNode} An ASTNode representing the new literal
*/
createLiteralFromSource: function(token, source) {
var node = {
type: astNodeTypes.Literal,
value: token.value,
raw: source.slice(token.range[0], token.range[1])
};
// regular expressions have regex properties
if (token.regex) {
node.regex = token.regex;
}
return node;
},
/**
* Create an ASTNode template element
* @param {Object} value Data on the element value
* @param {string} value.raw The raw template string
* @param {string} value.cooked The processed template string
* @param {boolean} tail True if this is the final element in a template string
* @returns {ASTNode} An ASTNode representing the template string element
*/
createTemplateElement: function(value, tail) {
return {
type: astNodeTypes.TemplateElement,
value: value,
tail: tail
};
},
/**
* Create an ASTNode template literal
* @param {ASTNode[]} quasis An array of the template string elements
* @param {ASTNode[]} expressions An array of the template string expressions
* @returns {ASTNode} An ASTNode representing the template string
*/
createTemplateLiteral: function(quasis, expressions) {
return {
type: astNodeTypes.TemplateLiteral,
quasis: quasis,
expressions: expressions
};
},
/**
* Create an ASTNode representation of a spread element
* @param {ASTNode} argument The array being spread
* @returns {ASTNode} An ASTNode representing a spread element
*/
createSpreadElement: function(argument) {
return {
type: astNodeTypes.SpreadElement,
argument: argument
};
},
/**
* Create an ASTNode tagged template expression
* @param {ASTNode} tag The tag expression
* @param {ASTNode} quasi A TemplateLiteral ASTNode representing
* the template string itself.
* @returns {ASTNode} An ASTNode representing the tagged template
*/
createTaggedTemplateExpression: function(tag, quasi) {
return {
type: astNodeTypes.TaggedTemplateExpression,
tag: tag,
quasi: quasi
};
},
/**
* Create an ASTNode representation of a member expression
* @param {string} accessor The member access method (bracket or period)
* @param {ASTNode} object The object being referenced
* @param {ASTNode} property The object-property being referenced
* @returns {ASTNode} An ASTNode representing a member expression
*/
createMemberExpression: function(accessor, object, property) {
return {
type: astNodeTypes.MemberExpression,
computed: accessor === "[",
object: object,
property: property
};
},
/**
* Create an ASTNode representation of a new expression
* @param {ASTNode} callee The constructor for the new object type
* @param {ASTNode} args The arguments passed to the constructor
* @returns {ASTNode} An ASTNode representing a new expression
*/
createNewExpression: function(callee, args) {
return {
type: astNodeTypes.NewExpression,
callee: callee,
"arguments": args
};
},
/**
* Create an ASTNode representation of a new object expression
* @param {ASTNode[]} properties An array of ASTNodes that represent all object
* properties and associated values
* @returns {ASTNode} An ASTNode representing a new object expression
*/
createObjectExpression: function(properties) {
return {
type: astNodeTypes.ObjectExpression,
properties: properties
};
},
/**
* Create an ASTNode representation of a postfix expression
* @param {string} operator The postfix operator ("++", "--", etc.)
* @param {ASTNode} argument The operator argument
* @returns {ASTNode} An ASTNode representing a postfix expression
*/
createPostfixExpression: function(operator, argument) {
return {
type: astNodeTypes.UpdateExpression,
operator: operator,
argument: argument,
prefix: false
};
},
/**
* Create an ASTNode representation of an entire program
* @param {ASTNode} body The program body
* @param {string} sourceType Either "module" or "script".
* @returns {ASTNode} An ASTNode representing an entire program
*/
createProgram: function(body, sourceType) {
return {
type: astNodeTypes.Program,
body: body,
sourceType: sourceType
};
},
/**
* Create an ASTNode representation of an object property
* @param {string} kind The type of property represented ("get", "set", etc.)
* @param {ASTNode} key The property key
* @param {ASTNode} value The new property value
* @param {boolean} method True if the property is also a method (value is a function)
* @param {boolean} shorthand True if the property is shorthand
* @param {boolean} computed True if the property value has been computed
* @returns {ASTNode} An ASTNode representing an object property
*/
createProperty: function(kind, key, value, method, shorthand, computed) {
return {
type: astNodeTypes.Property,
key: key,
value: value,
kind: kind,
method: method,
shorthand: shorthand,
computed: computed
};
},
/**
* Create an ASTNode representation of a rest element
* @param {ASTNode} argument The rest argument
* @returns {ASTNode} An ASTNode representing a rest element
*/
createRestElement: function (argument) {
return {
type: astNodeTypes.RestElement,
argument: argument
};
},
/**
* Create an ASTNode representation of a return statement
* @param {?ASTNode} argument The return argument, null if no argument is provided
* @returns {ASTNode} An ASTNode representing a return statement
*/
createReturnStatement: function(argument) {
return {
type: astNodeTypes.ReturnStatement,
argument: argument
};
},
/**
* Create an ASTNode representation of a sequence of expressions
* @param {ASTNode[]} expressions An array containing each expression, in order
* @returns {ASTNode} An ASTNode representing a sequence of expressions
*/
createSequenceExpression: function(expressions) {
return {
type: astNodeTypes.SequenceExpression,
expressions: expressions
};
},
/**
* Create an ASTNode representation of super
* @returns {ASTNode} An ASTNode representing super
*/
createSuper: function() {
return {
type: astNodeTypes.Super
};
},
/**
* Create an ASTNode representation of a switch case statement
* @param {ASTNode} test The case value to test against the switch value
* @param {ASTNode} consequent The consequent case statement
* @returns {ASTNode} An ASTNode representing a switch case
*/
createSwitchCase: function(test, consequent) {
return {
type: astNodeTypes.SwitchCase,
test: test,
consequent: consequent
};
},
/**
* Create an ASTNode representation of a switch statement
* @param {ASTNode} discriminant An expression to test against each case value
* @param {ASTNode[]} cases An array of switch case statements
* @returns {ASTNode} An ASTNode representing a switch statement
*/
createSwitchStatement: function(discriminant, cases) {
return {
type: astNodeTypes.SwitchStatement,
discriminant: discriminant,
cases: cases
};
},
/**
* Create an ASTNode representation of a this statement
* @returns {ASTNode} An ASTNode representing a this statement
*/
createThisExpression: function() {
return {
type: astNodeTypes.ThisExpression
};
},
/**
* Create an ASTNode representation of a throw statement
* @param {ASTNode} argument The argument to throw
* @returns {ASTNode} An ASTNode representing a throw statement
*/
createThrowStatement: function(argument) {
return {
type: astNodeTypes.ThrowStatement,
argument: argument
};
},
/**
* Create an ASTNode representation of a try statement
* @param {ASTNode} block The try block
* @param {ASTNode} handler A catch handler
* @param {?ASTNode} finalizer The final code block to run after the try/catch has run
* @returns {ASTNode} An ASTNode representing a try statement
*/
createTryStatement: function(block, handler, finalizer) {
return {
type: astNodeTypes.TryStatement,
block: block,
handler: handler,
finalizer: finalizer
};
},
/**
* Create an ASTNode representation of a unary expression
* @param {string} operator The unary operator
* @param {ASTNode} argument The unary operand
* @returns {ASTNode} An ASTNode representing a unary expression
*/
createUnaryExpression: function(operator, argument) {
if (operator === "++" || operator === "--") {
return {
type: astNodeTypes.UpdateExpression,
operator: operator,
argument: argument,
prefix: true
};
}
return {
type: astNodeTypes.UnaryExpression,
operator: operator,
argument: argument,
prefix: true
};
},
/**
* Create an ASTNode representation of a variable declaration
* @param {ASTNode[]} declarations An array of variable declarations
* @param {string} kind The kind of variable created ("var", "let", etc.)
* @returns {ASTNode} An ASTNode representing a variable declaration
*/
createVariableDeclaration: function(declarations, kind) {
return {
type: astNodeTypes.VariableDeclaration,
declarations: declarations,
kind: kind
};
},
/**
* Create an ASTNode representation of a variable declarator
* @param {ASTNode} id The variable ID
* @param {ASTNode} init The variable's initial value
* @returns {ASTNode} An ASTNode representing a variable declarator
*/
createVariableDeclarator: function(id, init) {
return {
type: astNodeTypes.VariableDeclarator,
id: id,
init: init
};
},
/**
* Create an ASTNode representation of a with statement
* @param {ASTNode} object The with statement object expression
* @param {ASTNode} body The with statement body
* @returns {ASTNode} An ASTNode representing a with statement
*/
createWithStatement: function(object, body) {
return {
type: astNodeTypes.WithStatement,
object: object,
body: body
};
},
createYieldExpression: function(argument, delegate) {
return {
type: astNodeTypes.YieldExpression,
argument: argument || null,
delegate: delegate
};
},
createJSXAttribute: function(name, value) {
return {
type: astNodeTypes.JSXAttribute,
name: name,
value: value || null
};
},
createJSXSpreadAttribute: function(argument) {
return {
type: astNodeTypes.JSXSpreadAttribute,
argument: argument
};
},
createJSXIdentifier: function(name) {
return {
type: astNodeTypes.JSXIdentifier,
name: name
};
},
createJSXNamespacedName: function(namespace, name) {
return {
type: astNodeTypes.JSXNamespacedName,
namespace: namespace,
name: name
};
},
createJSXMemberExpression: function(object, property) {
return {
type: astNodeTypes.JSXMemberExpression,
object: object,
property: property
};
},
createJSXElement: function(openingElement, closingElement, children) {
return {
type: astNodeTypes.JSXElement,
openingElement: openingElement,
closingElement: closingElement,
children: children
};
},
createJSXEmptyExpression: function() {
return {
type: astNodeTypes.JSXEmptyExpression
};
},
createJSXExpressionContainer: function(expression) {
return {
type: astNodeTypes.JSXExpressionContainer,
expression: expression
};
},
createJSXOpeningElement: function(name, attributes, selfClosing) {
return {
type: astNodeTypes.JSXOpeningElement,
name: name,
selfClosing: selfClosing,
attributes: attributes
};
},
createJSXClosingElement: function(name) {
return {
type: astNodeTypes.JSXClosingElement,
name: name
};
},
createExportSpecifier: function(local, exported) {
return {
type: astNodeTypes.ExportSpecifier,
exported: exported || local,
local: local
};
},
createImportDefaultSpecifier: function(local) {
return {
type: astNodeTypes.ImportDefaultSpecifier,
local: local
};
},
createImportNamespaceSpecifier: function(local) {
return {
type: astNodeTypes.ImportNamespaceSpecifier,
local: local
};
},
createExportNamedDeclaration: function(declaration, specifiers, source) {
return {
type: astNodeTypes.ExportNamedDeclaration,
declaration: declaration,
specifiers: specifiers,
source: source
};
},
createExportDefaultDeclaration: function(declaration) {
return {
type: astNodeTypes.ExportDefaultDeclaration,
declaration: declaration
};
},
createExportAllDeclaration: function(source) {
return {
type: astNodeTypes.ExportAllDeclaration,
source: source
};
},
createImportSpecifier: function(local, imported) {
return {
type: astNodeTypes.ImportSpecifier,
local: local || imported,
imported: imported
};
},
createImportDeclaration: function(specifiers, source) {
return {
type: astNodeTypes.ImportDeclaration,
specifiers: specifiers,
source: source
};
}
};