From b5da7737b9f5527a9e30082d166c350037d9135d Mon Sep 17 00:00:00 2001 From: Erik Arvidsson Date: Sat, 23 Apr 2016 13:39:42 -0700 Subject: [PATCH] Fix spread props and make ptc use import runtime --- src/codegeneration/JsxTransformer.js | 21 ++++++++----------- .../ProperTailCallTransformer.js | 19 ++++++++++++----- .../RewriteTailExpressionsTransformer.js | 17 ++++++++------- .../SpreadPropertiesTransformer.js | 3 +-- 4 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/codegeneration/JsxTransformer.js b/src/codegeneration/JsxTransformer.js index 776bcf02e..f32e75730 100644 --- a/src/codegeneration/JsxTransformer.js +++ b/src/codegeneration/JsxTransformer.js @@ -42,6 +42,7 @@ import { } from './ParseTreeFactory.js'; import {parseExpression} from './PlaceholderParser.js'; import {spreadProperties} from './SpreadPropertiesTransformer.js'; +import ImportRuntimeTrait from './ImportRuntimeTrait.js'; /** * Desugars JSX expressions. @@ -63,10 +64,10 @@ import {spreadProperties} from './SpreadPropertiesTransformer.js'; * * myFunc('p', null) */ -export class JsxTransformer extends ParseTreeTransformer { +export class JsxTransformer extends ImportRuntimeTrait(ParseTreeTransformer) { constructor(idGen, reporter, options) { super(); - this.options_ = options; + this.options = options; this.jsxFunction_ = null; } @@ -75,7 +76,7 @@ export class JsxTransformer extends ParseTreeTransformer { // --jsx -> React.createElement(tagName, opts, ...children) // --jsx=a.b.c -> a.b.c(tagName, opts, ...children) if (!this.jsxFunction_) { - let jsx = this.options_.jsx; + let jsx = this.options.jsx; if (typeof jsx === 'string') { this.jsxFunction_ = parseExpression([jsx]); } else { @@ -99,19 +100,15 @@ export class JsxTransformer extends ParseTreeTransformer { return createNullLiteral(); } if (tree.attributes.some(a => a.type === JSX_SPREAD_ATTRIBUTE)) { - return this.createSpreadAttributeExpression_(attrs); + // + // => + // React.createElement('a', + // $traceurRuntime.spreadProperties({b: 'b', c: 'c'}, d, g)) + return spreadProperties(attrs, this); } return createObjectLiteral(attrs); } - createSpreadAttributeExpression_(attrs) { - // - // => - // React.createElement('a', - // $traceurRuntime.spreadProperties({b: 'b', c: 'c'}, d, g)) - return spreadProperties(attrs); - } - transformJsxElementName(tree) { if (tree.names.length === 1) { let {value} = tree.names[0]; diff --git a/src/codegeneration/ProperTailCallTransformer.js b/src/codegeneration/ProperTailCallTransformer.js index f2524bf1f..44f0fb5cf 100644 --- a/src/codegeneration/ProperTailCallTransformer.js +++ b/src/codegeneration/ProperTailCallTransformer.js @@ -29,6 +29,7 @@ import { FunctionDeclaration, FunctionExpression, } from '../syntax/trees/ParseTrees.js'; +import ImportRuntimeTrait from './ImportRuntimeTrait.js'; // // Example: @@ -49,13 +50,15 @@ import { // }, this, arguments); // }) -export class ProperTailCallTransformer extends TempVarTransformer { +export class ProperTailCallTransformer extends + ImportRuntimeTrait(TempVarTransformer) { // TODO(mnieper): This transformer currently expects that classes and template // literals have already been desugared. Otherwise they are not guaranteed // to have proper tail calls. constructor(identifierGenerator, reporter, options) { super(identifierGenerator, reporter, options); this.inBlock_ = false; + this.options = options; } transformFunctionDeclaration(tree) { @@ -67,8 +70,11 @@ export class ProperTailCallTransformer extends TempVarTransformer { let nameIdExpression = id(tree.name.identifierToken); + const initTailRecursiveFunction = + this.getRuntimeExpression('initTailRecursiveFunction'); + let setupFlagExpression = parseExpression - `$traceurRuntime.initTailRecursiveFunction(${nameIdExpression})`; + `${initTailRecursiveFunction}(${nameIdExpression})`; let funcDecl = this.transformFunction_(tree, FunctionDeclaration); if (funcDecl === tree) { @@ -105,8 +111,10 @@ export class ProperTailCallTransformer extends TempVarTransformer { return tree; } - return parseExpression ` - $traceurRuntime.initTailRecursiveFunction(${functionExpression})`; + const initTailRecursiveFunction = + this.getRuntimeExpression('initTailRecursiveFunction'); + return parseExpression `${ + initTailRecursiveFunction}(${functionExpression})`; } transformFunction_(tree, constructor) { @@ -116,8 +124,9 @@ export class ProperTailCallTransformer extends TempVarTransformer { } let func = id(this.getTempIdentifier()); let innerFunction = createFunctionExpression(tree.parameterList, body); + const call = this.getRuntimeExpression('call'); let outerBody = createFunctionBody(parseStatements ` - return $traceurRuntime.call(${innerFunction}, this, arguments);`); + return ${call}(${innerFunction}, this, arguments);`); return new constructor(tree.location, tree.name, tree.functionKind, tree.parameterList, tree.typeAnnotation, tree.annotations, outerBody); } diff --git a/src/codegeneration/RewriteTailExpressionsTransformer.js b/src/codegeneration/RewriteTailExpressionsTransformer.js index a159cd114..fc7fb7ea5 100644 --- a/src/codegeneration/RewriteTailExpressionsTransformer.js +++ b/src/codegeneration/RewriteTailExpressionsTransformer.js @@ -43,7 +43,7 @@ import { OR } from '../syntax/TokenType.js'; -function createCall(tree, operand, thisArg) { +function createCall(tree, operand, thisArg, importRuntimeTransformer) { let argList = tree.args; // can be null let argArray = argList ? argList.args : []; argArray = argArray.map(arg => { @@ -52,8 +52,10 @@ function createCall(tree, operand, thisArg) { } return arg; }); + const continuation = + importRuntimeTransformer.getRuntimeExpression('continuation'); return new CallExpression(tree.location, - createMemberExpression('$traceurRuntime', 'continuation'), + continuation, new ArgumentList(argList ? argList.location : null, [operand, thisArg, createArrayLiteral(argArray)])); } @@ -86,7 +88,8 @@ export class RewriteTailExpressionsTransformer extends ParseTreeTransformer { } switch (operand.type) { case IDENTIFIER_EXPRESSION: - return createCall(tree, operand, createNullLiteral()); + return createCall(tree, operand, createNullLiteral(), + this.bodyTransformer_); case MEMBER_EXPRESSION: case MEMBER_LOOKUP_EXPRESSION: return this.transformMemberExpressionCall_(tree, operand) @@ -115,9 +118,9 @@ export class RewriteTailExpressionsTransformer extends ParseTreeTransformer { } if (assignment) { return createParenExpression(createCommaExpression([assignment, - createCall(tree, operand, thisArg)])); + createCall(tree, operand, thisArg, this.bodyTransformer_)])); } else { - return createCall(tree, operand, thisArg); + return createCall(tree, operand, thisArg, this.bodyTransformer_); } } @@ -144,8 +147,8 @@ export class RewriteTailExpressionsTransformer extends ParseTreeTransformer { } transformNewExpression(tree) { - return createCall(tree, createMemberExpression('$traceurRuntime', 'construct'), - tree.operand); + const construct = this.bodyTransformer_.getRuntimeExpression('construct'); + return createCall(tree, construct, tree.operand, this.bodyTransformer_); } transformArrayLiteral(tree) {return tree;} diff --git a/src/codegeneration/SpreadPropertiesTransformer.js b/src/codegeneration/SpreadPropertiesTransformer.js index 224cbd659..d6acbb7f5 100644 --- a/src/codegeneration/SpreadPropertiesTransformer.js +++ b/src/codegeneration/SpreadPropertiesTransformer.js @@ -71,6 +71,5 @@ export function spreadProperties(properties, self) { args.push(createObjectLiteral(accummulatedProps)); } const runtime = self.getRuntimeExpression('spreadProperties'); - return parseExpression `${runtime}.spreadProperties(${ - createArgumentList(args)})`; + return parseExpression `${runtime}(${createArgumentList(args)})`; }