From 461e762c0c77830dababdac901c0c6fb5fd7f51e Mon Sep 17 00:00:00 2001 From: "Nicholas C. Zakas" Date: Sat, 4 Apr 2015 11:02:41 -0700 Subject: [PATCH] New: Add Super node (fixes #115) --- espree.js | 2 +- lib/ast-node-factory.js | 140 ++++++++++-------- lib/ast-node-types.js | 1 + .../classes/class-one-method-super.result.js | 5 +- ...-function-call-in-object-literal.result.js | 5 +- .../super-function-call.result.js | 5 +- ...-property-call-in-object-literal.result.js | 5 +- .../super-property-call.result.js | 5 +- 8 files changed, 87 insertions(+), 81 deletions(-) diff --git a/espree.js b/espree.js index de6ce928..c6aab467 100644 --- a/espree.js +++ b/espree.js @@ -2862,7 +2862,7 @@ function parsePrimaryExpression() { if (allowSuper && matchKeyword("super") && state.inFunctionBody) { marker = markerCreate(); lex(); - return markerApply(marker, astNodeFactory.createIdentifier("super")); + return markerApply(marker, astNodeFactory.createSuper()); } if (matchKeyword("this")) { diff --git a/lib/ast-node-factory.js b/lib/ast-node-factory.js index e91053fb..2425ace9 100644 --- a/lib/ast-node-factory.js +++ b/lib/ast-node-factory.js @@ -44,7 +44,7 @@ module.exports = { * @param {ASTNode[]} elements An array of ASTNode elements * @returns {ASTNode} An ASTNode representing the entire array expression */ - createArrayExpression: function (elements) { + createArrayExpression: function(elements) { return { type: astNodeTypes.ArrayExpression, elements: elements @@ -80,7 +80,7 @@ module.exports = { * @param {ASTNode} right The right operand * @returns {ASTNode} An ASTNode representing the entire assignment expression */ - createAssignmentExpression: function (operator, left, right) { + createAssignmentExpression: function(operator, left, right) { return { type: astNodeTypes.AssignmentExpression, operator: operator, @@ -96,7 +96,7 @@ module.exports = { * @param {ASTNode} right The right operand * @returns {ASTNode} An ASTNode representing the entire binary expression */ - createBinaryExpression: function (operator, left, right) { + createBinaryExpression: function(operator, left, right) { var type = (operator === "||" || operator === "&&") ? astNodeTypes.LogicalExpression : astNodeTypes.BinaryExpression; return { @@ -112,7 +112,7 @@ module.exports = { * @param {ASTNode} body The block statement body * @returns {ASTNode} An ASTNode representing the entire block statement */ - createBlockStatement: function (body) { + createBlockStatement: function(body) { return { type: astNodeTypes.BlockStatement, body: body @@ -124,7 +124,7 @@ module.exports = { * @param {ASTNode} label The break statement label * @returns {ASTNode} An ASTNode representing the break statement */ - createBreakStatement: function (label) { + createBreakStatement: function(label) { return { type: astNodeTypes.BreakStatement, label: label @@ -137,7 +137,7 @@ module.exports = { * @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) { + createCallExpression: function(callee, args) { return { type: astNodeTypes.CallExpression, callee: callee, @@ -151,7 +151,7 @@ module.exports = { * @param {ASTNode} body The catch block body * @returns {ASTNode} An ASTNode representing the entire catch clause */ - createCatchClause: function (param, body) { + createCatchClause: function(param, body) { return { type: astNodeTypes.CatchClause, param: param, @@ -164,14 +164,14 @@ module.exports = { * @param {ASTNode} body The node representing the body of the class. * @returns {ASTNode} An ASTNode representing the class body. */ - createClassBody: function (body) { + createClassBody: function(body) { return { type: astNodeTypes.ClassBody, body: body }; }, - createClassExpression: function (id, superClass, body) { + createClassExpression: function(id, superClass, body) { return { type: astNodeTypes.ClassExpression, id: id, @@ -180,7 +180,7 @@ module.exports = { }; }, - createClassDeclaration: function (id, superClass, body) { + createClassDeclaration: function(id, superClass, body) { return { type: astNodeTypes.ClassDeclaration, id: id, @@ -189,7 +189,7 @@ module.exports = { }; }, - createMethodDefinition: function (propertyType, kind, key, value, computed) { + createMethodDefinition: function(propertyType, kind, key, value, computed) { return { type: astNodeTypes.MethodDefinition, key: key, @@ -207,7 +207,7 @@ module.exports = { * @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) { + createConditionalExpression: function(test, consequent, alternate) { return { type: astNodeTypes.ConditionalExpression, test: test, @@ -221,7 +221,7 @@ module.exports = { * @param {?ASTNode} label The optional continue label (null if not set) * @returns {ASTNode} An ASTNode representing the continue statement */ - createContinueStatement: function (label) { + createContinueStatement: function(label) { return { type: astNodeTypes.ContinueStatement, label: label @@ -232,7 +232,7 @@ module.exports = { * Create an ASTNode representation of a debugger statement * @returns {ASTNode} An ASTNode representing the debugger statement */ - createDebuggerStatement: function () { + createDebuggerStatement: function() { return { type: astNodeTypes.DebuggerStatement }; @@ -242,7 +242,7 @@ module.exports = { * Create an ASTNode representation of an empty statement * @returns {ASTNode} An ASTNode representing an empty statement */ - createEmptyStatement: function () { + createEmptyStatement: function() { return { type: astNodeTypes.EmptyStatement }; @@ -253,7 +253,7 @@ module.exports = { * @param {ASTNode} expression The expression * @returns {ASTNode} An ASTNode representing an expression statement */ - createExpressionStatement: function (expression) { + createExpressionStatement: function(expression) { return { type: astNodeTypes.ExpressionStatement, expression: expression @@ -266,7 +266,7 @@ module.exports = { * @param {ASTNode} body The while loop body * @returns {ASTNode} An ASTNode representing a while statement */ - createWhileStatement: function (test, body) { + createWhileStatement: function(test, body) { return { type: astNodeTypes.WhileStatement, test: test, @@ -280,7 +280,7 @@ module.exports = { * @param {ASTNode} body The do..while loop body * @returns {ASTNode} An ASTNode representing a do..while statement */ - createDoWhileStatement: function (test, body) { + createDoWhileStatement: function(test, body) { return { type: astNodeTypes.DoWhileStatement, body: body, @@ -296,7 +296,7 @@ module.exports = { * @param {ASTNode} body The statement body * @returns {ASTNode} An ASTNode representing a for statement */ - createForStatement: function (init, test, update, body) { + createForStatement: function(init, test, update, body) { return { type: astNodeTypes.ForStatement, init: init, @@ -313,7 +313,7 @@ module.exports = { * @param {ASTNode} body The statement body * @returns {ASTNode} An ASTNode representing a for..in statement */ - createForInStatement: function (left, right, body) { + createForInStatement: function(left, right, body) { return { type: astNodeTypes.ForInStatement, left: left, @@ -330,7 +330,7 @@ module.exports = { * @param {ASTNode} body The statement body * @returns {ASTNode} An ASTNode representing a for..of statement */ - createForOfStatement: function (left, right, body) { + createForOfStatement: function(left, right, body) { return { type: astNodeTypes.ForOfStatement, left: left, @@ -390,7 +390,7 @@ module.exports = { * @param {ASTNode} name The identifier name * @returns {ASTNode} An ASTNode representing an identifier */ - createIdentifier: function (name) { + createIdentifier: function(name) { return { type: astNodeTypes.Identifier, name: name @@ -404,7 +404,7 @@ module.exports = { * @param {ASTNode} alternate the "else" alternate statement * @returns {ASTNode} An ASTNode representing an if statement */ - createIfStatement: function (test, consequent, alternate) { + createIfStatement: function(test, consequent, alternate) { return { type: astNodeTypes.IfStatement, test: test, @@ -419,7 +419,7 @@ module.exports = { * @param {ASTNode} body The labeled statement body * @returns {ASTNode} An ASTNode representing a labeled statement */ - createLabeledStatement: function (label, body) { + createLabeledStatement: function(label, body) { return { type: astNodeTypes.LabeledStatement, label: label, @@ -433,7 +433,7 @@ module.exports = { * @param {string} source The source code to get the literal from * @returns {ASTNode} An ASTNode representing the new literal */ - createLiteralFromSource: function (token, source) { + createLiteralFromSource: function(token, source) { var node = { type: astNodeTypes.Literal, value: token.value, @@ -456,7 +456,7 @@ module.exports = { * @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) { + createTemplateElement: function(value, tail) { return { type: astNodeTypes.TemplateElement, value: value, @@ -470,7 +470,7 @@ module.exports = { * @param {ASTNode[]} expressions An array of the template string expressions * @returns {ASTNode} An ASTNode representing the template string */ - createTemplateLiteral: function (quasis, expressions) { + createTemplateLiteral: function(quasis, expressions) { return { type: astNodeTypes.TemplateLiteral, quasis: quasis, @@ -483,7 +483,7 @@ module.exports = { * @param {ASTNode} argument The array being spread * @returns {ASTNode} An ASTNode representing a spread element */ - createSpreadElement: function (argument) { + createSpreadElement: function(argument) { return { type: astNodeTypes.SpreadElement, argument: argument @@ -497,7 +497,7 @@ module.exports = { * the template string itself. * @returns {ASTNode} An ASTNode representing the tagged template */ - createTaggedTemplateExpression: function (tag, quasi) { + createTaggedTemplateExpression: function(tag, quasi) { return { type: astNodeTypes.TaggedTemplateExpression, tag: tag, @@ -512,7 +512,7 @@ module.exports = { * @param {ASTNode} property The object-property being referenced * @returns {ASTNode} An ASTNode representing a member expression */ - createMemberExpression: function (accessor, object, property) { + createMemberExpression: function(accessor, object, property) { return { type: astNodeTypes.MemberExpression, computed: accessor === "[", @@ -527,7 +527,7 @@ module.exports = { * @param {ASTNode} args The arguments passed to the constructor * @returns {ASTNode} An ASTNode representing a new expression */ - createNewExpression: function (callee, args) { + createNewExpression: function(callee, args) { return { type: astNodeTypes.NewExpression, callee: callee, @@ -541,7 +541,7 @@ module.exports = { * properties and associated values * @returns {ASTNode} An ASTNode representing a new object expression */ - createObjectExpression: function (properties) { + createObjectExpression: function(properties) { return { type: astNodeTypes.ObjectExpression, properties: properties @@ -554,7 +554,7 @@ module.exports = { * @param {ASTNode} argument The operator argument * @returns {ASTNode} An ASTNode representing a postfix expression */ - createPostfixExpression: function (operator, argument) { + createPostfixExpression: function(operator, argument) { return { type: astNodeTypes.UpdateExpression, operator: operator, @@ -569,7 +569,7 @@ module.exports = { * @param {string} sourceType Either "module" or "script". * @returns {ASTNode} An ASTNode representing an entire program */ - createProgram: function (body, sourceType) { + createProgram: function(body, sourceType) { return { type: astNodeTypes.Program, body: body, @@ -587,7 +587,7 @@ module.exports = { * @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) { + createProperty: function(kind, key, value, method, shorthand, computed) { return { type: astNodeTypes.Property, key: key, @@ -616,7 +616,7 @@ module.exports = { * @param {?ASTNode} argument The return argument, null if no argument is provided * @returns {ASTNode} An ASTNode representing a return statement */ - createReturnStatement: function (argument) { + createReturnStatement: function(argument) { return { type: astNodeTypes.ReturnStatement, argument: argument @@ -628,20 +628,30 @@ module.exports = { * @param {ASTNode[]} expressions An array containing each expression, in order * @returns {ASTNode} An ASTNode representing a sequence of expressions */ - createSequenceExpression: function (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) { + createSwitchCase: function(test, consequent) { return { type: astNodeTypes.SwitchCase, test: test, @@ -655,7 +665,7 @@ module.exports = { * @param {ASTNode[]} cases An array of switch case statements * @returns {ASTNode} An ASTNode representing a switch statement */ - createSwitchStatement: function (discriminant, cases) { + createSwitchStatement: function(discriminant, cases) { return { type: astNodeTypes.SwitchStatement, discriminant: discriminant, @@ -667,7 +677,7 @@ module.exports = { * Create an ASTNode representation of a this statement * @returns {ASTNode} An ASTNode representing a this statement */ - createThisExpression: function () { + createThisExpression: function() { return { type: astNodeTypes.ThisExpression }; @@ -678,7 +688,7 @@ module.exports = { * @param {ASTNode} argument The argument to throw * @returns {ASTNode} An ASTNode representing a throw statement */ - createThrowStatement: function (argument) { + createThrowStatement: function(argument) { return { type: astNodeTypes.ThrowStatement, argument: argument @@ -692,7 +702,7 @@ module.exports = { * @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) { + createTryStatement: function(block, handler, finalizer) { return { type: astNodeTypes.TryStatement, block: block, @@ -707,7 +717,7 @@ module.exports = { * @param {ASTNode} argument The unary operand * @returns {ASTNode} An ASTNode representing a unary expression */ - createUnaryExpression: function (operator, argument) { + createUnaryExpression: function(operator, argument) { if (operator === "++" || operator === "--") { return { type: astNodeTypes.UpdateExpression, @@ -730,7 +740,7 @@ module.exports = { * @param {string} kind The kind of variable created ("var", "let", etc.) * @returns {ASTNode} An ASTNode representing a variable declaration */ - createVariableDeclaration: function (declarations, kind) { + createVariableDeclaration: function(declarations, kind) { return { type: astNodeTypes.VariableDeclaration, declarations: declarations, @@ -744,7 +754,7 @@ module.exports = { * @param {ASTNode} init The variable's initial value * @returns {ASTNode} An ASTNode representing a variable declarator */ - createVariableDeclarator: function (id, init) { + createVariableDeclarator: function(id, init) { return { type: astNodeTypes.VariableDeclarator, id: id, @@ -758,7 +768,7 @@ module.exports = { * @param {ASTNode} body The with statement body * @returns {ASTNode} An ASTNode representing a with statement */ - createWithStatement: function (object, body) { + createWithStatement: function(object, body) { return { type: astNodeTypes.WithStatement, object: object, @@ -766,7 +776,7 @@ module.exports = { }; }, - createYieldExpression: function (argument, delegate) { + createYieldExpression: function(argument, delegate) { return { type: astNodeTypes.YieldExpression, argument: argument, @@ -774,7 +784,7 @@ module.exports = { }; }, - createJSXAttribute: function (name, value) { + createJSXAttribute: function(name, value) { return { type: astNodeTypes.JSXAttribute, name: name, @@ -782,21 +792,21 @@ module.exports = { }; }, - createJSXSpreadAttribute: function (argument) { + createJSXSpreadAttribute: function(argument) { return { type: astNodeTypes.JSXSpreadAttribute, argument: argument }; }, - createJSXIdentifier: function (name) { + createJSXIdentifier: function(name) { return { type: astNodeTypes.JSXIdentifier, name: name }; }, - createJSXNamespacedName: function (namespace, name) { + createJSXNamespacedName: function(namespace, name) { return { type: astNodeTypes.JSXNamespacedName, namespace: namespace, @@ -804,7 +814,7 @@ module.exports = { }; }, - createJSXMemberExpression: function (object, property) { + createJSXMemberExpression: function(object, property) { return { type: astNodeTypes.JSXMemberExpression, object: object, @@ -812,7 +822,7 @@ module.exports = { }; }, - createJSXElement: function (openingElement, closingElement, children) { + createJSXElement: function(openingElement, closingElement, children) { return { type: astNodeTypes.JSXElement, openingElement: openingElement, @@ -821,20 +831,20 @@ module.exports = { }; }, - createJSXEmptyExpression: function () { + createJSXEmptyExpression: function() { return { type: astNodeTypes.JSXEmptyExpression }; }, - createJSXExpressionContainer: function (expression) { + createJSXExpressionContainer: function(expression) { return { type: astNodeTypes.JSXExpressionContainer, expression: expression }; }, - createJSXOpeningElement: function (name, attributes, selfClosing) { + createJSXOpeningElement: function(name, attributes, selfClosing) { return { type: astNodeTypes.JSXOpeningElement, name: name, @@ -843,14 +853,14 @@ module.exports = { }; }, - createJSXClosingElement: function (name) { + createJSXClosingElement: function(name) { return { type: astNodeTypes.JSXClosingElement, name: name }; }, - createExportSpecifier: function (local, exported) { + createExportSpecifier: function(local, exported) { return { type: astNodeTypes.ExportSpecifier, exported: exported || local, @@ -858,21 +868,21 @@ module.exports = { }; }, - createImportDefaultSpecifier: function (local) { + createImportDefaultSpecifier: function(local) { return { type: astNodeTypes.ImportDefaultSpecifier, local: local }; }, - createImportNamespaceSpecifier: function (local) { + createImportNamespaceSpecifier: function(local) { return { type: astNodeTypes.ImportNamespaceSpecifier, local: local }; }, - createExportNamedDeclaration: function (declaration, specifiers, source) { + createExportNamedDeclaration: function(declaration, specifiers, source) { return { type: astNodeTypes.ExportNamedDeclaration, declaration: declaration, @@ -881,21 +891,21 @@ module.exports = { }; }, - createExportDefaultDeclaration: function (declaration) { + createExportDefaultDeclaration: function(declaration) { return { type: astNodeTypes.ExportDefaultDeclaration, declaration: declaration }; }, - createExportAllDeclaration: function (source) { + createExportAllDeclaration: function(source) { return { type: astNodeTypes.ExportAllDeclaration, source: source }; }, - createImportSpecifier: function (local, imported) { + createImportSpecifier: function(local, imported) { return { type: astNodeTypes.ImportSpecifier, local: local || imported, @@ -903,7 +913,7 @@ module.exports = { }; }, - createImportDeclaration: function (specifiers, source) { + createImportDeclaration: function(specifiers, source) { return { type: astNodeTypes.ImportDeclaration, specifiers: specifiers, diff --git a/lib/ast-node-types.js b/lib/ast-node-types.js index 6d019bed..5d14b7f4 100644 --- a/lib/ast-node-types.js +++ b/lib/ast-node-types.js @@ -78,6 +78,7 @@ module.exports = { ReturnStatement: "ReturnStatement", SequenceExpression: "SequenceExpression", SpreadElement: "SpreadElement", + Super: "Super", SwitchCase: "SwitchCase", SwitchStatement: "SwitchStatement", TaggedTemplateExpression: "TaggedTemplateExpression", diff --git a/tests/fixtures/ecma-features/classes/class-one-method-super.result.js b/tests/fixtures/ecma-features/classes/class-one-method-super.result.js index e6830e62..c107e13a 100644 --- a/tests/fixtures/ecma-features/classes/class-one-method-super.result.js +++ b/tests/fixtures/ecma-features/classes/class-one-method-super.result.js @@ -58,8 +58,7 @@ module.exports = { "expression": { "type": "CallExpression", "callee": { - "type": "Identifier", - "name": "super", + "type": "Super", "range": [ 27, 32 @@ -221,4 +220,4 @@ module.exports = { "column": 2 } } -}; \ No newline at end of file +}; diff --git a/tests/fixtures/ecma-features/superInFunctions/super-function-call-in-object-literal.result.js b/tests/fixtures/ecma-features/superInFunctions/super-function-call-in-object-literal.result.js index df6f71f2..3eb41481 100644 --- a/tests/fixtures/ecma-features/superInFunctions/super-function-call-in-object-literal.result.js +++ b/tests/fixtures/ecma-features/superInFunctions/super-function-call-in-object-literal.result.js @@ -60,8 +60,7 @@ module.exports = { "expression": { "type": "CallExpression", "callee": { - "type": "Identifier", - "name": "super", + "type": "Super", "range": [ 41, 46 @@ -224,4 +223,4 @@ module.exports = { "column": 2 } } -}; \ No newline at end of file +}; diff --git a/tests/fixtures/ecma-features/superInFunctions/super-function-call.result.js b/tests/fixtures/ecma-features/superInFunctions/super-function-call.result.js index 2126d0d7..8f3c1ee4 100644 --- a/tests/fixtures/ecma-features/superInFunctions/super-function-call.result.js +++ b/tests/fixtures/ecma-features/superInFunctions/super-function-call.result.js @@ -31,8 +31,7 @@ module.exports = { "expression": { "type": "CallExpression", "callee": { - "type": "Identifier", - "name": "super", + "type": "Super", "range": [ 21, 26 @@ -145,4 +144,4 @@ module.exports = { "column": 2 } } -}; \ No newline at end of file +}; diff --git a/tests/fixtures/ecma-features/superInFunctions/super-property-call-in-object-literal.result.js b/tests/fixtures/ecma-features/superInFunctions/super-property-call-in-object-literal.result.js index 7584de27..0c9d138f 100644 --- a/tests/fixtures/ecma-features/superInFunctions/super-property-call-in-object-literal.result.js +++ b/tests/fixtures/ecma-features/superInFunctions/super-property-call-in-object-literal.result.js @@ -63,8 +63,7 @@ module.exports = { "type": "MemberExpression", "computed": false, "object": { - "type": "Identifier", - "name": "super", + "type": "Super", "range": [ 41, 46 @@ -260,4 +259,4 @@ module.exports = { "column": 2 } } -}; \ No newline at end of file +}; diff --git a/tests/fixtures/ecma-features/superInFunctions/super-property-call.result.js b/tests/fixtures/ecma-features/superInFunctions/super-property-call.result.js index 6c700025..f0a31bb5 100644 --- a/tests/fixtures/ecma-features/superInFunctions/super-property-call.result.js +++ b/tests/fixtures/ecma-features/superInFunctions/super-property-call.result.js @@ -34,8 +34,7 @@ module.exports = { "type": "MemberExpression", "computed": false, "object": { - "type": "Identifier", - "name": "super", + "type": "Super", "range": [ 21, 26 @@ -181,4 +180,4 @@ module.exports = { "column": 2 } } -}; \ No newline at end of file +};