initial commit
This commit is contained in:
236
node_modules/jstransform/visitors/__tests__/es6-arrow-function-visitors-test.js
generated
vendored
Normal file
236
node_modules/jstransform/visitors/__tests__/es6-arrow-function-visitors-test.js
generated
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails dmitrys@fb.com
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
/*jshint -W117*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('es6ArrowFunctionsTransform', function() {
|
||||
var transformFn;
|
||||
var visitors;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
visitors = require('../es6-arrow-function-visitors').visitorList;
|
||||
transformFn = require('../../src/jstransform').transform;
|
||||
});
|
||||
|
||||
function transform(code) {
|
||||
return transformFn(visitors, code).code;
|
||||
}
|
||||
|
||||
function expectTransform(code, result) {
|
||||
expect(transform(code)).toEqual(result);
|
||||
}
|
||||
|
||||
it('should capture correct this value at different levels', function() {
|
||||
var code = transform([
|
||||
'var foo = {',
|
||||
' createFooGetter: function() {',
|
||||
' return (x) => [x, this];', // captures foo
|
||||
' },',
|
||||
' getParentThis: () => this', // captures parent this
|
||||
'};'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
expect(typeof foo.createFooGetter).toBe('function');
|
||||
expect(typeof foo.createFooGetter()).toBe('function');
|
||||
expect(typeof foo.getParentThis).toBe('function');
|
||||
|
||||
expect(foo.getParentThis()).toEqual(this);
|
||||
expect(foo.createFooGetter()(10)).toEqual([10, foo]);
|
||||
});
|
||||
|
||||
it('should map an array using arrow capturing this value', function() {
|
||||
this.factor = 10;
|
||||
|
||||
var code = transform(
|
||||
'[1, 2, 3].map(x => x * x * this.factor);'
|
||||
);
|
||||
|
||||
expect(eval(code)).toEqual([10, 40, 90]);
|
||||
});
|
||||
|
||||
it('binds if any `super` keyword is referenced', function() {
|
||||
var code = transform(
|
||||
'var fn=x=>super;'
|
||||
);
|
||||
|
||||
// We have to do a source text comparison here because `super` is a reserved
|
||||
// keyword (so we can't eval it).
|
||||
expect(code).toEqual('var fn=function(x){return super;}.bind(this);');
|
||||
});
|
||||
|
||||
it('should filter an array using arrow with two params', function() {
|
||||
this.factor = 0;
|
||||
|
||||
var code = transform([
|
||||
'[1, 2, 3].filter((v, idx) => {',
|
||||
' if (idx > 1 && this.factor > 0) {',
|
||||
' return true;',
|
||||
' }',
|
||||
' this.factor++;',
|
||||
' return false;',
|
||||
'});'
|
||||
].join('\n'));
|
||||
|
||||
expect(eval(code)).toEqual([3]);
|
||||
});
|
||||
|
||||
it('should fetch this value data from nested arrow', function() {
|
||||
var code = transform([
|
||||
'({',
|
||||
' bird: 22,',
|
||||
' run: function() {',
|
||||
' return () => () => this.bird;',
|
||||
' }',
|
||||
'}).run()()();'
|
||||
].join('\n'));
|
||||
|
||||
expect(eval(code)).toEqual(22);
|
||||
});
|
||||
|
||||
// Syntax tests.
|
||||
|
||||
it('should correctly transform arrows', function() {
|
||||
// 0 params, expression.
|
||||
expectTransform(
|
||||
'() => this.value;',
|
||||
'(function() {return this.value;}.bind(this));'
|
||||
);
|
||||
|
||||
// 0 params, expression wrapped in parens
|
||||
expectTransform(
|
||||
'() => (this.value);',
|
||||
'(function() {return this.value;}.bind(this));'
|
||||
);
|
||||
|
||||
// 1 param, no-parens, expression, no this.
|
||||
expectTransform(
|
||||
'x => x * x;',
|
||||
'(function(x) {return x * x;});'
|
||||
);
|
||||
|
||||
// 1 param, parens, expression, as argument, no this.
|
||||
expectTransform(
|
||||
'map((x) => x * x);',
|
||||
'map(function(x) {return x * x;});'
|
||||
);
|
||||
|
||||
// 2 params, block, as argument, nested.
|
||||
expectTransform(
|
||||
'makeRequest((response, error) => {'.concat(
|
||||
' return this.update(data => this.onData(data), response);',
|
||||
'});'),
|
||||
'makeRequest(function(response, error) {'.concat(
|
||||
' return this.update(function(data) {return this.onData(data);}.bind(this), response);',
|
||||
'}.bind(this));')
|
||||
);
|
||||
|
||||
// Assignment to a var, simple, 1 param.
|
||||
expectTransform(
|
||||
'var action = (value) => this.performAction(value);',
|
||||
'var action = function(value) {return this.performAction(value);}.bind(this);'
|
||||
);
|
||||
|
||||
// Preserve lines transforming ugly code.
|
||||
expectTransform([
|
||||
'(',
|
||||
'',
|
||||
'',
|
||||
' x,',
|
||||
' y',
|
||||
'',
|
||||
')',
|
||||
'',
|
||||
' =>',
|
||||
'',
|
||||
' {',
|
||||
' return x + y;',
|
||||
'};'
|
||||
].join('\n'), [
|
||||
'(function(',
|
||||
'',
|
||||
'',
|
||||
' x,',
|
||||
' y)',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
' ',
|
||||
'',
|
||||
' {',
|
||||
' return x + y;',
|
||||
'});'
|
||||
].join('\n'));
|
||||
|
||||
// Preserve line numbers with single parens-free param ugly code.
|
||||
expectTransform([
|
||||
'x',
|
||||
'',
|
||||
' =>',
|
||||
' x;'
|
||||
].join('\n'), [
|
||||
'(function(x)',
|
||||
'',
|
||||
' ',
|
||||
' {return x;});'
|
||||
].join('\n'));
|
||||
|
||||
// Preserve line numbers with single parens param ugly code.
|
||||
expectTransform([
|
||||
'(',
|
||||
'',
|
||||
' x',
|
||||
'',
|
||||
')',
|
||||
'',
|
||||
' =>',
|
||||
' x;'
|
||||
].join('\n'), [
|
||||
'(function(',
|
||||
'',
|
||||
' x)',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
' ',
|
||||
' {return x;});'
|
||||
].join('\n'));
|
||||
|
||||
// Preserve line numbers with parens around expression.
|
||||
expectTransform([
|
||||
'(x) => (',
|
||||
' x',
|
||||
');'
|
||||
].join('\n'), [
|
||||
'(function(x) ',
|
||||
' {return x;}',
|
||||
');'
|
||||
].join('\n'));
|
||||
|
||||
// Preserve typechecker annotation.
|
||||
expectTransform(
|
||||
'(/*string*/foo, /*bool*/bar) => foo;',
|
||||
'(function(/*string*/foo, /*bool*/bar) {return foo;});'
|
||||
);
|
||||
|
||||
// Binds this for arrows containing <this />
|
||||
expectTransform(
|
||||
'(() => <this />)',
|
||||
'((function() {return <this />;}.bind(this)))'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
103
node_modules/jstransform/visitors/__tests__/es6-call-spread-visitors-test.js
generated
vendored
Normal file
103
node_modules/jstransform/visitors/__tests__/es6-call-spread-visitors-test.js
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails dmitrys@fb.com
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('es6-call-spread-visitors', function() {
|
||||
var transformFn;
|
||||
var visitors;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
transformFn = require('../../src/jstransform').transform;
|
||||
|
||||
visitors = require('../es6-call-spread-visitors').visitorList;
|
||||
});
|
||||
|
||||
function transform(code, options) {
|
||||
return transformFn(visitors, code, options).code;
|
||||
}
|
||||
|
||||
it('should spread given data with context', function() {
|
||||
expect(transform('Math.max(1,\t[2], 3, ...[4, 5, 6])'))
|
||||
.toEqual('var $__0;($__0 = Math).max.apply($__0, [1,\t[2], 3].concat([4, 5, 6]))');
|
||||
});
|
||||
|
||||
it('should avoid unnecessary concat call', function() {
|
||||
expect(transform('window.Math.max(...list)'))
|
||||
.toEqual('var $__0;($__0 = window.Math).max.apply($__0, list)');
|
||||
});
|
||||
|
||||
it('should default to undefined context', function() {
|
||||
expect(transform('max(1, 2, ...list)'))
|
||||
.toEqual('max.apply(undefined, [1, 2].concat(list))');
|
||||
});
|
||||
|
||||
it('should handle computed method names', function() {
|
||||
expect(transform('Math["m" + (0 ? "in" : "ax")](1, 2, ...list)'))
|
||||
.toEqual('var $__0;($__0 = Math)["m" + (0 ? "in" : "ax")].apply($__0, [1, 2].concat(list))');
|
||||
});
|
||||
|
||||
it('should handle immediately invoked function expressions', function() {
|
||||
expect(transform('(function(a, b, c) { return a+b+c; })(1, 2, ...more)'))
|
||||
.toEqual('(function(a, b, c) { return a+b+c; }).apply(undefined, [1, 2].concat(more))');
|
||||
});
|
||||
|
||||
it('should spread while creating new instances', function() {
|
||||
expect(transform('new Set(1, 2, ...list)'))
|
||||
.toEqual('new (Function.prototype.bind.apply(Set, [null, 1, 2].concat(list)))');
|
||||
});
|
||||
|
||||
it('should create temporary variables when necessary in program scope', function() {
|
||||
expect(transform('foo().bar(arg1, arg2, ...more)'))
|
||||
.toEqual('var $__0;($__0 = foo()).bar.apply($__0, [arg1, arg2].concat(more))');
|
||||
});
|
||||
|
||||
it('should create temporary variables when necessary in function scope', function() {
|
||||
expect(transform('function fn(){ return foo().bar(arg1, arg2, ...more); }'))
|
||||
.toEqual('function fn(){var $__0; return ($__0 = foo()).bar.apply($__0, [arg1, arg2].concat(more)); }');
|
||||
});
|
||||
|
||||
it('should not evaluate context more than once', function() {
|
||||
var code = transform([
|
||||
'var obj = {',
|
||||
' calls: 0,',
|
||||
' get context() {',
|
||||
' this.calls++;',
|
||||
' return {',
|
||||
' add: function(a, b) { return a + b; }',
|
||||
' };',
|
||||
' }',
|
||||
'};',
|
||||
'var nums = [1, 2];',
|
||||
'obj.context.add(...nums);',
|
||||
'obj.calls === 1;',
|
||||
].join('\n'));
|
||||
expect(eval(code)).toEqual(true);
|
||||
});
|
||||
|
||||
it('should transform nested spread expressions', function() {
|
||||
var code = transform([
|
||||
'function getBase() {',
|
||||
' return {',
|
||||
' getParams: function(a, b) {',
|
||||
' return [a, b];',
|
||||
' }',
|
||||
' };',
|
||||
'}',
|
||||
'[].concat(...getBase().getParams(...[1, 2, 3])).join(" ");',
|
||||
].join('\n'));
|
||||
expect(eval(code)).toEqual("1 2");
|
||||
});
|
||||
|
||||
});
|
||||
1539
node_modules/jstransform/visitors/__tests__/es6-class-visitors-test.js
generated
vendored
Normal file
1539
node_modules/jstransform/visitors/__tests__/es6-class-visitors-test.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
300
node_modules/jstransform/visitors/__tests__/es6-destructuring-visitors-test.js
generated
vendored
Normal file
300
node_modules/jstransform/visitors/__tests__/es6-destructuring-visitors-test.js
generated
vendored
Normal file
@@ -0,0 +1,300 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails dmitrys@fb.com
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
/*jshint -W117*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('es6-destructuring-visitors', function() {
|
||||
var transformFn;
|
||||
|
||||
var destructuringVisitors;
|
||||
var conciseMethodVisitors;
|
||||
var shortObjectsVisitors;
|
||||
var reservedWordsVisitors;
|
||||
var restParamVisitors;
|
||||
var classVisitorsVisitors;
|
||||
var arrowFunctionVisitors;
|
||||
|
||||
var visitors;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
transformFn = require('../../src/jstransform').transform;
|
||||
|
||||
destructuringVisitors = require('../es6-destructuring-visitors').visitorList;
|
||||
conciseMethodVisitors = require('../es6-object-concise-method-visitors').visitorList;
|
||||
shortObjectsVisitors = require('../es6-object-short-notation-visitors').visitorList;
|
||||
reservedWordsVisitors = require('../reserved-words-visitors').visitorList;
|
||||
restParamVisitors = require('../es6-rest-param-visitors').visitorList;
|
||||
classVisitorsVisitors = require('../es6-class-visitors').visitorList;
|
||||
arrowFunctionVisitors = require('../es6-arrow-function-visitors').visitorList;
|
||||
|
||||
visitors = destructuringVisitors.concat(
|
||||
conciseMethodVisitors,
|
||||
shortObjectsVisitors,
|
||||
restParamVisitors,
|
||||
classVisitorsVisitors,
|
||||
arrowFunctionVisitors,
|
||||
reservedWordsVisitors
|
||||
);
|
||||
});
|
||||
|
||||
function transform(code) {
|
||||
return transformFn(visitors, code).code;
|
||||
}
|
||||
|
||||
function expectTransform(code, result) {
|
||||
expect(transform(code)).toEqual(result);
|
||||
}
|
||||
|
||||
it('should handle simple object pattern', function() {
|
||||
var code = transform([
|
||||
'var {x, y} = {x: 10, y: 20};',
|
||||
'(x + y);'
|
||||
].join('\n'));
|
||||
|
||||
expect(eval(code)).toEqual(30);
|
||||
});
|
||||
|
||||
it('should handle literal property names', function() {
|
||||
var code = transform([
|
||||
'var {x, "y y": yy, 0: z} = {x: 10, "y y": 20, 0: 30};',
|
||||
'([x, yy, z]);'
|
||||
].join('\n'));
|
||||
|
||||
expect(eval(code)).toEqual([10, 20, 30]);
|
||||
});
|
||||
|
||||
it('should handle array pattern assignment expression', function() {
|
||||
var code = transform([
|
||||
'var x = 10, y = 20;',
|
||||
'[x, y] = [y, x];',
|
||||
'([x, y]);'
|
||||
].join('\n'));
|
||||
|
||||
expect(eval(code)).toEqual([20, 10]);
|
||||
});
|
||||
|
||||
it('should should not redeclare vars with assignment expression', function() {
|
||||
var code = transform([
|
||||
'var x = 10, y = 20;',
|
||||
'(function() {',
|
||||
' [x, y] = [y, x];',
|
||||
'})();',
|
||||
'([x, y]);'
|
||||
].join('\n'));
|
||||
|
||||
expect(eval(code)).toEqual([20, 10]);
|
||||
});
|
||||
|
||||
it('should handle object pattern assignment expression', function() {
|
||||
var code = transform([
|
||||
'var x = 10, y = 20;',
|
||||
'({x, y} = {y, x});',
|
||||
'({x, y});'
|
||||
].join('\n'));
|
||||
|
||||
expect(eval(code)).toEqual({x: 10, y: 20});
|
||||
});
|
||||
|
||||
it('should destructure result of a function', function() {
|
||||
var code = transform([
|
||||
'var [x, y] = (function({x, y}) { return [x, y]; })({x: 1, y: 2});',
|
||||
'([x, y]);'
|
||||
].join('\n'));
|
||||
|
||||
expect(eval(code)).toEqual([1, 2]);
|
||||
});
|
||||
|
||||
it('should handle skipped array elements', function() {
|
||||
var code = transform([
|
||||
'var [x, , y] = [1, 2, 3];',
|
||||
'([x, y]);'
|
||||
].join('\n'));
|
||||
|
||||
expect(eval(code)).toEqual([1, 3]);
|
||||
});
|
||||
|
||||
it('should handle rest elements of an array', function() {
|
||||
var code = transform([
|
||||
'var [x, ...xs] = [1, 2, 3];'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
expect(x).toEqual(1);
|
||||
expect(xs).toEqual([2, 3]);
|
||||
});
|
||||
|
||||
it('should swap two variables w/o third using pattern', function() {
|
||||
var code = transform([
|
||||
'var x = 10, y = 20;',
|
||||
'var [x, y] = [y, x];',
|
||||
'([x, y]);'
|
||||
].join('\n'));
|
||||
|
||||
expect(eval(code)).toEqual([20, 10]);
|
||||
});
|
||||
|
||||
it('should transform complex pattern argument', function() {
|
||||
var code = transform([
|
||||
'function init(user, {ip, coords: [x, y], port}) {',
|
||||
' return [user, ip, x, y, port].join(", ");',
|
||||
'}'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
expect(init(
|
||||
'John Doe', {
|
||||
ip: '127.0.0.1',
|
||||
coords: [1, 2],
|
||||
port: 8080
|
||||
}
|
||||
)).toBe('John Doe, 127.0.0.1, 1, 2, 8080');
|
||||
});
|
||||
|
||||
it('should work with rest params', function() {
|
||||
var code = transform([
|
||||
'function foo({bar, baz}, ...rest) {',
|
||||
' return {bar, baz, qux: rest[0]};',
|
||||
'}'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
expect(foo({bar: 10, baz: 20}, 30))
|
||||
.toEqual({bar: 10, baz: 20, qux: 30});
|
||||
});
|
||||
|
||||
it('should work with class methods', function() {
|
||||
var code = transform([
|
||||
'class Point {',
|
||||
' constructor({x, y}) {',
|
||||
' this._x = x;',
|
||||
' this._y = y;',
|
||||
' }',
|
||||
'',
|
||||
' getData([deltaX, deltaY]) {',
|
||||
' return this._x + deltaX + this._y + deltaY',
|
||||
' }',
|
||||
'}'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
var x = 10, y = 20;
|
||||
var foo = new Point({x: x, y: y});
|
||||
var data = foo.getData([30, 40]);
|
||||
|
||||
expect(data).toBe(100);
|
||||
});
|
||||
|
||||
it('should work with object concise methods', function() {
|
||||
var code = transform([
|
||||
'var foo = {',
|
||||
' bar({x, y}) {',
|
||||
' return {x, y};',
|
||||
' }',
|
||||
'}'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
expect(foo.bar({x: 10, y: 20}))
|
||||
.toEqual({x: 10, y: 20});
|
||||
});
|
||||
|
||||
it('should work with arrows', function() {
|
||||
var code = transform([
|
||||
'var foo = ({x, y}, z) => x + y + z;'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
expect(foo({x: 10, y: 20}, 30))
|
||||
.toEqual(60);
|
||||
});
|
||||
|
||||
it('should work with arrows without other arguments', function() {
|
||||
var code = transform([
|
||||
'var foo = ({x, y}) => x + y;',
|
||||
'var bar = ([x, y]) => x + y;'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
expect(foo({x: 10, y: 20}))
|
||||
.toEqual(30);
|
||||
expect(bar([10, 20]))
|
||||
.toEqual(30);
|
||||
});
|
||||
|
||||
// Auto-generated temp vars test.
|
||||
it('should allocate correct temp index', function() {
|
||||
var code = transform([
|
||||
'function foo(x, {y}, {z}) {',
|
||||
' var {q} = {q: 30};',
|
||||
' return [$__0, $__1, $__2];',
|
||||
'}'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
expect(foo(1, {y: 10}, {z: 20}))
|
||||
.toEqual([{y: 10}, {z: 20}, {q: 30}]);
|
||||
});
|
||||
|
||||
it('should allocate correct temp nested index', function() {
|
||||
var code = transform([
|
||||
'var foo = function(x, {y}, {z}) {',
|
||||
' var {q, m: {v}} = {q: 30, m: {v: 40}};',
|
||||
' var {a} = (function({a}) { return $__0; })({a: 50});',
|
||||
' return [$__0, $__1, $__2, $__3, a];',
|
||||
'}'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
expect(foo(1, {y: 10}, {z: 20}))
|
||||
.toEqual([{y: 10}, {z: 20}, {q: 30, m: {v: 40}}, {v: 40}, 50]);
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Syntax tests.
|
||||
|
||||
it('should correctly transform structured patterns', function() {
|
||||
|
||||
// Variable declaration.
|
||||
expectTransform(
|
||||
'var a, {x, data: [y, , z]} = {x: 10, data: [1, 2, 3]};',
|
||||
'var a, $__0= {x: 10, data: [1, 2, 3]},x=$__0.x,$__1=$__0.data,y=$__1[0],z=$__1[2];'
|
||||
);
|
||||
|
||||
// Function parameters.
|
||||
expectTransform(
|
||||
'function f(a, {x, data: [y, z]}, b) {}',
|
||||
'function f(a, $__0 , b) {var x=$__0.x,$__1=$__0.data,y=$__1[0],z=$__1[1];}'
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle reserved words', function() {
|
||||
expectTransform(
|
||||
'var {delete: x} = {delete: 1};',
|
||||
'var $__0= {"delete": 1},x=$__0["delete"];'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
69
node_modules/jstransform/visitors/__tests__/es6-es7-object-integration-test.js
generated
vendored
Normal file
69
node_modules/jstransform/visitors/__tests__/es6-es7-object-integration-test.js
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails sema@fb.com javascript@lists.facebook.com
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('es6-es7-object-integration-test', function() {
|
||||
var transformFn;
|
||||
|
||||
var visitors;
|
||||
|
||||
// These are placeholder variables in scope that we can use to assert that a
|
||||
// specific variable reference was passed, rather than an object clone of it.
|
||||
var x = 123456;
|
||||
var z = 345678;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
transformFn = require('../../src/jstransform').transform;
|
||||
|
||||
var conciseMethodVisitors = require('../es6-object-concise-method-visitors').visitorList;
|
||||
var shortObjectsVisitors = require('../es6-object-short-notation-visitors').visitorList;
|
||||
var spreadPropertyVisitors = require('../es7-spread-property-visitors').visitorList;
|
||||
|
||||
visitors = spreadPropertyVisitors.concat(
|
||||
shortObjectsVisitors,
|
||||
conciseMethodVisitors
|
||||
);
|
||||
});
|
||||
|
||||
function transform(code) {
|
||||
return transformFn(visitors, code).code;
|
||||
}
|
||||
|
||||
it('handles spread with concise methods and short notation', function() {
|
||||
var code = 'var xyz = { ...x, y() { return 42; }, z }';
|
||||
var objectAssignMock = jest.genMockFunction();
|
||||
Object.assign = objectAssignMock;
|
||||
eval(transform(code));
|
||||
|
||||
var assignCalls = objectAssignMock.mock.calls;
|
||||
expect(assignCalls.length).toBe(1);
|
||||
expect(assignCalls[0].length).toBe(3);
|
||||
expect(assignCalls[0][0]).toEqual({});
|
||||
expect(assignCalls[0][1]).toEqual(x);
|
||||
|
||||
var trailingObject = assignCalls[0][2];
|
||||
expect(trailingObject.y()).toEqual(42);
|
||||
expect(trailingObject.z).toEqual(z);
|
||||
});
|
||||
|
||||
it('does not call assign when there are no spread properties', function() {
|
||||
var code = 'var xyz = { x, y() { return 42 }, z }';
|
||||
var objectAssignMock = jest.genMockFunction();
|
||||
Object.assign = objectAssignMock;
|
||||
eval(transform(code));
|
||||
expect(objectAssignMock).not.toBeCalled();
|
||||
});
|
||||
|
||||
});
|
||||
113
node_modules/jstransform/visitors/__tests__/es6-for-of-visitors-test.js
generated
vendored
Normal file
113
node_modules/jstransform/visitors/__tests__/es6-for-of-visitors-test.js
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails dmitrys@fb.com
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('es6-call-spread-visitors', function() {
|
||||
var transformFn;
|
||||
var visitors;
|
||||
var results;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
transformFn = require('../../src/jstransform').transform;
|
||||
|
||||
visitors = require('../es6-for-of-visitors').visitorList;
|
||||
results = undefined;
|
||||
});
|
||||
|
||||
function transform(code, options) {
|
||||
return transformFn(visitors, code, options).code;
|
||||
}
|
||||
|
||||
it('should correctly transform and run the simple case', function() {
|
||||
eval(transform([
|
||||
'var results = [];',
|
||||
'var y = [10, 20, 30];',
|
||||
'for (var x of y) {',
|
||||
' results.push(x);',
|
||||
'}',
|
||||
].join('\n')));
|
||||
|
||||
expect(results).toEqual([10, 20, 30]);
|
||||
});
|
||||
|
||||
it('should correctly run a simple for of without block', function() {
|
||||
eval(transform([
|
||||
'var results = [];',
|
||||
'var y = [10, 20, 30];',
|
||||
'for (var x of y)',
|
||||
' results.push(x);',
|
||||
].join('\n')));
|
||||
|
||||
expect(results).toEqual([10, 20, 30]);
|
||||
});
|
||||
|
||||
|
||||
it('should correctly run a simple for of without a var', function() {
|
||||
var x;
|
||||
eval(transform([
|
||||
'var results = [];',
|
||||
'var x;',
|
||||
'var y = [10, 20, 30];',
|
||||
'for (x of y) {',
|
||||
' results.push(x);',
|
||||
'}',
|
||||
].join('\n')));
|
||||
|
||||
expect(results).toEqual([10, 20, 30]);
|
||||
expect(x).toEqual(30);
|
||||
});
|
||||
|
||||
it('should correctly run a for of with expr on rhs', function() {
|
||||
eval(transform([
|
||||
'var results = [];',
|
||||
'for (var x of [10, 20, 30]) {',
|
||||
' results.push(x);',
|
||||
'}',
|
||||
].join('\n')));
|
||||
|
||||
expect(results).toEqual([10, 20, 30]);
|
||||
});
|
||||
|
||||
it('should correctly work with an interable', function() {
|
||||
|
||||
// Custom iterable object.
|
||||
var foo = {
|
||||
_data: [10, 20, 30],
|
||||
_index: 0,
|
||||
'@@iterator': function() {
|
||||
this._index = 0;
|
||||
return {
|
||||
next: () => {
|
||||
return {
|
||||
value: this._data[this._index++],
|
||||
done: this._index > this._data.length
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
// dummy statement to appease lint.
|
||||
foo;
|
||||
|
||||
eval(transform([
|
||||
'var results = [];',
|
||||
'for (var x of foo) {',
|
||||
' results.push(x);',
|
||||
'}',
|
||||
].join('\n')));
|
||||
|
||||
expect(results).toEqual([10, 20, 30]);
|
||||
});
|
||||
});
|
||||
108
node_modules/jstransform/visitors/__tests__/es6-object-computed-property-visitors-test.js
generated
vendored
Normal file
108
node_modules/jstransform/visitors/__tests__/es6-object-computed-property-visitors-test.js
generated
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails dmitrys@fb.com
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('es6-computed-property-visitors', function() {
|
||||
var transformFn;
|
||||
var visitors;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
transformFn = require('../../src/jstransform').transform;
|
||||
|
||||
visitors = require('../es6-object-computed-property-visitors').visitorList
|
||||
.concat(require('../es6-object-concise-method-visitors').visitorList)
|
||||
.concat(require('../es6-object-short-notation-visitors').visitorList)
|
||||
.concat(require('../es7-spread-property-visitors').visitorList);
|
||||
});
|
||||
|
||||
function transform(code, options) {
|
||||
return transformFn(visitors, code, options).code;
|
||||
}
|
||||
|
||||
it('should transforms simple computed properties', function() {
|
||||
var result;
|
||||
eval(transform([
|
||||
'var x = "foo", q = "bar";',
|
||||
'var result = {[x]: 1, y: 2, "z": 3, [x + q]: 4};',
|
||||
].join('\n')));
|
||||
|
||||
expect(result).toEqual({foo: 1, y: 2, z: 3, foobar: 4});
|
||||
});
|
||||
|
||||
it('should transform computed property', function() {
|
||||
expect(transform('var x = {alpha: 12, \'beta\': 34, [\'gam\' + \'ma\']: 56};'))
|
||||
.toEqual('var $__0;var x = ($__0={},$__0.alpha= 12,$__0[ \'beta\']= 34,$__0[ \'gam\' + \'ma\']= 56,$__0);');
|
||||
});
|
||||
|
||||
it('should handle spread operator', function() {
|
||||
expect(transform('({[\'a\'+\'b\']: \'ab\', ...cde})'))
|
||||
.toEqual('var $__0;(($__0={},$__0[\'a\'+\'b\']= \'ab\',Object.assign($__0 ,cde),$__0))');
|
||||
});
|
||||
|
||||
it('should handle consecutive spread operators', function() {
|
||||
expect(transform('({...a, [1+1]: 2, ...c, ...d})'))
|
||||
.toEqual('var $__0;(($__0={},Object.assign($__0,a),$__0[ 1+1]= 2,Object.assign($__0 ,c, d),$__0))');
|
||||
});
|
||||
|
||||
it('should handle everything individually while preserving whitespace', function() {
|
||||
var original = [
|
||||
'\n...\na\n', // spread property
|
||||
'\tb\t', // short object
|
||||
'\nc\n(\nx\n)\n{ return x * x; }\n', // concise method
|
||||
'\t[\td? "e": "f"\t]\t:\tfunction(y)\t{ return y * y; }\t', // computed property
|
||||
'\ng\n:\n"h"\n' // normal property
|
||||
].join(',');
|
||||
var transformed = [
|
||||
'Object.assign($__0\n,\na\n',
|
||||
'\t{b:b\t',
|
||||
'\nc:function\n(\nx\n)\n{ return x * x; }})',
|
||||
'$__0[\n\t\td? "e": "f"]=\t\t\tfunction(y)\t{ return y * y; }',
|
||||
'$__0.g=\t\n\n\n"h"\n'
|
||||
].join(',');
|
||||
expect(transform('({' + original + '})'))
|
||||
.toEqual('var $__0;(($__0={},' + transformed + ',$__0))');
|
||||
});
|
||||
|
||||
it('should fail for short notation with computed names', function() {
|
||||
expect(transform.bind(null, '({["a" + "b"]})')).toThrow();
|
||||
});
|
||||
|
||||
it('should handle concise generator methods with computed names', function() {
|
||||
expect(transform('({*["a" + b ](c) { return c * c; },\t*d(e) { return e * e; }})'))
|
||||
.toEqual('var $__0;(($__0={},$__0["a" + b]= function*(c) { return c * c; },$__0.d=\tfunction*(e) { return e * e; },$__0))');
|
||||
});
|
||||
|
||||
it('should evaluate simple object with computed properties', function() {
|
||||
var result = eval(transform('({["alp"+\'ha\']:1, [1>2?"beta":"gamma"]:3})'));
|
||||
expect(result).toEqual({alpha: 1, gamma: 3});
|
||||
});
|
||||
|
||||
it('should evaluate complex objects with computed properties', function() {
|
||||
var complex;
|
||||
eval(transform([
|
||||
'var spread = {identifier: 1, "literal": 2, ["comp"+"uted"]: "overwritten"};',
|
||||
'var short = "value";',
|
||||
'var complex = {short, ...spread, ["con"+"cise"]() { return "method"; }, [String.fromCharCode(100-1)+"omputed"]: "actual"};',
|
||||
].join('\n')));
|
||||
expect(complex).toEqual({
|
||||
short: 'value',
|
||||
identifier: 1,
|
||||
literal: 2,
|
||||
concise: complex.concise,
|
||||
computed: 'actual',
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
118
node_modules/jstransform/visitors/__tests__/es6-object-concise-method-visitors-test.js
generated
vendored
Normal file
118
node_modules/jstransform/visitors/__tests__/es6-object-concise-method-visitors-test.js
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails dmitrys@fb.com
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('es6-object-concise-method-visitors', function() {
|
||||
var transformFn;
|
||||
var conciseMethodVisitors;
|
||||
var restParamVisitors;
|
||||
var visitors;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
conciseMethodVisitors = require('../es6-object-concise-method-visitors').visitorList;
|
||||
restParamVisitors = require('../es6-rest-param-visitors').visitorList;
|
||||
transformFn = require('../../src/jstransform').transform;
|
||||
visitors = conciseMethodVisitors.concat(restParamVisitors);
|
||||
});
|
||||
|
||||
function transform(code) {
|
||||
return transformFn(visitors, code).code;
|
||||
}
|
||||
|
||||
function expectTransform(code, result) {
|
||||
expect(transform(code)).toEqual(result);
|
||||
}
|
||||
|
||||
// Functional tests.
|
||||
|
||||
it('should transform concise method and return 42', function() {
|
||||
/*global foo*/
|
||||
var code = transform([
|
||||
'var foo = {',
|
||||
' bar(x) {',
|
||||
' return x;',
|
||||
' }',
|
||||
'};'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
expect(foo.bar(42)).toEqual(42);
|
||||
});
|
||||
|
||||
it('should transform concise method with literal property', function() {
|
||||
var code = transform([
|
||||
'var foo = {',
|
||||
' "bar 1"(x) {',
|
||||
' return x;',
|
||||
' }',
|
||||
'};'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
expect(foo['bar 1'](42)).toEqual(42);
|
||||
});
|
||||
|
||||
|
||||
it('should work with rest params', function() {
|
||||
var code = transform([
|
||||
'({',
|
||||
' init(x, ...rest) {',
|
||||
' return rest.concat(x);',
|
||||
' }',
|
||||
'}).init(1, 2, 3);'
|
||||
].join('\n'));
|
||||
|
||||
expect(eval(code)).toEqual([2, 3, 1]);
|
||||
});
|
||||
|
||||
// Source code tests.
|
||||
it('should transform concise methods', function() {
|
||||
|
||||
// Should transform simple concise method.
|
||||
expectTransform(
|
||||
'var foo = {bar() {}};',
|
||||
'var foo = {bar:function() {}};'
|
||||
);
|
||||
|
||||
// Should transform inner objects.
|
||||
expectTransform(
|
||||
'({bar(x) { return {baz(y) {}}; }});',
|
||||
'({bar:function(x) { return {baz:function(y) {}}; }});'
|
||||
);
|
||||
});
|
||||
|
||||
it('should preserve generators', function() {
|
||||
// Identifier properties
|
||||
expectTransform(
|
||||
'var foo = {*bar(x) {yield x;}};',
|
||||
'var foo = {bar:function*(x) {yield x;}};'
|
||||
);
|
||||
|
||||
// Literal properties
|
||||
expectTransform(
|
||||
'var foo = {*"abc"(x) {yield x;}, *42(x) {yield x;}};',
|
||||
'var foo = {"abc":function*(x) {yield x;}, 42:function*(x) {yield x;}};'
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle reserved words', function() {
|
||||
expectTransform(
|
||||
'({delete(x) {}})',
|
||||
'({"delete":function(x) {}})'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
110
node_modules/jstransform/visitors/__tests__/es6-object-short-notation-visitors-test.js
generated
vendored
Normal file
110
node_modules/jstransform/visitors/__tests__/es6-object-short-notation-visitors-test.js
generated
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails dmitrys@fb.com
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('es6-object-short-notation-visitors', function() {
|
||||
var transformFn;
|
||||
|
||||
var destructuringVisitors;
|
||||
var shortObjectsVisitors;
|
||||
|
||||
var visitors;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
transformFn = require('../../src/jstransform').transform;
|
||||
|
||||
shortObjectsVisitors = require('../es6-object-short-notation-visitors').visitorList;
|
||||
destructuringVisitors = require('../es6-destructuring-visitors').visitorList;
|
||||
|
||||
visitors = shortObjectsVisitors.concat(destructuringVisitors);
|
||||
});
|
||||
|
||||
function transform(code) {
|
||||
return transformFn(visitors, code).code;
|
||||
}
|
||||
|
||||
function expectTransform(code, result) {
|
||||
expect(transform(code)).toEqual(result);
|
||||
}
|
||||
|
||||
// Functional tests.
|
||||
|
||||
it('should transform short notation and return 5', function() {
|
||||
var code = transform([
|
||||
'(function(x, y) {',
|
||||
' var data = {x, y};',
|
||||
' return data.x + data.y;',
|
||||
'})(2, 3);'
|
||||
].join('\n'));
|
||||
|
||||
expect(eval(code)).toEqual(5);
|
||||
});
|
||||
|
||||
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.
|
||||
it('should transform simple short notation', function() {
|
||||
|
||||
// Should transform simple short notation.
|
||||
expectTransform(
|
||||
'function foo(x, y) { return {x, y}; }',
|
||||
'function foo(x, y) { return {x:x, y:y}; }'
|
||||
);
|
||||
|
||||
// Should preserve lines transforming ugly code.
|
||||
expectTransform([
|
||||
'function',
|
||||
'',
|
||||
'foo (',
|
||||
' x,',
|
||||
' y',
|
||||
'',
|
||||
')',
|
||||
'',
|
||||
' {',
|
||||
' return {',
|
||||
' x,',
|
||||
' y};',
|
||||
'}'
|
||||
].join('\n'), [
|
||||
'function',
|
||||
'',
|
||||
'foo (',
|
||||
' x,',
|
||||
' y',
|
||||
'',
|
||||
')',
|
||||
'',
|
||||
' {',
|
||||
' return {',
|
||||
' x:x,',
|
||||
' y:y};',
|
||||
'}'
|
||||
].join('\n'));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
337
node_modules/jstransform/visitors/__tests__/es6-rest-param-visitors-test.js
generated
vendored
Normal file
337
node_modules/jstransform/visitors/__tests__/es6-rest-param-visitors-test.js
generated
vendored
Normal file
@@ -0,0 +1,337 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails dmitrys@fb.com
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
/*jshint -W117*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('es6-rest-param-visitors', () => {
|
||||
var transformFn;
|
||||
var visitorSet;
|
||||
var arrowFuncVisitors;
|
||||
var classVisitors;
|
||||
var restParamVisitors;
|
||||
|
||||
beforeEach(() => {
|
||||
require('mock-modules').dumpCache();
|
||||
arrowFuncVisitors = require('../es6-arrow-function-visitors').visitorList;
|
||||
classVisitors = require('../es6-class-visitors').visitorList;
|
||||
restParamVisitors = require('../es6-rest-param-visitors').visitorList;
|
||||
callSpreadVisitors = require('../es6-call-spread-visitors').visitorList;
|
||||
transformFn = require('../../src/jstransform').transform;
|
||||
|
||||
visitorSet =
|
||||
arrowFuncVisitors
|
||||
.concat(classVisitors)
|
||||
.concat(restParamVisitors)
|
||||
.concat(callSpreadVisitors);
|
||||
});
|
||||
|
||||
function transform(code) {
|
||||
return transformFn(visitorSet, code).code;
|
||||
}
|
||||
|
||||
function expectTransform(code, result) {
|
||||
expect(transform(code)).toEqual(result);
|
||||
}
|
||||
|
||||
describe('function expressions', () => {
|
||||
it('should capture 2 rest params, having 2 args', () => {
|
||||
var code = transform([
|
||||
'(function(x, y, ...args) {',
|
||||
' return [x, y, args.length, args[0], args[1]];',
|
||||
'})(1, 2, 3, 4);'
|
||||
].join('\n'));
|
||||
|
||||
expect(eval(code)).toEqual([1, 2, 2, 3, 4]);
|
||||
});
|
||||
|
||||
it('should transform rest parameters in nested functions', () => {
|
||||
var code = transform([
|
||||
'(function(x, ...args) {',
|
||||
' return function(...params) {',
|
||||
' return args.concat(params);',
|
||||
' };',
|
||||
'})(1, 2, 3)(4, 5);'
|
||||
].join('\n'));
|
||||
|
||||
expect(eval(code)).toEqual([2, 3, 4, 5]);
|
||||
});
|
||||
|
||||
it('should supply an array object', () => {
|
||||
var code = transform([
|
||||
'(function(...args) {',
|
||||
' return Array.isArray(args);',
|
||||
'})()'
|
||||
].join('\n'));
|
||||
|
||||
expect(eval(code)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('function declarations', () => {
|
||||
it('should capture 2 rest params, having 2 args', () => {
|
||||
var code = transform([
|
||||
'function test(x, y, ...args) {',
|
||||
' return [x, y, args.length, args[0], args[1]];',
|
||||
'}'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
expect(test(1, 2, 3, 4)).toEqual([1, 2, 2, 3, 4]);
|
||||
});
|
||||
|
||||
it('should transform rest parameters in nested functions', () => {
|
||||
var code = transform([
|
||||
'function testOuter(x, ...args) {',
|
||||
' function testInner(...params) {',
|
||||
' return args.concat(params);',
|
||||
' }',
|
||||
' return testInner;',
|
||||
'}'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
expect(testOuter(1, 2, 3)(4, 5)).toEqual([2, 3, 4, 5]);
|
||||
});
|
||||
|
||||
it('should supply an array object', () => {
|
||||
var code = transform([
|
||||
'function test(...args) {',
|
||||
' return Array.isArray(args);',
|
||||
'}'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
expect(test()).toBe(true);
|
||||
});
|
||||
|
||||
it('should work with temp var injections', () => {
|
||||
// Use call spread as example. It injects a temp var into function scope.
|
||||
var code = transform([
|
||||
'function test(bar, ...args) {',
|
||||
' return bar(...args);',
|
||||
'}'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
var fn = function() {
|
||||
return Array.prototype.slice.call(arguments).map(i => i + 1);
|
||||
};
|
||||
expect(test(fn, 1, 2, 3)).toEqual([2, 3, 4]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('arrow functions', () => {
|
||||
it('should transform non-block bodied arrow functions', () => {
|
||||
var code = transform([
|
||||
'var test = (...args) => args;'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
expect(test('foo', 'bar')).toEqual(['foo', 'bar']);
|
||||
});
|
||||
|
||||
it('should capture 2 rest params, having 2 args', () => {
|
||||
var code = transform([
|
||||
'var test = (x, y, ...args) => {',
|
||||
' return [x, y, args.length, args[0], args[1]];',
|
||||
'}'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
expect(test(1, 2, 3, 4)).toEqual([1, 2, 2, 3, 4]);
|
||||
});
|
||||
|
||||
it('should transform rest parameters in nested arrow functions', () => {
|
||||
var code = transform([
|
||||
'var testOuter = (x, ...args) => {',
|
||||
' var testInner = (...params) => {',
|
||||
' return args.concat(params);',
|
||||
' };',
|
||||
' return testInner;',
|
||||
'};'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
expect(testOuter(1, 2, 3)(4, 5)).toEqual([2, 3, 4, 5]);
|
||||
});
|
||||
|
||||
it('should supply an array object', () => {
|
||||
var code = transform([
|
||||
'var test = (...args) => {',
|
||||
' return Array.isArray(args);',
|
||||
'};'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
expect(test()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('class methods', () => {
|
||||
it('should capture 2 rest params, having 2 args', () => {
|
||||
var code = transform([
|
||||
'class Foo {',
|
||||
' constructor(x, y, ...args) {',
|
||||
' this.ctor = [x, y, args.length, args[0], args[1]];',
|
||||
' }',
|
||||
' testMethod(x, y, ...args) {',
|
||||
' return [x, y, args.length, args[0], args[1]];',
|
||||
' }',
|
||||
' static testMethod(x, y, ...args) {',
|
||||
' return [x, y, args.length, args[0], args[1]];',
|
||||
' }',
|
||||
'}'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
var fooInst = new Foo(1, 2, 3, 4);
|
||||
expect(fooInst.ctor).toEqual([1, 2, 2, 3, 4]);
|
||||
expect(fooInst.testMethod(1, 2, 3, 4)).toEqual([1, 2, 2, 3, 4]);
|
||||
expect(Foo.testMethod(1, 2, 3, 4)).toEqual([1, 2, 2, 3, 4]);
|
||||
});
|
||||
|
||||
it('should transform rest parameters in nested functions', () => {
|
||||
var code = transform([
|
||||
'class Foo {',
|
||||
' constructor(x, ...args) {',
|
||||
' function inner(...params) {',
|
||||
' return args.concat(params);',
|
||||
' }',
|
||||
' this.ctor = inner;',
|
||||
' }',
|
||||
' testMethod(x, ...args) {',
|
||||
' function inner(...params) {',
|
||||
' return args.concat(params);',
|
||||
' }',
|
||||
' return inner;',
|
||||
' }',
|
||||
' static testMethod(x, ...args) {',
|
||||
' function inner(...params) {',
|
||||
' return args.concat(params);',
|
||||
' }',
|
||||
' return inner;',
|
||||
' }',
|
||||
'}'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
var fooInst = new Foo(1, 2, 3);
|
||||
expect(fooInst.ctor(4, 5)).toEqual([2, 3, 4, 5]);
|
||||
expect(fooInst.testMethod(1, 2, 3)(4, 5)).toEqual([2, 3, 4, 5]);
|
||||
expect(Foo.testMethod(1, 2, 3)(4, 5)).toEqual([2, 3, 4, 5]);
|
||||
});
|
||||
|
||||
it('should supply an array object', () => {
|
||||
var code = transform([
|
||||
'class Foo {',
|
||||
' constructor(...args) {',
|
||||
' this.ctor = Array.isArray(args);',
|
||||
' }',
|
||||
' testMethod(...args) {',
|
||||
' return Array.isArray(args);',
|
||||
' }',
|
||||
' static testMethod(...args) {',
|
||||
' return Array.isArray(args);',
|
||||
' }',
|
||||
'}'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
var fooInst = new Foo();
|
||||
expect(fooInst.ctor).toBe(true);
|
||||
expect(fooInst.testMethod()).toBe(true);
|
||||
expect(Foo.testMethod()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('whitespace preservation', () => {
|
||||
it('1-line function decl with 2 args', () => {
|
||||
expectTransform(
|
||||
'function foo(x, y, ...args) { return x + y + args[0]; }',
|
||||
'function foo(x, y ) {for (var args=[],$__0=2,$__1=arguments.length;' +
|
||||
'$__0<$__1;$__0++) args.push(arguments[$__0]); return x + y + ' +
|
||||
'args[0]; }'
|
||||
);
|
||||
});
|
||||
|
||||
it('1-line function expression with 1 arg', () => {
|
||||
expectTransform(
|
||||
'(function(x, ...args) { return args;});',
|
||||
'(function(x ) {for (var args=[],$__0=1,$__1=arguments.length;' +
|
||||
'$__0<$__1;$__0++) args.push(arguments[$__0]); return args;});'
|
||||
);
|
||||
});
|
||||
|
||||
it('1-line function expression with no args', () => {
|
||||
expectTransform(
|
||||
'map(function(...args) { return args.map(log); });',
|
||||
'map(function() {for (var args=[],$__0=0,$__1=arguments.length;' +
|
||||
'$__0<$__1;$__0++) args.push(arguments[$__0]); ' +
|
||||
'return args.map(log); });'
|
||||
);
|
||||
});
|
||||
|
||||
it('preserves lines for ugly code', () => {
|
||||
expectTransform([
|
||||
'function',
|
||||
'',
|
||||
'foo (',
|
||||
' x,',
|
||||
' ...args',
|
||||
'',
|
||||
')',
|
||||
'',
|
||||
' {',
|
||||
' return args;',
|
||||
'}'
|
||||
].join('\n'), [
|
||||
'function',
|
||||
'',
|
||||
'foo (',
|
||||
' x',
|
||||
' ',
|
||||
'',
|
||||
')',
|
||||
'',
|
||||
' {for (var args=[],$__0=1,$__1=arguments.length;$__0<$__1;' +
|
||||
'$__0++) args.push(arguments[$__0]);',
|
||||
' return args;',
|
||||
'}'
|
||||
].join('\n'));
|
||||
});
|
||||
|
||||
it('preserves inline comments', () => {
|
||||
expectTransform(
|
||||
'function foo(/*string*/foo, /*bool*/bar, ...args) { return args; }',
|
||||
'function foo(/*string*/foo, /*bool*/bar ) {' +
|
||||
'for (var args=[],$__0=2,$__1=arguments.length;$__0<$__1;$__0++) ' +
|
||||
'args.push(arguments[$__0]); ' +
|
||||
'return args; ' +
|
||||
'}'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
241
node_modules/jstransform/visitors/__tests__/es6-template-visitors-test.js
generated
vendored
Normal file
241
node_modules/jstransform/visitors/__tests__/es6-template-visitors-test.js
generated
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails mroch@fb.com
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('ES6 Template Visitor', function() {
|
||||
var transformFn;
|
||||
var visitors;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
visitors = require('../es6-template-visitors').visitorList;
|
||||
transformFn = require('../../src/jstransform').transform;
|
||||
});
|
||||
|
||||
function transform(code) {
|
||||
return transformFn(visitors, code).code;
|
||||
}
|
||||
|
||||
function expectTransform(code, result) {
|
||||
expect(transform(code)).toEqual(result);
|
||||
}
|
||||
|
||||
function expectEval(code, result, setupFn) {
|
||||
var actual;
|
||||
if (setupFn) {
|
||||
eval(setupFn);
|
||||
}
|
||||
eval('actual = ' + transform(code));
|
||||
expect(actual).toEqual(result);
|
||||
}
|
||||
|
||||
function expectEvalTag(code, tagFn, scope) {
|
||||
/*jshint unused:false*/
|
||||
if (scope) {
|
||||
Object.keys(scope).forEach((key) => this[key] = scope[key]);
|
||||
}
|
||||
|
||||
var tagCalls = 0;
|
||||
var tag = function(...args) {
|
||||
tagCalls++;
|
||||
return tagFn.apply(this, args);
|
||||
};
|
||||
var result = transform(code);
|
||||
expect(result.split('\n').length).toBe(code.split('\n').length);
|
||||
eval(result);
|
||||
expect(tagCalls).toBe(1);
|
||||
}
|
||||
|
||||
function expectSiteObj(siteObj, cooked, raw) {
|
||||
expect(Array.isArray(siteObj)).toBe(true);
|
||||
expect(Object.isFrozen(siteObj)).toBe(true);
|
||||
expect(Array.isArray(siteObj.raw)).toBe(true);
|
||||
expect(Object.isFrozen(siteObj.raw)).toBe(true);
|
||||
expect(siteObj.length).toBe(cooked.length);
|
||||
expect(siteObj.raw.length).toBe(raw.length);
|
||||
for (var ii = 0; ii < cooked.length; ii++) {
|
||||
expect(siteObj[ii]).toEqual(cooked[ii]);
|
||||
}
|
||||
expect(siteObj.raw).toEqual(raw);
|
||||
}
|
||||
|
||||
it('should transform simple literals', function() {
|
||||
expectTransform('`foo bar`', '("foo bar")');
|
||||
|
||||
expectEval('`foo bar`', 'foo bar');
|
||||
expectEval('`$`', '$');
|
||||
expectEval('`$foo`', '$foo');
|
||||
});
|
||||
|
||||
it('should properly escape templates containing quotes', function() {
|
||||
expectTransform('`foo "bar"`', '("foo \\"bar\\"")');
|
||||
expectEval('`foo "bar"`', 'foo "bar"');
|
||||
|
||||
expectTransform("`foo 'bar'`", '("foo \'bar\'")');
|
||||
expectEval("`foo 'bar'`", "foo 'bar'");
|
||||
|
||||
// `foo \\"bar\\"` (foo, literal slash, "bar", literal slash)
|
||||
expectTransform('`foo \\\\"bar\\\\"`', '("foo \\\\\\"bar\\\\\\"")');
|
||||
expectEval('`foo \\\\\\"bar\\\\\\"`', 'foo \\"bar\\"');
|
||||
});
|
||||
|
||||
it('should transform simple substitutions', function() {
|
||||
expectTransform('`foo ${bar}`', '("foo " + bar)');
|
||||
expectTransform('`${foo} bar`', '("" + foo + " bar")');
|
||||
expectTransform('`${foo} ${bar}`', '("" + foo + " " + bar)');
|
||||
expectTransform('`${foo}${bar}`', '("" + foo + bar)');
|
||||
});
|
||||
|
||||
it('should transform expressions', function() {
|
||||
expectTransform('`foo ${bar()}`', '("foo " + bar())');
|
||||
expectTransform('`foo ${bar.baz}`', '("foo " + bar.baz)');
|
||||
expectTransform('`foo ${bar + 5}`', '("foo " + (bar + 5))');
|
||||
expectTransform('`${foo + 5} bar`', '("" + (foo + 5) + " bar")');
|
||||
expectTransform('`${foo + 5} ${bar}`', '("" + (foo + 5) + " " + bar)');
|
||||
expectTransform(
|
||||
'`${(function(b) {alert(4);})(a)}`',
|
||||
'("" + (function(b) {alert(4);})(a))');
|
||||
expectTransform("`${4 + 5}`", '("" + (4 + 5))');
|
||||
});
|
||||
|
||||
it('should transform tags with simple templates', function() {
|
||||
/*jshint unused:false*/
|
||||
var tag = function(elements) {
|
||||
expectSiteObj(elements, ['foo bar'], ['foo bar']);
|
||||
};
|
||||
var result = transform("tag`foo bar`");
|
||||
expect(result.split('\n').length).toBe(1);
|
||||
eval(result);
|
||||
|
||||
var a = { b: tag };
|
||||
eval(transform("a.b`foo bar`"));
|
||||
eval(transform("a['b']`foo bar`"));
|
||||
|
||||
var getTag = function() { return tag; };
|
||||
eval(transform("getTag()`foo bar`"));
|
||||
eval(transform("(getTag())`foo bar`"));
|
||||
});
|
||||
|
||||
it('should transform tags with substitutions', function() {
|
||||
expectTransform(
|
||||
"tag`foo ${bar} baz`",
|
||||
'tag(function() { var siteObj = ["foo ", " baz"]; ' +
|
||||
'siteObj.raw = ["foo ", " baz"]; Object.freeze(siteObj.raw); ' +
|
||||
'Object.freeze(siteObj); return siteObj; }(), bar)'
|
||||
);
|
||||
|
||||
expectEvalTag(
|
||||
"tag`foo ${bar + 'abc'} baz`",
|
||||
function(elements, ...args) {
|
||||
expectSiteObj(elements, ['foo ', ' baz'], ['foo ', ' baz']);
|
||||
expect(args.length).toBe(1);
|
||||
expect(args[0]).toBe('barabc');
|
||||
},
|
||||
{bar: 'bar'}
|
||||
);
|
||||
|
||||
expectEvalTag(
|
||||
"tag`foo ${bar + 'abc'}`",
|
||||
function(elements, ...args) {
|
||||
expectSiteObj(elements, ['foo ', ''], ['foo ', '']);
|
||||
expect(args.length).toBe(1);
|
||||
expect(args[0]).toBe('barabc');
|
||||
},
|
||||
{bar: 'bar'}
|
||||
);
|
||||
|
||||
expectEvalTag(
|
||||
"tag`foo\n\n\nbar`",
|
||||
(elements) => {
|
||||
expectSiteObj(elements, ['foo\n\n\nbar'], ['foo\n\n\nbar']);
|
||||
}
|
||||
);
|
||||
|
||||
expectEvalTag(
|
||||
"tag`a\nb\n${c}\nd`",
|
||||
(elements, ...args) => {
|
||||
expectSiteObj(elements, ['a\nb\n', '\nd'], ['a\nb\n', '\nd']);
|
||||
expect(args.length).toBe(1);
|
||||
expect(args[0]).toBe('c');
|
||||
},
|
||||
{c: 'c'}
|
||||
);
|
||||
});
|
||||
|
||||
it('should maintain line numbers', function() {
|
||||
expectTransform("`foo\n\nbar`", '("foo\\n\\nbar"\n\n)');
|
||||
expectTransform("`foo\n${bar}\nbaz`", '("foo\\n" + \nbar + "\\nbaz"\n)');
|
||||
expectTransform("`foo\\nbar`", '("foo\\nbar")');
|
||||
|
||||
expectTransform(
|
||||
"tag`a\nb\n${c}${d}\ne`",
|
||||
'tag(function() { var siteObj = ["a\\nb\\n", "", "\\ne"]; ' +
|
||||
'siteObj.raw = ["a\\nb\\n", "", "\\ne"]; Object.freeze(siteObj.raw); ' +
|
||||
'Object.freeze(siteObj); return siteObj; }(), \n\nc, d\n)'
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle multiple lines', function() {
|
||||
expectEval("`foo\n\nbar`", 'foo\n\nbar');
|
||||
expectEval("`foo\\nbar`", 'foo\nbar');
|
||||
expectEval("`foo\\\\nbar`", 'foo\\nbar');
|
||||
expectEval("`foo\n${bar}\nbaz`", 'foo\nabc\nbaz', 'var bar = "abc";');
|
||||
});
|
||||
|
||||
it('should handle numeric expressions', function() {
|
||||
expectEval("`foo${1}bar${2}`", 'foo1bar2');
|
||||
expectEval("`foo${1}${2}bar`", 'foo12bar');
|
||||
expectEval("`${1}${2}foo`", '12foo');
|
||||
expectEval("`${1}${2}`", '12');
|
||||
});
|
||||
|
||||
it('should handle primitive literals', function() {
|
||||
expectTransform("`${42}`", '("" + 42)');
|
||||
expectEval("`${42}`", '42');
|
||||
|
||||
expectTransform("`${'42'}`", '("" + \'42\')');
|
||||
expectEval("`${'42'}`", '42');
|
||||
|
||||
expectTransform("`${true}`", '("" + true)');
|
||||
expectEval("`${true}`", 'true');
|
||||
|
||||
expectTransform("`${null}`", '("" + null)');
|
||||
expectEval("`${null}`", 'null');
|
||||
|
||||
// undefined is actually an Identifier but it falls into the same category
|
||||
expectTransform("`${undefined}`", '("" + undefined)');
|
||||
expectEval("`${undefined}`", 'undefined');
|
||||
}),
|
||||
|
||||
it('should canonicalize line endings', function() {
|
||||
// TODO: should this be '("foo\\nbar"\r\n)' to maintain the number of lines
|
||||
// for editors that break on \r\n? I don't think we care in the transformed
|
||||
// code.
|
||||
expectTransform("`foo\r\nbar`", '("foo\\nbar"\n)');
|
||||
// TODO: same as above but with trailing \r
|
||||
expectTransform("`foo\rbar`", '("foo\\nbar")');
|
||||
|
||||
expectEval("`foo\r\nbar`", 'foo\nbar');
|
||||
expectEval("`foo\rbar`", 'foo\nbar');
|
||||
expectEval("`foo\r\n${bar}\r\nbaz`", 'foo\nabc\nbaz', 'var bar = "abc";');
|
||||
|
||||
expectEvalTag(
|
||||
"tag`foo\rbar`",
|
||||
(elements) => {
|
||||
expectSiteObj(elements, ['foo\nbar'], ['foo\rbar']);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
104
node_modules/jstransform/visitors/__tests__/es7-rest-property-helpers-test.js
generated
vendored
Normal file
104
node_modules/jstransform/visitors/__tests__/es7-rest-property-helpers-test.js
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails sema@fb.com
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('es7-rest-property-visitors', function() {
|
||||
var transformFn;
|
||||
|
||||
var visitors;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
transformFn = require('../../src/jstransform').transform;
|
||||
|
||||
visitors = require('../es6-destructuring-visitors').visitorList;
|
||||
});
|
||||
|
||||
function transform(code) {
|
||||
var lines = Array.prototype.join.call(arguments, '\n');
|
||||
return transformFn(visitors, lines).code;
|
||||
}
|
||||
|
||||
// Semantic tests.
|
||||
|
||||
it('picks off remaining properties from an object', function() {
|
||||
var code = transform(
|
||||
'({ x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 });',
|
||||
'([ x, y, z ]);'
|
||||
);
|
||||
expect(eval(code)).toEqual([1, 2, { a: 3, b: 4 }]);
|
||||
});
|
||||
|
||||
it('picks off remaining properties from a nested object', function() {
|
||||
var code = transform(
|
||||
'var complex = {',
|
||||
' x: { a: 1, b: 2, c: 3 },',
|
||||
' y: [4, 5, 6]',
|
||||
'};',
|
||||
'var {',
|
||||
' x: { a: xa, ...xbc },',
|
||||
' y: [y0, ...y12]',
|
||||
'} = complex;',
|
||||
'([ xa, xbc, y0, y12 ]);'
|
||||
);
|
||||
expect(eval(code)).toEqual([ 1, { b: 2, c: 3 }, 4, [5, 6] ]);
|
||||
});
|
||||
|
||||
it('only extracts own properties', function() {
|
||||
var code = transform(
|
||||
'var obj = Object.create({ x: 1 });',
|
||||
'obj.y = 2;',
|
||||
'({ ...y } = obj);',
|
||||
'(y);'
|
||||
);
|
||||
expect(eval(code)).toEqual({ y: 2 });
|
||||
});
|
||||
|
||||
it('only extracts own properties, except when they are explicit', function() {
|
||||
var code = transform(
|
||||
'var obj = Object.create({ x: 1, y: 2 });',
|
||||
'obj.z = 3;',
|
||||
'({ y, ...z } = obj);',
|
||||
'([ y, z ]);'
|
||||
);
|
||||
expect(eval(code)).toEqual([ 2, { z: 3 } ]);
|
||||
});
|
||||
|
||||
it('avoids passing extra properties when they are picked off', function() {
|
||||
var code = transform(
|
||||
'function base({ a, b, x }) { return [ a, b, x ]; }',
|
||||
'function wrapper({ x, y, ...restConfig }) {',
|
||||
' return base(restConfig);',
|
||||
'}',
|
||||
'wrapper({ x: 1, y: 2, a: 3, b: 4 });'
|
||||
);
|
||||
expect(eval(code)).toEqual([ 3, 4, undefined ]);
|
||||
});
|
||||
|
||||
// Syntax tests.
|
||||
|
||||
it('throws on leading rest properties', function () {
|
||||
expect(() => transform('({ ...x, y, z } = obj)')).toThrow();
|
||||
});
|
||||
|
||||
it('throws on multiple rest properties', function () {
|
||||
expect(() => transform('({ x, ...y, ...z } = obj)')).toThrow();
|
||||
});
|
||||
|
||||
// TODO: Ideally identifier reuse should fail to transform
|
||||
// it('throws on identifier reuse', function () {
|
||||
// expect(() => transform('({ x: { ...z }, y: { ...z } } = obj)')).toThrow();
|
||||
// });
|
||||
|
||||
});
|
||||
167
node_modules/jstransform/visitors/__tests__/es7-spread-property-visitors-test.js
generated
vendored
Normal file
167
node_modules/jstransform/visitors/__tests__/es7-spread-property-visitors-test.js
generated
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails sema@fb.com
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('es7-spread-property-visitors', function() {
|
||||
var transformFn;
|
||||
var originalAssign = Object.assign;
|
||||
var visitors;
|
||||
|
||||
// These are placeholder variables in scope that we can use to assert that a
|
||||
// specific variable reference was passed, rather than an object clone of it.
|
||||
var x = 123456;
|
||||
var y = 789012;
|
||||
var z = 345678;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
transformFn = require('../../src/jstransform').transform;
|
||||
|
||||
visitors = require('../es7-spread-property-visitors').visitorList;
|
||||
});
|
||||
|
||||
function transform(code) {
|
||||
return transformFn(visitors, code).code;
|
||||
}
|
||||
|
||||
function expectTransform(code, result) {
|
||||
expect(transform(code)).toEqual(result);
|
||||
}
|
||||
|
||||
function expectObjectAssign(code) {
|
||||
var objectAssignMock = jest.genMockFunction();
|
||||
Object.assign = objectAssignMock;
|
||||
eval(transform(code));
|
||||
return expect(objectAssignMock);
|
||||
}
|
||||
|
||||
afterEach(function() {
|
||||
Object.assign = originalAssign;
|
||||
});
|
||||
|
||||
// Polyfill sanity checks
|
||||
|
||||
it('has access to a working Object.assign implementation', function() {
|
||||
expect(typeof Object.assign).toBe('function');
|
||||
expect(Object.assign({ b: 2 }, null, { a: 1 })).toEqual({ a: 1, b: 2 });
|
||||
});
|
||||
|
||||
// Semantic tests.
|
||||
|
||||
it('uses Object.assign with an empty new target object', function() {
|
||||
expectObjectAssign(
|
||||
'var xy = { ...x, y: 2 }'
|
||||
).toBeCalledWith({}, x, { y: 2 });
|
||||
});
|
||||
|
||||
it('coalesces consecutive properties into a single object', function() {
|
||||
expectObjectAssign(
|
||||
'var xyz = { ...x, y: 2, z: z }'
|
||||
).toBeCalledWith({}, x, { y: 2, z: z });
|
||||
|
||||
});
|
||||
|
||||
it('avoids an unnecessary empty object when spread is not first', function() {
|
||||
expectObjectAssign(
|
||||
'var xy = { x: 1, ...y }'
|
||||
).toBeCalledWith({ x: 1}, y);
|
||||
});
|
||||
|
||||
it('passes the same value multiple times to Object.assign', function() {
|
||||
expectObjectAssign(
|
||||
'var xyz = { x: 1, y: 2, ...z, ...z }'
|
||||
).toBeCalledWith({ x: 1, y: 2}, z, z);
|
||||
});
|
||||
|
||||
it('keeps object literals as separate arguments to assign', function() {
|
||||
expectObjectAssign(
|
||||
'var xyz = { x: 1, ...({ y: 2 }), z: 3 }'
|
||||
).toBeCalledWith({ x: 1}, { y: 2 }, {z: 3 });
|
||||
});
|
||||
|
||||
it('does not call assign when there are no spread properties', function() {
|
||||
expectObjectAssign(
|
||||
'var xy = { x: 1, y: 2 }'
|
||||
).not.toBeCalled();
|
||||
});
|
||||
|
||||
// Syntax tests.
|
||||
|
||||
it('should preserve extra whitespace', function() {
|
||||
expectTransform(
|
||||
'let xyz = { x: 1, y : \n 2, ... \nz, ... z }',
|
||||
'let xyz = Object.assign({ x: 1, y : \n 2}, \nz, z )'
|
||||
);
|
||||
});
|
||||
|
||||
it('should preserve parenthesis', function() {
|
||||
expectTransform(
|
||||
'let xyz = { x: 1, ...({ y: 2 }), z: 3 }',
|
||||
'let xyz = Object.assign({ x: 1}, ({ y: 2 }), {z: 3 })'
|
||||
);
|
||||
});
|
||||
|
||||
it('should remove trailing commas after properties', function() {
|
||||
expectTransform(
|
||||
'let xyz = { ...x, y: 1, }',
|
||||
'let xyz = Object.assign({}, x, {y: 1 })'
|
||||
);
|
||||
});
|
||||
|
||||
it('should remove trailing commas after spread', function() {
|
||||
expectTransform(
|
||||
'let xyz = { x: 1, ...y, }',
|
||||
'let xyz = Object.assign({ x: 1}, y )'
|
||||
);
|
||||
});
|
||||
|
||||
// Don't transform
|
||||
|
||||
it('should not transform destructuring assignment', function() {
|
||||
expectTransform(
|
||||
'let { x, ...y } = z',
|
||||
'let { x, ...y } = z'
|
||||
);
|
||||
});
|
||||
|
||||
// Accessors are unsupported. We leave it unprocessed so that other,
|
||||
// chained transforms, can take over.
|
||||
|
||||
it('should not transform when there are getters', function() {
|
||||
expectTransform(
|
||||
'let xy = { ...x, get x() { } }',
|
||||
'let xy = { ...x, get x() { } }'
|
||||
);
|
||||
});
|
||||
|
||||
it('should not transform when there are setters', function() {
|
||||
expectTransform(
|
||||
'let xy = { set x(v) { }, ...y }',
|
||||
'let xy = { set x(v) { }, ...y }'
|
||||
);
|
||||
});
|
||||
|
||||
it('should silently ignore falsy values', function() {
|
||||
/*globals obj*/
|
||||
var code = transform([
|
||||
'var x = null;',
|
||||
'var y = { y: "y" };',
|
||||
'var obj = { ...x, ...y, ...{ ...false, z: "z", ...y } };'
|
||||
].join('\n'));
|
||||
|
||||
eval(code);
|
||||
|
||||
expect(obj).toEqual({ y: 'y', z: 'z' });
|
||||
});
|
||||
});
|
||||
95
node_modules/jstransform/visitors/__tests__/es7-trailing-comma-visitors-test.js
generated
vendored
Normal file
95
node_modules/jstransform/visitors/__tests__/es7-trailing-comma-visitors-test.js
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails dmitrys@fb.com
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('es7-trailing-comma-visitors', function() {
|
||||
var transformFn;
|
||||
var visitors;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
transformFn = require('../../src/jstransform').transform;
|
||||
|
||||
visitors = require('../es6-arrow-function-visitors').visitorList
|
||||
.concat(require('../es6-rest-param-visitors').visitorList)
|
||||
.concat(require('../es7-trailing-comma-visitors').visitorList);
|
||||
});
|
||||
|
||||
function transform(code) {
|
||||
return transformFn(visitors, code).code;
|
||||
}
|
||||
|
||||
function expectTransform(code, result) {
|
||||
expect(transform(code)).toEqual(result);
|
||||
}
|
||||
|
||||
it('should eliminate trailing commas in function calls', function() {
|
||||
expectTransform(
|
||||
'Math.max(1, 2 , )',
|
||||
'Math.max(1, 2 )'
|
||||
);
|
||||
});
|
||||
|
||||
it('should eliminate trailing commas when creating new objects', function() {
|
||||
expectTransform(
|
||||
'var pet = new Animal(\'cat\', NATURE_EVIL,\t);',
|
||||
'var pet = new Animal(\'cat\', NATURE_EVIL\t);'
|
||||
);
|
||||
});
|
||||
|
||||
it('should eliminate trailing commas in function expressions', function() {
|
||||
expectTransform(
|
||||
'var Animal = function(species, nature,) { this.species = species; };',
|
||||
'var Animal = function(species, nature) { this.species = species; };'
|
||||
);
|
||||
});
|
||||
|
||||
it('should eliminate trailing commas in function definitions', function() {
|
||||
expectTransform(
|
||||
'function Animal(species, nature,) { this.species = species; };',
|
||||
'function Animal(species, nature) { this.species = species; };'
|
||||
);
|
||||
});
|
||||
|
||||
it('should eliminate trailing commas in method definitions', function() {
|
||||
expectTransform(
|
||||
'class Animal{ setNature(nature,) { this.nature = nature; } }',
|
||||
'class Animal{ setNature(nature) { this.nature = nature; } }'
|
||||
);
|
||||
});
|
||||
|
||||
it('should eliminate trailing commas in arrow functions', function() {
|
||||
expectTransform(
|
||||
'var cube = ((x,) => x * x * x);',
|
||||
'var cube = (function(x) {return x * x * x;});'
|
||||
);
|
||||
|
||||
expectTransform(
|
||||
'var multiply = ((x,y,z,) => x * y * z);',
|
||||
'var multiply = (function(x,y,z) {return x * y * z;});'
|
||||
);
|
||||
});
|
||||
|
||||
it('should eliminate trailing commas after default arguments', function() {
|
||||
expectTransform(
|
||||
'(function foo(x = 5,) {})',
|
||||
'(function foo(x = 5) {})'
|
||||
);
|
||||
expectTransform(
|
||||
'(function foo({x} = {},) {})',
|
||||
'(function foo({x} = {}) {})'
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
56
node_modules/jstransform/visitors/__tests__/gen/generate-type-syntax-test.js
generated
vendored
Normal file
56
node_modules/jstransform/visitors/__tests__/gen/generate-type-syntax-test.js
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*jshint evil:true, multistr:true*/
|
||||
|
||||
var tests = require('./../type-syntax-test');
|
||||
var jstransform = require('../../../src/jstransform');
|
||||
var visitors = require('../../type-syntax').visitorList;
|
||||
var fs = require('fs');
|
||||
|
||||
var out = '/**\n\
|
||||
* WARNING: This file is autogenerated by\n\
|
||||
* src/visitors/flow/__tests__/gen/generate-type-syntax-test.js\n\
|
||||
* Do NOT modify this file directly! Instead, add your tests to\n\
|
||||
* src/visitors/flow/__tests__/type-syntax-test.js and run\n\
|
||||
* src/visitors/flow/__tests__/gen/generate-type-syntax-test.js\n\
|
||||
*/\n\n';
|
||||
|
||||
var data = {};
|
||||
Object.keys(tests).forEach(function(sectionName) {
|
||||
var section = tests[sectionName];
|
||||
var sectionData = {};
|
||||
section.forEach(function(testCode) {
|
||||
var code;
|
||||
sectionData[testCode] = {};
|
||||
var testData = {};
|
||||
try {
|
||||
code = jstransform.transform(visitors, testCode).code;
|
||||
testData.raworiginal = testCode;
|
||||
testData.transformed = code;
|
||||
try {
|
||||
eval(code);
|
||||
testData.eval = 'No error';
|
||||
} catch (e) {
|
||||
testData.eval = e.message;
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
testData.error = e.message;
|
||||
}
|
||||
sectionData[testCode] = testData;
|
||||
});
|
||||
data[sectionName] = sectionData;
|
||||
});
|
||||
|
||||
out += 'module.exports = ' + JSON.stringify(data, null, 2) + ';\n';
|
||||
|
||||
fs.writeFileSync(__dirname + '/type-syntax-test.rec.js', out);
|
||||
console.log('Recorded type-syntax-test.js output into type-syntax-test.rec.js');
|
||||
|
||||
712
node_modules/jstransform/visitors/__tests__/gen/type-syntax-test.rec.js
generated
vendored
Normal file
712
node_modules/jstransform/visitors/__tests__/gen/type-syntax-test.rec.js
generated
vendored
Normal file
@@ -0,0 +1,712 @@
|
||||
/**
|
||||
* WARNING: This file is autogenerated by
|
||||
* src/visitors/flow/__tests__/gen/generate-type-syntax-test.js
|
||||
* Do NOT modify this file directly! Instead, add your tests to
|
||||
* src/visitors/flow/__tests__/type-syntax-test.js and run
|
||||
* src/visitors/flow/__tests__/gen/generate-type-syntax-test.js
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
"TypeAnnotations": {
|
||||
"function foo(numVal: any){}": {
|
||||
"raworiginal": "function foo(numVal: any){}",
|
||||
"transformed": "function foo(numVal ){}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo(numVal: number){}": {
|
||||
"raworiginal": "function foo(numVal: number){}",
|
||||
"transformed": "function foo(numVal ){}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo(numVal: number, strVal: string){}": {
|
||||
"raworiginal": "function foo(numVal: number, strVal: string){}",
|
||||
"transformed": "function foo(numVal , strVal ){}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo(numVal: number, untypedVal){}": {
|
||||
"raworiginal": "function foo(numVal: number, untypedVal){}",
|
||||
"transformed": "function foo(numVal , untypedVal){}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo(untypedVal, numVal: number){}": {
|
||||
"raworiginal": "function foo(untypedVal, numVal: number){}",
|
||||
"transformed": "function foo(untypedVal, numVal ){}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo(nullableNum: ?number){}": {
|
||||
"raworiginal": "function foo(nullableNum: ?number){}",
|
||||
"transformed": "function foo(nullableNum ){}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo(callback: () => void){}": {
|
||||
"raworiginal": "function foo(callback: () => void){}",
|
||||
"transformed": "function foo(callback ){}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo(callback: () => number){}": {
|
||||
"raworiginal": "function foo(callback: () => number){}",
|
||||
"transformed": "function foo(callback ){}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo(callback: (_:bool) => number){}": {
|
||||
"raworiginal": "function foo(callback: (_:bool) => number){}",
|
||||
"transformed": "function foo(callback ){}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo(callback: (_1:bool, _2:string) => number){}": {
|
||||
"raworiginal": "function foo(callback: (_1:bool, _2:string) => number){}",
|
||||
"transformed": "function foo(callback ){}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo(callback: (_1:bool, ...foo:Array<number>) => number){}": {
|
||||
"raworiginal": "function foo(callback: (_1:bool, ...foo:Array<number>) => number){}",
|
||||
"transformed": "function foo(callback ){}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo():number{}": {
|
||||
"raworiginal": "function foo():number{}",
|
||||
"transformed": "function foo() {}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo():() => void{}": {
|
||||
"raworiginal": "function foo():() => void{}",
|
||||
"transformed": "function foo() {}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo():(_:bool) => number{}": {
|
||||
"raworiginal": "function foo():(_:bool) => number{}",
|
||||
"transformed": "function foo() {}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo():(_?:bool) => number{}": {
|
||||
"raworiginal": "function foo():(_?:bool) => number{}",
|
||||
"transformed": "function foo() {}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo(): {} {}": {
|
||||
"raworiginal": "function foo(): {} {}",
|
||||
"transformed": "function foo() {}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo<T>() {}": {
|
||||
"raworiginal": "function foo<T>() {}",
|
||||
"transformed": "function foo () {}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo<T: Foo>() {}": {
|
||||
"raworiginal": "function foo<T: Foo>() {}",
|
||||
"transformed": "function foo () {}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function foo<T,S>() {}": {
|
||||
"raworiginal": "function foo<T,S>() {}",
|
||||
"transformed": "function foo () {}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"a=function<T,S>() {}": {
|
||||
"raworiginal": "a=function<T,S>() {}",
|
||||
"transformed": "a=function () {}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"a={set fooProp(value:number){}}": {
|
||||
"raworiginal": "a={set fooProp(value:number){}}",
|
||||
"transformed": "a={set fooProp(value ){}}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"a={set fooProp(value:number): void{}}": {
|
||||
"raworiginal": "a={set fooProp(value:number): void{}}",
|
||||
"transformed": "a={set fooProp(value ) {}}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"a={get fooProp(): number {}}": {
|
||||
"raworiginal": "a={get fooProp(): number {}}",
|
||||
"transformed": "a={get fooProp() {}}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"class Foo {set fooProp(value:number){}}": {
|
||||
"raworiginal": "class Foo {set fooProp(value:number){}}",
|
||||
"transformed": "class Foo {set fooProp(value ){}}",
|
||||
"eval": "Unexpected reserved word"
|
||||
},
|
||||
"class Foo {set fooProp(value:number): void{}}": {
|
||||
"raworiginal": "class Foo {set fooProp(value:number): void{}}",
|
||||
"transformed": "class Foo {set fooProp(value ) {}}",
|
||||
"eval": "Unexpected reserved word"
|
||||
},
|
||||
"class Foo {get fooProp(): number{}}": {
|
||||
"raworiginal": "class Foo {get fooProp(): number{}}",
|
||||
"transformed": "class Foo {get fooProp() {}}",
|
||||
"eval": "Unexpected reserved word"
|
||||
},
|
||||
"var numVal:number;": {
|
||||
"raworiginal": "var numVal:number;",
|
||||
"transformed": "var numVal ;",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var numVal:number = otherNumVal;": {
|
||||
"raworiginal": "var numVal:number = otherNumVal;",
|
||||
"transformed": "var numVal = otherNumVal;",
|
||||
"eval": "otherNumVal is not defined"
|
||||
},
|
||||
"var a: {numVal: number};": {
|
||||
"raworiginal": "var a: {numVal: number};",
|
||||
"transformed": "var a ;",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a: {numVal: number;};": {
|
||||
"raworiginal": "var a: {numVal: number;};",
|
||||
"transformed": "var a ;",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a: {numVal: number; [indexer: string]: number};": {
|
||||
"raworiginal": "var a: {numVal: number; [indexer: string]: number};",
|
||||
"transformed": "var a ;",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a: ?{numVal: number};": {
|
||||
"raworiginal": "var a: ?{numVal: number};",
|
||||
"transformed": "var a ;",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a: {numVal: number; strVal: string}": {
|
||||
"raworiginal": "var a: {numVal: number; strVal: string}",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a: {subObj: {strVal: string}}": {
|
||||
"raworiginal": "var a: {subObj: {strVal: string}}",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a: {subObj: ?{strVal: string}}": {
|
||||
"raworiginal": "var a: {subObj: ?{strVal: string}}",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a: {param1: number; param2: string}": {
|
||||
"raworiginal": "var a: {param1: number; param2: string}",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a: {param1: number; param2?: string}": {
|
||||
"raworiginal": "var a: {param1: number; param2?: string}",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a: {add(x:number, ...y:Array<string>): void}": {
|
||||
"raworiginal": "var a: {add(x:number, ...y:Array<string>): void}",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a: { id<T>(x: T): T; }": {
|
||||
"raworiginal": "var a: { id<T>(x: T): T; }",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a:Array<number> = [1, 2, 3]": {
|
||||
"raworiginal": "var a:Array<number> = [1, 2, 3]",
|
||||
"transformed": "var a = [1, 2, 3]",
|
||||
"eval": "No error"
|
||||
},
|
||||
"a = class Foo<T> { }": {
|
||||
"raworiginal": "a = class Foo<T> { }",
|
||||
"transformed": "a = class Foo<T> { }",
|
||||
"eval": "Unexpected reserved word"
|
||||
},
|
||||
"a = class Foo<T> extends Bar<T> { }": {
|
||||
"raworiginal": "a = class Foo<T> extends Bar<T> { }",
|
||||
"transformed": "a = class Foo<T> extends Bar<T> { }",
|
||||
"eval": "Unexpected reserved word"
|
||||
},
|
||||
"class Foo<T> {}": {
|
||||
"raworiginal": "class Foo<T> {}",
|
||||
"transformed": "class Foo<T> {}",
|
||||
"eval": "Unexpected reserved word"
|
||||
},
|
||||
"class Foo<T: Bar> {}": {
|
||||
"raworiginal": "class Foo<T: Bar> {}",
|
||||
"transformed": "class Foo<T > {}",
|
||||
"eval": "Unexpected reserved word"
|
||||
},
|
||||
"class Foo<T> extends Bar<T> { }": {
|
||||
"raworiginal": "class Foo<T> extends Bar<T> { }",
|
||||
"transformed": "class Foo<T> extends Bar<T> { }",
|
||||
"eval": "Unexpected reserved word"
|
||||
},
|
||||
"class Foo<T> extends mixin(Bar) { }": {
|
||||
"raworiginal": "class Foo<T> extends mixin(Bar) { }",
|
||||
"transformed": "class Foo<T> extends mixin(Bar) { }",
|
||||
"eval": "Unexpected reserved word"
|
||||
},
|
||||
"class Foo<T> { bar<U>():number { return 42; }}": {
|
||||
"raworiginal": "class Foo<T> { bar<U>():number { return 42; }}",
|
||||
"transformed": "class Foo<T> { bar<U>() { return 42; }}",
|
||||
"eval": "Unexpected reserved word"
|
||||
},
|
||||
"class Foo { \"bar\"<T>() { } }": {
|
||||
"raworiginal": "class Foo { \"bar\"<T>() { } }",
|
||||
"transformed": "class Foo { \"bar\"<T>() { } }",
|
||||
"eval": "Unexpected reserved word"
|
||||
},
|
||||
"function foo(requiredParam, optParam?) {}": {
|
||||
"raworiginal": "function foo(requiredParam, optParam?) {}",
|
||||
"transformed": "function foo(requiredParam, optParam ) {}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"class Foo { prop1:string; prop2:number; }": {
|
||||
"raworiginal": "class Foo { prop1:string; prop2:number; }",
|
||||
"transformed": "class Foo { }",
|
||||
"eval": "Unexpected reserved word"
|
||||
},
|
||||
"var x : number | string = 4;": {
|
||||
"raworiginal": "var x : number | string = 4;",
|
||||
"transformed": "var x = 4;",
|
||||
"eval": "No error"
|
||||
},
|
||||
"class Array { concat(items:number | string) {}; }": {
|
||||
"raworiginal": "class Array { concat(items:number | string) {}; }",
|
||||
"transformed": "class Array { concat(items ) {}; }",
|
||||
"eval": "Unexpected reserved word"
|
||||
},
|
||||
"var x : () => number | () => string = fn;": {
|
||||
"raworiginal": "var x : () => number | () => string = fn;",
|
||||
"transformed": "var x = fn;",
|
||||
"eval": "fn is not defined"
|
||||
},
|
||||
"var x: typeof Y = Y;": {
|
||||
"raworiginal": "var x: typeof Y = Y;",
|
||||
"transformed": "var x = Y;",
|
||||
"eval": "Y is not defined"
|
||||
},
|
||||
"var x: typeof Y | number = Y;": {
|
||||
"raworiginal": "var x: typeof Y | number = Y;",
|
||||
"transformed": "var x = Y;",
|
||||
"eval": "Y is not defined"
|
||||
},
|
||||
"var {x}: {x: string; } = { x: \"hello\" };": {
|
||||
"raworiginal": "var {x}: {x: string; } = { x: \"hello\" };",
|
||||
"transformed": "var {x} = { x: \"hello\" };",
|
||||
"eval": "Unexpected token {"
|
||||
},
|
||||
"var {x}: {x: string } = { x: \"hello\" };": {
|
||||
"raworiginal": "var {x}: {x: string } = { x: \"hello\" };",
|
||||
"transformed": "var {x} = { x: \"hello\" };",
|
||||
"eval": "Unexpected token {"
|
||||
},
|
||||
"var [x]: Array<string> = [ \"hello\" ];": {
|
||||
"raworiginal": "var [x]: Array<string> = [ \"hello\" ];",
|
||||
"transformed": "var [x] = [ \"hello\" ];",
|
||||
"eval": "Unexpected token ["
|
||||
},
|
||||
"function foo({x}: { x: string; }) {}": {
|
||||
"raworiginal": "function foo({x}: { x: string; }) {}",
|
||||
"transformed": "function foo({x} ) {}",
|
||||
"eval": "Unexpected token {"
|
||||
},
|
||||
"function foo([x]: Array<string>) {}": {
|
||||
"raworiginal": "function foo([x]: Array<string>) {}",
|
||||
"transformed": "function foo([x] ) {}",
|
||||
"eval": "Unexpected token ["
|
||||
},
|
||||
"function foo(...rest: Array<number>) {}": {
|
||||
"raworiginal": "function foo(...rest: Array<number>) {}",
|
||||
"transformed": "function foo(...rest ) {}",
|
||||
"eval": "Unexpected token ."
|
||||
},
|
||||
"(function (...rest: Array<number>) {})": {
|
||||
"raworiginal": "(function (...rest: Array<number>) {})",
|
||||
"transformed": "(function (...rest ) {})",
|
||||
"eval": "Unexpected token ."
|
||||
},
|
||||
"((...rest: Array<number>) => rest)": {
|
||||
"raworiginal": "((...rest: Array<number>) => rest)",
|
||||
"transformed": "((...rest ) => rest)",
|
||||
"eval": "Unexpected token ."
|
||||
},
|
||||
"var a: Map<string, Array<string> >": {
|
||||
"raworiginal": "var a: Map<string, Array<string> >",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a: Map<string, Array<string>>": {
|
||||
"raworiginal": "var a: Map<string, Array<string>>",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a: number[]": {
|
||||
"raworiginal": "var a: number[]",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a: ?string[]": {
|
||||
"raworiginal": "var a: ?string[]",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a: Promise<bool>[]": {
|
||||
"raworiginal": "var a: Promise<bool>[]",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a:(...rest:Array<number>) => number": {
|
||||
"raworiginal": "var a:(...rest:Array<number>) => number",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
}
|
||||
},
|
||||
"Type Alias": {
|
||||
"type FBID = number;": {
|
||||
"raworiginal": "type FBID = number;",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"type Foo<T> = Bar<T>": {
|
||||
"raworiginal": "type Foo<T> = Bar<T>",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
}
|
||||
},
|
||||
"Interfaces": {
|
||||
"interface A {}": {
|
||||
"raworiginal": "interface A {}",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"interface A extends B {}": {
|
||||
"raworiginal": "interface A extends B {}",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"interface A<T> extends B<T>, C<T> {}": {
|
||||
"raworiginal": "interface A<T> extends B<T>, C<T> {}",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"interface A { foo: () => number; }": {
|
||||
"raworiginal": "interface A { foo: () => number; }",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"interface Dictionary { [index: string]: string; length: number; }": {
|
||||
"raworiginal": "interface Dictionary { [index: string]: string; length: number; }",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"class Foo implements Bar {}": {
|
||||
"raworiginal": "class Foo implements Bar {}",
|
||||
"transformed": "class Foo implements Bar {}",
|
||||
"eval": "Unexpected reserved word"
|
||||
},
|
||||
"class Foo extends Bar implements Bat, Man<number> {}": {
|
||||
"raworiginal": "class Foo extends Bar implements Bat, Man<number> {}",
|
||||
"transformed": "class Foo extends Bar implements Bat, Man<number> {}",
|
||||
"eval": "Unexpected reserved word"
|
||||
},
|
||||
"class Foo extends class Bar implements Bat {} {}": {
|
||||
"raworiginal": "class Foo extends class Bar implements Bat {} {}",
|
||||
"transformed": "class Foo extends class Bar implements Bat {} {}",
|
||||
"eval": "Unexpected reserved word"
|
||||
},
|
||||
"class Foo extends class Bar implements Bat {} implements Man {}": {
|
||||
"raworiginal": "class Foo extends class Bar implements Bat {} implements Man {}",
|
||||
"transformed": "class Foo extends class Bar implements Bat {} implements Man {}",
|
||||
"eval": "Unexpected reserved word"
|
||||
}
|
||||
},
|
||||
"Type Grouping": {
|
||||
"var a: (number)": {
|
||||
"raworiginal": "var a: (number)",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a: (() => number) | () => string": {
|
||||
"raworiginal": "var a: (() => number) | () => string",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a: number & (string | bool)": {
|
||||
"raworiginal": "var a: number & (string | bool)",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a: (typeof A)": {
|
||||
"raworiginal": "var a: (typeof A)",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
}
|
||||
},
|
||||
"XJS": {
|
||||
"<a />": {
|
||||
"raworiginal": "<a />",
|
||||
"transformed": "<a />",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<n:a n:v />": {
|
||||
"raworiginal": "<n:a n:v />",
|
||||
"transformed": "<n:a n:v />",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<a n:foo=\"bar\"> {value} <b><c /></b></a>": {
|
||||
"raworiginal": "<a n:foo=\"bar\"> {value} <b><c /></b></a>",
|
||||
"transformed": "<a n:foo=\"bar\"> {value} <b><c /></b></a>",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<a b={\" \"} c=\" \" d=\"&\" e=\"id=1&group=2\" f=\"�\" g=\"{*;\" h=\"&#x;\" />": {
|
||||
"raworiginal": "<a b={\" \"} c=\" \" d=\"&\" e=\"id=1&group=2\" f=\"�\" g=\"{*;\" h=\"&#x;\" />",
|
||||
"transformed": "<a b={\" \"} c=\" \" d=\"&\" e=\"id=1&group=2\" f=\"�\" g=\"{*;\" h=\"&#x;\" />",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<a\n/>": {
|
||||
"raworiginal": "<a\n/>",
|
||||
"transformed": "<a\n/>",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<日本語></日本語>": {
|
||||
"raworiginal": "<日本語></日本語>",
|
||||
"transformed": "<日本語></日本語>",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<AbC-def\n test=\"&&\">\nbar\nbaz\r\n</AbC-def>": {
|
||||
"raworiginal": "<AbC-def\n test=\"&&\">\nbar\nbaz\r\n</AbC-def>",
|
||||
"transformed": "<AbC-def\n test=\"&&\">\nbar\nbaz\r\n</AbC-def>",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<a b={x ? <c /> : <d />} />": {
|
||||
"raworiginal": "<a b={x ? <c /> : <d />} />",
|
||||
"transformed": "<a b={x ? <c /> : <d />} />",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<a>{}</a>": {
|
||||
"raworiginal": "<a>{}</a>",
|
||||
"transformed": "<a>{}</a>",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<a>{/* this is a comment */}</a>": {
|
||||
"raworiginal": "<a>{/* this is a comment */}</a>",
|
||||
"transformed": "<a>{/* this is a comment */}</a>",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<div>@test content</div>": {
|
||||
"raworiginal": "<div>@test content</div>",
|
||||
"transformed": "<div>@test content</div>",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<div><br />7x invalid-js-identifier</div>": {
|
||||
"raworiginal": "<div><br />7x invalid-js-identifier</div>",
|
||||
"transformed": "<div><br />7x invalid-js-identifier</div>",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<LeftRight left=<a /> right=<b>monkeys</b> />": {
|
||||
"raworiginal": "<LeftRight left=<a /> right=<b>monkeys</b> />",
|
||||
"transformed": "<LeftRight left=<a /> right=<b>monkeys</b> />",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<a.b></a.b>": {
|
||||
"raworiginal": "<a.b></a.b>",
|
||||
"transformed": "<a.b></a.b>",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<a.b.c></a.b.c>": {
|
||||
"raworiginal": "<a.b.c></a.b.c>",
|
||||
"transformed": "<a.b.c></a.b.c>",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"(<div />) < x;": {
|
||||
"raworiginal": "(<div />) < x;",
|
||||
"transformed": "(<div />) < x;",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<div {...props} />": {
|
||||
"raworiginal": "<div {...props} />",
|
||||
"transformed": "<div {...props} />",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<div {...props} post=\"attribute\" />": {
|
||||
"raworiginal": "<div {...props} post=\"attribute\" />",
|
||||
"transformed": "<div {...props} post=\"attribute\" />",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<div pre=\"leading\" pre2=\"attribute\" {...props}></div>": {
|
||||
"raworiginal": "<div pre=\"leading\" pre2=\"attribute\" {...props}></div>",
|
||||
"transformed": "<div pre=\"leading\" pre2=\"attribute\" {...props}></div>",
|
||||
"eval": "Unexpected token <"
|
||||
},
|
||||
"<a> </a>": {
|
||||
"raworiginal": "<a> </a>",
|
||||
"transformed": "<a> </a>",
|
||||
"eval": "Unexpected token <"
|
||||
}
|
||||
},
|
||||
"Call Properties": {
|
||||
"var a : { (): number }": {
|
||||
"raworiginal": "var a : { (): number }",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a : { (): number; }": {
|
||||
"raworiginal": "var a : { (): number; }",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a : { (): number; y: string; (x: string): string }": {
|
||||
"raworiginal": "var a : { (): number; y: string; (x: string): string }",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a : { <T>(x: T): number; }": {
|
||||
"raworiginal": "var a : { <T>(x: T): number; }",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"interface A { (): number; }": {
|
||||
"raworiginal": "interface A { (): number; }",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
}
|
||||
},
|
||||
"String Literal Types": {
|
||||
"function createElement(tagName: \"div\"): HTMLDivElement {}": {
|
||||
"raworiginal": "function createElement(tagName: \"div\"): HTMLDivElement {}",
|
||||
"transformed": "function createElement(tagName ) {}",
|
||||
"eval": "No error"
|
||||
},
|
||||
"function createElement(tagName: 'div'): HTMLDivElement {}": {
|
||||
"raworiginal": "function createElement(tagName: 'div'): HTMLDivElement {}",
|
||||
"transformed": "function createElement(tagName ) {}",
|
||||
"eval": "No error"
|
||||
}
|
||||
},
|
||||
"Qualified Generic Type": {
|
||||
"var a : A.B": {
|
||||
"raworiginal": "var a : A.B",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a : A.B.C": {
|
||||
"raworiginal": "var a : A.B.C",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a : A.B<T>": {
|
||||
"raworiginal": "var a : A.B<T>",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"var a : typeof A.B<T>": {
|
||||
"raworiginal": "var a : typeof A.B<T>",
|
||||
"transformed": "var a ",
|
||||
"eval": "No error"
|
||||
}
|
||||
},
|
||||
"Declare Statements": {
|
||||
"declare var foo": {
|
||||
"raworiginal": "declare var foo",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"declare var foo;": {
|
||||
"raworiginal": "declare var foo;",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"declare function foo(): void": {
|
||||
"raworiginal": "declare function foo(): void",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"declare function foo(): void;": {
|
||||
"raworiginal": "declare function foo(): void;",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"declare function foo<T>(): void;": {
|
||||
"raworiginal": "declare function foo<T>(): void;",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"declare function foo(x: number, y: string): void;": {
|
||||
"raworiginal": "declare function foo(x: number, y: string): void;",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"declare class A {}": {
|
||||
"raworiginal": "declare class A {}",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"declare class A<T> extends B<T> { x: number }": {
|
||||
"raworiginal": "declare class A<T> extends B<T> { x: number }",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"declare class A { static foo(): number; static x : string }": {
|
||||
"raworiginal": "declare class A { static foo(): number; static x : string }",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"declare class A { static [ indexer: number]: string }": {
|
||||
"raworiginal": "declare class A { static [ indexer: number]: string }",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"declare class A { static () : number }": {
|
||||
"raworiginal": "declare class A { static () : number }",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
}
|
||||
},
|
||||
"Declare Module": {
|
||||
"declare module A {}": {
|
||||
"raworiginal": "declare module A {}",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"declare module \"./a/b.js\" {}": {
|
||||
"raworiginal": "declare module \"./a/b.js\" {}",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"declare module A { declare var x: number; }": {
|
||||
"raworiginal": "declare module A { declare var x: number; }",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"declare module A { declare function foo(): number; }": {
|
||||
"raworiginal": "declare module A { declare function foo(): number; }",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
},
|
||||
"declare module A { declare class B { foo(): number; } }": {
|
||||
"raworiginal": "declare module A { declare class B { foo(): number; } }",
|
||||
"transformed": " ",
|
||||
"eval": "No error"
|
||||
}
|
||||
},
|
||||
"Typecasts": {
|
||||
"(xxx: number)": {
|
||||
"raworiginal": "(xxx: number)",
|
||||
"transformed": "(xxx )",
|
||||
"eval": "xxx is not defined"
|
||||
},
|
||||
"({xxx: 0, yyy: \"hey\"}: {xxx: number; yyy: string})": {
|
||||
"raworiginal": "({xxx: 0, yyy: \"hey\"}: {xxx: number; yyy: string})",
|
||||
"transformed": "({xxx: 0, yyy: \"hey\"} )",
|
||||
"eval": "No error"
|
||||
},
|
||||
"((xxx) => xxx + 1: (xxx: number) => number)": {
|
||||
"raworiginal": "((xxx) => xxx + 1: (xxx: number) => number)",
|
||||
"transformed": "((xxx) => xxx + 1 )",
|
||||
"eval": "Unexpected token >"
|
||||
},
|
||||
"((xxx: number), (yyy: string))": {
|
||||
"raworiginal": "((xxx: number), (yyy: string))",
|
||||
"transformed": "((xxx ), (yyy ))",
|
||||
"eval": "xxx is not defined"
|
||||
},
|
||||
"((xxx: any): number)": {
|
||||
"raworiginal": "((xxx: any): number)",
|
||||
"transformed": "((xxx ) )",
|
||||
"eval": "xxx is not defined"
|
||||
}
|
||||
}
|
||||
};
|
||||
142
node_modules/jstransform/visitors/__tests__/jsx-helpers-test.js
generated
vendored
Normal file
142
node_modules/jstransform/visitors/__tests__/jsx-helpers-test.js
generated
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails jeffmo@fb.com
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('jsx', function() {
|
||||
var jsx = require('../jsx-helpers');
|
||||
var utils = require('jstransform/src/utils');
|
||||
var esprima = require('esprima-fb');
|
||||
|
||||
function runWithLiteral(text, isLast) {
|
||||
var source = '<div>' + text + '</div>';
|
||||
var ast = esprima.parse(source, { range: true });
|
||||
var state = utils.createState(source);
|
||||
var literal = ast.body[0].expression.children[0];
|
||||
state.g.position = literal.range[0];
|
||||
jsx.renderJSXLiteral(literal, isLast, state);
|
||||
return state;
|
||||
}
|
||||
|
||||
function runWithAttribute(inlineAttribute, isLast) {
|
||||
var source = '<div ' + inlineAttribute + ' />';
|
||||
var ast = esprima.parse(source, { range: true });
|
||||
var state = utils.createState(source);
|
||||
var attribute = ast.body[0].expression.openingElement.attributes[0];
|
||||
state.g.position = attribute.value.range[0];
|
||||
jsx.renderJSXExpressionContainer(
|
||||
function() {},
|
||||
attribute.value,
|
||||
isLast,
|
||||
[],
|
||||
state
|
||||
);
|
||||
return state;
|
||||
}
|
||||
|
||||
it('should render simple literal', function() {
|
||||
var state = runWithLiteral('a', true);
|
||||
expect(state.g.buffer).toEqual('"a"');
|
||||
});
|
||||
|
||||
|
||||
it('should render simple literal with single space before', function() {
|
||||
var state = runWithLiteral(' a', true);
|
||||
expect(state.g.buffer).toEqual('" a"');
|
||||
});
|
||||
|
||||
it('should render simple literal with single space before' +
|
||||
' from multiple spaces', function() {
|
||||
var state = runWithLiteral(' \t a', true);
|
||||
expect(state.g.buffer).toEqual('" a"');
|
||||
});
|
||||
|
||||
it('should render simple literal with single space after', function() {
|
||||
var state = runWithLiteral('a ', true);
|
||||
expect(state.g.buffer).toEqual('"a "');
|
||||
});
|
||||
|
||||
it('should render simple literal with single space after' +
|
||||
' from multiple spaces', function() {
|
||||
var state = runWithLiteral('a \t \t ', true);
|
||||
expect(state.g.buffer).toEqual('"a "');
|
||||
});
|
||||
|
||||
it('should render multiline literal as last', function() {
|
||||
var state = runWithLiteral(
|
||||
' sdfsdfsdf\n' +
|
||||
' sdlkfjsdfljs\n' +
|
||||
' ',
|
||||
true);
|
||||
|
||||
expect(state.g.buffer).toEqual(
|
||||
'" sdfsdfsdf" + " " +\n' +
|
||||
' "sdlkfjsdfljs"\n' +
|
||||
' ');
|
||||
});
|
||||
|
||||
it('should render multiline literal as not last', function() {
|
||||
var state = runWithLiteral(
|
||||
' sdfsdfsdf\n' +
|
||||
' sdlkfjsdfljs\n' +
|
||||
' ',
|
||||
false);
|
||||
|
||||
expect(state.g.buffer).toEqual(
|
||||
'" sdfsdfsdf" + " " +\n' +
|
||||
' "sdlkfjsdfljs", \n' +
|
||||
' ');
|
||||
});
|
||||
|
||||
it('should render attribute expressions', function() {
|
||||
var state = runWithAttribute('attr={"foo"}', true);
|
||||
expect(state.g.buffer).toEqual('"foo"');
|
||||
});
|
||||
|
||||
it('should render attribute expressions as not last', function() {
|
||||
var state = runWithAttribute('attr={"foo"}', false);
|
||||
expect(state.g.buffer).toEqual('"foo", ');
|
||||
});
|
||||
|
||||
it('should render attribute expressions with spaces', function() {
|
||||
var state = runWithAttribute('attr={ "foo"\n }', true);
|
||||
expect(state.g.buffer).toEqual(' "foo"\n ');
|
||||
});
|
||||
|
||||
it('should render attribute expressions with commas before trailing ' +
|
||||
'whitespace', function() {
|
||||
var state = runWithAttribute('attr={\n"foo"\n }', false);
|
||||
expect(state.g.buffer).toEqual('\n"foo", \n ');
|
||||
});
|
||||
|
||||
it('should render empty child expressions with comments', function() {
|
||||
var source = '<div>{/*comment*/}</div>';
|
||||
var ast = esprima.parse(source, {range: true});
|
||||
var child = ast.body[0].expression.children[0];
|
||||
var state = utils.createState(source, child);
|
||||
state.g.position = child.range[0];
|
||||
jsx.renderJSXExpressionContainer(function() {}, child, true, [], state);
|
||||
expect(state.g.buffer).toBe('/*comment*/');
|
||||
});
|
||||
|
||||
it('should not render commas after empty child expressions even if they\'re' +
|
||||
'not last', function() {
|
||||
var source = '<div>{/*comment*/}</div>';
|
||||
var ast = esprima.parse(source, {range: true});
|
||||
var child = ast.body[0].expression.children[0];
|
||||
var state = utils.createState(source, child);
|
||||
state.g.position = child.range[0];
|
||||
jsx.renderJSXExpressionContainer(function() {}, child, false, [], state);
|
||||
expect(state.g.buffer).toBe('/*comment*/');
|
||||
});
|
||||
});
|
||||
175
node_modules/jstransform/visitors/__tests__/react-display-name-test.js
generated
vendored
Normal file
175
node_modules/jstransform/visitors/__tests__/react-display-name-test.js
generated
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails react-core
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
var transformFn = require('jstransform').transform;
|
||||
var visitors = require('../react-display-name-visitors').visitorList;
|
||||
|
||||
function transform(code) {
|
||||
return transformFn(visitors, code);
|
||||
}
|
||||
|
||||
describe('react displayName jsx', function() {
|
||||
|
||||
it('should only inject displayName if missing', function() {
|
||||
var code = [
|
||||
'"use strict";',
|
||||
'var Whateva = React.createClass({',
|
||||
' displayName: "Whateva",',
|
||||
' render: function() {',
|
||||
' return null;',
|
||||
' }',
|
||||
'});'
|
||||
].join('\n');
|
||||
|
||||
var result = [
|
||||
'"use strict";',
|
||||
'var Whateva = React.createClass({',
|
||||
' displayName: "Whateva",',
|
||||
' render: function() {',
|
||||
' return null;',
|
||||
' }',
|
||||
'});'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code).code).toEqual(result);
|
||||
});
|
||||
|
||||
it('should inject displayName in simple assignment', () => {
|
||||
var code = [
|
||||
'var Component = React.createClass({',
|
||||
' render: function() {',
|
||||
' return null;',
|
||||
' }',
|
||||
'});'
|
||||
].join('\n');
|
||||
|
||||
var result = [
|
||||
'var Component = React.createClass({displayName: "Component",',
|
||||
' render: function() {',
|
||||
' return null;',
|
||||
' }',
|
||||
'});'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code).code).toEqual(result);
|
||||
});
|
||||
|
||||
it('should inject displayName in simple assignment without var', () => {
|
||||
var code = [
|
||||
'var Component;',
|
||||
'Component = React.createClass({',
|
||||
' render: function() {',
|
||||
' return null;',
|
||||
' }',
|
||||
'});'
|
||||
].join('\n');
|
||||
|
||||
var result = [
|
||||
'var Component;',
|
||||
'Component = React.createClass({displayName: "Component",',
|
||||
' render: function() {',
|
||||
' return null;',
|
||||
' }',
|
||||
'});'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code).code).toEqual(result);
|
||||
});
|
||||
|
||||
it('should inject displayName in property assignment', () => {
|
||||
var code = [
|
||||
'ns.Component = React.createClass({',
|
||||
' render: function() {',
|
||||
' return null;',
|
||||
' }',
|
||||
'});'
|
||||
].join('\n');
|
||||
|
||||
var result = [
|
||||
'ns.Component = React.createClass({displayName: "ns.Component",',
|
||||
' render: function() {',
|
||||
' return null;',
|
||||
' }',
|
||||
'});'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code).code).toEqual(result);
|
||||
});
|
||||
|
||||
it('should inject displayName in chained property assignment', () => {
|
||||
var code = [
|
||||
'ns.ns1.Component = React.createClass({',
|
||||
' render: function() {',
|
||||
' return null;',
|
||||
' }',
|
||||
'});'
|
||||
].join('\n');
|
||||
|
||||
var result = [
|
||||
'ns.ns1.Component = React.createClass({displayName: "ns.ns1.Component",',
|
||||
' render: function() {',
|
||||
' return null;',
|
||||
' }',
|
||||
'});'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code).code).toEqual(result);
|
||||
});
|
||||
|
||||
|
||||
it('should inject displayName in exports property assignment', () => {
|
||||
var code = [
|
||||
'exports.Component = React.createClass({',
|
||||
' render: function() {',
|
||||
' return null;',
|
||||
' }',
|
||||
'});'
|
||||
].join('\n');
|
||||
|
||||
var result = [
|
||||
'exports.Component = React.createClass({displayName: "Component",',
|
||||
' render: function() {',
|
||||
' return null;',
|
||||
' }',
|
||||
'});'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code).code).toEqual(result);
|
||||
});
|
||||
|
||||
it('should inject displayName in object declaration', () => {
|
||||
var code = [
|
||||
'exports = {',
|
||||
' Component: React.createClass({',
|
||||
' render: function() {',
|
||||
' return null;',
|
||||
' }',
|
||||
' })',
|
||||
'};'
|
||||
].join('\n');
|
||||
|
||||
var result = [
|
||||
'exports = {',
|
||||
' Component: React.createClass({displayName: "Component",',
|
||||
' render: function() {',
|
||||
' return null;',
|
||||
' }',
|
||||
' })',
|
||||
'};'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code).code).toEqual(result);
|
||||
});
|
||||
|
||||
});
|
||||
394
node_modules/jstransform/visitors/__tests__/react-jsx-test.js
generated
vendored
Normal file
394
node_modules/jstransform/visitors/__tests__/react-jsx-test.js
generated
vendored
Normal file
@@ -0,0 +1,394 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails react-core
|
||||
*/
|
||||
|
||||
/*jshint evil:true, unused:false*/
|
||||
|
||||
'use strict';
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
var transformFn = require('jstransform').transform;
|
||||
var visitors = require('../react-jsx-visitors').visitorList;
|
||||
|
||||
function transform(code) {
|
||||
return transformFn(visitors, code);
|
||||
}
|
||||
|
||||
describe('react jsx', function() {
|
||||
|
||||
// These are placeholder variables in scope that we can use to assert that a
|
||||
// specific variable reference was passed, rather than an object clone of it.
|
||||
var x = 123456;
|
||||
var y = 789012;
|
||||
var z = 345678;
|
||||
|
||||
var expectObjectAssign = function(code) {
|
||||
/*eslint-disable no-unused-vars, no-eval*/
|
||||
var Component = jest.genMockFunction();
|
||||
var Child = jest.genMockFunction();
|
||||
var objectAssignMock = jest.genMockFunction();
|
||||
React.__spread = objectAssignMock;
|
||||
eval(transform(code).code);
|
||||
return expect(objectAssignMock);
|
||||
/*eslint-enable*/
|
||||
};
|
||||
|
||||
var React = {
|
||||
createElement: jest.genMockFunction()
|
||||
};
|
||||
|
||||
it('should convert simple tags', function() {
|
||||
var code = 'var x = <div></div>;';
|
||||
var result = 'var x = React.createElement("div", null);';
|
||||
|
||||
expect(transform(code).code).toEqual(result);
|
||||
});
|
||||
|
||||
it('should convert simple text', function() {
|
||||
var code = 'var x = <div>text</div>;';
|
||||
var result = 'var x = React.createElement("div", null, "text");';
|
||||
|
||||
expect(transform(code).code).toEqual(result);
|
||||
});
|
||||
|
||||
it('should have correct comma in nested children', function() {
|
||||
var code = [
|
||||
'var x = <div>',
|
||||
' <div><br /></div>',
|
||||
' <Component>{foo}<br />{bar}</Component>',
|
||||
' <br />',
|
||||
'</div>;'
|
||||
].join('\n');
|
||||
var result = [
|
||||
'var x = React.createElement("div", null, ',
|
||||
' React.createElement("div", null, ' +
|
||||
'React.createElement("br", null)), ',
|
||||
' React.createElement(Component, null, foo, ' +
|
||||
'React.createElement("br", null), bar), ',
|
||||
' React.createElement("br", null)',
|
||||
');'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code).code).toEqual(result);
|
||||
});
|
||||
|
||||
it('should avoid wrapping in extra parens if not needed', function() {
|
||||
// Try with a single composite child, wrapped in a div.
|
||||
var code = [
|
||||
'var x = <div>',
|
||||
' <Component />',
|
||||
'</div>;'
|
||||
].join('\n');
|
||||
var result = [
|
||||
'var x = React.createElement("div", null, ',
|
||||
' React.createElement(Component, null)',
|
||||
');'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code).code).toEqual(result);
|
||||
|
||||
// Try with a single interpolated child, wrapped in a div.
|
||||
code = [
|
||||
'var x = <div>',
|
||||
' {this.props.children}',
|
||||
'</div>;'
|
||||
].join('\n');
|
||||
result = [
|
||||
'var x = React.createElement("div", null, ',
|
||||
' this.props.children',
|
||||
');'
|
||||
].join('\n');
|
||||
expect(transform(code).code).toEqual(result);
|
||||
|
||||
// Try with a single interpolated child, wrapped in a composite.
|
||||
code = [
|
||||
'var x = <Composite>',
|
||||
' {this.props.children}',
|
||||
'</Composite>;'
|
||||
].join('\n');
|
||||
result = [
|
||||
'var x = React.createElement(Composite, null, ',
|
||||
' this.props.children',
|
||||
');'
|
||||
].join('\n');
|
||||
expect(transform(code).code).toEqual(result);
|
||||
|
||||
// Try with a single composite child, wrapped in a composite.
|
||||
code = [
|
||||
'var x = <Composite>',
|
||||
' <Composite2 />',
|
||||
'</Composite>;'
|
||||
].join('\n');
|
||||
result = [
|
||||
'var x = React.createElement(Composite, null, ',
|
||||
' React.createElement(Composite2, null)',
|
||||
');'
|
||||
].join('\n');
|
||||
expect(transform(code).code).toEqual(result);
|
||||
});
|
||||
|
||||
it('should insert commas after expressions before whitespace', function() {
|
||||
var code = [
|
||||
'var x =',
|
||||
' <div',
|
||||
' attr1={',
|
||||
' "foo" + "bar"',
|
||||
' }',
|
||||
' attr2={',
|
||||
' "foo" + "bar" +',
|
||||
' ',
|
||||
' "baz" + "bug"',
|
||||
' }',
|
||||
' attr3={',
|
||||
' "foo" + "bar" +',
|
||||
' "baz" + "bug"',
|
||||
' // Extra line here.',
|
||||
' }',
|
||||
' attr4="baz">',
|
||||
' </div>;'
|
||||
].join('\n');
|
||||
var result = [
|
||||
'var x =',
|
||||
' React.createElement("div", {',
|
||||
' attr1: ',
|
||||
' "foo" + "bar", ',
|
||||
' ',
|
||||
' attr2: ',
|
||||
' "foo" + "bar" +',
|
||||
' ',
|
||||
' "baz" + "bug", ',
|
||||
' ',
|
||||
' attr3: ',
|
||||
' "foo" + "bar" +',
|
||||
' "baz" + "bug", ',
|
||||
' // Extra line here.',
|
||||
' ',
|
||||
' attr4: "baz"}',
|
||||
' );'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code).code).toEqual(result);
|
||||
});
|
||||
|
||||
it('should properly handle comments adjacent to children', function() {
|
||||
var code = [
|
||||
'var x = (',
|
||||
' <div>',
|
||||
' {/* A comment at the beginning */}',
|
||||
' {/* A second comment at the beginning */}',
|
||||
' <span>',
|
||||
' {/* A nested comment */}',
|
||||
' </span>',
|
||||
' {/* A sandwiched comment */}',
|
||||
' <br />',
|
||||
' {/* A comment at the end */}',
|
||||
' {/* A second comment at the end */}',
|
||||
' </div>',
|
||||
');'
|
||||
].join('\n');
|
||||
var result = [
|
||||
'var x = (',
|
||||
' React.createElement("div", null, ',
|
||||
' /* A comment at the beginning */',
|
||||
' /* A second comment at the beginning */',
|
||||
' React.createElement("span", null',
|
||||
' /* A nested comment */',
|
||||
' ), ',
|
||||
' /* A sandwiched comment */',
|
||||
' React.createElement("br", null)',
|
||||
' /* A comment at the end */',
|
||||
' /* A second comment at the end */',
|
||||
' )',
|
||||
');'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code).code).toBe(result);
|
||||
});
|
||||
|
||||
it('should properly handle comments between props', function() {
|
||||
var code = [
|
||||
'var x = (',
|
||||
' <div',
|
||||
' /* a multi-line',
|
||||
' comment */',
|
||||
' attr1="foo">',
|
||||
' <span // a double-slash comment',
|
||||
' attr2="bar"',
|
||||
' />',
|
||||
' </div>',
|
||||
');'
|
||||
].join('\n');
|
||||
var result = [
|
||||
'var x = (',
|
||||
' React.createElement("div", {',
|
||||
' /* a multi-line',
|
||||
' comment */',
|
||||
' attr1: "foo"}, ',
|
||||
' React.createElement("span", {// a double-slash comment',
|
||||
' attr2: "bar"}',
|
||||
' )',
|
||||
' )',
|
||||
');'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code).code).toBe(result);
|
||||
});
|
||||
|
||||
it('should not strip tags with a single child of ', function() {
|
||||
var code = [
|
||||
'<div> </div>;'
|
||||
].join('\n');
|
||||
var result = [
|
||||
'React.createElement("div", null, "\u00A0");'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code).code).toBe(result);
|
||||
});
|
||||
|
||||
it('should not strip even coupled with other whitespace', function() {
|
||||
var code = [
|
||||
'<div> </div>;'
|
||||
].join('\n');
|
||||
var result = [
|
||||
'React.createElement("div", null, "\u00A0 ");'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code).code).toBe(result);
|
||||
});
|
||||
|
||||
it('should handle hasOwnProperty correctly', function() {
|
||||
var code = '<hasOwnProperty>testing</hasOwnProperty>;';
|
||||
var result = 'React.createElement("hasOwnProperty", null, "testing");';
|
||||
expect(transform(code).code).toBe(result);
|
||||
});
|
||||
|
||||
it('should allow constructor as prop', function() {
|
||||
var code = '<Component constructor="foo" />;';
|
||||
var result = 'React.createElement(Component, {constructor: "foo"});';
|
||||
|
||||
expect(transform(code).code).toBe(result);
|
||||
});
|
||||
|
||||
it('should allow JS namespacing', function() {
|
||||
var code = '<Namespace.Component />;';
|
||||
var result = 'React.createElement(Namespace.Component, null);';
|
||||
|
||||
expect(transform(code).code).toBe(result);
|
||||
});
|
||||
|
||||
it('should allow deeper JS namespacing', function() {
|
||||
var code = '<Namespace.DeepNamespace.Component />;';
|
||||
var result =
|
||||
'React.createElement(Namespace.DeepNamespace.Component, null);';
|
||||
|
||||
expect(transform(code).code).toBe(result);
|
||||
});
|
||||
|
||||
it('should disallow XML namespacing', function() {
|
||||
var code = '<Namespace:Component />;';
|
||||
|
||||
expect(() => transform(code)).toThrow();
|
||||
});
|
||||
|
||||
it('wraps props in React.__spread for spread attributes', function() {
|
||||
var code =
|
||||
'<Component { ... x } y\n' +
|
||||
'={2 } z />';
|
||||
var result =
|
||||
'React.createElement(Component, React.__spread({}, x , {y: \n' +
|
||||
'2, z: true}))';
|
||||
|
||||
expect(transform(code).code).toBe(result);
|
||||
});
|
||||
|
||||
it('adds appropriate newlines when using spread attribute', function() {
|
||||
var code =
|
||||
'<Component\n' +
|
||||
' {...this.props}\n' +
|
||||
' sound="moo" />';
|
||||
var result =
|
||||
'React.createElement(Component, React.__spread({}, \n' +
|
||||
' this.props, \n' +
|
||||
' {sound: "moo"}))';
|
||||
|
||||
expect(transform(code).code).toBe(result);
|
||||
});
|
||||
|
||||
it('handles overparenthesized JS', function() {
|
||||
var code =
|
||||
'<foo a={(b)} c={(d)}>Foo {(e+f //A line comment\n' +
|
||||
'/* A multiline comment */)\n' +
|
||||
'} bar\n' +
|
||||
'</foo>';
|
||||
var result = 'React.createElement("foo", {a: (b), c: (d)}, "Foo ", (e+f //A line comment\n' +
|
||||
'/* A multiline comment */), \n' +
|
||||
'" bar"\n' +
|
||||
')';
|
||||
expect(transform(code).code).toBe(result);
|
||||
});
|
||||
|
||||
it('should transform known hyphenated tags', function() {
|
||||
var code = '<font-face />;';
|
||||
var result = 'React.createElement("font-face", null);';
|
||||
|
||||
expect(transform(code).code).toBe(result);
|
||||
});
|
||||
|
||||
it('does not call React.__spread when there are no spreads', function() {
|
||||
expectObjectAssign(
|
||||
'<Component x={y} />'
|
||||
).not.toBeCalled();
|
||||
});
|
||||
|
||||
it('should not throw for unknown hyphenated tags', function() {
|
||||
var code = '<x-component />;';
|
||||
expect(function() {
|
||||
transform(code);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('calls assign with a new target object for spreads', function() {
|
||||
expectObjectAssign(
|
||||
'<Component {...x} />'
|
||||
).toBeCalledWith({}, x);
|
||||
});
|
||||
|
||||
it('calls assign with an empty object when the spread is first', function() {
|
||||
expectObjectAssign(
|
||||
'<Component { ...x } y={2} />'
|
||||
).toBeCalledWith({}, x, {y: 2});
|
||||
});
|
||||
|
||||
it('coalesces consecutive properties into a single object', function() {
|
||||
expectObjectAssign(
|
||||
'<Component { ... x } y={2} z />'
|
||||
).toBeCalledWith({}, x, {y: 2, z: true});
|
||||
});
|
||||
|
||||
it('avoids an unnecessary empty object when spread is not first', function() {
|
||||
expectObjectAssign(
|
||||
'<Component x={1} {...y} />'
|
||||
).toBeCalledWith({x: 1}, y);
|
||||
});
|
||||
|
||||
it('passes the same value multiple times to React.__spread', function() {
|
||||
expectObjectAssign(
|
||||
'<Component x={1} y="2" {...z} {...z}><Child /></Component>'
|
||||
).toBeCalledWith({x: 1, y: '2'}, z, z);
|
||||
});
|
||||
|
||||
it('evaluates sequences before passing them to React.__spread', function() {
|
||||
expectObjectAssign(
|
||||
'<Component x="1" {...(z = { y: 2 }, z)} z={3}>Text</Component>'
|
||||
).toBeCalledWith({x: '1'}, {y: 2}, {z: 3});
|
||||
});
|
||||
|
||||
});
|
||||
87
node_modules/jstransform/visitors/__tests__/reserved-words-test.js
generated
vendored
Normal file
87
node_modules/jstransform/visitors/__tests__/reserved-words-test.js
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails jeffmo@fb.com
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
|
||||
jest.autoMockOff();
|
||||
|
||||
describe('reserved-words', function() {
|
||||
var transformFn;
|
||||
var visitors;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
visitors = require('../reserved-words-visitors').visitorList;
|
||||
transformFn = require('../../src/jstransform').transform;
|
||||
});
|
||||
|
||||
function transform(code, opts) {
|
||||
// No need for visitors as long as we are not in es5 mode.
|
||||
return transformFn(visitors, code, opts).code;
|
||||
}
|
||||
|
||||
describe('reserved words in member expressions', function() {
|
||||
it('should transform to reserved word members to computed', function() {
|
||||
var code = 'foo.delete;';
|
||||
|
||||
expect(transform(code)).toEqual('foo["delete"];');
|
||||
});
|
||||
|
||||
it('should handle parenthesis', function() {
|
||||
var code = '(foo++).delete;';
|
||||
expect(transform(code)).toEqual('(foo++)["delete"];');
|
||||
|
||||
code = '(foo.bar()).delete;';
|
||||
expect(transform(code)).toEqual('(foo.bar())["delete"];');
|
||||
});
|
||||
|
||||
it('should handle call expressions', function() {
|
||||
var code = 'foo.return();';
|
||||
|
||||
expect(transform(code)).toEqual('foo["return"]();');
|
||||
});
|
||||
|
||||
it('should only quote ES3 reserved words', function() {
|
||||
var code = 'foo.await();';
|
||||
|
||||
expect(transform(code)).toEqual('foo.await();');
|
||||
});
|
||||
|
||||
it('should work with newlines', function() {
|
||||
var code = 'foo.\ncatch();';
|
||||
expect(transform(code)).toEqual('foo\n["catch"]();');
|
||||
|
||||
// This one is weird but it works.
|
||||
code = 'foo.\n catch();';
|
||||
expect(transform(code)).toEqual('foo\n ["catch"]();');
|
||||
|
||||
code = 'foo\n.catch();';
|
||||
expect(transform(code)).toEqual('foo\n["catch"]();');
|
||||
|
||||
code = 'foo\n .catch();';
|
||||
expect(transform(code)).toEqual('foo\n ["catch"]();');
|
||||
});
|
||||
});
|
||||
|
||||
describe('reserved words in properties', function() {
|
||||
it('should quote reserved words in properties', function() {
|
||||
var code = 'var x = {null: 1};';
|
||||
|
||||
expect(transform(code)).toEqual('var x = {"null": 1};');
|
||||
});
|
||||
|
||||
it('should only quote ES3 reserved words', function() {
|
||||
var code = 'var x = {await: 1};';
|
||||
|
||||
expect(transform(code)).toEqual('var x = {await: 1};');
|
||||
});
|
||||
});
|
||||
});
|
||||
146
node_modules/jstransform/visitors/__tests__/trailing-comma-visitors-test.js
generated
vendored
Normal file
146
node_modules/jstransform/visitors/__tests__/trailing-comma-visitors-test.js
generated
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails oncall+jsinfra@xmail.facebook.com
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('trailing-comma', function() {
|
||||
var transformFn;
|
||||
var visitors;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
visitors = require('../trailing-comma-visitors').visitorList;
|
||||
transformFn = require('../../src/jstransform').transform;
|
||||
});
|
||||
|
||||
function transform(code) {
|
||||
return transformFn(visitors, code).code;
|
||||
}
|
||||
|
||||
// Functional tests.
|
||||
|
||||
it('should strip commas from arrays', function() {
|
||||
var code = [
|
||||
'([',
|
||||
' 1,',
|
||||
' 2, /* last item */',
|
||||
']);'
|
||||
].join('\n');
|
||||
|
||||
expect(eval(transform(code))).toEqual([1, 2]);
|
||||
});
|
||||
|
||||
it('should strip commas from objects', function() {
|
||||
var code = [
|
||||
'({',
|
||||
' x: 1,',
|
||||
' y: 2, // last item',
|
||||
'});'
|
||||
].join('\n');
|
||||
|
||||
expect(eval(transform(code))).toEqual({x: 1, y: 2});
|
||||
});
|
||||
|
||||
// Syntax tests.
|
||||
|
||||
it('should transform code with trailing comma in an array', function() {
|
||||
var code = [
|
||||
'var arr = [',
|
||||
' 1,',
|
||||
' [2, 3,],',
|
||||
' 4 /* last, item */ ,',
|
||||
'];'
|
||||
].join('\n');
|
||||
var result = [
|
||||
'var arr = [',
|
||||
' 1,',
|
||||
' [2, 3],',
|
||||
' 4 /* last item */ ',
|
||||
'];'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code)).toEqual(result);
|
||||
});
|
||||
|
||||
it('should transform code with trailing comma in an array', function() {
|
||||
var code = [
|
||||
'var arr = [',
|
||||
' 1,',
|
||||
' 2, /* last item */',
|
||||
'];'
|
||||
].join('\n');
|
||||
var result = [
|
||||
'var arr = [',
|
||||
' 1,',
|
||||
' 2 /* last item */',
|
||||
'];'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code)).toEqual(result);
|
||||
});
|
||||
|
||||
it('should not strip trailing parenthesis', function() {
|
||||
var code = [
|
||||
'var result = [',
|
||||
' value1,',
|
||||
' (condition ? 1 : 2),',
|
||||
'];'
|
||||
].join('\n');
|
||||
var result = [
|
||||
'var result = [',
|
||||
' value1,',
|
||||
' (condition ? 1 : 2)',
|
||||
'];'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code)).toEqual(result);
|
||||
});
|
||||
|
||||
it('should transform code with trailing comma in an object', function() {
|
||||
var code = [
|
||||
'var obj = {',
|
||||
' x: 1,',
|
||||
' y: 2, /*last item*/',
|
||||
'};'
|
||||
].join('\n');
|
||||
var result = [
|
||||
'var obj = {',
|
||||
' x: 1,',
|
||||
' y: 2 /*last item*/',
|
||||
'};'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code)).toEqual(result);
|
||||
});
|
||||
|
||||
it('should NOT transform code with trailing hole in an array', function() {
|
||||
var code = [
|
||||
'var arr = [',
|
||||
' 1,',
|
||||
' 2,',
|
||||
' , /*last hole*/',
|
||||
'];'
|
||||
].join('\n');
|
||||
var result = [
|
||||
'var arr = [',
|
||||
' 1,',
|
||||
' 2,',
|
||||
' , /*last hole*/',
|
||||
'];'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code)).toEqual(result);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
83
node_modules/jstransform/visitors/__tests__/type-alias-syntax-test.js
generated
vendored
Normal file
83
node_modules/jstransform/visitors/__tests__/type-alias-syntax-test.js
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('static type syntax syntax', function() {
|
||||
var flowSyntaxVisitors;
|
||||
var jstransform;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
|
||||
flowSyntaxVisitors = require('../type-syntax.js').visitorList;
|
||||
jstransform = require('jstransform');
|
||||
});
|
||||
|
||||
function transform(code, visitors) {
|
||||
var opts = {sourceType: 'nonStrictModule'};
|
||||
code = jstransform.transform(
|
||||
flowSyntaxVisitors,
|
||||
code.join('\n'),
|
||||
opts
|
||||
).code;
|
||||
|
||||
if (visitors) {
|
||||
code = jstransform.transform(visitors, code, opts).code;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
describe('type alias', () => {
|
||||
it('strips type aliases', () => {
|
||||
/*global type*/
|
||||
/*global sanityCheck*/
|
||||
var code = transform([
|
||||
'var type = 42;',
|
||||
'type FBID = number;',
|
||||
'type type = string',
|
||||
'type += 42;'
|
||||
]);
|
||||
eval(code);
|
||||
expect(type).toBe(84);
|
||||
});
|
||||
|
||||
it('strips import-type statements', () => {
|
||||
var code = transform([
|
||||
'import type DefaultExport from "MyModule";',
|
||||
'var sanityCheck = 42;',
|
||||
]);
|
||||
eval(code);
|
||||
expect(sanityCheck).toBe(42);
|
||||
});
|
||||
|
||||
it('strips export-type statements', () => {
|
||||
var code = transform([
|
||||
'export type foo = number;',
|
||||
'var sanityCheck = 42;',
|
||||
]);
|
||||
eval(code);
|
||||
expect(sanityCheck).toBe(42);
|
||||
});
|
||||
|
||||
it('catches up correctly', () => {
|
||||
var code = transform([
|
||||
"var X = require('X');",
|
||||
'type FBID = number;',
|
||||
]);
|
||||
expect(code).toBe([
|
||||
"var X = require('X');",
|
||||
' '
|
||||
].join('\n'));
|
||||
});
|
||||
});
|
||||
});
|
||||
291
node_modules/jstransform/visitors/__tests__/type-class-syntax-test.js
generated
vendored
Normal file
291
node_modules/jstransform/visitors/__tests__/type-class-syntax-test.js
generated
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
/*jshint -W117*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('static type class syntax', function() {
|
||||
var classSyntaxVisitors;
|
||||
var visitorList;
|
||||
var flowSyntaxVisitors;
|
||||
var jstransform;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
|
||||
classSyntaxVisitors =
|
||||
require('../es6-class-visitors').visitorList;
|
||||
flowSyntaxVisitors = require('../type-syntax.js').visitorList;
|
||||
jstransform = require('jstransform');
|
||||
|
||||
visitorList = classSyntaxVisitors;
|
||||
});
|
||||
|
||||
function transform(code, visitors) {
|
||||
visitors = visitors ? visitorList.concat(visitors) : visitorList;
|
||||
|
||||
code = jstransform.transform(
|
||||
flowSyntaxVisitors,
|
||||
code.join('\n')
|
||||
).code;
|
||||
|
||||
return jstransform.transform(
|
||||
visitors,
|
||||
code
|
||||
).code;
|
||||
}
|
||||
|
||||
describe('param type annotations', () => {
|
||||
it('strips single param annotation', () => {
|
||||
var code = transform([
|
||||
'class Foo {',
|
||||
' method1(param1: bool) {',
|
||||
' return param1;',
|
||||
' }',
|
||||
'}',
|
||||
'',
|
||||
'var Bar = class {',
|
||||
' method1(param1: bool) {',
|
||||
' return param1;',
|
||||
' }',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
expect((new Foo()).method1(42)).toBe(42);
|
||||
expect((new Bar()).method1(42)).toBe(42);
|
||||
});
|
||||
|
||||
it('strips multiple param annotations', () => {
|
||||
var code = transform([
|
||||
'class Foo {',
|
||||
' method1(param1: bool, param2: number) {',
|
||||
' return [param1, param2];',
|
||||
' }',
|
||||
'}',
|
||||
'',
|
||||
'var Bar = class {',
|
||||
' method1(param1: bool, param2: number) {',
|
||||
' return [param1, param2];',
|
||||
' }',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
expect((new Foo()).method1(true, 42)).toEqual([true, 42]);
|
||||
expect((new Bar()).method1(true, 42)).toEqual([true, 42]);
|
||||
});
|
||||
|
||||
it('strips higher-order param annotations', () => {
|
||||
var code = transform([
|
||||
'class Foo {',
|
||||
' method1(param1: (_:bool) => number) {',
|
||||
' return param1;',
|
||||
' }',
|
||||
'}',
|
||||
'',
|
||||
'var Bar = class {',
|
||||
' method1(param1: (_:bool) => number) {',
|
||||
' return param1;',
|
||||
' }',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
|
||||
var callback = function(param) {
|
||||
return param ? 42 : 0;
|
||||
};
|
||||
expect((new Foo()).method1(callback)).toBe(callback);
|
||||
expect((new Bar()).method1(callback)).toBe(callback);
|
||||
});
|
||||
|
||||
it('strips annotated params next to non-annotated params', () => {
|
||||
var code = transform([
|
||||
'class Foo {',
|
||||
' method1(param1, param2: number) {',
|
||||
' return [param1, param2];',
|
||||
' }',
|
||||
'}',
|
||||
'',
|
||||
'var Bar = class {',
|
||||
' method1(param1, param2: number) {',
|
||||
' return [param1, param2];',
|
||||
' }',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
expect((new Foo()).method1('p1', 42)).toEqual(['p1', 42]);
|
||||
expect((new Bar()).method1('p1', 42)).toEqual(['p1', 42]);
|
||||
});
|
||||
|
||||
it('strips annotated params before a rest parameter', () => {
|
||||
var restParamVisitors =
|
||||
require('../es6-rest-param-visitors').visitorList;
|
||||
|
||||
var code = transform([
|
||||
'class Foo {',
|
||||
' method1(param1: number, ...args) {',
|
||||
' return [param1, args];',
|
||||
' }',
|
||||
'}',
|
||||
'',
|
||||
'var Bar = class {',
|
||||
' method1(param1: number, ...args) {',
|
||||
' return [param1, args];',
|
||||
' }',
|
||||
'}'
|
||||
], restParamVisitors);
|
||||
eval(code);
|
||||
expect((new Foo()).method1(42, 43, 44)).toEqual([42, [43, 44]]);
|
||||
expect((new Bar()).method1(42, 43, 44)).toEqual([42, [43, 44]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('return type annotations', () => {
|
||||
it('strips method return types', () => {
|
||||
var code = transform([
|
||||
'class Foo {',
|
||||
' method1(param1:number): () => number {',
|
||||
' return function() { return param1; };',
|
||||
' }',
|
||||
'}',
|
||||
'',
|
||||
'var Bar = class {',
|
||||
' method1(param1:number): () => number {',
|
||||
' return function() { return param1; };',
|
||||
' }',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
expect((new Foo()).method1(42)()).toBe(42);
|
||||
expect((new Bar()).method1(42)()).toBe(42);
|
||||
});
|
||||
});
|
||||
|
||||
describe('parametric type annotation', () => {
|
||||
it('strips parametric class type annotations', () => {
|
||||
var code = transform([
|
||||
'class Foo<T> {',
|
||||
' method1(param1) {',
|
||||
' return param1;',
|
||||
' }',
|
||||
'}',
|
||||
'',
|
||||
// TODO: Need to add support to esprima for this
|
||||
// 'var Bar = class<T> {',
|
||||
// ' method1(param1) {',
|
||||
// ' return param1;',
|
||||
// ' }',
|
||||
// '}'
|
||||
]);
|
||||
eval(code);
|
||||
expect((new Foo()).method1(42)).toBe(42);
|
||||
// expect((new Bar()).method1(42)).toBe(42);
|
||||
});
|
||||
|
||||
it('strips multi-parameter class type annotations', () => {
|
||||
var code = transform([
|
||||
'class Foo<T,S> {',
|
||||
' method1(param1) {',
|
||||
' return param1;',
|
||||
' }',
|
||||
'}',
|
||||
'',
|
||||
// TODO: Need to add support to esprima for this
|
||||
// 'var Bar = class<T> {',
|
||||
// ' method1(param1) {',
|
||||
// ' return param1;',
|
||||
// ' }',
|
||||
// '}'
|
||||
]);
|
||||
eval(code);
|
||||
expect((new Foo()).method1(42)).toBe(42);
|
||||
// expect(bar(42)).toBe(42);
|
||||
});
|
||||
|
||||
it('strips parametric method type annotations', () => {
|
||||
var code = transform([
|
||||
'class Foo<T> {',
|
||||
' method1<T>(param1) {',
|
||||
' return param1;',
|
||||
' }',
|
||||
'}',
|
||||
'',
|
||||
// TODO: Need to add support to esprima for this
|
||||
// 'var Bar = class<T> {',
|
||||
// ' method1<T>(param1) {',
|
||||
// ' return param1;',
|
||||
// ' }',
|
||||
// '}'
|
||||
]);
|
||||
eval(code);
|
||||
expect((new Foo()).method1(42)).toBe(42);
|
||||
// expect((new Bar()).method1(42)).toBe(42);
|
||||
});
|
||||
|
||||
it('strips multi-parameter class type annotations', () => {
|
||||
var code = transform([
|
||||
'class Foo<T,S> {',
|
||||
' method1<T,S>(param1) {',
|
||||
' return param1;',
|
||||
' }',
|
||||
'}',
|
||||
'',
|
||||
// TODO: Need to add support to esprima for this
|
||||
// 'var Bar = class<T> {',
|
||||
// ' method1(param1) {',
|
||||
// ' return param1;',
|
||||
// ' }',
|
||||
// '}'
|
||||
]);
|
||||
eval(code);
|
||||
expect((new Foo()).method1(42)).toBe(42);
|
||||
// expect(bar(42)).toBe(42);
|
||||
});
|
||||
});
|
||||
|
||||
describe('class property annotations', () => {
|
||||
it('strips single class property', () => {
|
||||
var code = transform([
|
||||
'class Foo {',
|
||||
' prop1: T;',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
expect((new Foo()).prop1).toEqual(undefined);
|
||||
});
|
||||
|
||||
it('strips multiple adjacent class properties', () => {
|
||||
var code = transform([
|
||||
'class Foo {',
|
||||
' prop1: T;',
|
||||
' prop2: U;',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
expect((new Foo()).prop1).toEqual(undefined);
|
||||
expect((new Foo()).prop2).toEqual(undefined);
|
||||
});
|
||||
|
||||
it('strips class properties between methods', () => {
|
||||
var code = transform([
|
||||
'class Foo {',
|
||||
' method1() {}',
|
||||
' prop1: T;',
|
||||
' method2() {}',
|
||||
' prop2: U;',
|
||||
' method3() {}',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
expect((new Foo()).prop1).toEqual(undefined);
|
||||
expect((new Foo()).prop2).toEqual(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
291
node_modules/jstransform/visitors/__tests__/type-function-syntax-test.js
generated
vendored
Normal file
291
node_modules/jstransform/visitors/__tests__/type-function-syntax-test.js
generated
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
/*jshint -W117*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('static type function syntax', function() {
|
||||
var flowSyntaxVisitors;
|
||||
var jstransform;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
|
||||
flowSyntaxVisitors = require('../type-syntax.js').visitorList;
|
||||
jstransform = require('jstransform');
|
||||
});
|
||||
|
||||
function transform(code, visitors) {
|
||||
code = code.join('\n');
|
||||
|
||||
// We run the flow transform first
|
||||
code = jstransform.transform(
|
||||
flowSyntaxVisitors,
|
||||
code
|
||||
).code;
|
||||
|
||||
if (visitors) {
|
||||
code = jstransform.transform(
|
||||
visitors,
|
||||
code
|
||||
).code;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
describe('param type annotations', () => {
|
||||
it('strips single param annotation', () => {
|
||||
var code = transform([
|
||||
'function foo(param1: bool) {',
|
||||
' return param1;',
|
||||
'}',
|
||||
'',
|
||||
'var bar = function(param1: bool) {',
|
||||
' return param1;',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
expect(foo(42)).toBe(42);
|
||||
expect(bar(42)).toBe(42);
|
||||
});
|
||||
|
||||
it('strips multiple param annotations', () => {
|
||||
var code = transform([
|
||||
'function foo(param1: bool, param2: number) {',
|
||||
' return [param1, param2];',
|
||||
'}',
|
||||
'',
|
||||
'var bar = function(param1: bool, param2: number) {',
|
||||
' return [param1, param2];',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
expect(foo(true, 42)).toEqual([true, 42]);
|
||||
expect(bar(true, 42)).toEqual([true, 42]);
|
||||
});
|
||||
|
||||
it('strips higher-order param annotations', () => {
|
||||
var code = transform([
|
||||
'function foo(param1: (_:bool) => number) {',
|
||||
' return param1;',
|
||||
'}',
|
||||
'',
|
||||
'var bar = function(param1: (_:bool) => number) {',
|
||||
' return param1;',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
|
||||
var callback = function(param) {
|
||||
return param ? 42 : 0;
|
||||
};
|
||||
expect(foo(callback)).toBe(callback);
|
||||
expect(bar(callback)).toBe(callback);
|
||||
});
|
||||
|
||||
it('strips annotated params next to non-annotated params', () => {
|
||||
var code = transform([
|
||||
'function foo(param1, param2: number) {',
|
||||
' return [param1, param2];',
|
||||
'}',
|
||||
'',
|
||||
'var bar = function(param1, param2: number) {',
|
||||
' return [param1, param2];',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
expect(foo('p1', 42)).toEqual(['p1', 42]);
|
||||
expect(bar('p1', 42)).toEqual(['p1', 42]);
|
||||
});
|
||||
|
||||
it('strips annotated params before a rest parameter', () => {
|
||||
var restParamVisitors =
|
||||
require('../es6-rest-param-visitors').visitorList;
|
||||
|
||||
var code = transform([
|
||||
'function foo(param1: number, ...args) {',
|
||||
' return [param1, args];',
|
||||
'}',
|
||||
'',
|
||||
'var bar = function(param1: number, ...args) {',
|
||||
' return [param1, args];',
|
||||
'}'
|
||||
], restParamVisitors);
|
||||
eval(code);
|
||||
expect(foo(42, 43, 44)).toEqual([42, [43, 44]]);
|
||||
expect(bar(42, 43, 44)).toEqual([42, [43, 44]]);
|
||||
});
|
||||
|
||||
it('strips annotated rest parameter', () => {
|
||||
var restParamVisitors =
|
||||
require('../es6-rest-param-visitors').visitorList;
|
||||
|
||||
var code = transform([
|
||||
'function foo(param1: number, ...args: Array<number>) {',
|
||||
' return [param1, args];',
|
||||
'}',
|
||||
'',
|
||||
'var bar = function(param1: number, ...args: Array<number>) {',
|
||||
' return [param1, args];',
|
||||
'}'
|
||||
], restParamVisitors);
|
||||
eval(code);
|
||||
expect(foo(42, 43, 44)).toEqual([42, [43, 44]]);
|
||||
expect(bar(42, 43, 44)).toEqual([42, [43, 44]]);
|
||||
});
|
||||
|
||||
it('strips optional param marker without type annotation', () => {
|
||||
var code = transform([
|
||||
'function foo(param1?, param2 ?) {',
|
||||
' return 42;',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
expect(foo()).toBe(42);
|
||||
});
|
||||
|
||||
it('strips optional param marker with type annotation', () => {
|
||||
var code = transform([
|
||||
'function foo(param1?:number, param2 ?: string, param3 ? : bool) {',
|
||||
' return 42;',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
expect(foo()).toBe(42);
|
||||
});
|
||||
});
|
||||
|
||||
describe('return type annotations', () => {
|
||||
it('strips function return types', () => {
|
||||
var code = transform([
|
||||
'function foo(param1:number): () => number {',
|
||||
' return function() { return param1; };',
|
||||
'}',
|
||||
'',
|
||||
'var bar = function(param1:number): () => number {',
|
||||
' return function() { return param1; };',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
expect(foo(42)()).toBe(42);
|
||||
expect(bar(42)()).toBe(42);
|
||||
});
|
||||
|
||||
it('strips void return types', () => {
|
||||
var code = transform([
|
||||
'function foo(param1): void {',
|
||||
' param1();',
|
||||
'}',
|
||||
'',
|
||||
'var bar = function(param1): void {',
|
||||
' param1();',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
|
||||
var counter = 0;
|
||||
function testFn() {
|
||||
counter++;
|
||||
}
|
||||
|
||||
foo(testFn);
|
||||
expect(counter).toBe(1);
|
||||
|
||||
bar(testFn);
|
||||
expect(counter).toBe(2);
|
||||
});
|
||||
|
||||
it('strips void return types with rest params', () => {
|
||||
var code = transform(
|
||||
[
|
||||
'function foo(param1, ...rest): void {',
|
||||
' param1();',
|
||||
'}',
|
||||
'',
|
||||
'var bar = function(param1, ...rest): void {',
|
||||
' param1();',
|
||||
'}'
|
||||
],
|
||||
require('../es6-rest-param-visitors').visitorList
|
||||
);
|
||||
eval(code);
|
||||
|
||||
var counter = 0;
|
||||
function testFn() {
|
||||
counter++;
|
||||
}
|
||||
|
||||
foo(testFn);
|
||||
expect(counter).toBe(1);
|
||||
|
||||
bar(testFn);
|
||||
expect(counter).toBe(2);
|
||||
});
|
||||
|
||||
it('strips object return types', () => {
|
||||
var code = transform([
|
||||
'function foo(param1:number): {num: number} {',
|
||||
' return {num: param1};',
|
||||
'}',
|
||||
'',
|
||||
'var bar = function(param1:number): {num: number} {',
|
||||
' return {num: param1};',
|
||||
'}'
|
||||
]);
|
||||
|
||||
eval(code);
|
||||
expect(foo(42)).toEqual({num: 42});
|
||||
expect(bar(42)).toEqual({num: 42});
|
||||
});
|
||||
});
|
||||
|
||||
describe('parametric type annotation', () => {
|
||||
it('strips parametric type annotations', () => {
|
||||
var code = transform([
|
||||
'function foo<T>(param1) {',
|
||||
' return param1;',
|
||||
'}',
|
||||
'',
|
||||
'var bar = function<T>(param1) {',
|
||||
' return param1;',
|
||||
'}',
|
||||
]);
|
||||
eval(code);
|
||||
expect(foo(42)).toBe(42);
|
||||
expect(bar(42)).toBe(42);
|
||||
});
|
||||
|
||||
it('strips multi-parameter type annotations', () => {
|
||||
var restParamVisitors =
|
||||
require('../es6-rest-param-visitors').visitorList;
|
||||
|
||||
var code = transform([
|
||||
'function foo<T, S>(param1) {',
|
||||
' return param1;',
|
||||
'}',
|
||||
'',
|
||||
'var bar = function<T,S>(param1) {',
|
||||
' return param1;',
|
||||
'}'
|
||||
], restParamVisitors);
|
||||
eval(code);
|
||||
expect(foo(42)).toBe(42);
|
||||
expect(bar(42)).toBe(42);
|
||||
});
|
||||
});
|
||||
|
||||
describe('arrow functions', () => {
|
||||
// TODO: We don't currently support arrow functions, but we should
|
||||
// soon! The only reason we don't now is because we don't
|
||||
// need it at this very moment and I'm in a rush to get the
|
||||
// basics in.
|
||||
});
|
||||
});
|
||||
65
node_modules/jstransform/visitors/__tests__/type-interface-syntax-test.js
generated
vendored
Normal file
65
node_modules/jstransform/visitors/__tests__/type-interface-syntax-test.js
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('static type interface syntax', function() {
|
||||
var flowSyntaxVisitors;
|
||||
var jstransform;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
|
||||
flowSyntaxVisitors = require('../type-syntax.js').visitorList;
|
||||
jstransform = require('jstransform');
|
||||
});
|
||||
|
||||
function transform(code, visitors) {
|
||||
code = jstransform.transform(
|
||||
flowSyntaxVisitors,
|
||||
code.join('\n')
|
||||
).code;
|
||||
|
||||
if (visitors) {
|
||||
code = jstransform.transform(
|
||||
visitors,
|
||||
code
|
||||
).code;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
describe('Interface Declaration', () => {
|
||||
it('strips interface declarations', () => {
|
||||
/*global interface*/
|
||||
var code = transform([
|
||||
'var interface = 42;',
|
||||
'interface A { foo: () => number; }',
|
||||
'if (true) interface += 42;',
|
||||
'interface A<T> extends B, C<T> { foo: () => number; }',
|
||||
'interface += 42;'
|
||||
]);
|
||||
eval(code);
|
||||
expect(interface).toBe(126);
|
||||
});
|
||||
|
||||
it('catches up correctly', () => {
|
||||
var code = transform([
|
||||
"var X = require('X');",
|
||||
'interface A { foo: () => number; }',
|
||||
]);
|
||||
expect(code).toBe([
|
||||
"var X = require('X');",
|
||||
' '
|
||||
].join('\n'));
|
||||
});
|
||||
});
|
||||
});
|
||||
179
node_modules/jstransform/visitors/__tests__/type-object-method-syntax-test.js
generated
vendored
Normal file
179
node_modules/jstransform/visitors/__tests__/type-object-method-syntax-test.js
generated
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
/*jshint -W117*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('static type object-method syntax', function() {
|
||||
var flowSyntaxVisitors;
|
||||
var jstransform;
|
||||
var visitorList;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
|
||||
flowSyntaxVisitors = require('../type-syntax.js').visitorList;
|
||||
jstransform = require('jstransform');
|
||||
objMethodVisitors =
|
||||
require('../es6-object-concise-method-visitors');
|
||||
|
||||
visitorList = objMethodVisitors.visitorList;
|
||||
});
|
||||
|
||||
function transform(code, visitors) {
|
||||
visitors = visitors ? visitorList.concat(visitors) : visitorList;
|
||||
|
||||
// We run the flow transform first
|
||||
code = jstransform.transform(
|
||||
flowSyntaxVisitors,
|
||||
code.join('\n')
|
||||
).code;
|
||||
|
||||
code = jstransform.transform(
|
||||
visitors,
|
||||
code
|
||||
).code;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
describe('param type annotations', () => {
|
||||
it('strips single param annotation', () => {
|
||||
var code = transform([
|
||||
'var foo = {',
|
||||
' bar(param1: bool) {',
|
||||
' return param1;',
|
||||
' }',
|
||||
'};',
|
||||
]);
|
||||
eval(code);
|
||||
expect(foo.bar(42)).toBe(42);
|
||||
});
|
||||
|
||||
it('strips multiple param annotations', () => {
|
||||
var code = transform([
|
||||
'var foo = {',
|
||||
' bar(param1: bool, param2: number) {',
|
||||
' return [param1, param2];',
|
||||
' }',
|
||||
'};'
|
||||
]);
|
||||
eval(code);
|
||||
expect(foo.bar(true, 42)).toEqual([true, 42]);
|
||||
});
|
||||
|
||||
it('strips higher-order param annotations', () => {
|
||||
var code = transform([
|
||||
'var foo = {',
|
||||
' bar(param1: (_:bool) => number) {',
|
||||
' return param1;',
|
||||
' }',
|
||||
'};'
|
||||
]);
|
||||
eval(code);
|
||||
|
||||
var callback = function(param) {
|
||||
return param ? 42 : 0;
|
||||
};
|
||||
expect(foo.bar(callback)).toBe(callback);
|
||||
});
|
||||
|
||||
it('strips annotated params next to non-annotated params', () => {
|
||||
var code = transform([
|
||||
'var foo = {',
|
||||
' bar(param1, param2: number) {',
|
||||
' return [param1, param2];',
|
||||
' }',
|
||||
'}',
|
||||
]);
|
||||
eval(code);
|
||||
expect(foo.bar('p1', 42)).toEqual(['p1', 42]);
|
||||
});
|
||||
|
||||
it('strips annotated params before a rest parameter', () => {
|
||||
var restParamVisitors =
|
||||
require('../es6-rest-param-visitors').visitorList;
|
||||
|
||||
var code = transform([
|
||||
'var foo = {',
|
||||
' bar(param1: number, ...args) {',
|
||||
' return [param1, args];',
|
||||
' }',
|
||||
'}',
|
||||
], restParamVisitors);
|
||||
eval(code);
|
||||
expect(foo.bar(42, 43, 44)).toEqual([42, [43, 44]]);
|
||||
});
|
||||
|
||||
it('strips annotated rest parameter', () => {
|
||||
var restParamVisitors =
|
||||
require('../es6-rest-param-visitors').visitorList;
|
||||
|
||||
var code = transform([
|
||||
'var foo = {',
|
||||
' bar(param1: number, ...args: Array<number>): Array<any> {',
|
||||
' return [param1, args];',
|
||||
' }',
|
||||
'}',
|
||||
], restParamVisitors);
|
||||
eval(code);
|
||||
expect(foo.bar(42, 43, 44)).toEqual([42, [43, 44]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('return type annotations', () => {
|
||||
it('strips function return types', () => {
|
||||
var code = transform([
|
||||
'var foo = {',
|
||||
' bar(param1:number): () => number {',
|
||||
' return function() { return param1; };',
|
||||
' }',
|
||||
'}',
|
||||
]);
|
||||
eval(code);
|
||||
expect(foo.bar(42)()).toBe(42);
|
||||
});
|
||||
});
|
||||
|
||||
describe('parametric type annotation', () => {
|
||||
// TODO: Fix esprima parsing for these cases
|
||||
/*
|
||||
it('strips parametric type annotations', () => {
|
||||
// TODO: Doesnt parse
|
||||
var code = transform([
|
||||
'var foo = {',
|
||||
' bar<T>(param1) {',
|
||||
' return param1;',
|
||||
' }',
|
||||
'}',
|
||||
]);
|
||||
eval(code);
|
||||
expect(foo.bar(42)).toBe(42);
|
||||
});
|
||||
|
||||
it('strips multi-parameter type annotations', () => {
|
||||
// TODO: Doesnt parse
|
||||
var restParamVisitors =
|
||||
require('../es6-rest-param-visitors').visitorList;
|
||||
|
||||
var code = transform([
|
||||
'var foo = {',
|
||||
' bar<T, S>(param1) {',
|
||||
' return param1;',
|
||||
' }',
|
||||
'}',
|
||||
], restParamVisitors);
|
||||
eval(code);
|
||||
expect(foo.bar(42)).toBe(42);
|
||||
});
|
||||
*/
|
||||
});
|
||||
});
|
||||
84
node_modules/jstransform/visitors/__tests__/type-pattern-syntax-test.js
generated
vendored
Normal file
84
node_modules/jstransform/visitors/__tests__/type-pattern-syntax-test.js
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
/*jshint -W117*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('static type pattern syntax', function() {
|
||||
var flowSyntaxVisitors;
|
||||
var jstransform;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
|
||||
flowSyntaxVisitors = require('../type-syntax.js').visitorList;
|
||||
jstransform = require('jstransform');
|
||||
destructuringVisitors =
|
||||
require('../es6-destructuring-visitors');
|
||||
|
||||
visitorList = destructuringVisitors.visitorList;
|
||||
});
|
||||
|
||||
function transform(code, visitors) {
|
||||
visitors = visitors ? visitorList.concat(visitors) : visitorList;
|
||||
|
||||
// We run the flow transform first
|
||||
code = jstransform.transform(
|
||||
flowSyntaxVisitors,
|
||||
code.join('\n')
|
||||
).code;
|
||||
|
||||
code = jstransform.transform(
|
||||
visitors,
|
||||
code
|
||||
).code;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
describe('Object Pattern', () => {
|
||||
it('strips function argument type annotation', () => {
|
||||
var code = transform([
|
||||
'function foo({x, y}: {x: number; y: number}) { return x+y; }',
|
||||
'var thirty = foo({x: 10, y: 20});'
|
||||
]);
|
||||
eval(code);
|
||||
expect(thirty).toBe(30);
|
||||
});
|
||||
it('strips var declaration type annotation', () => {
|
||||
var code = transform([
|
||||
'var {x, y}: {x: number; y: string} = { x: 42, y: "hello" };'
|
||||
]);
|
||||
eval(code);
|
||||
expect(x).toBe(42);
|
||||
expect(y).toBe("hello");
|
||||
});
|
||||
});
|
||||
|
||||
describe('Array Pattern', () => {
|
||||
it('strips function argument type annotation', () => {
|
||||
var code = transform([
|
||||
'function foo([x, y]: Array<number>) { return x+y; }',
|
||||
'var thirty = foo([10, 20]);'
|
||||
]);
|
||||
eval(code);
|
||||
expect(thirty).toBe(30);
|
||||
});
|
||||
it('strips var declaration type annotation', () => {
|
||||
var code = transform([
|
||||
'var [x, y]: Array<number> = [42, "hello"];'
|
||||
]);
|
||||
eval(code);
|
||||
expect(x).toBe(42);
|
||||
expect(y).toBe("hello");
|
||||
});
|
||||
});
|
||||
});
|
||||
207
node_modules/jstransform/visitors/__tests__/type-syntax-test.js
generated
vendored
Normal file
207
node_modules/jstransform/visitors/__tests__/type-syntax-test.js
generated
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*jshint evil: true*/
|
||||
/*jshint loopfunc: true*/
|
||||
|
||||
if (!!module.parent) {
|
||||
module.exports = {
|
||||
'TypeAnnotations': [
|
||||
'function foo(numVal: any){}',
|
||||
'function foo(numVal: number){}',
|
||||
'function foo(numVal: number, strVal: string){}',
|
||||
'function foo(numVal: number, untypedVal){}',
|
||||
'function foo(untypedVal, numVal: number){}',
|
||||
'function foo(nullableNum: ?number){}',
|
||||
'function foo(callback: () => void){}',
|
||||
'function foo(callback: () => number){}',
|
||||
'function foo(callback: (_:bool) => number){}',
|
||||
'function foo(callback: (_1:bool, _2:string) => number){}',
|
||||
'function foo(callback: (_1:bool, ...foo:Array<number>) => number){}',
|
||||
'function foo():number{}',
|
||||
'function foo():() => void{}',
|
||||
'function foo():(_:bool) => number{}',
|
||||
'function foo():(_?:bool) => number{}',
|
||||
'function foo(): {} {}',
|
||||
'function foo<T>() {}',
|
||||
'function foo<T: Foo>() {}',
|
||||
'function foo<T,S>() {}',
|
||||
'a=function<T,S>() {}',
|
||||
'a={set fooProp(value:number){}}',
|
||||
'a={set fooProp(value:number): void{}}',
|
||||
'a={get fooProp(): number {}}',
|
||||
'class Foo {set fooProp(value:number){}}',
|
||||
'class Foo {set fooProp(value:number): void{}}',
|
||||
'class Foo {get fooProp(): number{}}',
|
||||
'var numVal:number;',
|
||||
'var numVal:number = otherNumVal;',
|
||||
'var a: {numVal: number};',
|
||||
'var a: {numVal: number;};',
|
||||
'var a: {numVal: number; [indexer: string]: number};',
|
||||
'var a: ?{numVal: number};',
|
||||
'var a: {numVal: number; strVal: string}',
|
||||
'var a: {subObj: {strVal: string}}',
|
||||
'var a: {subObj: ?{strVal: string}}',
|
||||
'var a: {param1: number; param2: string}',
|
||||
'var a: {param1: number; param2?: string}',
|
||||
'var a: {add(x:number, ...y:Array<string>): void}',
|
||||
'var a: { id<T>(x: T): T; }',
|
||||
'var a:Array<number> = [1, 2, 3]',
|
||||
'a = class Foo<T> { }',
|
||||
'a = class Foo<T> extends Bar<T> { }',
|
||||
'class Foo<T> {}',
|
||||
'class Foo<T: Bar> {}',
|
||||
'class Foo<T> extends Bar<T> { }',
|
||||
'class Foo<T> extends mixin(Bar) { }',
|
||||
'class Foo<T> { bar<U>():number { return 42; }}',
|
||||
'class Foo { "bar"<T>() { } }',
|
||||
'function foo(requiredParam, optParam?) {}',
|
||||
'class Foo { prop1:string; prop2:number; }',
|
||||
'var x : number | string = 4;',
|
||||
'class Array { concat(items:number | string) {}; }',
|
||||
'var x : () => number | () => string = fn;',
|
||||
'var x: typeof Y = Y;',
|
||||
'var x: typeof Y | number = Y;',
|
||||
'var {x}: {x: string; } = { x: "hello" };',
|
||||
'var {x}: {x: string } = { x: "hello" };',
|
||||
'var [x]: Array<string> = [ "hello" ];',
|
||||
'function foo({x}: { x: string; }) {}',
|
||||
'function foo([x]: Array<string>) {}',
|
||||
'function foo(...rest: Array<number>) {}',
|
||||
'(function (...rest: Array<number>) {})',
|
||||
'((...rest: Array<number>) => rest)',
|
||||
'var a: Map<string, Array<string> >',
|
||||
'var a: Map<string, Array<string>>',
|
||||
'var a: number[]',
|
||||
'var a: ?string[]',
|
||||
'var a: Promise<bool>[]',
|
||||
'var a:(...rest:Array<number>) => number'
|
||||
],
|
||||
'Type Alias': [
|
||||
'type FBID = number;',
|
||||
'type Foo<T> = Bar<T>',
|
||||
],
|
||||
'Interfaces': [
|
||||
'interface A {}',
|
||||
'interface A extends B {}',
|
||||
'interface A<T> extends B<T>, C<T> {}',
|
||||
'interface A { foo: () => number; }',
|
||||
'interface Dictionary { [index: string]: string; length: number; }',
|
||||
'class Foo implements Bar {}',
|
||||
'class Foo extends Bar implements Bat, Man<number> {}',
|
||||
'class Foo extends class Bar implements Bat {} {}',
|
||||
'class Foo extends class Bar implements Bat {} implements Man {}',
|
||||
],
|
||||
'Type Grouping': [
|
||||
'var a: (number)',
|
||||
'var a: (() => number) | () => string',
|
||||
'var a: number & (string | bool)',
|
||||
'var a: (typeof A)',
|
||||
],
|
||||
'XJS': [
|
||||
'<a />',
|
||||
'<n:a n:v />',
|
||||
'<a n:foo="bar"> {value} <b><c /></b></a>',
|
||||
'<a b={" "} c=" " d="&" e="id=1&group=2" f="�" g="{*;" h="&#x;" />',
|
||||
'<a\n/>',
|
||||
'<日本語></日本語>',
|
||||
'<AbC-def\n test="&&">\nbar\nbaz\r\n</AbC-def>',
|
||||
'<a b={x ? <c /> : <d />} />',
|
||||
'<a>{}</a>',
|
||||
'<a>{/* this is a comment */}</a>',
|
||||
'<div>@test content</div>',
|
||||
'<div><br />7x invalid-js-identifier</div>',
|
||||
'<LeftRight left=<a /> right=<b>monkeys</b> />',
|
||||
'<a.b></a.b>',
|
||||
'<a.b.c></a.b.c>',
|
||||
'(<div />) < x;',
|
||||
'<div {...props} />',
|
||||
'<div {...props} post="attribute" />',
|
||||
'<div pre="leading" pre2="attribute" {...props}></div>',
|
||||
'<a> </a>',
|
||||
],
|
||||
'Call Properties': [
|
||||
'var a : { (): number }',
|
||||
'var a : { (): number; }',
|
||||
'var a : { (): number; y: string; (x: string): string }',
|
||||
'var a : { <T>(x: T): number; }',
|
||||
'interface A { (): number; }',
|
||||
],
|
||||
'String Literal Types': [
|
||||
'function createElement(tagName: "div"): HTMLDivElement {}',
|
||||
'function createElement(tagName: \'div\'): HTMLDivElement {}',
|
||||
],
|
||||
'Qualified Generic Type': [
|
||||
'var a : A.B',
|
||||
'var a : A.B.C',
|
||||
'var a : A.B<T>',
|
||||
'var a : typeof A.B<T>',
|
||||
],
|
||||
'Declare Statements': [
|
||||
'declare var foo',
|
||||
'declare var foo;',
|
||||
'declare function foo(): void',
|
||||
'declare function foo(): void;',
|
||||
'declare function foo<T>(): void;',
|
||||
'declare function foo(x: number, y: string): void;',
|
||||
'declare class A {}',
|
||||
'declare class A<T> extends B<T> { x: number }',
|
||||
'declare class A { static foo(): number; static x : string }',
|
||||
'declare class A { static [ indexer: number]: string }',
|
||||
'declare class A { static () : number }',
|
||||
],
|
||||
'Declare Module': [
|
||||
'declare module A {}',
|
||||
'declare module "./a/b.js" {}',
|
||||
'declare module A { declare var x: number; }',
|
||||
'declare module A { declare function foo(): number; }',
|
||||
'declare module A { declare class B { foo(): number; } }',
|
||||
],
|
||||
'Typecasts': [
|
||||
'(xxx: number)',
|
||||
'({xxx: 0, yyy: "hey"}: {xxx: number; yyy: string})',
|
||||
// distinguish between function type params and typecasts
|
||||
'((xxx) => xxx + 1: (xxx: number) => number)',
|
||||
// parens disambiguate groups from casts
|
||||
'((xxx: number), (yyy: string))',
|
||||
'((xxx: any): number)',
|
||||
],
|
||||
};
|
||||
} else {
|
||||
require('mock-modules').autoMockOff();
|
||||
var tests = require('./gen/type-syntax-test.rec.js');
|
||||
var transform = require('../../src/jstransform').transform;
|
||||
var visitors = require('../type-syntax').visitorList;
|
||||
|
||||
describe('transforms match expectations', function() {
|
||||
Object.keys(tests).forEach(function(sectionName) {
|
||||
var section = tests[sectionName];
|
||||
Object.keys(section).forEach(function(testCode) {
|
||||
it('transforms "' + testCode + '"', function() {
|
||||
expect(transform(visitors, testCode).code).toBe(section[testCode].transformed);
|
||||
});
|
||||
|
||||
it('evals "' + testCode + '"', function() {
|
||||
var transformed = transform(visitors, testCode).code;
|
||||
var expected = section[testCode].eval;
|
||||
|
||||
var evalFn = function() {
|
||||
eval(transformed);
|
||||
};
|
||||
|
||||
if (expected === 'No error') {
|
||||
expect(evalFn).not.toThrow();
|
||||
} else {
|
||||
expect(evalFn).toThrow(expected);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
201
node_modules/jstransform/visitors/__tests__/type-variable-declaration-syntax-test.js
generated
vendored
Normal file
201
node_modules/jstransform/visitors/__tests__/type-variable-declaration-syntax-test.js
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
/*jshint -W117*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('static type variable declaration syntax', function() {
|
||||
var flowSyntaxVisitors;
|
||||
var jstransform;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
|
||||
flowSyntaxVisitors = require('../type-syntax.js').visitorList;
|
||||
jstransform = require('jstransform');
|
||||
});
|
||||
|
||||
function transform(code, visitors) {
|
||||
code = code.join('\n');
|
||||
|
||||
// We run the flow transform first
|
||||
code = jstransform.transform(
|
||||
flowSyntaxVisitors,
|
||||
code
|
||||
).code;
|
||||
|
||||
if (visitors) {
|
||||
code = jstransform.transform(
|
||||
visitors,
|
||||
code
|
||||
).code;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
describe('basic annotations', () => {
|
||||
it('strips single annotated declarator without initializer', () => {
|
||||
var code = transform([
|
||||
'var myNum = 42;',
|
||||
'function foo() {',
|
||||
' var myNum:number;',
|
||||
' return myNum;',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
expect(foo()).toBe(undefined);
|
||||
});
|
||||
|
||||
it('strips single annotated declarator with initializer', () => {
|
||||
var code = transform([
|
||||
'var myNum:number = 42;',
|
||||
]);
|
||||
eval(code);
|
||||
expect(myNum).toBe(42);
|
||||
});
|
||||
|
||||
it('strips single annotated nullable declarator with initializer', () => {
|
||||
var code = transform([
|
||||
'var myNum:?number = 42;',
|
||||
]);
|
||||
eval(code);
|
||||
expect(myNum).toBe(42);
|
||||
});
|
||||
|
||||
it(
|
||||
'strips single annotated nullable declarator without initializer',
|
||||
() => {
|
||||
var code = transform([
|
||||
'var myNum:?number;',
|
||||
'myNum = null;',
|
||||
]);
|
||||
eval(code);
|
||||
expect(myNum).toBe(null);
|
||||
}
|
||||
);
|
||||
|
||||
it('strips multiple annotation declarations without initializers', () => {
|
||||
var code = transform([
|
||||
'var num1 = 42;',
|
||||
'var num2 = 43;',
|
||||
'function foo() {',
|
||||
' var num1:number, num2:number;',
|
||||
' return [num1, num2];',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
expect(foo()).toEqual([undefined, undefined]);
|
||||
});
|
||||
|
||||
it('strips multiple annotation declarations without initializers', () => {
|
||||
var code = transform([
|
||||
'var num1:number = 42, num2:number = 43;'
|
||||
]);
|
||||
eval(code);
|
||||
expect(num1).toBe(42);
|
||||
expect(num2).toBe(43);
|
||||
});
|
||||
});
|
||||
|
||||
describe('function type annotations', () => {
|
||||
it('strips function type annotations without initializer', () => {
|
||||
var code = transform([
|
||||
'var myFunc = function() { return "NOPE"; };',
|
||||
'function foo() {',
|
||||
' var myFunc:(_:bool) => number;',
|
||||
' return myFunc;',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
expect(foo()).toBe(undefined);
|
||||
});
|
||||
|
||||
it('strips function type annotations with initializer', () => {
|
||||
var code = transform([
|
||||
'var myFunc:(_:bool) => number = function(p1) {',
|
||||
' return 42;',
|
||||
'};'
|
||||
]);
|
||||
eval(code);
|
||||
expect(myFunc()).toBe(42);
|
||||
});
|
||||
});
|
||||
|
||||
describe('object type annotations', () => {
|
||||
it('strips empty object type annotations without initializer', () => {
|
||||
var code = transform([
|
||||
'var myObj = "NOPE";',
|
||||
'function foo() {',
|
||||
' var myObj:{};',
|
||||
' return myObj;',
|
||||
'}'
|
||||
]);
|
||||
eval(code);
|
||||
expect(foo()).toBe(undefined);
|
||||
});
|
||||
|
||||
it('strips empty object type annotations with initializer', () => {
|
||||
var code = transform([
|
||||
'var myObj:{} = {YEP: true};'
|
||||
]);
|
||||
eval(code);
|
||||
expect(myObj.YEP).toBe(true);
|
||||
});
|
||||
|
||||
it('strips empty nullable object type annotations with initializer', () => {
|
||||
var code = transform([
|
||||
'var myObj:?{} = {YEP: true};'
|
||||
]);
|
||||
eval(code);
|
||||
expect(myObj.YEP).toBe(true);
|
||||
});
|
||||
|
||||
it('strips object type with basic property annotation', () => {
|
||||
var code = transform([
|
||||
'var myObj:{arrProp:Array} = {YEP: [true]};'
|
||||
]);
|
||||
eval(code);
|
||||
expect(myObj.YEP).toEqual([true]);
|
||||
});
|
||||
|
||||
it('strips object type with multiple property annotations', () => {
|
||||
var code = transform([
|
||||
'var myObj:{numProp: number; strProp: string} = {',
|
||||
' numProp: 42,',
|
||||
' strProp: "YEP"',
|
||||
'};'
|
||||
]);
|
||||
eval(code);
|
||||
expect(myObj.numProp).toBe(42);
|
||||
expect(myObj.strProp).toBe("YEP");
|
||||
});
|
||||
|
||||
it('strips object type with parametric property annotation', () => {
|
||||
var code = transform([
|
||||
'var myObj:{arrProp:Array<bool>} = {YEP: [true]};'
|
||||
]);
|
||||
eval(code);
|
||||
expect(myObj.YEP).toEqual([true]);
|
||||
});
|
||||
|
||||
it('strips object type with function property annotation', () => {
|
||||
var code = transform([
|
||||
'var myObj:{myMethod:() => void} = {',
|
||||
' myMethod: function() {',
|
||||
' return 42;',
|
||||
' }',
|
||||
'};'
|
||||
]);
|
||||
eval(code);
|
||||
expect(myObj.myMethod()).toBe(42);
|
||||
});
|
||||
});
|
||||
});
|
||||
118
node_modules/jstransform/visitors/__tests__/undefined-to-void-0-visitors-test.js
generated
vendored
Normal file
118
node_modules/jstransform/visitors/__tests__/undefined-to-void-0-visitors-test.js
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails oncall+jsinfra@xmail.facebook.com
|
||||
*/
|
||||
|
||||
/*jshint evil:true*/
|
||||
|
||||
require('mock-modules').autoMockOff();
|
||||
|
||||
describe('undefined to void 0', function() {
|
||||
var transformFn;
|
||||
var visitors;
|
||||
|
||||
beforeEach(function() {
|
||||
require('mock-modules').dumpCache();
|
||||
visitors = require('../undefined-to-void-0-visitors').visitorList;
|
||||
transformFn = require('../../src/jstransform').transform;
|
||||
});
|
||||
|
||||
function transform(code) {
|
||||
return transformFn(visitors, code).code;
|
||||
}
|
||||
|
||||
it('should transform when undefined is not in scope', function() {
|
||||
var code = [
|
||||
'(function() {',
|
||||
' foo.undefined = bar;',
|
||||
' ({undefined: foo});',
|
||||
' var bar = undefined;',
|
||||
' bar = undefined;',
|
||||
' foo.bar = undefined;',
|
||||
' undefined.foo = bar;',
|
||||
' foo[undefined] = bar;',
|
||||
' ({foo: undefined});',
|
||||
'})(undefined);'
|
||||
].join('\n');
|
||||
|
||||
var result = [
|
||||
'(function() {',
|
||||
' foo.undefined = bar;',
|
||||
' ({undefined: foo});',
|
||||
' var bar = (void 0);',
|
||||
' bar = (void 0);',
|
||||
' foo.bar = (void 0);',
|
||||
' (void 0).foo = bar;',
|
||||
' foo[(void 0)] = bar;',
|
||||
' ({foo: (void 0)});',
|
||||
'})((void 0));'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code)).toEqual(result);
|
||||
});
|
||||
|
||||
it('should not transform when undefined is function argument', function() {
|
||||
var code = [
|
||||
'(function(undefined) {', // declared here
|
||||
' return undefined;',
|
||||
'})(1);'
|
||||
].join('\n');
|
||||
|
||||
var result = [
|
||||
'(function(undefined) {', // declared here
|
||||
' return undefined;',
|
||||
'})(1);'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code)).toEqual(result);
|
||||
});
|
||||
|
||||
it('should not transform when undefined is defined in local scope', function() {
|
||||
var code = [
|
||||
'(function() {',
|
||||
' var undefined;', // declared here
|
||||
' undefined = 1;', // assignment to declared variable
|
||||
' return undefined;',
|
||||
'})();'
|
||||
].join('\n');
|
||||
|
||||
var result = [
|
||||
'(function() {',
|
||||
' var undefined;', // declared here
|
||||
' undefined = 1;', // assignment to declared variable
|
||||
' return undefined;',
|
||||
'})();'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code)).toEqual(result);
|
||||
});
|
||||
|
||||
it('should not transform when undefined is defined in lexical scope', function() {
|
||||
var code = [
|
||||
'(function(undefined) {', // declared here
|
||||
' return (function() {',
|
||||
' return undefined;', // respects lexical scope
|
||||
' })();',
|
||||
'})();'
|
||||
].join('\n');
|
||||
|
||||
var result = [
|
||||
'(function(undefined) {', // declared here
|
||||
' return (function() {',
|
||||
' return undefined;', // respects lexical scope
|
||||
' })();',
|
||||
'})();'
|
||||
].join('\n');
|
||||
|
||||
expect(transform(code)).toEqual(result);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
153
node_modules/jstransform/visitors/es6-arrow-function-visitors.js
generated
vendored
Normal file
153
node_modules/jstransform/visitors/es6-arrow-function-visitors.js
generated
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*global exports:true*/
|
||||
|
||||
/**
|
||||
* Desugars ES6 Arrow functions to ES3 function expressions.
|
||||
* If the function contains `this` expression -- automatically
|
||||
* binds the function to current value of `this`.
|
||||
*
|
||||
* Single parameter, simple expression:
|
||||
*
|
||||
* [1, 2, 3].map(x => x * x);
|
||||
*
|
||||
* [1, 2, 3].map(function(x) { return x * x; });
|
||||
*
|
||||
* Several parameters, complex block:
|
||||
*
|
||||
* this.users.forEach((user, idx) => {
|
||||
* return this.isActive(idx) && this.send(user);
|
||||
* });
|
||||
*
|
||||
* this.users.forEach(function(user, idx) {
|
||||
* return this.isActive(idx) && this.send(user);
|
||||
* }.bind(this));
|
||||
*
|
||||
*/
|
||||
var restParamVisitors = require('./es6-rest-param-visitors');
|
||||
var destructuringVisitors = require('./es6-destructuring-visitors');
|
||||
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
function visitArrowFunction(traverse, node, path, state) {
|
||||
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(traverse, node, path, state);
|
||||
|
||||
// Skip arrow.
|
||||
utils.catchupWhiteSpace(node.body.range[0], state);
|
||||
|
||||
var renderBody = node.body.type == Syntax.BlockStatement
|
||||
? renderStatementBody
|
||||
: renderExpressionBody;
|
||||
|
||||
path.unshift(node);
|
||||
renderBody(traverse, node, path, state);
|
||||
path.shift();
|
||||
|
||||
// Bind the function only if `this` value is used
|
||||
// inside it or inside any sub-expression.
|
||||
var containsBindingSyntax =
|
||||
utils.containsChildMatching(node.body, function(node) {
|
||||
return node.type === Syntax.ThisExpression
|
||||
|| (node.type === Syntax.Identifier
|
||||
&& node.name === "super")
|
||||
|| (node.type === Syntax.JSXIdentifier
|
||||
&& node.name === 'this');
|
||||
});
|
||||
|
||||
if (containsBindingSyntax) {
|
||||
utils.append('.bind(this)', state);
|
||||
}
|
||||
|
||||
utils.catchupWhiteSpace(node.range[1], state);
|
||||
|
||||
// Close wrapper if not in the expression.
|
||||
if (notInExpression) {
|
||||
utils.append(')', state);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function renderParams(traverse, node, path, state) {
|
||||
// To preserve inline typechecking directives, we
|
||||
// distinguish between parens-free and paranthesized single param.
|
||||
if (isParensFreeSingleParam(node, state) || !node.params.length) {
|
||||
utils.append('(', state);
|
||||
}
|
||||
if (node.params.length !== 0) {
|
||||
path.unshift(node);
|
||||
traverse(node.params, path, state);
|
||||
path.unshift();
|
||||
}
|
||||
utils.append(')', state);
|
||||
}
|
||||
|
||||
function isParensFreeSingleParam(node, state) {
|
||||
return node.params.length === 1 &&
|
||||
state.g.source[state.g.position] !== '(';
|
||||
}
|
||||
|
||||
function renderExpressionBody(traverse, node, path, state) {
|
||||
// Wrap simple expression bodies into a block
|
||||
// with explicit return statement.
|
||||
utils.append('{', state);
|
||||
|
||||
// Special handling of rest param.
|
||||
if (node.rest) {
|
||||
utils.append(
|
||||
restParamVisitors.renderRestParamSetup(node, state),
|
||||
state
|
||||
);
|
||||
}
|
||||
|
||||
// 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);
|
||||
renderStatementBody(traverse, node, path, state);
|
||||
utils.append(';}', state);
|
||||
}
|
||||
|
||||
function renderStatementBody(traverse, node, path, state) {
|
||||
traverse(node.body, path, state);
|
||||
utils.catchup(node.body.range[1], state);
|
||||
}
|
||||
|
||||
visitArrowFunction.test = function(node, path, state) {
|
||||
return node.type === Syntax.ArrowFunctionExpression;
|
||||
};
|
||||
|
||||
exports.visitorList = [
|
||||
visitArrowFunction
|
||||
];
|
||||
|
||||
112
node_modules/jstransform/visitors/es6-call-spread-visitors.js
generated
vendored
Normal file
112
node_modules/jstransform/visitors/es6-call-spread-visitors.js
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
/*global exports:true*/
|
||||
|
||||
/**
|
||||
* Implements ES6 call spread.
|
||||
*
|
||||
* instance.method(a, b, c, ...d)
|
||||
*
|
||||
* instance.method.apply(instance, [a, b, c].concat(d))
|
||||
*
|
||||
*/
|
||||
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
|
||||
function process(traverse, node, path, state) {
|
||||
utils.move(node.range[0], state);
|
||||
traverse(node, path, state);
|
||||
utils.catchup(node.range[1], state);
|
||||
}
|
||||
|
||||
function visitCallSpread(traverse, node, path, state) {
|
||||
utils.catchup(node.range[0], state);
|
||||
|
||||
if (node.type === Syntax.NewExpression) {
|
||||
// Input = new Set(1, 2, ...list)
|
||||
// Output = new (Function.prototype.bind.apply(Set, [null, 1, 2].concat(list)))
|
||||
utils.append('new (Function.prototype.bind.apply(', state);
|
||||
process(traverse, node.callee, path, state);
|
||||
} else if (node.callee.type === Syntax.MemberExpression) {
|
||||
// Input = get().fn(1, 2, ...more)
|
||||
// Output = (_ = get()).fn.apply(_, [1, 2].apply(more))
|
||||
var tempVar = utils.injectTempVar(state);
|
||||
utils.append('(' + tempVar + ' = ', state);
|
||||
process(traverse, node.callee.object, path, state);
|
||||
utils.append(')', state);
|
||||
if (node.callee.property.type === Syntax.Identifier) {
|
||||
utils.append('.', state);
|
||||
process(traverse, node.callee.property, path, state);
|
||||
} else {
|
||||
utils.append('[', state);
|
||||
process(traverse, node.callee.property, path, state);
|
||||
utils.append(']', state);
|
||||
}
|
||||
utils.append('.apply(' + tempVar, state);
|
||||
} else {
|
||||
// Input = max(1, 2, ...list)
|
||||
// Output = max.apply(undefined, [1, 2].concat(list))
|
||||
var needsToBeWrappedInParenthesis =
|
||||
node.callee.type === Syntax.FunctionDeclaration ||
|
||||
node.callee.type === Syntax.FunctionExpression;
|
||||
if (needsToBeWrappedInParenthesis) {
|
||||
utils.append('(', state);
|
||||
}
|
||||
process(traverse, node.callee, path, state);
|
||||
if (needsToBeWrappedInParenthesis) {
|
||||
utils.append(')', state);
|
||||
}
|
||||
utils.append('.apply(undefined', state);
|
||||
}
|
||||
utils.append(', ', state);
|
||||
|
||||
var args = node.arguments.slice();
|
||||
var spread = args.pop();
|
||||
if (args.length || node.type === Syntax.NewExpression) {
|
||||
utils.append('[', state);
|
||||
if (node.type === Syntax.NewExpression) {
|
||||
utils.append('null' + (args.length ? ', ' : ''), state);
|
||||
}
|
||||
while (args.length) {
|
||||
var arg = args.shift();
|
||||
utils.move(arg.range[0], state);
|
||||
traverse(arg, path, state);
|
||||
if (args.length) {
|
||||
utils.catchup(args[0].range[0], state);
|
||||
} else {
|
||||
utils.catchup(arg.range[1], state);
|
||||
}
|
||||
}
|
||||
utils.append('].concat(', state);
|
||||
process(traverse, spread.argument, path, state);
|
||||
utils.append(')', state);
|
||||
} else {
|
||||
process(traverse, spread.argument, path, state);
|
||||
}
|
||||
utils.append(node.type === Syntax.NewExpression ? '))' : ')', state);
|
||||
|
||||
utils.move(node.range[1], state);
|
||||
return false;
|
||||
}
|
||||
|
||||
visitCallSpread.test = function(node, path, state) {
|
||||
return (
|
||||
(
|
||||
node.type === Syntax.CallExpression ||
|
||||
node.type === Syntax.NewExpression
|
||||
) &&
|
||||
node.arguments.length > 0 &&
|
||||
node.arguments[node.arguments.length - 1].type === Syntax.SpreadElement
|
||||
);
|
||||
};
|
||||
|
||||
exports.visitorList = [
|
||||
visitCallSpread
|
||||
];
|
||||
581
node_modules/jstransform/visitors/es6-class-visitors.js
generated
vendored
Normal file
581
node_modules/jstransform/visitors/es6-class-visitors.js
generated
vendored
Normal file
@@ -0,0 +1,581 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*jslint node:true*/
|
||||
|
||||
/**
|
||||
* @typechecks
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var base62 = require('base62');
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
var reservedWordsHelper = require('./reserved-words-helper');
|
||||
|
||||
var declareIdentInLocalScope = utils.declareIdentInLocalScope;
|
||||
var initScopeMetadata = utils.initScopeMetadata;
|
||||
|
||||
var SUPER_PROTO_IDENT_PREFIX = '____SuperProtoOf';
|
||||
|
||||
var _anonClassUUIDCounter = 0;
|
||||
var _mungedSymbolMaps = {};
|
||||
|
||||
function resetSymbols() {
|
||||
_anonClassUUIDCounter = 0;
|
||||
_mungedSymbolMaps = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to generate a unique class for use with code-gens for anonymous class
|
||||
* expressions.
|
||||
*
|
||||
* @param {object} state
|
||||
* @return {string}
|
||||
*/
|
||||
function _generateAnonymousClassName(state) {
|
||||
var mungeNamespace = state.mungeNamespace || '';
|
||||
return '____Class' + mungeNamespace + base62.encode(_anonClassUUIDCounter++);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an identifier name, munge it using the current state's mungeNamespace.
|
||||
*
|
||||
* @param {string} identName
|
||||
* @param {object} state
|
||||
* @return {string}
|
||||
*/
|
||||
function _getMungedName(identName, state) {
|
||||
var mungeNamespace = state.mungeNamespace;
|
||||
var shouldMinify = state.g.opts.minify;
|
||||
|
||||
if (shouldMinify) {
|
||||
if (!_mungedSymbolMaps[mungeNamespace]) {
|
||||
_mungedSymbolMaps[mungeNamespace] = {
|
||||
symbolMap: {},
|
||||
identUUIDCounter: 0
|
||||
};
|
||||
}
|
||||
|
||||
var symbolMap = _mungedSymbolMaps[mungeNamespace].symbolMap;
|
||||
if (!symbolMap[identName]) {
|
||||
symbolMap[identName] =
|
||||
base62.encode(_mungedSymbolMaps[mungeNamespace].identUUIDCounter++);
|
||||
}
|
||||
identName = symbolMap[identName];
|
||||
}
|
||||
return '$' + mungeNamespace + identName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts super class information from a class node.
|
||||
*
|
||||
* Information includes name of the super class and/or the expression string
|
||||
* (if extending from an expression)
|
||||
*
|
||||
* @param {object} node
|
||||
* @param {object} state
|
||||
* @return {object}
|
||||
*/
|
||||
function _getSuperClassInfo(node, state) {
|
||||
var ret = {
|
||||
name: null,
|
||||
expression: null
|
||||
};
|
||||
if (node.superClass) {
|
||||
if (node.superClass.type === Syntax.Identifier) {
|
||||
ret.name = node.superClass.name;
|
||||
} else {
|
||||
// Extension from an expression
|
||||
ret.name = _generateAnonymousClassName(state);
|
||||
ret.expression = state.g.source.substring(
|
||||
node.superClass.range[0],
|
||||
node.superClass.range[1]
|
||||
);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used with .filter() to find the constructor method in a list of
|
||||
* MethodDefinition nodes.
|
||||
*
|
||||
* @param {object} classElement
|
||||
* @return {boolean}
|
||||
*/
|
||||
function _isConstructorMethod(classElement) {
|
||||
return classElement.type === Syntax.MethodDefinition &&
|
||||
classElement.key.type === Syntax.Identifier &&
|
||||
classElement.key.name === 'constructor';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} node
|
||||
* @param {object} state
|
||||
* @return {boolean}
|
||||
*/
|
||||
function _shouldMungeIdentifier(node, state) {
|
||||
return (
|
||||
!!state.methodFuncNode &&
|
||||
!utils.getDocblock(state).hasOwnProperty('preventMunge') &&
|
||||
/^_(?!_)/.test(node.name)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function} traverse
|
||||
* @param {object} node
|
||||
* @param {array} path
|
||||
* @param {object} state
|
||||
*/
|
||||
function visitClassMethod(traverse, node, path, state) {
|
||||
if (!state.g.opts.es5 && (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);
|
||||
path.unshift(node);
|
||||
traverse(node.value, path, state);
|
||||
path.shift();
|
||||
return false;
|
||||
}
|
||||
visitClassMethod.test = function(node, path, state) {
|
||||
return node.type === Syntax.MethodDefinition;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {function} traverse
|
||||
* @param {object} node
|
||||
* @param {array} path
|
||||
* @param {object} state
|
||||
*/
|
||||
function visitClassFunctionExpression(traverse, node, path, state) {
|
||||
var methodNode = path[0];
|
||||
var isGetter = methodNode.kind === 'get';
|
||||
var isSetter = methodNode.kind === 'set';
|
||||
|
||||
state = utils.updateState(state, {
|
||||
methodFuncNode: node
|
||||
});
|
||||
|
||||
if (methodNode.key.name === 'constructor') {
|
||||
utils.append('function ' + state.className, state);
|
||||
} else {
|
||||
var methodAccessorComputed = methodNode.computed;
|
||||
var methodAccessor;
|
||||
var prototypeOrStatic = methodNode.static ? '' : '.prototype';
|
||||
var objectAccessor = state.className + prototypeOrStatic;
|
||||
|
||||
if (methodNode.key.type === Syntax.Identifier) {
|
||||
// foo() {}
|
||||
methodAccessor = methodNode.key.name;
|
||||
if (_shouldMungeIdentifier(methodNode.key, state)) {
|
||||
methodAccessor = _getMungedName(methodAccessor, state);
|
||||
}
|
||||
if (isGetter || isSetter) {
|
||||
methodAccessor = JSON.stringify(methodAccessor);
|
||||
} else if (reservedWordsHelper.isReservedWord(methodAccessor)) {
|
||||
methodAccessorComputed = true;
|
||||
methodAccessor = JSON.stringify(methodAccessor);
|
||||
}
|
||||
} else if (methodNode.key.type === Syntax.Literal) {
|
||||
// 'foo bar'() {} | get 'foo bar'() {} | set 'foo bar'() {}
|
||||
methodAccessor = JSON.stringify(methodNode.key.value);
|
||||
methodAccessorComputed = true;
|
||||
}
|
||||
|
||||
if (isSetter || isGetter) {
|
||||
utils.append(
|
||||
'Object.defineProperty(' +
|
||||
objectAccessor + ',' +
|
||||
methodAccessor + ',' +
|
||||
'{configurable:true,' +
|
||||
methodNode.kind + ':function',
|
||||
state
|
||||
);
|
||||
} else {
|
||||
if (state.g.opts.es3) {
|
||||
if (methodAccessorComputed) {
|
||||
methodAccessor = '[' + methodAccessor + ']';
|
||||
} else {
|
||||
methodAccessor = '.' + methodAccessor;
|
||||
}
|
||||
utils.append(
|
||||
objectAccessor +
|
||||
methodAccessor + '=function' + (node.generator ? '*' : ''),
|
||||
state
|
||||
);
|
||||
} else {
|
||||
if (!methodAccessorComputed) {
|
||||
methodAccessor = JSON.stringify(methodAccessor);
|
||||
}
|
||||
utils.append(
|
||||
'Object.defineProperty(' +
|
||||
objectAccessor + ',' +
|
||||
methodAccessor + ',' +
|
||||
'{writable:true,configurable:true,' +
|
||||
'value:function' + (node.generator ? '*' : ''),
|
||||
state
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
utils.move(methodNode.key.range[1], state);
|
||||
utils.append('(', state);
|
||||
|
||||
var params = node.params;
|
||||
if (params.length > 0) {
|
||||
utils.catchupNewlines(params[0].range[0], state);
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
utils.catchup(node.params[i].range[0], state);
|
||||
path.unshift(node);
|
||||
traverse(params[i], path, state);
|
||||
path.shift();
|
||||
}
|
||||
}
|
||||
|
||||
var closingParenPosition = utils.getNextSyntacticCharOffset(')', state);
|
||||
utils.catchupWhiteSpace(closingParenPosition, state);
|
||||
|
||||
var openingBracketPosition = utils.getNextSyntacticCharOffset('{', state);
|
||||
utils.catchup(openingBracketPosition + 1, state);
|
||||
|
||||
if (!state.scopeIsStrict) {
|
||||
utils.append('"use strict";', state);
|
||||
state = utils.updateState(state, {
|
||||
scopeIsStrict: true
|
||||
});
|
||||
}
|
||||
utils.move(node.body.range[0] + '{'.length, state);
|
||||
|
||||
path.unshift(node);
|
||||
traverse(node.body, path, state);
|
||||
path.shift();
|
||||
utils.catchup(node.body.range[1], state);
|
||||
|
||||
if (methodNode.key.name !== 'constructor') {
|
||||
if (isGetter || isSetter || !state.g.opts.es3) {
|
||||
utils.append('})', state);
|
||||
}
|
||||
utils.append(';', state);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
visitClassFunctionExpression.test = function(node, path, state) {
|
||||
return node.type === Syntax.FunctionExpression
|
||||
&& path[0].type === Syntax.MethodDefinition;
|
||||
};
|
||||
|
||||
function visitClassMethodParam(traverse, node, path, state) {
|
||||
var paramName = node.name;
|
||||
if (_shouldMungeIdentifier(node, state)) {
|
||||
paramName = _getMungedName(node.name, state);
|
||||
}
|
||||
utils.append(paramName, state);
|
||||
utils.move(node.range[1], state);
|
||||
}
|
||||
visitClassMethodParam.test = function(node, path, state) {
|
||||
if (!path[0] || !path[1]) {
|
||||
return;
|
||||
}
|
||||
|
||||
var parentFuncExpr = path[0];
|
||||
var parentClassMethod = path[1];
|
||||
|
||||
return parentFuncExpr.type === Syntax.FunctionExpression
|
||||
&& parentClassMethod.type === Syntax.MethodDefinition
|
||||
&& node.type === Syntax.Identifier;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {function} traverse
|
||||
* @param {object} node
|
||||
* @param {array} path
|
||||
* @param {object} state
|
||||
*/
|
||||
function _renderClassBody(traverse, node, path, state) {
|
||||
var className = state.className;
|
||||
var superClass = state.superClass;
|
||||
|
||||
// Set up prototype of constructor on same line as `extends` for line-number
|
||||
// preservation. This relies on function-hoisting if a constructor function is
|
||||
// defined in the class body.
|
||||
if (superClass.name) {
|
||||
// If the super class is an expression, we need to memoize the output of the
|
||||
// expression into the generated class name variable and use that to refer
|
||||
// to the super class going forward. Example:
|
||||
//
|
||||
// class Foo extends mixin(Bar, Baz) {}
|
||||
// --transforms to--
|
||||
// function Foo() {} var ____Class0Blah = mixin(Bar, Baz);
|
||||
if (superClass.expression !== null) {
|
||||
utils.append(
|
||||
'var ' + superClass.name + '=' + superClass.expression + ';',
|
||||
state
|
||||
);
|
||||
}
|
||||
|
||||
var keyName = superClass.name + '____Key';
|
||||
var keyNameDeclarator = '';
|
||||
if (!utils.identWithinLexicalScope(keyName, state)) {
|
||||
keyNameDeclarator = 'var ';
|
||||
declareIdentInLocalScope(keyName, initScopeMetadata(node), state);
|
||||
}
|
||||
utils.append(
|
||||
'for(' + keyNameDeclarator + keyName + ' in ' + superClass.name + '){' +
|
||||
'if(' + superClass.name + '.hasOwnProperty(' + keyName + ')){' +
|
||||
className + '[' + keyName + ']=' +
|
||||
superClass.name + '[' + keyName + '];' +
|
||||
'}' +
|
||||
'}',
|
||||
state
|
||||
);
|
||||
|
||||
var superProtoIdentStr = SUPER_PROTO_IDENT_PREFIX + superClass.name;
|
||||
if (!utils.identWithinLexicalScope(superProtoIdentStr, state)) {
|
||||
utils.append(
|
||||
'var ' + superProtoIdentStr + '=' + superClass.name + '===null?' +
|
||||
'null:' + superClass.name + '.prototype;',
|
||||
state
|
||||
);
|
||||
declareIdentInLocalScope(superProtoIdentStr, initScopeMetadata(node), state);
|
||||
}
|
||||
|
||||
utils.append(
|
||||
className + '.prototype=Object.create(' + superProtoIdentStr + ');',
|
||||
state
|
||||
);
|
||||
utils.append(
|
||||
className + '.prototype.constructor=' + className + ';',
|
||||
state
|
||||
);
|
||||
utils.append(
|
||||
className + '.__superConstructor__=' + superClass.name + ';',
|
||||
state
|
||||
);
|
||||
}
|
||||
|
||||
// If there's no constructor method specified in the class body, create an
|
||||
// empty constructor function at the top (same line as the class keyword)
|
||||
if (!node.body.body.filter(_isConstructorMethod).pop()) {
|
||||
utils.append('function ' + className + '(){', state);
|
||||
if (!state.scopeIsStrict) {
|
||||
utils.append('"use strict";', state);
|
||||
}
|
||||
if (superClass.name) {
|
||||
utils.append(
|
||||
'if(' + superClass.name + '!==null){' +
|
||||
superClass.name + '.apply(this,arguments);}',
|
||||
state
|
||||
);
|
||||
}
|
||||
utils.append('}', state);
|
||||
}
|
||||
|
||||
utils.move(node.body.range[0] + '{'.length, state);
|
||||
traverse(node.body, path, state);
|
||||
utils.catchupWhiteSpace(node.range[1], state);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function} traverse
|
||||
* @param {object} node
|
||||
* @param {array} path
|
||||
* @param {object} state
|
||||
*/
|
||||
function visitClassDeclaration(traverse, node, path, state) {
|
||||
var className = node.id.name;
|
||||
var superClass = _getSuperClassInfo(node, state);
|
||||
|
||||
state = utils.updateState(state, {
|
||||
mungeNamespace: className,
|
||||
className: className,
|
||||
superClass: superClass
|
||||
});
|
||||
|
||||
_renderClassBody(traverse, node, path, state);
|
||||
|
||||
return false;
|
||||
}
|
||||
visitClassDeclaration.test = function(node, path, state) {
|
||||
return node.type === Syntax.ClassDeclaration;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {function} traverse
|
||||
* @param {object} node
|
||||
* @param {array} path
|
||||
* @param {object} state
|
||||
*/
|
||||
function visitClassExpression(traverse, node, path, state) {
|
||||
var className = node.id && node.id.name || _generateAnonymousClassName(state);
|
||||
var superClass = _getSuperClassInfo(node, state);
|
||||
|
||||
utils.append('(function(){', state);
|
||||
|
||||
state = utils.updateState(state, {
|
||||
mungeNamespace: className,
|
||||
className: className,
|
||||
superClass: superClass
|
||||
});
|
||||
|
||||
_renderClassBody(traverse, node, path, state);
|
||||
|
||||
utils.append('return ' + className + ';})()', state);
|
||||
return false;
|
||||
}
|
||||
visitClassExpression.test = function(node, path, state) {
|
||||
return node.type === Syntax.ClassExpression;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {function} traverse
|
||||
* @param {object} node
|
||||
* @param {array} path
|
||||
* @param {object} state
|
||||
*/
|
||||
function visitPrivateIdentifier(traverse, node, path, state) {
|
||||
utils.append(_getMungedName(node.name, state), state);
|
||||
utils.move(node.range[1], state);
|
||||
}
|
||||
visitPrivateIdentifier.test = function(node, path, state) {
|
||||
if (node.type === Syntax.Identifier && _shouldMungeIdentifier(node, state)) {
|
||||
// Always munge non-computed properties of MemberExpressions
|
||||
// (a la preventing access of properties of unowned objects)
|
||||
if (path[0].type === Syntax.MemberExpression && path[0].object !== node
|
||||
&& path[0].computed === false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Always munge identifiers that were declared within the method function
|
||||
// scope
|
||||
if (utils.identWithinLexicalScope(node.name, state, state.methodFuncNode)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Always munge private keys on object literals defined within a method's
|
||||
// scope.
|
||||
if (path[0].type === Syntax.Property
|
||||
&& path[1].type === Syntax.ObjectExpression) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Always munge function parameters
|
||||
if (path[0].type === Syntax.FunctionExpression
|
||||
|| path[0].type === Syntax.FunctionDeclaration
|
||||
|| path[0].type === Syntax.ArrowFunctionExpression) {
|
||||
for (var i = 0; i < path[0].params.length; i++) {
|
||||
if (path[0].params[i] === node) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {function} traverse
|
||||
* @param {object} node
|
||||
* @param {array} path
|
||||
* @param {object} state
|
||||
*/
|
||||
function visitSuperCallExpression(traverse, node, path, state) {
|
||||
var superClassName = state.superClass.name;
|
||||
|
||||
if (node.callee.type === Syntax.Identifier) {
|
||||
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);
|
||||
} else if (node.callee.type === Syntax.MemberExpression) {
|
||||
utils.append(SUPER_PROTO_IDENT_PREFIX + superClassName, state);
|
||||
utils.move(node.callee.object.range[1], state);
|
||||
|
||||
if (node.callee.computed) {
|
||||
// ["a" + "b"]
|
||||
utils.catchup(node.callee.property.range[1] + ']'.length, state);
|
||||
} else {
|
||||
// .ab
|
||||
utils.append('.' + node.callee.property.name, state);
|
||||
}
|
||||
|
||||
utils.append('.call(', state);
|
||||
utils.move(node.callee.range[1], state);
|
||||
}
|
||||
|
||||
utils.append('this', state);
|
||||
if (node.arguments.length > 0) {
|
||||
utils.append(',', state);
|
||||
utils.catchupWhiteSpace(node.arguments[0].range[0], state);
|
||||
traverse(node.arguments, path, state);
|
||||
}
|
||||
|
||||
utils.catchupWhiteSpace(node.range[1], state);
|
||||
utils.append(')', state);
|
||||
return false;
|
||||
}
|
||||
visitSuperCallExpression.test = function(node, path, state) {
|
||||
if (state.superClass && node.type === Syntax.CallExpression) {
|
||||
var callee = node.callee;
|
||||
if (callee.type === Syntax.Identifier && callee.name === 'super'
|
||||
|| callee.type == Syntax.MemberExpression
|
||||
&& callee.object.name === 'super') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {function} traverse
|
||||
* @param {object} node
|
||||
* @param {array} path
|
||||
* @param {object} state
|
||||
*/
|
||||
function visitSuperMemberExpression(traverse, node, path, state) {
|
||||
var superClassName = state.superClass.name;
|
||||
|
||||
utils.append(SUPER_PROTO_IDENT_PREFIX + superClassName, state);
|
||||
utils.move(node.object.range[1], state);
|
||||
}
|
||||
visitSuperMemberExpression.test = function(node, path, state) {
|
||||
return state.superClass
|
||||
&& node.type === Syntax.MemberExpression
|
||||
&& node.object.type === Syntax.Identifier
|
||||
&& node.object.name === 'super';
|
||||
};
|
||||
|
||||
exports.resetSymbols = resetSymbols;
|
||||
|
||||
exports.visitorList = [
|
||||
visitClassDeclaration,
|
||||
visitClassExpression,
|
||||
visitClassFunctionExpression,
|
||||
visitClassMethod,
|
||||
visitClassMethodParam,
|
||||
visitPrivateIdentifier,
|
||||
visitSuperCallExpression,
|
||||
visitSuperMemberExpression
|
||||
];
|
||||
274
node_modules/jstransform/visitors/es6-destructuring-visitors.js
generated
vendored
Normal file
274
node_modules/jstransform/visitors/es6-destructuring-visitors.js
generated
vendored
Normal file
@@ -0,0 +1,274 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*global exports:true*/
|
||||
|
||||
/**
|
||||
* Implements ES6 destructuring assignment and pattern matchng.
|
||||
*
|
||||
* function init({port, ip, coords: [x, y]}) {
|
||||
* return (x && y) ? {id, port} : {ip};
|
||||
* };
|
||||
*
|
||||
* function init($__0) {
|
||||
* var
|
||||
* port = $__0.port,
|
||||
* ip = $__0.ip,
|
||||
* $__1 = $__0.coords,
|
||||
* x = $__1[0],
|
||||
* y = $__1[1];
|
||||
* return (x && y) ? {id, port} : {ip};
|
||||
* }
|
||||
*
|
||||
* var x, {ip, port} = init({ip, port});
|
||||
*
|
||||
* var x, $__0 = init({ip, port}), ip = $__0.ip, port = $__0.port;
|
||||
*
|
||||
*/
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
|
||||
var reservedWordsHelper = require('./reserved-words-helper');
|
||||
var restParamVisitors = require('./es6-rest-param-visitors');
|
||||
var restPropertyHelpers = require('./es7-rest-property-helpers');
|
||||
|
||||
// -------------------------------------------------------
|
||||
// 1. Structured variable declarations.
|
||||
//
|
||||
// var [a, b] = [b, a];
|
||||
// var {x, y} = {y, x};
|
||||
// -------------------------------------------------------
|
||||
|
||||
function visitStructuredVariable(traverse, node, path, state) {
|
||||
// Allocate new temp for the pattern.
|
||||
utils.append(utils.getTempVar(state.localScope.tempVarIndex) + '=', state);
|
||||
// Skip the pattern and assign the init to the temp.
|
||||
utils.catchupWhiteSpace(node.init.range[0], state);
|
||||
traverse(node.init, path, state);
|
||||
utils.catchup(node.init.range[1], state);
|
||||
// Render the destructured data.
|
||||
utils.append(',' + getDestructuredComponents(node.id, state), state);
|
||||
state.localScope.tempVarIndex++;
|
||||
return false;
|
||||
}
|
||||
|
||||
visitStructuredVariable.test = function(node, path, state) {
|
||||
return node.type === Syntax.VariableDeclarator &&
|
||||
isStructuredPattern(node.id);
|
||||
};
|
||||
|
||||
function isStructuredPattern(node) {
|
||||
return node.type === Syntax.ObjectPattern ||
|
||||
node.type === Syntax.ArrayPattern;
|
||||
}
|
||||
|
||||
// Main function which does actual recursive destructuring
|
||||
// of nested complex structures.
|
||||
function getDestructuredComponents(node, state) {
|
||||
var tmpIndex = state.localScope.tempVarIndex;
|
||||
var components = [];
|
||||
var patternItems = getPatternItems(node);
|
||||
|
||||
for (var idx = 0; idx < patternItems.length; idx++) {
|
||||
var item = patternItems[idx];
|
||||
if (!item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item.type === Syntax.SpreadElement) {
|
||||
// Spread/rest of an array.
|
||||
// TODO(dmitrys): support spread in the middle of a pattern
|
||||
// and also for function param patterns: [x, ...xs, y]
|
||||
components.push(item.argument.name +
|
||||
'=Array.prototype.slice.call(' +
|
||||
utils.getTempVar(tmpIndex) + ',' + idx + ')'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (item.type === Syntax.SpreadProperty) {
|
||||
var restExpression = restPropertyHelpers.renderRestExpression(
|
||||
utils.getTempVar(tmpIndex),
|
||||
patternItems
|
||||
);
|
||||
components.push(item.argument.name + '=' + restExpression);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Depending on pattern type (Array or Object), we get
|
||||
// corresponding pattern item parts.
|
||||
var accessor = getPatternItemAccessor(node, item, tmpIndex, idx);
|
||||
var value = getPatternItemValue(node, item);
|
||||
|
||||
// TODO(dmitrys): implement default values: {x, y=5}
|
||||
if (value.type === Syntax.Identifier) {
|
||||
// Simple pattern item.
|
||||
components.push(value.name + '=' + accessor);
|
||||
} else {
|
||||
// Complex sub-structure.
|
||||
components.push(
|
||||
utils.getTempVar(++state.localScope.tempVarIndex) + '=' + accessor +
|
||||
',' + getDestructuredComponents(value, state)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return components.join(',');
|
||||
}
|
||||
|
||||
function getPatternItems(node) {
|
||||
return node.properties || node.elements;
|
||||
}
|
||||
|
||||
function getPatternItemAccessor(node, patternItem, tmpIndex, idx) {
|
||||
var tmpName = utils.getTempVar(tmpIndex);
|
||||
if (node.type === Syntax.ObjectPattern) {
|
||||
if (reservedWordsHelper.isReservedWord(patternItem.key.name)) {
|
||||
return tmpName + '["' + patternItem.key.name + '"]';
|
||||
} else if (patternItem.key.type === Syntax.Literal) {
|
||||
return tmpName + '[' + JSON.stringify(patternItem.key.value) + ']';
|
||||
} else if (patternItem.key.type === Syntax.Identifier) {
|
||||
return tmpName + '.' + patternItem.key.name;
|
||||
}
|
||||
} else if (node.type === Syntax.ArrayPattern) {
|
||||
return tmpName + '[' + idx + ']';
|
||||
}
|
||||
}
|
||||
|
||||
function getPatternItemValue(node, patternItem) {
|
||||
return node.type === Syntax.ObjectPattern
|
||||
? patternItem.value
|
||||
: patternItem;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
// 2. Assignment expression.
|
||||
//
|
||||
// [a, b] = [b, a];
|
||||
// ({x, y} = {y, x});
|
||||
// -------------------------------------------------------
|
||||
|
||||
function visitStructuredAssignment(traverse, node, path, state) {
|
||||
var exprNode = node.expression;
|
||||
utils.append('var ' + utils.getTempVar(state.localScope.tempVarIndex) + '=', state);
|
||||
|
||||
utils.catchupWhiteSpace(exprNode.right.range[0], state);
|
||||
traverse(exprNode.right, path, state);
|
||||
utils.catchup(exprNode.right.range[1], state);
|
||||
|
||||
utils.append(
|
||||
';' + getDestructuredComponents(exprNode.left, state) + ';',
|
||||
state
|
||||
);
|
||||
|
||||
utils.catchupWhiteSpace(node.range[1], state);
|
||||
state.localScope.tempVarIndex++;
|
||||
return false;
|
||||
}
|
||||
|
||||
visitStructuredAssignment.test = function(node, path, state) {
|
||||
// We consider the expression statement rather than just assignment
|
||||
// expression to cover case with object patters which should be
|
||||
// wrapped in grouping operator: ({x, y} = {y, x});
|
||||
return node.type === Syntax.ExpressionStatement &&
|
||||
node.expression.type === Syntax.AssignmentExpression &&
|
||||
isStructuredPattern(node.expression.left);
|
||||
};
|
||||
|
||||
// -------------------------------------------------------
|
||||
// 3. Structured parameter.
|
||||
//
|
||||
// function foo({x, y}) { ... }
|
||||
// -------------------------------------------------------
|
||||
|
||||
function visitStructuredParameter(traverse, node, path, state) {
|
||||
utils.append(utils.getTempVar(getParamIndex(node, path)), state);
|
||||
utils.catchupWhiteSpace(node.range[1], state);
|
||||
return true;
|
||||
}
|
||||
|
||||
function getParamIndex(paramNode, path) {
|
||||
var funcNode = path[0];
|
||||
var tmpIndex = 0;
|
||||
for (var k = 0; k < funcNode.params.length; k++) {
|
||||
var param = funcNode.params[k];
|
||||
if (param === paramNode) {
|
||||
break;
|
||||
}
|
||||
if (isStructuredPattern(param)) {
|
||||
tmpIndex++;
|
||||
}
|
||||
}
|
||||
return tmpIndex;
|
||||
}
|
||||
|
||||
visitStructuredParameter.test = function(node, path, state) {
|
||||
return isStructuredPattern(node) && isFunctionNode(path[0]);
|
||||
};
|
||||
|
||||
function isFunctionNode(node) {
|
||||
return (node.type == Syntax.FunctionDeclaration ||
|
||||
node.type == Syntax.FunctionExpression ||
|
||||
node.type == Syntax.MethodDefinition ||
|
||||
node.type == Syntax.ArrowFunctionExpression);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
// 4. Function body for structured parameters.
|
||||
//
|
||||
// function foo({x, y}) { x; y; }
|
||||
// -------------------------------------------------------
|
||||
|
||||
function visitFunctionBodyForStructuredParameter(traverse, node, path, state) {
|
||||
var funcNode = path[0];
|
||||
|
||||
utils.catchup(funcNode.body.range[0] + 1, state);
|
||||
renderDestructuredComponents(funcNode, state);
|
||||
|
||||
if (funcNode.rest) {
|
||||
utils.append(
|
||||
restParamVisitors.renderRestParamSetup(funcNode, state),
|
||||
state
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function renderDestructuredComponents(funcNode, state) {
|
||||
var destructuredComponents = [];
|
||||
|
||||
for (var k = 0; k < funcNode.params.length; k++) {
|
||||
var param = funcNode.params[k];
|
||||
if (isStructuredPattern(param)) {
|
||||
destructuredComponents.push(
|
||||
getDestructuredComponents(param, state)
|
||||
);
|
||||
state.localScope.tempVarIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (destructuredComponents.length) {
|
||||
utils.append('var ' + destructuredComponents.join(',') + ';', state);
|
||||
}
|
||||
}
|
||||
|
||||
visitFunctionBodyForStructuredParameter.test = function(node, path, state) {
|
||||
return node.type === Syntax.BlockStatement && isFunctionNode(path[0]);
|
||||
};
|
||||
|
||||
exports.visitorList = [
|
||||
visitStructuredVariable,
|
||||
visitStructuredAssignment,
|
||||
visitStructuredParameter,
|
||||
visitFunctionBodyForStructuredParameter
|
||||
];
|
||||
|
||||
exports.renderDestructuredComponents = renderDestructuredComponents;
|
||||
|
||||
123
node_modules/jstransform/visitors/es6-for-of-visitors.js
generated
vendored
Normal file
123
node_modules/jstransform/visitors/es6-for-of-visitors.js
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
/*global exports:true*/
|
||||
|
||||
/**
|
||||
* Implements ES6 for-of loop, making optimization
|
||||
* for arrays. If an object is not an array, instantiates
|
||||
* an iterator for this object, assuming the runtime
|
||||
* support for the iterator is implemented.
|
||||
*
|
||||
* ES6:
|
||||
*
|
||||
* for (var v of <expr>) <body>
|
||||
*
|
||||
* Compiled ES3:
|
||||
*
|
||||
* for (var v,
|
||||
* _iter = <expr>,
|
||||
* _isArray = Array.isArray(_iter),
|
||||
* _k = 0,
|
||||
* _iter = _isArray ? _iter : _iter[Symbol.iterator]();;
|
||||
* ) {
|
||||
*
|
||||
* if (_isArray) {
|
||||
* if (_k >= _iter.length) break;
|
||||
* v = _iter[_k++];
|
||||
* } else {
|
||||
* _k = _iter.next();
|
||||
* if (_k.done) break;
|
||||
* v = _k.value;
|
||||
* }
|
||||
*
|
||||
* <body>
|
||||
* }
|
||||
*/
|
||||
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
|
||||
function process(traverse, node, path, state) {
|
||||
utils.move(node.range[0], state);
|
||||
traverse(node, path, state);
|
||||
utils.catchup(node.range[1], state);
|
||||
}
|
||||
|
||||
function visitForOfStatement(traverse, node, path, state) {
|
||||
var iter = utils.injectTempVar(state);
|
||||
var isArray = utils.injectTempVar(state);
|
||||
var k = utils.injectTempVar(state);
|
||||
|
||||
var variable;
|
||||
|
||||
if (node.left.type === Syntax.VariableDeclaration) {
|
||||
variable = node.left.declarations[0].id.name;
|
||||
utils.append('var ' + variable + ';', state);
|
||||
} else {
|
||||
variable = node.left.name;
|
||||
}
|
||||
|
||||
utils.append('for(', state);
|
||||
|
||||
utils.append(iter + '=', state);
|
||||
process(traverse, node.right, path, state);
|
||||
|
||||
// Setup iterator with optimization for arrays.
|
||||
utils.append(
|
||||
',' + isArray + '=Array.isArray(' + iter + '),' +
|
||||
k + '=0,' +
|
||||
iter + '=' + isArray + '?' + iter + ':' +
|
||||
iter + '[/*global Symbol*/typeof Symbol=="function"' +
|
||||
'?Symbol.iterator:"@@iterator"]();;',
|
||||
state
|
||||
);
|
||||
|
||||
// Jump to the body creating block if needed.
|
||||
if (node.body.type === Syntax.BlockStatement) {
|
||||
utils.catchup(node.body.range[0] + 1, state);
|
||||
} else {
|
||||
utils.catchup(node.body.range[0], state);
|
||||
utils.append('{', state);
|
||||
}
|
||||
|
||||
// Arrays case.
|
||||
utils.append(
|
||||
'if(' + isArray + '){' +
|
||||
'if(' + k + '>=' + iter + '.length) break;',
|
||||
state
|
||||
);
|
||||
|
||||
utils.append(variable + '=' + iter + '[' + k + '++];', state);
|
||||
|
||||
// Iterators case.
|
||||
utils.append(
|
||||
'}else{' + k + '=' + iter + '.next();' +
|
||||
'if(' + k + '.done) break;',
|
||||
state
|
||||
);
|
||||
|
||||
utils.append(variable + '=' + k + '.value;}', state);
|
||||
|
||||
traverse(node.body, path, state);
|
||||
utils.catchup(node.body.range[1], state);
|
||||
|
||||
if (node.body.type !== Syntax.BlockStatement) {
|
||||
utils.append('}', state);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
visitForOfStatement.test = function(node, path, state) {
|
||||
return node.type === Syntax.ForOfStatement;
|
||||
};
|
||||
|
||||
exports.visitorList = [
|
||||
visitForOfStatement,
|
||||
];
|
||||
106
node_modules/jstransform/visitors/es6-object-computed-property-visitors.js
generated
vendored
Normal file
106
node_modules/jstransform/visitors/es6-object-computed-property-visitors.js
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*jslint node: true*/
|
||||
|
||||
var es6ObjectConciseMethods = require('./es6-object-concise-method-visitors');
|
||||
var es7SpreadProperties = require('./es7-spread-property-visitors');
|
||||
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
|
||||
function process(traverse, node, path, state) {
|
||||
utils.catchupWhiteSpace(node.range[0], state);
|
||||
traverse(node, path, state);
|
||||
utils.catchup(node.range[1], state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: This visitor is capable of handling the following transforms too:
|
||||
* - ES7 object literal spread,
|
||||
* - ES6 object concise methods,
|
||||
* - ES6 object short notation,
|
||||
* This is because of limitations in the jstransform framework, which isn't
|
||||
* capable of feeding the output of one visitor to another. Additionally,
|
||||
* any attempt to share logic between these visitors only increases code
|
||||
* complixity. And so, we are forced to create a single complex one that
|
||||
* handles all cases.
|
||||
*
|
||||
* {alpha: 12, \'beta\': 34, ['gam' + 'ma']: 56} // before
|
||||
* (_={},_.alpha=12,_['beta']=34,_['gam' + 'ma']=56,_) // after
|
||||
*/
|
||||
function es6ObjectComputedProperties(traverse, node, path, state) {
|
||||
var obj = utils.injectTempVar(state);
|
||||
utils.append('(' + obj + '={}', state);
|
||||
for (var ii = 0; ii < node.properties.length; ++ii) {
|
||||
var property = node.properties[ii];
|
||||
utils.append(',', state);
|
||||
|
||||
if (property.type === Syntax.SpreadProperty) {
|
||||
utils.append('Object.assign(' + obj, state);
|
||||
var nextComputedPropertyIndex = ii + 1;
|
||||
while (
|
||||
nextComputedPropertyIndex < node.properties.length &&
|
||||
!node.properties[nextComputedPropertyIndex].computed
|
||||
) {
|
||||
nextComputedPropertyIndex += 1;
|
||||
}
|
||||
utils.catchupWhiteSpace(node.properties[ii].range[0], state);
|
||||
var lastWasSpread = es7SpreadProperties.renderSpreadProperties(
|
||||
traverse,
|
||||
node.properties.slice(ii, nextComputedPropertyIndex),
|
||||
path,
|
||||
state,
|
||||
true // previousWasSpread
|
||||
);
|
||||
utils.append((lastWasSpread ? '' : '}') + ')', state);
|
||||
ii = nextComputedPropertyIndex - 1;
|
||||
continue;
|
||||
|
||||
// short notation / dot access
|
||||
} else if (
|
||||
property.type === Syntax.Property &&
|
||||
property.key.type === Syntax.Identifier &&
|
||||
!property.computed
|
||||
) {
|
||||
utils.append(obj + '.' + property.key.name + '=', state);
|
||||
|
||||
// literals / computed properties
|
||||
} else if (property.type === Syntax.Property) {
|
||||
utils.append(obj + '[', state);
|
||||
process(traverse, property.key, path, state);
|
||||
utils.append(']=', state);
|
||||
}
|
||||
|
||||
// concise methods
|
||||
if (property.method === true) {
|
||||
utils.catchupWhiteSpace(property.key.range[1], state);
|
||||
es6ObjectConciseMethods.renderConciseMethod(traverse, property, path, state);
|
||||
}
|
||||
process(traverse, property.value, path, state);
|
||||
}
|
||||
utils.catchupWhiteSpace(node.range[1], state);
|
||||
utils.append(',' + obj + ')', state);
|
||||
return false;
|
||||
}
|
||||
es6ObjectComputedProperties.test = function(node, path, state) {
|
||||
if (node.type !== Syntax.ObjectExpression) {
|
||||
return false;
|
||||
}
|
||||
for (var ii = 0; ii < node.properties.length; ++ii) {
|
||||
if (node.properties[ii].computed) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
exports.visitorList = [
|
||||
es6ObjectComputedProperties,
|
||||
];
|
||||
70
node_modules/jstransform/visitors/es6-object-concise-method-visitors.js
generated
vendored
Normal file
70
node_modules/jstransform/visitors/es6-object-concise-method-visitors.js
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*jslint node:true*/
|
||||
|
||||
/**
|
||||
* Desugars concise methods of objects to function expressions.
|
||||
*
|
||||
* var foo = {
|
||||
* method(x, y) { ... }
|
||||
* };
|
||||
*
|
||||
* var foo = {
|
||||
* method: function(x, y) { ... }
|
||||
* };
|
||||
*
|
||||
*/
|
||||
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
var reservedWordsHelper = require('./reserved-words-helper');
|
||||
|
||||
function visitObjectConciseMethod(traverse, node, path, state) {
|
||||
var isGenerator = node.value.generator;
|
||||
if (isGenerator) {
|
||||
utils.catchupWhiteSpace(node.range[0] + 1, state);
|
||||
}
|
||||
if (reservedWordsHelper.isReservedWord(node.key.name)) {
|
||||
utils.catchup(node.key.range[0], state);
|
||||
utils.append('"', state);
|
||||
utils.catchup(node.key.range[1], state);
|
||||
utils.append('"', state);
|
||||
}
|
||||
|
||||
utils.catchup(node.key.range[1], state);
|
||||
utils.append(':', state);
|
||||
renderConciseMethod(traverse, node, path, state);
|
||||
return false;
|
||||
}
|
||||
|
||||
// This method is also used by es6-object-computed-property-visitor to render
|
||||
// the method for concise computed properties.
|
||||
function renderConciseMethod(traverse, property, path, state) {
|
||||
if (property.computed) {
|
||||
var closingSquareBracketIndex = state.g.source.indexOf(']', property.key.range[1]);
|
||||
utils.catchup(closingSquareBracketIndex, state);
|
||||
utils.move(closingSquareBracketIndex + 1, state);
|
||||
}
|
||||
utils.append("function" + (property.value.generator ? "*" : ""), state);
|
||||
path.unshift(property);
|
||||
traverse(property.value, path, state);
|
||||
path.shift();
|
||||
}
|
||||
|
||||
visitObjectConciseMethod.test = function(node, path, state) {
|
||||
return node.type === Syntax.Property &&
|
||||
node.value.type === Syntax.FunctionExpression &&
|
||||
node.method === true;
|
||||
};
|
||||
|
||||
exports.renderConciseMethod = renderConciseMethod;
|
||||
exports.visitorList = [
|
||||
visitObjectConciseMethod
|
||||
];
|
||||
46
node_modules/jstransform/visitors/es6-object-short-notation-visitors.js
generated
vendored
Normal file
46
node_modules/jstransform/visitors/es6-object-short-notation-visitors.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*jslint node: true*/
|
||||
|
||||
/**
|
||||
* Desugars ES6 Object Literal short notations into ES3 full notation.
|
||||
*
|
||||
* // Easier return values.
|
||||
* function foo(x, y) {
|
||||
* return {x, y}; // {x: x, y: y}
|
||||
* };
|
||||
*
|
||||
* // Destructuring.
|
||||
* function init({port, ip, coords: {x, y}}) { ... }
|
||||
*
|
||||
*/
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
function visitObjectLiteralShortNotation(traverse, node, path, state) {
|
||||
utils.catchup(node.key.range[1], state);
|
||||
utils.append(':' + node.key.name, state);
|
||||
return false;
|
||||
}
|
||||
|
||||
visitObjectLiteralShortNotation.test = function(node, path, state) {
|
||||
return node.type === Syntax.Property &&
|
||||
node.kind === 'init' &&
|
||||
node.shorthand === true &&
|
||||
path[0].type !== Syntax.ObjectPattern;
|
||||
};
|
||||
|
||||
exports.visitorList = [
|
||||
visitObjectLiteralShortNotation
|
||||
];
|
||||
|
||||
100
node_modules/jstransform/visitors/es6-rest-param-visitors.js
generated
vendored
Normal file
100
node_modules/jstransform/visitors/es6-rest-param-visitors.js
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*jslint node:true*/
|
||||
|
||||
/**
|
||||
* Desugars ES6 rest parameters into an ES3 arguments array.
|
||||
*
|
||||
* function printf(template, ...args) {
|
||||
* args.forEach(...);
|
||||
* }
|
||||
*
|
||||
* We could use `Array.prototype.slice.call`, but that usage of arguments causes
|
||||
* functions to be deoptimized in V8, so instead we use a for-loop.
|
||||
*
|
||||
* function printf(template) {
|
||||
* for (var args = [], $__0 = 1, $__1 = arguments.length; $__0 < $__1; $__0++)
|
||||
* args.push(arguments[$__0]);
|
||||
* args.forEach(...);
|
||||
* }
|
||||
*
|
||||
*/
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
|
||||
|
||||
|
||||
function _nodeIsFunctionWithRestParam(node) {
|
||||
return (node.type === Syntax.FunctionDeclaration
|
||||
|| node.type === Syntax.FunctionExpression
|
||||
|| node.type === Syntax.ArrowFunctionExpression)
|
||||
&& node.rest;
|
||||
}
|
||||
|
||||
function visitFunctionParamsWithRestParam(traverse, node, path, state) {
|
||||
if (node.parametricType) {
|
||||
utils.catchup(node.parametricType.range[0], state);
|
||||
path.unshift(node);
|
||||
traverse(node.parametricType, path, state);
|
||||
path.shift();
|
||||
}
|
||||
|
||||
// Render params.
|
||||
if (node.params.length) {
|
||||
path.unshift(node);
|
||||
traverse(node.params, path, state);
|
||||
path.shift();
|
||||
} else {
|
||||
// -3 is for ... of the rest.
|
||||
utils.catchup(node.rest.range[0] - 3, state);
|
||||
}
|
||||
utils.catchupWhiteSpace(node.rest.range[1], state);
|
||||
utils.catchup(node.body.range[0], state);
|
||||
|
||||
path.unshift(node);
|
||||
traverse(node.body, path, state);
|
||||
path.shift();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
visitFunctionParamsWithRestParam.test = function(node, path, state) {
|
||||
return _nodeIsFunctionWithRestParam(node);
|
||||
};
|
||||
|
||||
function renderRestParamSetup(functionNode, state) {
|
||||
var idx = state.localScope.tempVarIndex++;
|
||||
var len = state.localScope.tempVarIndex++;
|
||||
|
||||
return 'for (var ' + functionNode.rest.name + '=[],' +
|
||||
utils.getTempVar(idx) + '=' + functionNode.params.length + ',' +
|
||||
utils.getTempVar(len) + '=arguments.length;' +
|
||||
utils.getTempVar(idx) + '<' + utils.getTempVar(len) + ';' +
|
||||
utils.getTempVar(idx) + '++) ' +
|
||||
functionNode.rest.name + '.push(arguments[' + utils.getTempVar(idx) + ']);';
|
||||
}
|
||||
|
||||
function visitFunctionBodyWithRestParam(traverse, node, path, state) {
|
||||
utils.catchup(node.range[0] + 1, state);
|
||||
var parentNode = path[0];
|
||||
utils.append(renderRestParamSetup(parentNode, state), state);
|
||||
return true;
|
||||
}
|
||||
|
||||
visitFunctionBodyWithRestParam.test = function(node, path, state) {
|
||||
return node.type === Syntax.BlockStatement
|
||||
&& _nodeIsFunctionWithRestParam(path[0]);
|
||||
};
|
||||
|
||||
exports.renderRestParamSetup = renderRestParamSetup;
|
||||
exports.visitorList = [
|
||||
visitFunctionParamsWithRestParam,
|
||||
visitFunctionBodyWithRestParam
|
||||
];
|
||||
153
node_modules/jstransform/visitors/es6-template-visitors.js
generated
vendored
Normal file
153
node_modules/jstransform/visitors/es6-template-visitors.js
generated
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*jslint node:true*/
|
||||
|
||||
/**
|
||||
* @typechecks
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
|
||||
/**
|
||||
* http://people.mozilla.org/~jorendorff/es6-draft.html#sec-12.1.9
|
||||
*/
|
||||
function visitTemplateLiteral(traverse, node, path, state) {
|
||||
var templateElements = node.quasis;
|
||||
|
||||
utils.append('(', state);
|
||||
for (var ii = 0; ii < templateElements.length; ii++) {
|
||||
var templateElement = templateElements[ii];
|
||||
if (templateElement.value.raw !== '') {
|
||||
utils.append(getCookedValue(templateElement), state);
|
||||
if (!templateElement.tail) {
|
||||
// + between element and substitution
|
||||
utils.append(' + ', state);
|
||||
}
|
||||
// maintain line numbers
|
||||
utils.move(templateElement.range[0], state);
|
||||
utils.catchupNewlines(templateElement.range[1], state);
|
||||
} else { // templateElement.value.raw === ''
|
||||
// Concatenat adjacent substitutions, e.g. `${x}${y}`. Empty templates
|
||||
// appear before the first and after the last element - nothing to add in
|
||||
// those cases.
|
||||
if (ii === 0) {
|
||||
utils.append('"" + ', state);
|
||||
}
|
||||
if (ii > 0 && !templateElement.tail) {
|
||||
// + between substitution and substitution
|
||||
utils.append(' + ', state);
|
||||
}
|
||||
}
|
||||
|
||||
utils.move(templateElement.range[1], state);
|
||||
if (!templateElement.tail) {
|
||||
var substitution = node.expressions[ii];
|
||||
if (substitution.type === Syntax.Identifier ||
|
||||
substitution.type === Syntax.Literal ||
|
||||
substitution.type === Syntax.MemberExpression ||
|
||||
substitution.type === Syntax.CallExpression) {
|
||||
utils.catchup(substitution.range[1], state);
|
||||
} else {
|
||||
utils.append('(', state);
|
||||
traverse(substitution, path, state);
|
||||
utils.catchup(substitution.range[1], state);
|
||||
utils.append(')', state);
|
||||
}
|
||||
// if next templateElement isn't empty...
|
||||
if (templateElements[ii + 1].value.cooked !== '') {
|
||||
utils.append(' + ', state);
|
||||
}
|
||||
}
|
||||
}
|
||||
utils.move(node.range[1], state);
|
||||
utils.append(')', state);
|
||||
return false;
|
||||
}
|
||||
|
||||
visitTemplateLiteral.test = function(node, path, state) {
|
||||
return node.type === Syntax.TemplateLiteral;
|
||||
};
|
||||
|
||||
/**
|
||||
* http://people.mozilla.org/~jorendorff/es6-draft.html#sec-12.2.6
|
||||
*/
|
||||
function visitTaggedTemplateExpression(traverse, node, path, state) {
|
||||
var template = node.quasi;
|
||||
var numQuasis = template.quasis.length;
|
||||
|
||||
// print the tag
|
||||
utils.move(node.tag.range[0], state);
|
||||
traverse(node.tag, path, state);
|
||||
utils.catchup(node.tag.range[1], state);
|
||||
|
||||
// print array of template elements
|
||||
utils.append('(function() { var siteObj = [', state);
|
||||
for (var ii = 0; ii < numQuasis; ii++) {
|
||||
utils.append(getCookedValue(template.quasis[ii]), state);
|
||||
if (ii !== numQuasis - 1) {
|
||||
utils.append(', ', state);
|
||||
}
|
||||
}
|
||||
utils.append(']; siteObj.raw = [', state);
|
||||
for (ii = 0; ii < numQuasis; ii++) {
|
||||
utils.append(getRawValue(template.quasis[ii]), state);
|
||||
if (ii !== numQuasis - 1) {
|
||||
utils.append(', ', state);
|
||||
}
|
||||
}
|
||||
utils.append(
|
||||
']; Object.freeze(siteObj.raw); Object.freeze(siteObj); return siteObj; }()',
|
||||
state
|
||||
);
|
||||
|
||||
// print substitutions
|
||||
if (numQuasis > 1) {
|
||||
for (ii = 0; ii < template.expressions.length; ii++) {
|
||||
var expression = template.expressions[ii];
|
||||
utils.append(', ', state);
|
||||
|
||||
// maintain line numbers by calling catchupWhiteSpace over the whole
|
||||
// previous TemplateElement
|
||||
utils.move(template.quasis[ii].range[0], state);
|
||||
utils.catchupNewlines(template.quasis[ii].range[1], state);
|
||||
|
||||
utils.move(expression.range[0], state);
|
||||
traverse(expression, path, state);
|
||||
utils.catchup(expression.range[1], state);
|
||||
}
|
||||
}
|
||||
|
||||
// print blank lines to push the closing ) down to account for the final
|
||||
// TemplateElement.
|
||||
utils.catchupNewlines(node.range[1], state);
|
||||
|
||||
utils.append(')', state);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
visitTaggedTemplateExpression.test = function(node, path, state) {
|
||||
return node.type === Syntax.TaggedTemplateExpression;
|
||||
};
|
||||
|
||||
function getCookedValue(templateElement) {
|
||||
return JSON.stringify(templateElement.value.cooked);
|
||||
}
|
||||
|
||||
function getRawValue(templateElement) {
|
||||
return JSON.stringify(templateElement.value.raw);
|
||||
}
|
||||
|
||||
exports.visitorList = [
|
||||
visitTemplateLiteral,
|
||||
visitTaggedTemplateExpression
|
||||
];
|
||||
73
node_modules/jstransform/visitors/es7-rest-property-helpers.js
generated
vendored
Normal file
73
node_modules/jstransform/visitors/es7-rest-property-helpers.js
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*jslint node:true*/
|
||||
|
||||
/**
|
||||
* Desugars ES7 rest properties into ES5 object iteration.
|
||||
*/
|
||||
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
|
||||
// TODO: This is a pretty massive helper, it should only be defined once, in the
|
||||
// transform's runtime environment. We don't currently have a runtime though.
|
||||
var restFunction =
|
||||
'(function(source, exclusion) {' +
|
||||
'var rest = {};' +
|
||||
'var hasOwn = Object.prototype.hasOwnProperty;' +
|
||||
'if (source == null) {' +
|
||||
'throw new TypeError();' +
|
||||
'}' +
|
||||
'for (var key in source) {' +
|
||||
'if (hasOwn.call(source, key) && !hasOwn.call(exclusion, key)) {' +
|
||||
'rest[key] = source[key];' +
|
||||
'}' +
|
||||
'}' +
|
||||
'return rest;' +
|
||||
'})';
|
||||
|
||||
function getPropertyNames(properties) {
|
||||
var names = [];
|
||||
for (var i = 0; i < properties.length; i++) {
|
||||
var property = properties[i];
|
||||
if (property.type === Syntax.SpreadProperty) {
|
||||
continue;
|
||||
}
|
||||
if (property.type === Syntax.Identifier) {
|
||||
names.push(property.name);
|
||||
} else {
|
||||
names.push(property.key.name);
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
function getRestFunctionCall(source, exclusion) {
|
||||
return restFunction + '(' + source + ',' + exclusion + ')';
|
||||
}
|
||||
|
||||
function getSimpleShallowCopy(accessorExpression) {
|
||||
// This could be faster with 'Object.assign({}, ' + accessorExpression + ')'
|
||||
// but to unify code paths and avoid a ES6 dependency we use the same
|
||||
// helper as for the exclusion case.
|
||||
return getRestFunctionCall(accessorExpression, '{}');
|
||||
}
|
||||
|
||||
function renderRestExpression(accessorExpression, excludedProperties) {
|
||||
var excludedNames = getPropertyNames(excludedProperties);
|
||||
if (!excludedNames.length) {
|
||||
return getSimpleShallowCopy(accessorExpression);
|
||||
}
|
||||
return getRestFunctionCall(
|
||||
accessorExpression,
|
||||
'{' + excludedNames.join(':1,') + ':1}'
|
||||
);
|
||||
}
|
||||
|
||||
exports.renderRestExpression = renderRestExpression;
|
||||
126
node_modules/jstransform/visitors/es7-spread-property-visitors.js
generated
vendored
Normal file
126
node_modules/jstransform/visitors/es7-spread-property-visitors.js
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
/*global exports:true*/
|
||||
|
||||
/**
|
||||
* Implements ES7 object spread property.
|
||||
* https://gist.github.com/sebmarkbage/aa849c7973cb4452c547
|
||||
*
|
||||
* { ...a, x: 1 }
|
||||
*
|
||||
* Object.assign({}, a, {x: 1 })
|
||||
*
|
||||
*/
|
||||
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
|
||||
function visitObjectLiteralSpread(traverse, node, path, state) {
|
||||
utils.catchup(node.range[0], state);
|
||||
|
||||
utils.append('Object.assign({', state);
|
||||
|
||||
// Skip the original {
|
||||
utils.move(node.range[0] + 1, state);
|
||||
|
||||
var lastWasSpread = renderSpreadProperties(
|
||||
traverse,
|
||||
node.properties,
|
||||
path,
|
||||
state,
|
||||
false // previousWasSpread
|
||||
);
|
||||
|
||||
// Strip any non-whitespace between the last item and the end.
|
||||
// We only catch up on whitespace so that we ignore any trailing commas which
|
||||
// are stripped out for IE8 support. Unfortunately, this also strips out any
|
||||
// trailing comments.
|
||||
utils.catchupWhiteSpace(node.range[1] - 1, state);
|
||||
|
||||
// Skip the trailing }
|
||||
utils.move(node.range[1], state);
|
||||
|
||||
if (!lastWasSpread) {
|
||||
utils.append('}', state);
|
||||
}
|
||||
|
||||
utils.append(')', state);
|
||||
return false;
|
||||
}
|
||||
|
||||
// This method is also used by es6-object-computed-property-visitor.
|
||||
function renderSpreadProperties(traverse, properties, path, state, previousWasSpread) {
|
||||
|
||||
for (var i = 0; i < properties.length; i++) {
|
||||
var property = properties[i];
|
||||
if (property.type === Syntax.SpreadProperty) {
|
||||
|
||||
// Close the previous object or initial object
|
||||
if (!previousWasSpread) {
|
||||
utils.append('}', state);
|
||||
}
|
||||
|
||||
if (i === 0) {
|
||||
// Normally there will be a comma when we catch up, but not before
|
||||
// the first property.
|
||||
utils.append(',', state);
|
||||
}
|
||||
|
||||
utils.catchup(property.range[0], state);
|
||||
|
||||
// skip ...
|
||||
utils.move(property.range[0] + 3, state);
|
||||
|
||||
traverse(property.argument, path, state);
|
||||
|
||||
utils.catchup(property.range[1], state);
|
||||
|
||||
previousWasSpread = true;
|
||||
|
||||
} else {
|
||||
|
||||
utils.catchup(property.range[0], state);
|
||||
|
||||
if (previousWasSpread) {
|
||||
utils.append('{', state);
|
||||
}
|
||||
|
||||
traverse(property, path, state);
|
||||
|
||||
utils.catchup(property.range[1], state);
|
||||
|
||||
previousWasSpread = false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return previousWasSpread;
|
||||
}
|
||||
|
||||
visitObjectLiteralSpread.test = function(node, path, state) {
|
||||
if (node.type !== Syntax.ObjectExpression) {
|
||||
return false;
|
||||
}
|
||||
// Tight loop optimization
|
||||
var hasAtLeastOneSpreadProperty = false;
|
||||
for (var i = 0; i < node.properties.length; i++) {
|
||||
var property = node.properties[i];
|
||||
if (property.type === Syntax.SpreadProperty) {
|
||||
hasAtLeastOneSpreadProperty = true;
|
||||
} else if (property.kind !== 'init') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return hasAtLeastOneSpreadProperty;
|
||||
};
|
||||
|
||||
exports.renderSpreadProperties = renderSpreadProperties;
|
||||
exports.visitorList = [
|
||||
visitObjectLiteralSpread
|
||||
];
|
||||
103
node_modules/jstransform/visitors/es7-trailing-comma-visitors.js
generated
vendored
Normal file
103
node_modules/jstransform/visitors/es7-trailing-comma-visitors.js
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
|
||||
/**
|
||||
* Strips trailing commas from function calls. Transforms:
|
||||
*
|
||||
* foo('bar',)
|
||||
*
|
||||
* into:
|
||||
*
|
||||
* foo('bar')
|
||||
*/
|
||||
|
||||
function visitFunctionCallArguments(traverse, node, path, state) {
|
||||
|
||||
utils.catchup(node.callee.range[0], state);
|
||||
traverse(node.callee, [node].concat(path), state);
|
||||
|
||||
var args = node['arguments'];
|
||||
for (var index = 0; index < args.length; ++index) {
|
||||
utils.catchup(args[index].range[0], state);
|
||||
traverse(args[index], [node].concat(path), state);
|
||||
utils.catchup(args[index].range[1], state);
|
||||
}
|
||||
|
||||
// delete first comma between the last argument and the closing parenthesis
|
||||
utils.catchup(node.range[1], state, function(value) {
|
||||
return value.replace(",", '');
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
visitFunctionCallArguments.test = function(node, path, state) {
|
||||
return (
|
||||
node.type === Syntax.CallExpression ||
|
||||
node.type === Syntax.NewExpression
|
||||
) && (
|
||||
node['arguments'].length > 0
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Strips trailing commas from function expressions / function declarations /
|
||||
* method calls. Transforms:
|
||||
*
|
||||
* var fnExp = function(bar,) { ... };
|
||||
* function fnDec(bar,) { ... };
|
||||
* class Test { foo(bar, ) { ... } };
|
||||
*
|
||||
* into:
|
||||
*
|
||||
* var fnExp = function(bar) { ... };
|
||||
* function fnDec(bar) { ... };
|
||||
* class Test { foo(bar) { ... } };
|
||||
|
||||
*/
|
||||
|
||||
function visitFunctionDefinitionArguments(traverse, node, path, state) {
|
||||
var end = node.range[1];
|
||||
if (node.type === Syntax.MethodDefinition) {
|
||||
node = node.value;
|
||||
}
|
||||
for (var index = 0; index < node.params.length; ++index) {
|
||||
utils.catchup(node.params[index].range[0], state);
|
||||
traverse(node.params[index], [node].concat(path), state);
|
||||
utils.catchup(node.params[index].range[1], state);
|
||||
}
|
||||
|
||||
// delete first comma between the last argument and the closing parenthesis
|
||||
utils.catchup(node.body.range[0], state, function(value) {
|
||||
var commaIndex = value.substr(0, value.indexOf(")")).indexOf(",");
|
||||
return commaIndex > -1 ? value.replace(/,/, '') : value;
|
||||
});
|
||||
traverse(node.body, [node].concat(path), state);
|
||||
utils.catchup(end, state);
|
||||
return false;
|
||||
}
|
||||
|
||||
visitFunctionDefinitionArguments.test = function(node, path, state) {
|
||||
return (
|
||||
node.type === Syntax.FunctionExpression ||
|
||||
node.type === Syntax.FunctionDeclaration ||
|
||||
node.type === Syntax.MethodDefinition
|
||||
) && (
|
||||
node.params && node.params.length > 0 || // function expression/declaration
|
||||
node.value && node.value.params.length > 0 // method definition
|
||||
);
|
||||
};
|
||||
|
||||
exports.visitorList = [
|
||||
visitFunctionCallArguments,
|
||||
visitFunctionDefinitionArguments,
|
||||
];
|
||||
161
node_modules/jstransform/visitors/index.js
generated
vendored
Normal file
161
node_modules/jstransform/visitors/index.js
generated
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
/*global exports:true*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var es6ArrowFunction = require('./es6-arrow-function-visitors');
|
||||
var es6CallSpread = require('./es6-call-spread-visitors');
|
||||
var es6Class = require('./es6-class-visitors');
|
||||
var es6Destructuring = require('./es6-destructuring-visitors');
|
||||
var es6ForOf = require('./es6-for-of-visitors');
|
||||
var es6ObjectComputedProperty =
|
||||
require('./es6-object-computed-property-visitors');
|
||||
var es6ObjectConciseMethod = require('./es6-object-concise-method-visitors');
|
||||
var es6ObjectShortNotation = require('./es6-object-short-notation-visitors');
|
||||
var es6RestParam = require('./es6-rest-param-visitors');
|
||||
var es6Template = require('./es6-template-visitors');
|
||||
var es7SpreadProperty = require('./es7-spread-property-visitors');
|
||||
var es7TrailingComma = require('./es7-trailing-comma-visitors');
|
||||
var reactDisplayName = require('./react-display-name-visitors');
|
||||
var reactJSX = require('./react-jsx-visitors');
|
||||
var reservedWords = require('./reserved-words-visitors');
|
||||
var trailingComma = require('./trailing-comma-visitors');
|
||||
var undefinedToVoid0 = require('./undefined-to-void-0-visitors');
|
||||
|
||||
// Map from transformName => orderedListOfVisitors.
|
||||
var transformVisitors = {
|
||||
'es6-arrow-function': es6ArrowFunction.visitorList,
|
||||
'es6-call-spread': es6CallSpread.visitorList,
|
||||
'es6-class': es6Class.visitorList,
|
||||
'es6-destructuring': es6Destructuring.visitorList,
|
||||
'es6-for-of': es6ForOf.visitorList,
|
||||
'es6-object-computed-property': es6ObjectComputedProperty.visitorList,
|
||||
'es6-object-concise-method': es6ObjectConciseMethod.visitorList,
|
||||
'es6-object-short-notation': es6ObjectShortNotation.visitorList,
|
||||
'es6-rest-param': es6RestParam.visitorList,
|
||||
'es6-template': es6Template.visitorList,
|
||||
'es7-spread-property': es7SpreadProperty.visitorList,
|
||||
'es7-trailing-comma': es7TrailingComma.visitorList,
|
||||
'react-display-name': reactDisplayName.visitorList,
|
||||
'react-jsx': reactJSX.visitorList,
|
||||
'reserved-words': reservedWords.visitorList,
|
||||
'trailing-comma': trailingComma.visitorList,
|
||||
'undefined-to-void-0': undefinedToVoid0.visitorList
|
||||
};
|
||||
|
||||
|
||||
// Sets of transforms. Useful for quickly building up with simple options.
|
||||
var transformSets = {
|
||||
'es6': [
|
||||
'es6-arrow-function',
|
||||
'es6-call-spread',
|
||||
'es6-class',
|
||||
'es6-destructuring',
|
||||
'es6-for-of',
|
||||
'es6-object-computed-property',
|
||||
'es6-object-concise-method',
|
||||
'es6-object-short-notation',
|
||||
'es6-rest-param',
|
||||
'es6-template'
|
||||
],
|
||||
'es7': [
|
||||
'es7-spread-property',
|
||||
'es7-trailing-comma'
|
||||
],
|
||||
'react': [
|
||||
'react-jsx',
|
||||
'react-display-name'
|
||||
],
|
||||
'target:es3': [
|
||||
'reserved-words',
|
||||
'trailing-comma'
|
||||
],
|
||||
'utility': [
|
||||
'undefined-to-void-0'
|
||||
]
|
||||
};
|
||||
// harmony is all newer transforms. Define it here so we don't duplicate.
|
||||
transformSets.harmony = transformSets.es6.concat(transformSets.es7);
|
||||
|
||||
|
||||
// Specifies the order in which each transform should run.
|
||||
var transformRunOrder = [
|
||||
'reserved-words',
|
||||
'es6-destructuring',
|
||||
'es6-arrow-function',
|
||||
// needs to be before concice-methods, short-notation, spread-property
|
||||
'es6-object-computed-property',
|
||||
'es6-object-concise-method',
|
||||
'es6-object-short-notation',
|
||||
'es6-class',
|
||||
'es6-rest-param',
|
||||
'es6-template',
|
||||
'es6-call-spread',
|
||||
'es6-for-of',
|
||||
'es7-spread-property',
|
||||
// These are 2 distinct transforms - 'trailing-comma' handles array & object
|
||||
// literals. 'es7-trailing-comma' handles extra arguments in function calls.
|
||||
'trailing-comma',
|
||||
'es7-trailing-comma',
|
||||
'react-jsx',
|
||||
'react-display-name',
|
||||
'undefined-to-void-0'
|
||||
];
|
||||
|
||||
/**
|
||||
* Given a list of transform names, return the ordered list of visitors to be
|
||||
* passed to the transform() function.
|
||||
*
|
||||
* @param {array?} excludes
|
||||
* @return {array}
|
||||
*/
|
||||
function getAllVisitors(excludes) {
|
||||
var ret = [];
|
||||
for (var i = 0, il = transformRunOrder.length; i < il; i++) {
|
||||
if (!excludes || excludes.indexOf(transformRunOrder[i]) === -1) {
|
||||
ret = ret.concat(transformVisitors[transformRunOrder[i]]);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a list of visitor set names, return the ordered list of visitors to be
|
||||
* passed to jstransform.
|
||||
*
|
||||
* @param {array}
|
||||
* @return {array}
|
||||
*/
|
||||
function getVisitorsBySet(sets) {
|
||||
var visitorsToInclude = sets.reduce(function(visitors, set) {
|
||||
if (!transformSets.hasOwnProperty(set)) {
|
||||
throw new Error('Unknown visitor set: ' + set);
|
||||
}
|
||||
transformSets[set].forEach(function(visitor) {
|
||||
visitors[visitor] = true;
|
||||
});
|
||||
return visitors;
|
||||
}, {});
|
||||
|
||||
var visitorList = [];
|
||||
for (var i = 0; i < transformRunOrder.length; i++) {
|
||||
if (visitorsToInclude.hasOwnProperty(transformRunOrder[i])) {
|
||||
visitorList = visitorList.concat(transformVisitors[transformRunOrder[i]]);
|
||||
}
|
||||
}
|
||||
|
||||
return visitorList;
|
||||
}
|
||||
|
||||
exports.getVisitorsBySet = getVisitorsBySet;
|
||||
exports.getAllVisitors = getAllVisitors;
|
||||
exports.transformVisitors = transformVisitors;
|
||||
|
||||
138
node_modules/jstransform/visitors/jsx-helpers.js
generated
vendored
Normal file
138
node_modules/jstransform/visitors/jsx-helpers.js
generated
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
/*global exports:true*/
|
||||
'use strict';
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
|
||||
function commaAfterLastParen(value) {
|
||||
var state = 'normal';
|
||||
var commaPos = 0;
|
||||
for (var i = 0; i < value.length; ++i) {
|
||||
if (state === 'normal') {
|
||||
if (value.substr(i, 2) === '//') {
|
||||
state = 'singleline';
|
||||
i += 1;
|
||||
} else if (value.substr(i, 2) === '/*') {
|
||||
state = 'multiline';
|
||||
i += 1;
|
||||
} else if (value.charAt(i).trim() !== '') {
|
||||
commaPos = i + 1;
|
||||
}
|
||||
} else if (state === 'singleline' && value.charAt(i) === '\n') {
|
||||
state = 'normal';
|
||||
} else if (state === 'multiline' &&
|
||||
value.charAt(i) === '*' &&
|
||||
i + 1 < value.length &&
|
||||
value.charAt(i + 1) === '/') {
|
||||
i += 1;
|
||||
state = 'normal';
|
||||
}
|
||||
}
|
||||
return value.substring(0, commaPos) + ', ' + trimLeft(value.substring(commaPos));
|
||||
}
|
||||
|
||||
function renderJSXLiteral(object, isLast, state, start, end) {
|
||||
var lines = object.value.split(/\r\n|\n|\r/);
|
||||
|
||||
if (start) {
|
||||
utils.append(start, state);
|
||||
}
|
||||
|
||||
var lastNonEmptyLine = 0;
|
||||
|
||||
lines.forEach(function(line, index) {
|
||||
if (line.match(/[^ \t]/)) {
|
||||
lastNonEmptyLine = index;
|
||||
}
|
||||
});
|
||||
|
||||
lines.forEach(function(line, index) {
|
||||
var isFirstLine = index === 0;
|
||||
var isLastLine = index === lines.length - 1;
|
||||
var isLastNonEmptyLine = index === lastNonEmptyLine;
|
||||
|
||||
// replace rendered whitespace tabs with spaces
|
||||
var trimmedLine = line.replace(/\t/g, ' ');
|
||||
|
||||
// trim whitespace touching a newline
|
||||
if (!isFirstLine) {
|
||||
trimmedLine = trimmedLine.replace(/^[ ]+/, '');
|
||||
}
|
||||
if (!isLastLine) {
|
||||
trimmedLine = trimmedLine.replace(/[ ]+$/, '');
|
||||
}
|
||||
|
||||
if (!isFirstLine) {
|
||||
utils.append(line.match(/^[ \t]*/)[0], state);
|
||||
}
|
||||
|
||||
if (trimmedLine || isLastNonEmptyLine) {
|
||||
utils.append(
|
||||
JSON.stringify(trimmedLine) +
|
||||
(!isLastNonEmptyLine ? ' + " " +' : ''),
|
||||
state);
|
||||
|
||||
if (isLastNonEmptyLine) {
|
||||
if (end) {
|
||||
utils.append(end, state);
|
||||
}
|
||||
if (!isLast) {
|
||||
utils.append(', ', state);
|
||||
}
|
||||
}
|
||||
|
||||
// only restore tail whitespace if line had literals
|
||||
if (trimmedLine && !isLastLine) {
|
||||
utils.append(line.match(/[ \t]*$/)[0], state);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isLastLine) {
|
||||
utils.append('\n', state);
|
||||
}
|
||||
});
|
||||
|
||||
utils.move(object.range[1], state);
|
||||
}
|
||||
|
||||
function renderJSXExpressionContainer(traverse, object, isLast, path, state) {
|
||||
// Plus 1 to skip `{`.
|
||||
utils.move(object.range[0] + 1, state);
|
||||
utils.catchup(object.expression.range[0], state);
|
||||
traverse(object.expression, path, state);
|
||||
|
||||
if (!isLast && object.expression.type !== Syntax.JSXEmptyExpression) {
|
||||
// If we need to append a comma, make sure to do so after the expression.
|
||||
utils.catchup(object.expression.range[1], state, trimLeft);
|
||||
utils.catchup(object.range[1] - 1, state, commaAfterLastParen);
|
||||
} else {
|
||||
// Minus 1 to skip `}`.
|
||||
utils.catchup(object.range[1] - 1, state, trimLeft);
|
||||
}
|
||||
utils.move(object.range[1], state);
|
||||
return false;
|
||||
}
|
||||
|
||||
function quoteAttrName(attr) {
|
||||
// Quote invalid JS identifiers.
|
||||
if (!/^[a-z_$][a-z\d_$]*$/i.test(attr)) {
|
||||
return '"' + attr + '"';
|
||||
}
|
||||
return attr;
|
||||
}
|
||||
|
||||
function trimLeft(value) {
|
||||
return value.replace(/^[ ]+/, '');
|
||||
}
|
||||
|
||||
exports.renderJSXExpressionContainer = renderJSXExpressionContainer;
|
||||
exports.renderJSXLiteral = renderJSXLiteral;
|
||||
exports.quoteAttrName = quoteAttrName;
|
||||
exports.trimLeft = trimLeft;
|
||||
126
node_modules/jstransform/visitors/react-display-name-visitors.js
generated
vendored
Normal file
126
node_modules/jstransform/visitors/react-display-name-visitors.js
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
/*global exports:true*/
|
||||
'use strict';
|
||||
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
|
||||
function shouldAddDisplayName(object) {
|
||||
if (object &&
|
||||
object.type === Syntax.CallExpression &&
|
||||
object.callee.type === Syntax.MemberExpression &&
|
||||
object.callee.object.type === Syntax.Identifier &&
|
||||
object.callee.object.name === 'React' &&
|
||||
object.callee.property.type === Syntax.Identifier &&
|
||||
object.callee.property.name === 'createClass' &&
|
||||
object.arguments.length === 1 &&
|
||||
object.arguments[0].type === Syntax.ObjectExpression) {
|
||||
// Verify that the displayName property isn't already set
|
||||
var properties = object.arguments[0].properties;
|
||||
var safe = properties.every(function(property) {
|
||||
var value = property.key.type === Syntax.Identifier ?
|
||||
property.key.name :
|
||||
property.key.value;
|
||||
return value !== 'displayName';
|
||||
});
|
||||
return safe;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If `expr` is an Identifier or MemberExpression node made of identifiers and
|
||||
* dot accesses, return a list of the identifier parts. Other nodes return null.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* MyComponent -> ['MyComponent']
|
||||
* namespace.MyComponent -> ['namespace', 'MyComponent']
|
||||
* namespace['foo'] -> null
|
||||
* namespace['foo'].bar -> ['bar']
|
||||
*/
|
||||
function flattenIdentifierOrMemberExpression(expr) {
|
||||
if (expr.type === Syntax.Identifier) {
|
||||
return [expr.name];
|
||||
} else if (expr.type === Syntax.MemberExpression) {
|
||||
if (!expr.computed && expr.property.type === Syntax.Identifier) {
|
||||
var flattenedObject = flattenIdentifierOrMemberExpression(expr.object);
|
||||
if (flattenedObject) {
|
||||
flattenedObject.push(expr.property.name);
|
||||
return flattenedObject;
|
||||
} else {
|
||||
return [expr.property.name];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the following:
|
||||
*
|
||||
* var MyComponent = React.createClass({
|
||||
* render: ...
|
||||
* });
|
||||
*
|
||||
* into:
|
||||
*
|
||||
* var MyComponent = React.createClass({
|
||||
* displayName: 'MyComponent',
|
||||
* render: ...
|
||||
* });
|
||||
*
|
||||
* Also catches:
|
||||
*
|
||||
* MyComponent = React.createClass(...);
|
||||
* namespace.MyComponent = React.createClass(...);
|
||||
* exports.MyComponent = React.createClass(...);
|
||||
* module.exports = {MyComponent: React.createClass(...)};
|
||||
*/
|
||||
function visitReactDisplayName(traverse, object, path, state) {
|
||||
var left, right;
|
||||
|
||||
if (object.type === Syntax.AssignmentExpression) {
|
||||
left = object.left;
|
||||
right = object.right;
|
||||
} else if (object.type === Syntax.Property) {
|
||||
left = object.key;
|
||||
right = object.value;
|
||||
} else if (object.type === Syntax.VariableDeclarator) {
|
||||
left = object.id;
|
||||
right = object.init;
|
||||
}
|
||||
|
||||
if (right && shouldAddDisplayName(right)) {
|
||||
var displayNamePath = flattenIdentifierOrMemberExpression(left);
|
||||
if (displayNamePath) {
|
||||
if (displayNamePath.length > 1 && displayNamePath[0] === 'exports') {
|
||||
displayNamePath.shift();
|
||||
}
|
||||
|
||||
var displayName = displayNamePath.join('.');
|
||||
|
||||
utils.catchup(right.arguments[0].range[0] + 1, state);
|
||||
utils.append('displayName: "' + displayName + '",', state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visitReactDisplayName.test = function(object, path, state) {
|
||||
return (
|
||||
object.type === Syntax.AssignmentExpression ||
|
||||
object.type === Syntax.Property ||
|
||||
object.type === Syntax.VariableDeclarator
|
||||
);
|
||||
};
|
||||
|
||||
exports.visitorList = [
|
||||
visitReactDisplayName
|
||||
];
|
||||
242
node_modules/jstransform/visitors/react-jsx-visitors.js
generated
vendored
Normal file
242
node_modules/jstransform/visitors/react-jsx-visitors.js
generated
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
/*global exports:true*/
|
||||
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
|
||||
var jsxHelpers = require('./jsx-helpers');
|
||||
|
||||
var renderJSXExpressionContainer = jsxHelpers.renderJSXExpressionContainer;
|
||||
var renderJSXLiteral = jsxHelpers.renderJSXLiteral;
|
||||
var quoteAttrName = jsxHelpers.quoteAttrName;
|
||||
var trimLeft = jsxHelpers.trimLeft;
|
||||
|
||||
/**
|
||||
* Customized desugar processor for React JSX. Currently:
|
||||
*
|
||||
* <X> </X> => React.createElement(X, null)
|
||||
* <X prop="1" /> => React.createElement(X, {prop: '1'}, null)
|
||||
* <X prop="2"><Y /></X> => React.createElement(X, {prop:'2'},
|
||||
* React.createElement(Y, null)
|
||||
* )
|
||||
* <div /> => React.createElement("div", null)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Removes all non-whitespace/parenthesis characters
|
||||
*/
|
||||
var reNonWhiteParen = /([^\s\(\)])/g;
|
||||
function stripNonWhiteParen(value) {
|
||||
return value.replace(reNonWhiteParen, '');
|
||||
}
|
||||
|
||||
var tagConvention = /^[a-z]|\-/;
|
||||
function isTagName(name) {
|
||||
return tagConvention.test(name);
|
||||
}
|
||||
|
||||
function visitReactTag(traverse, object, path, state) {
|
||||
var openingElement = object.openingElement;
|
||||
var nameObject = openingElement.name;
|
||||
var attributesObject = openingElement.attributes;
|
||||
|
||||
utils.catchup(openingElement.range[0], state, trimLeft);
|
||||
|
||||
if (nameObject.type === Syntax.JSXNamespacedName && nameObject.namespace) {
|
||||
throw new Error('Namespace tags are not supported. ReactJSX is not XML.');
|
||||
}
|
||||
|
||||
// We assume that the React runtime is already in scope
|
||||
utils.append('React.createElement(', state);
|
||||
|
||||
if (nameObject.type === Syntax.JSXIdentifier && isTagName(nameObject.name)) {
|
||||
utils.append('"' + nameObject.name + '"', state);
|
||||
utils.move(nameObject.range[1], state);
|
||||
} else {
|
||||
// Use utils.catchup in this case so we can easily handle
|
||||
// JSXMemberExpressions which look like Foo.Bar.Baz. This also handles
|
||||
// JSXIdentifiers that aren't fallback tags.
|
||||
utils.move(nameObject.range[0], state);
|
||||
utils.catchup(nameObject.range[1], state);
|
||||
}
|
||||
|
||||
utils.append(', ', state);
|
||||
|
||||
var hasAttributes = attributesObject.length;
|
||||
|
||||
var hasAtLeastOneSpreadProperty = attributesObject.some(function(attr) {
|
||||
return attr.type === Syntax.JSXSpreadAttribute;
|
||||
});
|
||||
|
||||
// if we don't have any attributes, pass in null
|
||||
if (hasAtLeastOneSpreadProperty) {
|
||||
utils.append('React.__spread({', state);
|
||||
} else if (hasAttributes) {
|
||||
utils.append('{', state);
|
||||
} else {
|
||||
utils.append('null', state);
|
||||
}
|
||||
|
||||
// keep track of if the previous attribute was a spread attribute
|
||||
var previousWasSpread = false;
|
||||
|
||||
// write attributes
|
||||
attributesObject.forEach(function(attr, index) {
|
||||
var isLast = index === attributesObject.length - 1;
|
||||
|
||||
if (attr.type === Syntax.JSXSpreadAttribute) {
|
||||
// Close the previous object or initial object
|
||||
if (!previousWasSpread) {
|
||||
utils.append('}, ', state);
|
||||
}
|
||||
|
||||
// Move to the expression start, ignoring everything except parenthesis
|
||||
// and whitespace.
|
||||
utils.catchup(attr.range[0], state, stripNonWhiteParen);
|
||||
// Plus 1 to skip `{`.
|
||||
utils.move(attr.range[0] + 1, state);
|
||||
utils.catchup(attr.argument.range[0], state, stripNonWhiteParen);
|
||||
|
||||
traverse(attr.argument, path, state);
|
||||
|
||||
utils.catchup(attr.argument.range[1], state);
|
||||
|
||||
// Move to the end, ignoring parenthesis and the closing `}`
|
||||
utils.catchup(attr.range[1] - 1, state, stripNonWhiteParen);
|
||||
|
||||
if (!isLast) {
|
||||
utils.append(', ', state);
|
||||
}
|
||||
|
||||
utils.move(attr.range[1], state);
|
||||
|
||||
previousWasSpread = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If the next attribute is a spread, we're effective last in this object
|
||||
if (!isLast) {
|
||||
isLast = attributesObject[index + 1].type === Syntax.JSXSpreadAttribute;
|
||||
}
|
||||
|
||||
if (attr.name.namespace) {
|
||||
throw new Error(
|
||||
'Namespace attributes are not supported. ReactJSX is not XML.');
|
||||
}
|
||||
var name = attr.name.name;
|
||||
|
||||
utils.catchup(attr.range[0], state, trimLeft);
|
||||
|
||||
if (previousWasSpread) {
|
||||
utils.append('{', state);
|
||||
}
|
||||
|
||||
utils.append(quoteAttrName(name), state);
|
||||
utils.append(': ', state);
|
||||
|
||||
if (!attr.value) {
|
||||
state.g.buffer += 'true';
|
||||
state.g.position = attr.name.range[1];
|
||||
if (!isLast) {
|
||||
utils.append(', ', state);
|
||||
}
|
||||
} else {
|
||||
utils.move(attr.name.range[1], state);
|
||||
// Use catchupNewlines to skip over the '=' in the attribute
|
||||
utils.catchupNewlines(attr.value.range[0], state);
|
||||
if (attr.value.type === Syntax.Literal) {
|
||||
renderJSXLiteral(attr.value, isLast, state);
|
||||
} else {
|
||||
renderJSXExpressionContainer(traverse, attr.value, isLast, path, state);
|
||||
}
|
||||
}
|
||||
|
||||
utils.catchup(attr.range[1], state, trimLeft);
|
||||
|
||||
previousWasSpread = false;
|
||||
});
|
||||
|
||||
if (!openingElement.selfClosing) {
|
||||
utils.catchup(openingElement.range[1] - 1, state, trimLeft);
|
||||
utils.move(openingElement.range[1], state);
|
||||
}
|
||||
|
||||
if (hasAttributes && !previousWasSpread) {
|
||||
utils.append('}', state);
|
||||
}
|
||||
|
||||
if (hasAtLeastOneSpreadProperty) {
|
||||
utils.append(')', state);
|
||||
}
|
||||
|
||||
// filter out whitespace
|
||||
var childrenToRender = object.children.filter(function(child) {
|
||||
return !(child.type === Syntax.Literal
|
||||
&& typeof child.value === 'string'
|
||||
&& child.value.match(/^[ \t]*[\r\n][ \t\r\n]*$/));
|
||||
});
|
||||
if (childrenToRender.length > 0) {
|
||||
var lastRenderableIndex;
|
||||
|
||||
childrenToRender.forEach(function(child, index) {
|
||||
if (child.type !== Syntax.JSXExpressionContainer ||
|
||||
child.expression.type !== Syntax.JSXEmptyExpression) {
|
||||
lastRenderableIndex = index;
|
||||
}
|
||||
});
|
||||
|
||||
if (lastRenderableIndex !== undefined) {
|
||||
utils.append(', ', state);
|
||||
}
|
||||
|
||||
childrenToRender.forEach(function(child, index) {
|
||||
utils.catchup(child.range[0], state, trimLeft);
|
||||
|
||||
var isLast = index >= lastRenderableIndex;
|
||||
|
||||
if (child.type === Syntax.Literal) {
|
||||
renderJSXLiteral(child, isLast, state);
|
||||
} else if (child.type === Syntax.JSXExpressionContainer) {
|
||||
renderJSXExpressionContainer(traverse, child, isLast, path, state);
|
||||
} else {
|
||||
traverse(child, path, state);
|
||||
if (!isLast) {
|
||||
utils.append(', ', state);
|
||||
}
|
||||
}
|
||||
|
||||
utils.catchup(child.range[1], state, trimLeft);
|
||||
});
|
||||
}
|
||||
|
||||
if (openingElement.selfClosing) {
|
||||
// everything up to />
|
||||
utils.catchup(openingElement.range[1] - 2, state, trimLeft);
|
||||
utils.move(openingElement.range[1], state);
|
||||
} else {
|
||||
// everything up to </ sdflksjfd>
|
||||
utils.catchup(object.closingElement.range[0], state, trimLeft);
|
||||
utils.move(object.closingElement.range[1], state);
|
||||
}
|
||||
|
||||
utils.append(')', state);
|
||||
return false;
|
||||
}
|
||||
|
||||
visitReactTag.test = function(object, path, state) {
|
||||
return object.type === Syntax.JSXElement;
|
||||
};
|
||||
|
||||
exports.visitorList = [
|
||||
visitReactTag
|
||||
];
|
||||
67
node_modules/jstransform/visitors/reserved-words-helper.js
generated
vendored
Normal file
67
node_modules/jstransform/visitors/reserved-words-helper.js
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
var KEYWORDS = [
|
||||
'break', 'do', 'in', 'typeof', 'case', 'else', 'instanceof', 'var', 'catch',
|
||||
'export', 'new', 'void', 'class', 'extends', 'return', 'while', 'const',
|
||||
'finally', 'super', 'with', 'continue', 'for', 'switch', 'yield', 'debugger',
|
||||
'function', 'this', 'default', 'if', 'throw', 'delete', 'import', 'try'
|
||||
];
|
||||
|
||||
var FUTURE_RESERVED_WORDS = [
|
||||
'enum', 'await', 'implements', 'package', 'protected', 'static', 'interface',
|
||||
'private', 'public'
|
||||
];
|
||||
|
||||
var LITERALS = [
|
||||
'null',
|
||||
'true',
|
||||
'false'
|
||||
];
|
||||
|
||||
// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-reserved-words
|
||||
var RESERVED_WORDS = [].concat(
|
||||
KEYWORDS,
|
||||
FUTURE_RESERVED_WORDS,
|
||||
LITERALS
|
||||
);
|
||||
|
||||
var reservedWordsMap = Object.create(null);
|
||||
RESERVED_WORDS.forEach(function(k) {
|
||||
reservedWordsMap[k] = true;
|
||||
});
|
||||
|
||||
/**
|
||||
* This list should not grow as new reserved words are introdued. This list is
|
||||
* of words that need to be quoted because ES3-ish browsers do not allow their
|
||||
* use as identifier names.
|
||||
*/
|
||||
var ES3_FUTURE_RESERVED_WORDS = [
|
||||
'enum', 'implements', 'package', 'protected', 'static', 'interface',
|
||||
'private', 'public'
|
||||
];
|
||||
|
||||
var ES3_RESERVED_WORDS = [].concat(
|
||||
KEYWORDS,
|
||||
ES3_FUTURE_RESERVED_WORDS,
|
||||
LITERALS
|
||||
);
|
||||
|
||||
var es3ReservedWordsMap = Object.create(null);
|
||||
ES3_RESERVED_WORDS.forEach(function(k) {
|
||||
es3ReservedWordsMap[k] = true;
|
||||
});
|
||||
|
||||
exports.isReservedWord = function(word) {
|
||||
return !!reservedWordsMap[word];
|
||||
};
|
||||
|
||||
exports.isES3ReservedWord = function(word) {
|
||||
return !!es3ReservedWordsMap[word];
|
||||
};
|
||||
67
node_modules/jstransform/visitors/reserved-words-visitors.js
generated
vendored
Normal file
67
node_modules/jstransform/visitors/reserved-words-visitors.js
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
/*global exports:true*/
|
||||
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
var reserverdWordsHelper = require('./reserved-words-helper');
|
||||
|
||||
/**
|
||||
* Code adapted from https://github.com/spicyj/es3ify
|
||||
* The MIT License (MIT)
|
||||
* Copyright (c) 2014 Ben Alpert
|
||||
*/
|
||||
|
||||
function visitProperty(traverse, node, path, state) {
|
||||
utils.catchup(node.key.range[0], state);
|
||||
utils.append('"', state);
|
||||
utils.catchup(node.key.range[1], state);
|
||||
utils.append('"', state);
|
||||
utils.catchup(node.value.range[0], state);
|
||||
traverse(node.value, path, state);
|
||||
return false;
|
||||
}
|
||||
|
||||
visitProperty.test = function(node) {
|
||||
return node.type === Syntax.Property &&
|
||||
node.key.type === Syntax.Identifier &&
|
||||
!node.method &&
|
||||
!node.shorthand &&
|
||||
!node.computed &&
|
||||
reserverdWordsHelper.isES3ReservedWord(node.key.name);
|
||||
};
|
||||
|
||||
function visitMemberExpression(traverse, node, path, state) {
|
||||
traverse(node.object, path, state);
|
||||
// Member expression range does not include parenthesis, so simply specifying
|
||||
// node.object.range[1] as the start position doesn't work. Neither does
|
||||
// node.property.range[0] - 1 as that won't catch expressions that span
|
||||
// newlines (period on previous line). So instead we'll catchup and remove
|
||||
// any periods.
|
||||
utils.catchup(node.property.range[0], state, function(s) {
|
||||
return s.replace('.', '');
|
||||
});
|
||||
utils.append('[', state);
|
||||
utils.catchupWhiteSpace(node.property.range[0], state);
|
||||
utils.append('"', state);
|
||||
utils.catchup(node.property.range[1], state);
|
||||
utils.append('"]', state);
|
||||
return false;
|
||||
}
|
||||
|
||||
visitMemberExpression.test = function(node) {
|
||||
return node.type === Syntax.MemberExpression &&
|
||||
node.property.type === Syntax.Identifier &&
|
||||
reserverdWordsHelper.isES3ReservedWord(node.property.name);
|
||||
};
|
||||
|
||||
exports.visitorList = [
|
||||
visitProperty,
|
||||
visitMemberExpression
|
||||
];
|
||||
74
node_modules/jstransform/visitors/trailing-comma-visitors.js
generated
vendored
Normal file
74
node_modules/jstransform/visitors/trailing-comma-visitors.js
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
|
||||
/**
|
||||
* Strips trailing commas from array and object expressions. Transforms:
|
||||
*
|
||||
* var arr = [
|
||||
* foo,
|
||||
* bar,
|
||||
* ];
|
||||
*
|
||||
* var obj = {
|
||||
* foo: 1,
|
||||
* bar: 2,
|
||||
* };
|
||||
*
|
||||
* into:
|
||||
*
|
||||
* var arr = [
|
||||
* foo,
|
||||
* bar
|
||||
* ];
|
||||
*
|
||||
* var obj = {
|
||||
* foo: 1,
|
||||
* bar: 2
|
||||
* };
|
||||
*
|
||||
*/
|
||||
function visitArrayOrObjectExpression(traverse, node, path, state) {
|
||||
var items = node.elements || node.properties;
|
||||
var lastItem = items[items.length - 1];
|
||||
|
||||
// Transform items if needed.
|
||||
path.unshift(node);
|
||||
traverse(items, path, state);
|
||||
path.shift();
|
||||
|
||||
// Catch up to the end of the last item.
|
||||
utils.catchup(lastItem.range[1], state);
|
||||
|
||||
// Strip any non-whitespace between the last item and the end.
|
||||
utils.catchup(node.range[1] - 1, state, function(value) {
|
||||
return value.replace(/,/g, '');
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
visitArrayOrObjectExpression.test = function(node, path, state) {
|
||||
return (node.type === Syntax.ArrayExpression ||
|
||||
node.type === Syntax.ObjectExpression) &&
|
||||
(node.elements || node.properties).length > 0 &&
|
||||
// We don't want to run the transform on arrays with trailing holes, since
|
||||
// it would change semantics.
|
||||
!hasTrailingHole(node);
|
||||
};
|
||||
|
||||
function hasTrailingHole(node) {
|
||||
return node.elements && node.elements.length > 0 &&
|
||||
node.elements[node.elements.length - 1] === null;
|
||||
}
|
||||
|
||||
exports.visitorList = [
|
||||
visitArrayOrObjectExpression
|
||||
];
|
||||
190
node_modules/jstransform/visitors/type-syntax.js
generated
vendored
Normal file
190
node_modules/jstransform/visitors/type-syntax.js
generated
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
var esprima = require('esprima-fb');
|
||||
var utils = require('../src/utils');
|
||||
|
||||
var Syntax = esprima.Syntax;
|
||||
|
||||
function _isFunctionNode(node) {
|
||||
return node.type === Syntax.FunctionDeclaration
|
||||
|| node.type === Syntax.FunctionExpression
|
||||
|| node.type === Syntax.ArrowFunctionExpression;
|
||||
}
|
||||
|
||||
function visitClassProperty(traverse, node, path, state) {
|
||||
utils.catchup(node.range[0], state);
|
||||
utils.catchupWhiteOut(node.range[1], state);
|
||||
return false;
|
||||
}
|
||||
visitClassProperty.test = function(node, path, state) {
|
||||
return node.type === Syntax.ClassProperty;
|
||||
};
|
||||
|
||||
function visitTypeAlias(traverse, node, path, state) {
|
||||
utils.catchupWhiteOut(node.range[1], state);
|
||||
return false;
|
||||
}
|
||||
visitTypeAlias.test = function(node, path, state) {
|
||||
return node.type === Syntax.TypeAlias;
|
||||
};
|
||||
|
||||
function visitTypeCast(traverse, node, path, state) {
|
||||
path.unshift(node);
|
||||
traverse(node.expression, path, state);
|
||||
path.shift();
|
||||
|
||||
utils.catchup(node.typeAnnotation.range[0], state);
|
||||
utils.catchupWhiteOut(node.typeAnnotation.range[1], state);
|
||||
return false;
|
||||
}
|
||||
visitTypeCast.test = function(node, path, state) {
|
||||
return node.type === Syntax.TypeCastExpression;
|
||||
};
|
||||
|
||||
function visitInterfaceDeclaration(traverse, node, path, state) {
|
||||
utils.catchupWhiteOut(node.range[1], state);
|
||||
return false;
|
||||
}
|
||||
visitInterfaceDeclaration.test = function(node, path, state) {
|
||||
return node.type === Syntax.InterfaceDeclaration;
|
||||
};
|
||||
|
||||
function visitDeclare(traverse, node, path, state) {
|
||||
utils.catchupWhiteOut(node.range[1], state);
|
||||
return false;
|
||||
}
|
||||
visitDeclare.test = function(node, path, state) {
|
||||
switch (node.type) {
|
||||
case Syntax.DeclareVariable:
|
||||
case Syntax.DeclareFunction:
|
||||
case Syntax.DeclareClass:
|
||||
case Syntax.DeclareModule:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
function visitFunctionParametricAnnotation(traverse, node, path, state) {
|
||||
utils.catchup(node.range[0], state);
|
||||
utils.catchupWhiteOut(node.range[1], state);
|
||||
return false;
|
||||
}
|
||||
visitFunctionParametricAnnotation.test = function(node, path, state) {
|
||||
return node.type === Syntax.TypeParameterDeclaration
|
||||
&& path[0]
|
||||
&& _isFunctionNode(path[0])
|
||||
&& node === path[0].typeParameters;
|
||||
};
|
||||
|
||||
function visitFunctionReturnAnnotation(traverse, node, path, state) {
|
||||
utils.catchup(node.range[0], state);
|
||||
utils.catchupWhiteOut(node.range[1], state);
|
||||
return false;
|
||||
}
|
||||
visitFunctionReturnAnnotation.test = function(node, path, state) {
|
||||
return path[0] && _isFunctionNode(path[0]) && node === path[0].returnType;
|
||||
};
|
||||
|
||||
function visitOptionalFunctionParameterAnnotation(traverse, node, path, state) {
|
||||
utils.catchup(node.range[0] + node.name.length, state);
|
||||
utils.catchupWhiteOut(node.range[1], state);
|
||||
return false;
|
||||
}
|
||||
visitOptionalFunctionParameterAnnotation.test = function(node, path, state) {
|
||||
return node.type === Syntax.Identifier
|
||||
&& node.optional
|
||||
&& path[0]
|
||||
&& _isFunctionNode(path[0]);
|
||||
};
|
||||
|
||||
function visitTypeAnnotatedIdentifier(traverse, node, path, state) {
|
||||
utils.catchup(node.typeAnnotation.range[0], state);
|
||||
utils.catchupWhiteOut(node.typeAnnotation.range[1], state);
|
||||
return false;
|
||||
}
|
||||
visitTypeAnnotatedIdentifier.test = function(node, path, state) {
|
||||
return node.type === Syntax.Identifier && node.typeAnnotation;
|
||||
};
|
||||
|
||||
function visitTypeAnnotatedObjectOrArrayPattern(traverse, node, path, state) {
|
||||
utils.catchup(node.typeAnnotation.range[0], state);
|
||||
utils.catchupWhiteOut(node.typeAnnotation.range[1], state);
|
||||
return false;
|
||||
}
|
||||
visitTypeAnnotatedObjectOrArrayPattern.test = function(node, path, state) {
|
||||
var rightType = node.type === Syntax.ObjectPattern
|
||||
|| node.type === Syntax.ArrayPattern;
|
||||
return rightType && node.typeAnnotation;
|
||||
};
|
||||
|
||||
/**
|
||||
* Methods cause trouble, since esprima parses them as a key/value pair, where
|
||||
* the location of the value starts at the method body. For example
|
||||
* { bar(x:number,...y:Array<number>):number {} }
|
||||
* is parsed as
|
||||
* { bar: function(x: number, ...y:Array<number>): number {} }
|
||||
* except that the location of the FunctionExpression value is 40-something,
|
||||
* which is the location of the function body. This means that by the time we
|
||||
* visit the params, rest param, and return type organically, we've already
|
||||
* catchup()'d passed them.
|
||||
*/
|
||||
function visitMethod(traverse, node, path, state) {
|
||||
path.unshift(node);
|
||||
traverse(node.key, path, state);
|
||||
|
||||
path.unshift(node.value);
|
||||
traverse(node.value.params, path, state);
|
||||
node.value.rest && traverse(node.value.rest, path, state);
|
||||
node.value.returnType && traverse(node.value.returnType, path, state);
|
||||
traverse(node.value.body, path, state);
|
||||
|
||||
path.shift();
|
||||
|
||||
path.shift();
|
||||
return false;
|
||||
}
|
||||
|
||||
visitMethod.test = function(node, path, state) {
|
||||
return (node.type === "Property" && (node.method || node.kind === "set" || node.kind === "get"))
|
||||
|| (node.type === "MethodDefinition");
|
||||
};
|
||||
|
||||
function visitImportType(traverse, node, path, state) {
|
||||
utils.catchupWhiteOut(node.range[1], state);
|
||||
return false;
|
||||
}
|
||||
visitImportType.test = function(node, path, state) {
|
||||
return node.type === 'ImportDeclaration'
|
||||
&& (node.importKind === 'type' || node.importKind === 'typeof');
|
||||
};
|
||||
|
||||
function visitExportType(traverse, node, path, state) {
|
||||
utils.catchupWhiteOut(node.range[1], state);
|
||||
}
|
||||
visitExportType.test = function(node, path, state) {
|
||||
return node.type === 'ExportDeclaration'
|
||||
&& node.declaration.type === 'TypeAlias';
|
||||
};
|
||||
|
||||
exports.visitorList = [
|
||||
visitClassProperty,
|
||||
visitDeclare,
|
||||
visitExportType,
|
||||
visitImportType,
|
||||
visitInterfaceDeclaration,
|
||||
visitFunctionParametricAnnotation,
|
||||
visitFunctionReturnAnnotation,
|
||||
visitMethod,
|
||||
visitOptionalFunctionParameterAnnotation,
|
||||
visitTypeAlias,
|
||||
visitTypeCast,
|
||||
visitTypeAnnotatedIdentifier,
|
||||
visitTypeAnnotatedObjectOrArrayPattern
|
||||
];
|
||||
141
node_modules/jstransform/visitors/undefined-to-void-0-visitors.js
generated
vendored
Normal file
141
node_modules/jstransform/visitors/undefined-to-void-0-visitors.js
generated
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* Copyright 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
var Syntax = require('esprima-fb').Syntax;
|
||||
var utils = require('../src/utils');
|
||||
|
||||
/**
|
||||
* Replaces `undefined` with `(void 0)` when it appears as an rvalue and is
|
||||
* undeclared in the lexical scope.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* (function() {
|
||||
* foo.undefined = bar;
|
||||
* ({undefined: foo});
|
||||
*
|
||||
* var bar = undefined;
|
||||
* bar = undefined;
|
||||
* foo.bar = undefined;
|
||||
* undefined.foo = bar;
|
||||
* foo[undefined] = bar;
|
||||
* ({foo: undefined});
|
||||
* })(undefined);
|
||||
*
|
||||
* (function(undefined) { // declared here
|
||||
* return undefined;
|
||||
* })(1);
|
||||
*
|
||||
* (function() {
|
||||
* var undefined; // declared here
|
||||
* undefined = 1; // assignment to declared variable
|
||||
* return undefined;
|
||||
* })();
|
||||
*
|
||||
* (function(undefined) { // declared here
|
||||
* return (function() {
|
||||
* return undefined; // respects lexical scope
|
||||
* })();
|
||||
* })();
|
||||
*
|
||||
* Becomes:
|
||||
*
|
||||
* (function() {
|
||||
* foo.undefined = bar;
|
||||
* ({undefined: foo});
|
||||
*
|
||||
* var bar = (void 0);
|
||||
* bar = (void 0);
|
||||
* foo.bar = (void 0);
|
||||
* (void 0).foo = bar;
|
||||
* foo[(void 0)] = bar;
|
||||
* ({foo: (void 0)});
|
||||
* })((void 0));
|
||||
*
|
||||
* (function(undefined) { // declared here
|
||||
* return undefined;
|
||||
* })(1);
|
||||
*
|
||||
* (function() {
|
||||
* var undefined; // declared here
|
||||
* undefined = 1; // assignment to declared variable
|
||||
* return undefined;
|
||||
* })();
|
||||
*
|
||||
* (function(undefined) { // declared here
|
||||
* return (function() {
|
||||
* return undefined; // respects lexical scope
|
||||
* })();
|
||||
* })();
|
||||
*
|
||||
*
|
||||
*
|
||||
* NOTE: Any assignment to `undefined` where `undefined` is not declared in the
|
||||
* lexical scope will result in an exception.
|
||||
*/
|
||||
|
||||
function visitIdentifierUndefined(traverse, node, path, state) {
|
||||
utils.catchup(node.range[1], state, function(value) {
|
||||
return '(void 0)';
|
||||
});
|
||||
}
|
||||
|
||||
visitIdentifierUndefined.test = function(node, path, state) {
|
||||
if (
|
||||
node.type === Syntax.Identifier
|
||||
&& node.name === 'undefined'
|
||||
&& !utils.identWithinLexicalScope('undefined', state)
|
||||
) {
|
||||
if (path[0]) {
|
||||
switch (path[0].type) {
|
||||
case Syntax.FunctionDeclaration:
|
||||
case Syntax.FunctionExpression:
|
||||
case Syntax.ArrowFunctionExpression:
|
||||
// skips: function params
|
||||
if (node !== path[0].body) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case Syntax.AssignmentExpression:
|
||||
// throws for: `undefined = foo` (where `undefined` is not declared)
|
||||
if (node === path[0].left) {
|
||||
throw new Error(
|
||||
'Illegal assignment to `undefined`. '
|
||||
+ 'This breaks assumptions of the transform.'
|
||||
);
|
||||
}
|
||||
break;
|
||||
case Syntax.MemberExpression:
|
||||
// skips: `foo.undefined` but not `foo[undefined]`
|
||||
if (node === path[0].property && !path[0].computed) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case Syntax.VariableDeclarator:
|
||||
// skips: `var undefined`
|
||||
if (node !== path[0].init) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case Syntax.Property:
|
||||
// skips: `undefined: foo`
|
||||
if (node === path[0].key) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
exports.visitorList = [
|
||||
visitIdentifierUndefined
|
||||
];
|
||||
Reference in New Issue
Block a user