jstransform
Advanced tools
Comparing version 5.0.0 to 6.0.0
{ | ||
"name": "jstransform", | ||
"version": "5.0.0", | ||
"version": "6.0.0", | ||
"description": "A simple AST visitor-based JS transformer", | ||
@@ -24,3 +24,3 @@ "contributors": [ | ||
"base62": "0.1.1", | ||
"esprima-fb": "~4001.1.0-dev-harmony-fb", | ||
"esprima-fb": "~4001.1001.0-dev-harmony-fb", | ||
"source-map": "0.1.31" | ||
@@ -38,3 +38,3 @@ }, | ||
"devDependencies": { | ||
"jest-cli": "0.1.5" | ||
"jest-cli": "^0.1.5" | ||
}, | ||
@@ -41,0 +41,0 @@ "jest": { |
@@ -16,3 +16,3 @@ /** | ||
* | ||
* @emails jeffmo@fb.com javascript@lists.facebook.com | ||
* @emails jeffmo@fb.com | ||
*/ | ||
@@ -19,0 +19,0 @@ |
@@ -41,3 +41,4 @@ /** | ||
parentNode.type === Syntax.FunctionDeclaration | ||
|| parentNode.type === Syntax.FunctionExpression; | ||
|| parentNode.type === Syntax.FunctionExpression | ||
|| parentNode.type === Syntax.ArrowFunctionExpression; | ||
@@ -84,3 +85,4 @@ return node.type === Syntax.BlockStatement && parentIsFunction; | ||
parentScope: state.localScope, | ||
identifiers: {} | ||
identifiers: {}, | ||
tempVarIndex: 0 | ||
}, | ||
@@ -239,3 +241,3 @@ scopeIsStrict: scopeIsStrict | ||
var SourceMapGenerator = require('source-map').SourceMapGenerator; | ||
state.g.sourceMap = new SourceMapGenerator({file: 'transformed.js'}); | ||
state.g.sourceMap = new SourceMapGenerator({file: options.filename || 'transformed.js'}); | ||
} | ||
@@ -246,3 +248,3 @@ | ||
var ret = {code: state.g.buffer}; | ||
var ret = {code: state.g.buffer, extra: state.g.extra}; | ||
if (options.sourceMap) { | ||
@@ -249,0 +251,0 @@ ret.sourceMap = state.g.sourceMap; |
@@ -43,3 +43,4 @@ /** | ||
parentScope: null, | ||
identifiers: {} | ||
identifiers: {}, | ||
tempVarIndex: 0 | ||
}, | ||
@@ -57,2 +58,7 @@ /** | ||
/** | ||
* Ref to the node for the current MethodDefinition | ||
* @type {Object} | ||
*/ | ||
methodNode: null, | ||
/** | ||
* Ref to the node for the FunctionExpression of the enclosing | ||
@@ -103,2 +109,7 @@ * MethodDefinition | ||
/** | ||
* Auxiliary data to be returned by transforms | ||
* @type {Object} | ||
*/ | ||
extra: {}, | ||
/** | ||
* Buffer containing the result | ||
@@ -244,2 +255,12 @@ * @type {String} | ||
/** | ||
* Returns original source for an AST node. | ||
* @param {object} node | ||
* @param {object} state | ||
* @return {string} | ||
*/ | ||
function getNodeSourceText(node, state) { | ||
return state.g.source.substring(node.range[0], node.range[1]); | ||
} | ||
/** | ||
* Removes all non-whitespace characters | ||
@@ -578,1 +599,2 @@ */ | ||
exports.getOrderedChildren = getOrderedChildren; | ||
exports.getNodeSourceText = getNodeSourceText; |
@@ -18,3 +18,3 @@ /** | ||
/** | ||
* @emails dmitrys@fb.com javascript@lists.facebook.com | ||
* @emails dmitrys@fb.com | ||
*/ | ||
@@ -111,3 +111,3 @@ | ||
'() => this.value;', | ||
'function() {return this.value;}.bind(this);' | ||
'(function() {return this.value;}.bind(this));' | ||
); | ||
@@ -118,3 +118,3 @@ | ||
'() => (this.value);', | ||
'function() {return this.value;}.bind(this);' | ||
'(function() {return this.value;}.bind(this));' | ||
); | ||
@@ -125,3 +125,3 @@ | ||
'x => x * x;', | ||
'function(x) {return x * x;};' | ||
'(function(x) {return x * x;});' | ||
); | ||
@@ -167,3 +167,3 @@ | ||
].join('\n'), [ | ||
'function(', | ||
'(function(', | ||
'', | ||
@@ -180,3 +180,3 @@ '', | ||
' return x + y;', | ||
'};' | ||
'});' | ||
].join('\n')); | ||
@@ -191,6 +191,6 @@ | ||
].join('\n'), [ | ||
'function(x)', | ||
'(function(x)', | ||
'', | ||
' ', | ||
' {return x;};' | ||
' {return x;});' | ||
].join('\n')); | ||
@@ -209,3 +209,3 @@ | ||
].join('\n'), [ | ||
'function(', | ||
'(function(', | ||
'', | ||
@@ -217,3 +217,3 @@ ' x)', | ||
' ', | ||
' {return x;};' | ||
' {return x;});' | ||
].join('\n')); | ||
@@ -227,5 +227,5 @@ | ||
].join('\n'), [ | ||
'function(x) ', | ||
'(function(x) ', | ||
' {return x;}', | ||
';' | ||
');' | ||
].join('\n')); | ||
@@ -236,3 +236,3 @@ | ||
'(/*string*/foo, /*bool*/bar) => foo;', | ||
'function(/*string*/foo, /*bool*/bar) {return foo;};' | ||
'(function(/*string*/foo, /*bool*/bar) {return foo;});' | ||
); | ||
@@ -239,0 +239,0 @@ |
@@ -16,3 +16,3 @@ /** | ||
* | ||
* @emails jeffmo@fb.com javascript@lists.facebook.com | ||
* @emails jeffmo@fb.com | ||
*/ | ||
@@ -26,7 +26,15 @@ | ||
var transformFn; | ||
var classVisitors; | ||
var arrowFunctionVisitors; | ||
var visitors; | ||
beforeEach(function() { | ||
visitors = require('../es6-class-visitors').visitorList; | ||
require('mock-modules').dumpCache(); | ||
transformFn = require('../../src/jstransform').transform; | ||
classVisitors = require('../es6-class-visitors').visitorList; | ||
arrowFunctionVisitors = require('../es6-arrow-function-visitors').visitorList; | ||
visitors = classVisitors.concat(arrowFunctionVisitors); | ||
}); | ||
@@ -49,3 +57,5 @@ | ||
'class B {', | ||
' bar() {}', | ||
' bar() {', | ||
' class C {}', | ||
' }', | ||
'}' | ||
@@ -62,3 +72,5 @@ ].join('\n'); | ||
'function B(){"use strict";}', | ||
' B.prototype.bar=function() {"use strict";};', | ||
' B.prototype.bar=function() {"use strict";', | ||
' function C(){}', | ||
' };', | ||
'' | ||
@@ -158,3 +170,3 @@ ].join('\n'); | ||
' ', | ||
' Bar.call(this,p1,', | ||
' ____SuperProtoOfBar.foo.call(this,p1,', | ||
' p2);', | ||
@@ -456,10 +468,12 @@ ' };', | ||
'class Parent {', | ||
' constructor(p1, p2) {', | ||
' bar(p1, p2) {', | ||
' this.p1 = p1;', | ||
' this.p2 = p2;', | ||
' }', | ||
' "baz qux"(p3) {', | ||
' this.p3 = p3;', | ||
' }', | ||
'}', | ||
'class Child extends Parent {', | ||
' constructor() {}', | ||
' bar() {', | ||
@@ -469,2 +483,6 @@ ' super("a", "b");', | ||
' }', | ||
' "baz qux"() {', | ||
' super("c");', | ||
' this["baz qux run"] = true;', | ||
' }', | ||
'}' | ||
@@ -479,2 +497,3 @@ ].join('\n')); | ||
expect(childInst.barRan).toBe(undefined); | ||
childInst.bar(); | ||
@@ -484,2 +503,9 @@ expect(childInst.p1).toBe('a'); | ||
expect(childInst.barRan).toBe(true); | ||
expect(childInst.p3).toBe(undefined); | ||
expect(childInst['baz qux run']).toBe(undefined); | ||
childInst['baz qux'](); | ||
expect(childInst.p3).toBe('c'); | ||
expect(childInst['baz qux run']).toBe(true); | ||
}); | ||
@@ -755,2 +781,19 @@ | ||
it('consistently munges private idents in nested arrow funcs', function() { | ||
var code = transform([ | ||
'class Foo {', | ||
' bar(_p1, p2) {', | ||
' return (_a, b) => {', | ||
' return [_p1, p2, _a, b];', | ||
' };', | ||
' }', | ||
'}' | ||
].join('\n')); | ||
eval(code); | ||
var fooInst = new Foo(); | ||
expect(fooInst.bar('a', 'b')('c', 'd')).toEqual(['a', 'b', 'c', 'd']); | ||
}); | ||
it('does not munge dunder-scored properties', function() { | ||
@@ -996,2 +1039,38 @@ var code = transform([ | ||
}); | ||
// TODO: Support this with an option | ||
// There isn't a simple way to support both this and IE8 at the same | ||
// time, so for now we're not supporting it at all. That said, if | ||
// someone should feel so inclined to build non-ie8 support for it, | ||
// feel free to do so and just make it possible to enable/disable | ||
// this functionality via a transform option | ||
it('throws upon encountering getter methods', function() { | ||
expect(function() { | ||
transform([ | ||
'class Foo {', | ||
' get title() {', | ||
' return 42;', | ||
' }', | ||
'}' | ||
].join('\n')); | ||
}).toThrow( | ||
'This transform does not support getter methods for ES6 classes. ' + | ||
'(line: 2, col: 2)' | ||
); | ||
}); | ||
it('throws upon encountering setter methods', function() { | ||
expect(function() { | ||
transform([ | ||
'class Foo {', | ||
' set title(value) {', | ||
' this._title = value;', | ||
' }', | ||
'}' | ||
].join('\n')); | ||
}).toThrow( | ||
'This transform does not support setter methods for ES6 classes. ' + | ||
'(line: 2, col: 2)' | ||
); | ||
}); | ||
}); | ||
@@ -1089,3 +1168,3 @@ }); | ||
' ', | ||
' Bar.call(this,p1,', | ||
' ____SuperProtoOfBar.foo.call(this,p1,', | ||
' p2);', | ||
@@ -1092,0 +1171,0 @@ ' };', |
@@ -18,3 +18,3 @@ /** | ||
/** | ||
* @emails dmitrys@fb.com javascript@lists.facebook.com | ||
* @emails dmitrys@fb.com | ||
*/ | ||
@@ -21,0 +21,0 @@ |
@@ -18,3 +18,3 @@ /** | ||
/** | ||
* @emails dmitrys@fb.com javascript@lists.facebook.com | ||
* @emails dmitrys@fb.com | ||
*/ | ||
@@ -28,2 +28,6 @@ | ||
var transformFn; | ||
var destructuringVisitors; | ||
var shortObjectsVisitors; | ||
var visitors; | ||
@@ -33,4 +37,8 @@ | ||
require('mock-modules').dumpCache(); | ||
visitors = require('../es6-object-short-notation-visitors').visitorList; | ||
transformFn = require('../../src/jstransform').transform; | ||
shortObjectsVisitors = require('../es6-object-short-notation-visitors').visitorList; | ||
destructuringVisitors = require('../es6-destructuring-visitors').visitorList; | ||
visitors = shortObjectsVisitors.concat(destructuringVisitors); | ||
}); | ||
@@ -59,2 +67,14 @@ | ||
it('should transform work with destructuring and return 10', function() { | ||
var code = transform([ | ||
'var x = 5, y = 5;', | ||
'(function({x, y}) {', | ||
' var data = {x, y};', | ||
' return data.x + data.y;', | ||
'})({x, y});' | ||
].join('\n')); | ||
expect(eval(code)).toEqual(10); | ||
}); | ||
// Source code tests. | ||
@@ -69,17 +89,2 @@ it('should transform simple short notation', function() { | ||
// Should transform: short notation in complex object pattern. | ||
expectTransform([ | ||
'function init({name, points: [{x, y}, {z, q}]}) {', | ||
' return function([{data: {value, score}}]) {', | ||
' return {z, q, score, name};', | ||
' };', | ||
'}' | ||
].join('\n'), [ | ||
'function init({name:name, points: [{x:x, y:y}, {z:z, q:q}]}) {', | ||
' return function([{data: {value:value, score:score}}]) {', | ||
' return {z:z, q:q, score:score, name:name};', | ||
' };', | ||
'}' | ||
].join('\n')); | ||
// Should preserve lines transforming ugly code. | ||
@@ -89,7 +94,7 @@ expectTransform([ | ||
'', | ||
'foo ({', | ||
'foo (', | ||
' x,', | ||
' y', | ||
'', | ||
'})', | ||
')', | ||
'', | ||
@@ -104,7 +109,7 @@ ' {', | ||
'', | ||
'foo ({', | ||
' x:x,', | ||
' y:y', | ||
'foo (', | ||
' x,', | ||
' y', | ||
'', | ||
'})', | ||
')', | ||
'', | ||
@@ -111,0 +116,0 @@ ' {', |
@@ -18,3 +18,3 @@ /** | ||
/** | ||
* @emails dmitrys@fb.com javascript@lists.facebook.com | ||
* @emails dmitrys@fb.com | ||
*/ | ||
@@ -21,0 +21,0 @@ |
/** | ||
* @emails mroch@fb.com javascript@lists.facebook.com | ||
* @emails mroch@fb.com | ||
*/ | ||
@@ -4,0 +4,0 @@ |
@@ -42,2 +42,4 @@ /** | ||
var restParamVisitors = require('./es6-rest-param-visitors'); | ||
var destructuringVisitors = require('./es6-destructuring-visitors'); | ||
var Syntax = require('esprima-fb').Syntax; | ||
@@ -50,5 +52,12 @@ var utils = require('../src/utils'); | ||
function visitArrowFunction(traverse, node, path, state) { | ||
// Prologue. | ||
var notInExpression = (path[0].type === Syntax.ExpressionStatement); | ||
// Wrap a function into a grouping operator, if it's not | ||
// in the expression position. | ||
if (notInExpression) { | ||
utils.append('(', state); | ||
} | ||
utils.append('function', state); | ||
renderParams(node, state); | ||
renderParams(traverse, node, path, state); | ||
@@ -74,6 +83,11 @@ // Skip arrow. | ||
// Close wrapper if not in the expression. | ||
if (notInExpression) { | ||
utils.append(')', state); | ||
} | ||
return false; | ||
} | ||
function renderParams(node, state) { | ||
function renderParams(traverse, node, path, state) { | ||
// To preserve inline typechecking directives, we | ||
@@ -85,3 +99,5 @@ // distinguish between parens-free and paranthesized single param. | ||
if (node.params.length !== 0) { | ||
utils.catchup(node.params[node.params.length - 1].range[1], state); | ||
path.unshift(node); | ||
traverse(node.params, path, state); | ||
path.unshift(); | ||
} | ||
@@ -100,2 +116,4 @@ utils.append(')', state); | ||
utils.append('{', state); | ||
// Special handling of rest param. | ||
if (node.rest) { | ||
@@ -107,2 +125,16 @@ utils.append( | ||
} | ||
// Special handling of destructured params. | ||
destructuringVisitors.renderDestructuredComponents( | ||
node, | ||
utils.updateState(state, { | ||
localScope: { | ||
parentNode: state.parentNode, | ||
parentScope: state.parentScope, | ||
identifiers: state.identifiers, | ||
tempVarIndex: 0 | ||
} | ||
}) | ||
); | ||
utils.append('return ', state); | ||
@@ -109,0 +141,0 @@ renderStatementBody(traverse, node, path, state); |
@@ -145,2 +145,12 @@ /** | ||
function visitClassMethod(traverse, node, path, state) { | ||
if (node.kind === 'get' || node.kind === 'set') { | ||
throw new Error( | ||
'This transform does not support ' + node.kind + 'ter methods for ES6 ' + | ||
'classes. (line: ' + node.loc.start.line + ', col: ' + | ||
node.loc.start.column + ')' | ||
); | ||
} | ||
state = utils.updateState(state, { | ||
methodNode: node | ||
}); | ||
utils.catchup(node.range[0], state); | ||
@@ -172,10 +182,20 @@ path.unshift(node); | ||
} else { | ||
var methodName = methodNode.key.name; | ||
if (_shouldMungeIdentifier(methodNode.key, state)) { | ||
methodName = _getMungedName(methodName, state); | ||
var methodAccessor; | ||
var prototypeOrStatic = methodNode.static ? '' : '.prototype'; | ||
if (methodNode.key.type === Syntax.Identifier) { | ||
// foo() {} | ||
methodAccessor = methodNode.key.name; | ||
if (_shouldMungeIdentifier(methodNode.key, state)) { | ||
methodAccessor = _getMungedName(methodAccessor, state); | ||
} | ||
methodAccessor = '.' + methodAccessor; | ||
} else if (methodNode.key.type === Syntax.Literal) { | ||
// 'foo bar'() {} | ||
methodAccessor = '[' + JSON.stringify(methodNode.key.value) + ']'; | ||
} | ||
var prototypeOrStatic = methodNode.static ? '' : 'prototype.'; | ||
utils.append( | ||
state.className + '.' + prototypeOrStatic + methodName + '=function', | ||
state.className + prototypeOrStatic + | ||
methodAccessor + '=function', | ||
state | ||
@@ -202,2 +222,5 @@ ); | ||
utils.append('"use strict";', state); | ||
state = utils.updateState(state, { | ||
scopeIsStrict: true | ||
}); | ||
} | ||
@@ -417,3 +440,4 @@ utils.move(node.body.range[0] + '{'.length, state); | ||
if (path[0].type === Syntax.FunctionExpression | ||
|| path[0].type === Syntax.FunctionDeclaration) { | ||
|| path[0].type === Syntax.FunctionDeclaration | ||
|| path[0].type === Syntax.ArrowFunctionExpression) { | ||
for (var i = 0; i < path[0].params.length; i++) { | ||
@@ -439,3 +463,13 @@ if (path[0].params[i] === node) { | ||
if (node.callee.type === Syntax.Identifier) { | ||
utils.append(superClassName + '.call(', state); | ||
if (_isConstructorMethod(state.methodNode)) { | ||
utils.append(superClassName + '.call(', state); | ||
} else { | ||
var protoProp = SUPER_PROTO_IDENT_PREFIX + superClassName; | ||
if (state.methodNode.key.type === Syntax.Identifier) { | ||
protoProp += '.' + state.methodNode.key.name; | ||
} else if (state.methodNode.key.type === Syntax.Literal) { | ||
protoProp += '[' + JSON.stringify(state.methodNode.key.value) + ']'; | ||
} | ||
utils.append(protoProp + ".call(", state); | ||
} | ||
utils.move(node.callee.range[1], state); | ||
@@ -442,0 +476,0 @@ } else if (node.callee.type === Syntax.MemberExpression) { |
@@ -46,3 +46,4 @@ /** | ||
node.kind === 'init' && | ||
node.shorthand === true; | ||
node.shorthand === true && | ||
path[0].type !== Syntax.ObjectPattern; | ||
}; | ||
@@ -49,0 +50,0 @@ |
@@ -35,2 +35,4 @@ /** | ||
function _nodeIsFunctionWithRestParam(node) { | ||
@@ -46,7 +48,5 @@ return (node.type === Syntax.FunctionDeclaration | ||
if (node.params.length) { | ||
utils.catchup(node.params[node.params.length - 1].range[0], state); | ||
path.unshift(node); | ||
traverse(node.params[node.params.length - 1], path, state); | ||
traverse(node.params, path, state); | ||
path.shift(); | ||
utils.catchup(node.params[node.params.length - 1].range[1], state); | ||
} else { | ||
@@ -57,2 +57,8 @@ // -3 is for ... of the rest. | ||
utils.catchupWhiteSpace(node.rest.range[1], state); | ||
path.unshift(node); | ||
traverse(node.body, path, state); | ||
path.shift(); | ||
return false; | ||
} | ||
@@ -75,4 +81,3 @@ | ||
utils.append(renderRestParamSetup(parentNode), state); | ||
traverse(node.body, path, state); | ||
return false; | ||
return true; | ||
} | ||
@@ -79,0 +84,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
167163
27
4660
85
+ Addedesprima-fb@4001.1001.0-dev-harmony-fb(transitive)
- Removedesprima-fb@4001.1.0-dev-harmony-fb(transitive)