es6-templates
Advanced tools
Comparing version 0.1.0 to 0.2.0
{ | ||
"name": "es6-templates", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"homepage": "https://github.com/square/es6-templates", | ||
@@ -5,0 +5,0 @@ "authors": [ |
154
lib/index.js
var assert = require('assert'); | ||
var through = require('through'); | ||
var esprima = require('esprima-fb'); | ||
var recast = require('recast'); | ||
var types = recast.types; | ||
var PathVisitor = types.PathVisitor; | ||
var n = types.namedTypes; | ||
var b = types.builders; | ||
assert.ok( | ||
/harmony/.test(esprima.version), | ||
'looking for esprima harmony but found: ' + esprima.version | ||
); | ||
function Visitor() { | ||
PathVisitor.apply(this, arguments); | ||
} | ||
Visitor.prototype = Object.create(PathVisitor.prototype); | ||
Visitor.prototype.constructor = Visitor; | ||
/** | ||
* Visits a node of an AST looking for template string expressions. This is | ||
* intended to be used with the ast-types `traverse()` function. | ||
* Visits a template literal, replacing it with a series of string | ||
* concatenations. For example, given: | ||
* | ||
* @param {Object} node | ||
* @this {ast-types.Path} | ||
* ```js | ||
* `1 + 1 = ${1 + 1}` | ||
* ``` | ||
* | ||
* The following output will be generated: | ||
* | ||
* ```js | ||
* "1 + 1 = " + (1 + 1) | ||
* ``` | ||
* | ||
* @param {NodePath} path | ||
* @returns {AST.Literal|AST.BinaryExpression} | ||
*/ | ||
function visitNode(node) { | ||
var replacement; | ||
Visitor.prototype.visitTemplateLiteral = function(path) { | ||
var node = path.node; | ||
var replacement = b.literal(node.quasis[0].value.cooked); | ||
if (n.TemplateLiteral.check(node)) { | ||
replacement = b.literal(node.quasis[0].value.cooked); | ||
for (var i = 1, length = node.quasis.length; i < length; i++) { | ||
replacement = b.binaryExpression( | ||
for (var i = 1, length = node.quasis.length; i < length; i++) { | ||
replacement = b.binaryExpression( | ||
'+', | ||
b.binaryExpression( | ||
'+', | ||
b.binaryExpression( | ||
'+', | ||
replacement, | ||
node.expressions[i - 1] | ||
), | ||
b.literal(node.quasis[i].value.cooked) | ||
); | ||
} | ||
} else if (n.TaggedTemplateExpression.check(node)) { | ||
var args = []; | ||
var strings = b.callExpression( | ||
b.functionExpression( | ||
null, | ||
[], | ||
b.blockStatement([ | ||
b.variableDeclaration( | ||
'var', | ||
[ | ||
b.variableDeclarator( | ||
b.identifier('strings'), | ||
b.arrayExpression(node.quasi.quasis.map(function(quasi) { | ||
return b.literal(quasi.value.cooked); | ||
})) | ||
) | ||
] | ||
), | ||
b.expressionStatement(b.assignmentExpression( | ||
'=', | ||
b.memberExpression(b.identifier('strings'), b.identifier('raw'), false), | ||
b.arrayExpression(node.quasi.quasis.map(function(quasi) { | ||
return b.literal(quasi.value.raw); | ||
})) | ||
)), | ||
b.returnStatement(b.identifier('strings')) | ||
]) | ||
replacement, | ||
node.expressions[i - 1] | ||
), | ||
[] | ||
b.literal(node.quasis[i].value.cooked) | ||
); | ||
} | ||
args.push(strings); | ||
args.push.apply(args, node.quasi.expressions); | ||
return replacement; | ||
}; | ||
replacement = b.callExpression( | ||
node.tag, | ||
args | ||
); | ||
} | ||
/** | ||
* Visits the path wrapping a TaggedTemplateExpression node, which has the form | ||
* | ||
* ```js | ||
* htmlEncode `<span id=${id}>${text}</span>` | ||
* ``` | ||
* | ||
* @param {NodePath} path | ||
* @returns {AST.CallExpression} | ||
*/ | ||
Visitor.prototype.visitTaggedTemplateExpression = function(path) { | ||
var node = path.node; | ||
var args = []; | ||
var strings = b.callExpression( | ||
b.functionExpression( | ||
null, | ||
[], | ||
b.blockStatement([ | ||
b.variableDeclaration( | ||
'var', | ||
[ | ||
b.variableDeclarator( | ||
b.identifier('strings'), | ||
b.arrayExpression(node.quasi.quasis.map(function(quasi) { | ||
return b.literal(quasi.value.cooked); | ||
})) | ||
) | ||
] | ||
), | ||
b.expressionStatement(b.assignmentExpression( | ||
'=', | ||
b.memberExpression(b.identifier('strings'), b.identifier('raw'), false), | ||
b.arrayExpression(node.quasi.quasis.map(function(quasi) { | ||
return b.literal(quasi.value.raw); | ||
})) | ||
)), | ||
b.returnStatement(b.identifier('strings')) | ||
]) | ||
), | ||
[] | ||
); | ||
if (replacement) { | ||
this.replace(replacement); | ||
} | ||
} | ||
args.push(strings); | ||
args.push.apply(args, node.quasi.expressions); | ||
return b.callExpression( | ||
node.tag, | ||
args | ||
); | ||
}; | ||
var VISITOR = new Visitor(); | ||
/** | ||
@@ -97,3 +118,3 @@ * Transform an Esprima AST generated from ES6 by replacing all template string | ||
function transform(ast) { | ||
return types.traverse(ast, visitNode); | ||
return types.visit(ast, VISITOR); | ||
} | ||
@@ -108,2 +129,3 @@ | ||
* @param {string} source | ||
* @param {{sourceFileName: string, sourceMapName: string}} mapOptions | ||
* @return {string} | ||
@@ -115,6 +137,2 @@ */ | ||
var recastOptions = { | ||
// Use the harmony branch of Esprima that installs with this project | ||
// instead of the master branch that recast provides. | ||
esprima: esprima, | ||
sourceFileName: mapOptions.sourceFileName, | ||
@@ -121,0 +139,0 @@ sourceMapName: mapOptions.sourceMapName |
{ | ||
"name": "es6-templates", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "ES6 template strings compiled to ES5.", | ||
@@ -11,12 +11,10 @@ "main": "lib/index.js", | ||
"type": "git", | ||
"url": "git@github.com:square/es6-templates.git" | ||
"url": "git@github.com:esnext/es6-templates.git" | ||
}, | ||
"dependencies": { | ||
"ast-types": "^0.4.9", | ||
"esprima-fb": "^6001.1001.0-dev-harmony-fb", | ||
"recast": "~0.7.0", | ||
"through": "~2.3.4" | ||
"recast": "~0.8.0", | ||
"through": "~2.3.6" | ||
}, | ||
"devDependencies": { | ||
"example-runner": "0.1.0" | ||
"example-runner": "~0.2.0" | ||
}, | ||
@@ -23,0 +21,0 @@ "scripts": { |
@@ -121,3 +121,3 @@ # es6-templates | ||
When you have a change you'd like to see in the master repository, [send a pull | ||
request](https://github.com/square/es6-templates/pulls). Before we merge | ||
request](https://github.com/esnext/es6-templates/pulls). Before we merge | ||
your request, we'll make sure you're in the list of people who have signed a | ||
@@ -124,0 +124,0 @@ CLA. |
29007
2
24
226
+ Addedast-types@0.5.7(transitive)
+ Addedesprima-fb@7001.1.0-dev-harmony-fb(transitive)
+ Addedrecast@0.8.8(transitive)
- Removedast-types@^0.4.9
- Removedast-types@0.4.13(transitive)
- Removedesprima-fb@6001.1001.0-dev-harmony-fb(transitive)
- Removedrecast@0.7.5(transitive)
Updatedrecast@~0.8.0
Updatedthrough@~2.3.6