From 404058f9dad0c7da92b338987e301a1d7661c9a1 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Sat, 6 Dec 2014 20:43:32 +1100 Subject: [PATCH] Add object memo getters, this expressions and improve tenary syntax in playground --- acorn.js | 39 +++++-- package.json | 2 +- test/tests-6to5-playground.js | 195 +++++++++++++++++++++++++++++++++- 3 files changed, 226 insertions(+), 10 deletions(-) diff --git a/acorn.js b/acorn.js index 46d430a819..a440be64ac 100644 --- a/acorn.js +++ b/acorn.js @@ -885,7 +885,12 @@ case 123: ++tokPos; return finishToken(_braceL); case 125: ++tokPos; return finishToken(_braceR, undefined, !inXJSChild); case 63: ++tokPos; return finishToken(_question); - case 64: ++tokPos; return finishToken(_at); + + case 64: + if (options.playground) { + ++tokPos; + return finishToken(_at); + } case 58: ++tokPos; @@ -1707,7 +1712,6 @@ node.loc.end = lastEndLoc; if (options.ranges) node.range[1] = lastEnd; - console.log(node); return node; } @@ -2374,9 +2378,23 @@ return finishNode(node, "AssignmentExpression"); } node.test = expr; - node.consequent = parseExpression(true); - expect(_colon); - node.alternate = parseExpression(true, noIn); + var consequent = node.consequent = parseExpression(true); + if (consequent.type === "BindMemberExpression" && tokType !== _colon) { + // this is a hack to make, revisit at a later date + if (consequent.arguments.length) { + node.alternate = { + type: "CallExpression", + arguments: consequent.arguments, + callee: consequent.property + }; + } else { + node.alternate = consequent.property; + } + node.consequent = consequent.object; + } else { + expect(_colon); + node.alternate = parseExpression(true, noIn); + } return finishNode(node, "ConditionalExpression"); } return expr; @@ -2510,7 +2528,12 @@ return finishNode(node, "ThisExpression"); case _at: - unexpected(); // todo: @foo -> this.foo + var node = startNode(); + next(); + node.object = { type: "ThisExpression" } + node.property = parseExprSubscripts(); + node.computed = false; + return finishNode(node, "MemberExpression"); case _yield: if (inGenerator) return parseYield(); @@ -2726,7 +2749,7 @@ prop.method = true; prop.value = parseMethod(isGenerator, isAsync); } else if (options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && - (prop.key.name === "get" || prop.key.name === "set")) { + (prop.key.name === "get" || prop.key.name === "set" || (options.playground && prop.key.name === "memo"))) { if (isGenerator || isAsync) unexpected(); prop.kind = prop.key.name; parsePropertyName(prop); @@ -2934,7 +2957,7 @@ var isGenerator = eat(_star); parsePropertyName(method); if (tokType !== _parenL && !method.computed && method.key.type === "Identifier" && - (method.key.name === "get" || method.key.name === "set")) { + (method.key.name === "get" || method.key.name === "set" || (options.playground && method.key.name === "memo"))) { if (isGenerator || isAsync) unexpected(); method.kind = method.key.name; parsePropertyName(method); diff --git a/package.json b/package.json index c97fcd0a72..1e3a5bbb6a 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "acorn-6to5", "description": "Acorn fork used by 6to5", "main": "acorn.js", - "version": "0.9.1-11", + "version": "0.9.1-12", "maintainers": [ { "name": "Marijn Haverbeke", diff --git a/test/tests-6to5-playground.js b/test/tests-6to5-playground.js index 48386298cb..85b016d2cc 100644 --- a/test/tests-6to5-playground.js +++ b/test/tests-6to5-playground.js @@ -4,9 +4,202 @@ if (typeof exports != "undefined") { var testAssert = require("./driver.js").testAssert; } +// This shorthand + +test("@foo", { + "type": "Program", + "start": 0, + "end": 4, + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 4, + "expression": { + "type": "MemberExpression", + "start": 0, + "end": 4, + "object": { + "type": "ThisExpression" + }, + "property": { + "type": "Identifier", + "start": 1, + "end": 4, + "name": "foo" + }, + "computed": false + } + } + ] +}, { + playground: true +}); + +test("@foo();", { + "type": "Program", + "start": 0, + "end": 7, + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 7, + "expression": { + "type": "MemberExpression", + "start": 0, + "end": 6, + "object": { + "type": "ThisExpression" + }, + "property": { + "type": "CallExpression", + "start": 1, + "end": 6, + "callee": { + "type": "Identifier", + "start": 1, + "end": 4, + "name": "foo" + }, + "arguments": [] + }, + "computed": false + } + } + ] +}, { + playground: true +}); + +// Object getter memoisation + +test("class Foo { memo bar() {} }", { + type: "Program", + start: 0, + end: 27, + body: [{ + type: "ClassDeclaration", + start: 0, + end: 27, + id: { + type: "Identifier", + start: 6, + end: 9, + name: "Foo" + }, + superClass: null, + body: { + type: "ClassBody", + start: 10, + end: 27, + body: [{ + type: "MethodDefinition", + start: 12, + end: 25, + static: false, + computed: false, + key: { + type: "Identifier", + start: 17, + end: 20, + name: "bar" + }, + kind: "memo", + value: { + type: "FunctionExpression", + start: 20, + end: 25, + id: null, + params: [], + defaults: [], + rest: null, + generator: false, + async: false, + body: { + type: "BlockStatement", + start: 23, + end: 25, + body: [] + }, + expression: false + } + }] + } + }] +}, { + playground: true, + ecmaVersion: 6 +}); + +test("var foo = { memo bar() {} };", +{ + type: "Program", + start: 0, + end: 28, + body: [{ + type: "VariableDeclaration", + start: 0, + end: 28, + declarations: [{ + type: "VariableDeclarator", + start: 4, + end: 27, + id: { + type: "Identifier", + start: 4, + end: 7, + name: "foo" + }, + init: { + type: "ObjectExpression", + start: 10, + end: 27, + properties: [{ + type: "Property", + start: 12, + end: 25, + method: false, + shorthand: false, + computed: false, + key: { + type: "Identifier", + start: 17, + end: 20, + name: "bar" + }, + kind: "memo", + value: { + type: "FunctionExpression", + start: 20, + end: 25, + id: null, + params: [], + defaults: [], + rest: null, + generator: false, + async: false, + body: { + type: "BlockStatement", + start: 23, + end: 25, + body: [] + }, + expression: false + } + }] + } + }], + kind: "var" + }] +}, { + playground: true, + ecmaVersion: 6 +}); + // Memoization assignment operator -// Make sure conditionals still work +//- Make sure conditionals still work test("y ? 1 : 2", { type: "Program",