Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f01e5c3af | ||
|
|
6847211971 | ||
|
|
965e246259 | ||
|
|
af59eb7d6a | ||
|
|
def4319058 | ||
|
|
d90383b1ba | ||
|
|
1ac40ee834 | ||
|
|
3d5d170eff | ||
|
|
b5bdba46f1 | ||
|
|
c4e162b8e5 | ||
|
|
98bc750b05 | ||
|
|
84002ed1ce | ||
|
|
aaab2db0ec |
10
Makefile
10
Makefile
@@ -6,7 +6,7 @@ MOCHA_CMD = node_modules/mocha/bin/_mocha
|
||||
|
||||
export NODE_ENV = test
|
||||
|
||||
.PHONY: clean test test-cov tlint est-travis test-appveyor test-browser publish bench build
|
||||
.PHONY: clean test test-cov test-clean lint test-travis test-spec test-browser publish bench build
|
||||
|
||||
clean:
|
||||
rm -rf coverage templates.json test/tmp dist
|
||||
@@ -18,19 +18,23 @@ bench:
|
||||
lint:
|
||||
$(JSHINT_CMD) lib bin benchmark/index.js
|
||||
|
||||
test-clean:
|
||||
rm -rf test/tmp
|
||||
|
||||
test:
|
||||
make lint
|
||||
$(MOCHA_CMD)
|
||||
make test-clean
|
||||
|
||||
test-cov:
|
||||
rm -rf coverage
|
||||
node $(ISTANBUL_CMD) $(MOCHA_CMD) --
|
||||
|
||||
test-appveyor:
|
||||
test-spec:
|
||||
node $(ISTANBUL_CMD) $(MOCHA_CMD) -- --reporter spec
|
||||
|
||||
test-travis:
|
||||
make test-appveyor
|
||||
make test-spec
|
||||
if test -n "$$CODECLIMATE_REPO_TOKEN"; then codeclimate < coverage/lcov.info; fi
|
||||
|
||||
test-browser:
|
||||
|
||||
12
README.md
12
README.md
@@ -49,6 +49,7 @@ It's as easy as:
|
||||
- [Caveats](#caveats)
|
||||
- [Polyfill](#polyfill)
|
||||
- [Optional runtime](#optional-runtime)
|
||||
- [React/JSX](#reactjsx)
|
||||
- [Differences](#differences)
|
||||
|
||||
## [Features](FEATURES.md)
|
||||
@@ -84,7 +85,10 @@ It's as easy as:
|
||||
- [Gulp](https://github.com/sindresorhus/gulp-6to5)
|
||||
- [Grunt](https://github.com/sindresorhus/grunt-6to5)
|
||||
- [Jade](https://github.com/Apoxx/jade-6to5)
|
||||
- [Jest](https://github.com/6to5/6to5-jest)
|
||||
- [Karma](https://github.com/shuhei/karma-6to5-preprocessor)
|
||||
- [Mocha](https://github.com/6to5/6to5-mocha)
|
||||
- [Rails](https://github.com/6to5/6to5-rails)
|
||||
- [webpack](https://github.com/Couto/6to5-loader)
|
||||
|
||||
### CLI
|
||||
@@ -401,6 +405,14 @@ require("6to5").runtime("myCustomNamespace");
|
||||
See [Options - runtime](#options) for documentation on changing the reference in
|
||||
generated code.
|
||||
|
||||
## React/JSX
|
||||
|
||||
6to5 has built-in support for React v0.12. Tags are automatically transformed to
|
||||
their equivalent `React.createElement(...)` and `displayName` is automatically
|
||||
inferred and added to all `React.createClass` calls.
|
||||
|
||||
To disable this behaviour add `react` to your blacklist.
|
||||
|
||||
## Differences
|
||||
|
||||
### Philosophy
|
||||
|
||||
@@ -10,7 +10,7 @@ install:
|
||||
test_script:
|
||||
- "node --version"
|
||||
- "npm --version"
|
||||
- "make test-appveyor"
|
||||
- "make test-spec"
|
||||
|
||||
build: "off"
|
||||
|
||||
|
||||
123
lib/6to5/generation/buffer.js
Normal file
123
lib/6to5/generation/buffer.js
Normal file
@@ -0,0 +1,123 @@
|
||||
module.exports = Buffer;
|
||||
|
||||
var util = require("../util");
|
||||
var _ = require("lodash");
|
||||
|
||||
function Buffer(position, format) {
|
||||
this.position = position;
|
||||
this._indent = format.indent.base;
|
||||
this.format = format;
|
||||
this.buf = "";
|
||||
}
|
||||
|
||||
Buffer.prototype.get = function () {
|
||||
return this.buf.trimRight();
|
||||
};
|
||||
|
||||
Buffer.prototype.getIndent = function () {
|
||||
if (this.format.compact) {
|
||||
return "";
|
||||
} else {
|
||||
return util.repeat(this._indent, this.format.indent.style);
|
||||
}
|
||||
};
|
||||
|
||||
Buffer.prototype.indentSize = function () {
|
||||
return this.getIndent().length;
|
||||
};
|
||||
|
||||
Buffer.prototype.indent = function () {
|
||||
this._indent++;
|
||||
};
|
||||
|
||||
Buffer.prototype.dedent = function () {
|
||||
this._indent--;
|
||||
};
|
||||
|
||||
Buffer.prototype.semicolon = function () {
|
||||
if (this.format.semicolons) this.push(";");
|
||||
};
|
||||
|
||||
Buffer.prototype.ensureSemicolon = function () {
|
||||
if (!this.isLast(";")) this.semicolon();
|
||||
};
|
||||
|
||||
Buffer.prototype.rightBrace = function () {
|
||||
this.newline(true);
|
||||
this.push("}");
|
||||
};
|
||||
|
||||
Buffer.prototype.keyword = function (name) {
|
||||
this.push(name);
|
||||
this.push(" ");
|
||||
};
|
||||
|
||||
Buffer.prototype.space = function () {
|
||||
if (this.buf && !this.isLast([" ", "\n"])) {
|
||||
this.push(" ");
|
||||
}
|
||||
};
|
||||
|
||||
Buffer.prototype.removeLast = function (cha) {
|
||||
if (!this.isLast(cha)) return;
|
||||
|
||||
this.buf = this.buf.slice(0, -1);
|
||||
this.position.unshift(cha);
|
||||
};
|
||||
|
||||
Buffer.prototype.newline = function (i, removeLast) {
|
||||
if (!this.buf) return;
|
||||
if (this.format.compact) return;
|
||||
if (this.endsWith("{\n")) return;
|
||||
|
||||
if (_.isBoolean(i)) {
|
||||
removeLast = i;
|
||||
i = null;
|
||||
}
|
||||
|
||||
if (_.isNumber(i)) {
|
||||
var self = this;
|
||||
_.times(i, function () {
|
||||
self.newline(null, removeLast);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (removeLast && this.isLast("\n")) this.removeLast("\n");
|
||||
|
||||
this.removeLast(" ");
|
||||
this.buf = this.buf.replace(/\n(\s+)$/, "\n");
|
||||
this._push("\n");
|
||||
};
|
||||
|
||||
Buffer.prototype.push = function (str, noIndent) {
|
||||
if (this._indent && !noIndent && str !== "\n") {
|
||||
// we have an indent level and we aren't pushing a newline
|
||||
var indent = this.getIndent();
|
||||
|
||||
// replace all newlines with newlines with the indentation
|
||||
str = str.replace(/\n/g, "\n" + indent);
|
||||
|
||||
// we've got a newline before us so prepend on the indentation
|
||||
if (this.isLast("\n")) str = indent + str;
|
||||
}
|
||||
|
||||
this._push(str);
|
||||
};
|
||||
|
||||
Buffer.prototype._push = function (str) {
|
||||
this.position.push(str);
|
||||
this.buf += str;
|
||||
};
|
||||
|
||||
Buffer.prototype.endsWith = function (str) {
|
||||
return this.buf.slice(-str.length) === str;
|
||||
};
|
||||
|
||||
Buffer.prototype.isLast = function (cha, trimRight) {
|
||||
var buf = this.buf;
|
||||
if (trimRight) buf = buf.trimRight();
|
||||
|
||||
var chars = [].concat(cha);
|
||||
return _.contains(chars, _.last(buf));
|
||||
};
|
||||
@@ -8,6 +8,7 @@ module.exports.CodeGenerator = CodeGenerator;
|
||||
var Whitespace = require("./whitespace");
|
||||
var SourceMap = require("./source-map");
|
||||
var Position = require("./position");
|
||||
var Buffer = require("./buffer");
|
||||
var util = require("../util");
|
||||
var n = require("./node");
|
||||
var t = require("../types");
|
||||
@@ -18,18 +19,21 @@ function CodeGenerator(ast, opts, code) {
|
||||
|
||||
this.comments = ast.comments || [];
|
||||
this.tokens = ast.tokens || [];
|
||||
this.opts = opts;
|
||||
this.format = CodeGenerator.normaliseOptions(opts);
|
||||
this.ast = ast;
|
||||
this.buf = "";
|
||||
|
||||
this.format = CodeGenerator.normaliseOptions(opts);
|
||||
this._indent = this.format.indent.base;
|
||||
|
||||
this.whitespace = new Whitespace(this.tokens, this.comments);
|
||||
this.position = new Position;
|
||||
this.map = new SourceMap(this.position, opts, code);
|
||||
this.buffer = new Buffer(this.position, this.format);
|
||||
}
|
||||
|
||||
_.each(Buffer.prototype, function (fn, key) {
|
||||
CodeGenerator.prototype[key] = function () {
|
||||
return fn.apply(this.buffer, arguments);
|
||||
};
|
||||
});
|
||||
|
||||
CodeGenerator.normaliseOptions = function (opts) {
|
||||
opts = opts.format || {};
|
||||
|
||||
@@ -65,125 +69,15 @@ _.each(CodeGenerator.generators, function (generator) {
|
||||
_.extend(CodeGenerator.prototype, generator);
|
||||
});
|
||||
|
||||
CodeGenerator.prototype.newline = function (i, removeLast) {
|
||||
if (!this.buf) return;
|
||||
if (this.format.compact) return;
|
||||
if (this.endsWith("{\n")) return;
|
||||
|
||||
if (_.isBoolean(i)) {
|
||||
removeLast = i;
|
||||
i = null;
|
||||
}
|
||||
|
||||
if (_.isNumber(i)) {
|
||||
var self = this;
|
||||
_.times(i, function () {
|
||||
self.newline(null, removeLast);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (removeLast && this.isLast("\n")) this.removeLast("\n");
|
||||
|
||||
this.removeLast(" ");
|
||||
this.buf = this.buf.replace(/\n(\s+)$/, "\n");
|
||||
this._push("\n");
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.removeLast = function (cha) {
|
||||
if (!this.isLast(cha)) return;
|
||||
|
||||
this.buf = this.buf.slice(0, -1);
|
||||
this.position.unshift(cha);
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.semicolon = function () {
|
||||
if (this.format.semicolons) this.push(";");
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.ensureSemicolon = function () {
|
||||
if (!this.isLast(";")) this.semicolon();
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.rightBrace = function () {
|
||||
this.newline(true);
|
||||
this.push("}");
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.keyword = function (name) {
|
||||
this.push(name);
|
||||
this.push(" ");
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.space = function () {
|
||||
if (this.buf && !this.isLast([" ", "\n"])) {
|
||||
this.push(" ");
|
||||
}
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.push = function (str, noIndent) {
|
||||
if (this._indent && !noIndent && str !== "\n") {
|
||||
// we have an indent level and we aren't pushing a newline
|
||||
var indent = this.getIndent();
|
||||
|
||||
// replace all newlines with newlines with the indentation
|
||||
str = str.replace(/\n/g, "\n" + indent);
|
||||
|
||||
// we've got a newline before us so prepend on the indentation
|
||||
if (this.isLast("\n")) str = indent + str;
|
||||
}
|
||||
|
||||
this._push(str);
|
||||
};
|
||||
|
||||
CodeGenerator.prototype._push = function (str) {
|
||||
this.position.push(str);
|
||||
this.buf += str;
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.endsWith = function (str) {
|
||||
return this.buf.slice(-str.length) === str;
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.isLast = function (cha, trimRight) {
|
||||
var buf = this.buf;
|
||||
if (trimRight) buf = buf.trimRight();
|
||||
|
||||
var chars = [].concat(cha);
|
||||
return _.contains(chars, _.last(buf));
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.getIndent = function () {
|
||||
if (this.format.compact) {
|
||||
return "";
|
||||
} else {
|
||||
return util.repeat(this._indent, this.format.indent.style);
|
||||
}
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.indentSize = function () {
|
||||
return this.getIndent().length;
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.indent = function () {
|
||||
this._indent++;
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.dedent = function () {
|
||||
this._indent--;
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.generate = function () {
|
||||
var ast = this.ast;
|
||||
|
||||
this.print(ast);
|
||||
|
||||
this.buf = this.buf.trimRight();
|
||||
|
||||
return {
|
||||
map: this.map.get(),
|
||||
ast: ast,
|
||||
code: this.buf
|
||||
code: this.buffer.get()
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -1,294 +0,0 @@
|
||||
module.exports = Node;
|
||||
|
||||
var t = require("../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function Node(node, parent) {
|
||||
this.parent = parent;
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
Node.whitespace = {
|
||||
FunctionExpression: 1,
|
||||
FunctionStatement: 1,
|
||||
ClassExpression: 1,
|
||||
ClassStatement: 1,
|
||||
ForOfStatement: 1,
|
||||
ForInStatement: 1,
|
||||
ForStatement: 1,
|
||||
SwitchStatement: 1,
|
||||
IfStatement: { before: 1 },
|
||||
//Property: { before: 1 },
|
||||
Literal: { after: 1 }
|
||||
};
|
||||
|
||||
_.each(Node.whitespace, function (amounts, type) {
|
||||
if (_.isNumber(amounts)) amounts = { after: amounts, before: amounts };
|
||||
Node.whitespace[type] = amounts;
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
Node.PRECEDENCE = {};
|
||||
|
||||
_.each([
|
||||
["||"],
|
||||
["&&"],
|
||||
["|"],
|
||||
["^"],
|
||||
["&"],
|
||||
["==", "===", "!=", "!=="],
|
||||
["<", ">", "<=", ">=", "in", "instanceof"],
|
||||
[">>", "<<", ">>>"],
|
||||
["+", "-"],
|
||||
["*", "/", "%"]
|
||||
], function (tier, i) {
|
||||
_.each(tier, function (op) {
|
||||
Node.PRECEDENCE[op] = i;
|
||||
});
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
Node.prototype.isUserWhitespacable = function () {
|
||||
//var parent = this.parent;
|
||||
var node = this.node;
|
||||
|
||||
if (t.isUserWhitespacable(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//if (t.isArrayExpression(parent)) {
|
||||
// return true;
|
||||
//}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
Node.prototype.needsWhitespace = function (type) {
|
||||
var parent = this.parent;
|
||||
var node = this.node;
|
||||
if (!node) return 0;
|
||||
|
||||
if (t.isExpressionStatement(node)) {
|
||||
node = node.expression;
|
||||
}
|
||||
|
||||
if (type === "before") {
|
||||
if (t.isProperty(node) && parent.properties[0] === node) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (t.isSwitchCase(node) && parent.cases[0] === node) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (type === "after") {
|
||||
if (t.isCallExpression(node)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
var exprs = [];
|
||||
|
||||
if (t.isVariableDeclaration(node)) {
|
||||
exprs = _.map(node.declarations, "init");
|
||||
}
|
||||
|
||||
if (t.isArrayExpression(node)) {
|
||||
exprs = node.elements;
|
||||
}
|
||||
|
||||
if (t.isObjectExpression(node)) {
|
||||
exprs = node.properties;
|
||||
}
|
||||
|
||||
var lines = 0;
|
||||
|
||||
_.each(exprs, function (expr) {
|
||||
lines = Node.needsWhitespace(expr, node, type);
|
||||
if (lines) return false;
|
||||
});
|
||||
|
||||
if (lines) return lines;
|
||||
}
|
||||
|
||||
if (t.isCallExpression(node) && t.isFunction(node.callee)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
var opts = Node.whitespace[node.type];
|
||||
return (opts && opts[type]) || 0;
|
||||
};
|
||||
|
||||
Node.prototype.needsWhitespaceBefore = function () {
|
||||
return this.needsWhitespace("before");
|
||||
};
|
||||
|
||||
Node.prototype.needsWhitespaceAfter = function () {
|
||||
return this.needsWhitespace("after");
|
||||
};
|
||||
|
||||
Node.prototype.needsParens = function () {
|
||||
var parent = this.parent;
|
||||
var node = this.node;
|
||||
|
||||
if (!parent) return false;
|
||||
|
||||
//
|
||||
if (t.isUnaryLike(node)) {
|
||||
return t.isMemberExpression(parent) && parent.object === node;
|
||||
}
|
||||
|
||||
if (t.isBinary(node)) {
|
||||
//
|
||||
if (t.isCallExpression(parent) && parent.callee === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
if (t.isUnaryLike(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
if (t.isMemberExpression(parent) && parent.object === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isBinary(parent)) {
|
||||
var parentOp = parent.operator;
|
||||
var parentPos = Node.PRECEDENCE[parentOp];
|
||||
|
||||
var nodeOp = node.operator;
|
||||
var nodePos = Node.PRECEDENCE[nodeOp];
|
||||
|
||||
if (parentPos > nodePos) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (parentPos === nodePos && parent.right === node) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isBinaryExpression(node) && node.operator === "in") {
|
||||
// var i = (1 in []);
|
||||
if (t.isVariableDeclarator(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// for ((1 in []);;);
|
||||
if (t.isFor(parent)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// (class {});
|
||||
if (t.isClassExpression(node) && t.isExpressionStatement(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isSequenceExpression(node)) {
|
||||
if (t.isForStatement(parent)) {
|
||||
// Although parentheses wouldn't hurt around sequence
|
||||
// expressions in the head of for loops, traditional style
|
||||
// dictates that e.g. i++, j++ should not be wrapped with
|
||||
// parentheses.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (t.isExpressionStatement(parent) && parent.expression === node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise err on the side of overparenthesization, adding
|
||||
// explicit exceptions above if this proves overzealous.
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
if (t.isYieldExpression(node)) {
|
||||
return t.isBinary(parent) ||
|
||||
t.isUnaryLike(parent) ||
|
||||
t.isCallExpression(parent) ||
|
||||
t.isMemberExpression(parent) ||
|
||||
t.isNewExpression(parent) ||
|
||||
t.isConditionalExpression(parent) ||
|
||||
t.isYieldExpression(parent);
|
||||
}
|
||||
|
||||
if (t.isNewExpression(parent) && parent.callee === node) {
|
||||
return t.isCallExpression(node) || _.some(node, function (val) {
|
||||
return t.isCallExpression(val);
|
||||
});
|
||||
}
|
||||
|
||||
// (1).valueOf()
|
||||
if (t.isLiteral(node) && _.isNumber(node.value) && t.isMemberExpression(parent) && parent.object === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isAssignmentExpression(node) || t.isConditionalExpression(node)) {
|
||||
//
|
||||
if (t.isUnaryLike(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
if (t.isBinary(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
if (t.isCallExpression(parent) && parent.callee === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
if (t.isConditionalExpression(parent) && parent.test === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
if (t.isMemberExpression(parent) && parent.object === node) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isFunctionExpression(node)) {
|
||||
// function () {};
|
||||
if (t.isExpressionStatement(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// (function test() {}).name;
|
||||
if (t.isMemberExpression(parent) && parent.object === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// (function () {})();
|
||||
if (t.isCallExpression(parent) && parent.callee === node) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// ({ x, y }) = { x: 5, y: 6 };
|
||||
if (t.isObjectPattern(node) && t.isAssignmentExpression(parent) && parent.left == node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
_.each(Node.prototype, function (fn, key) {
|
||||
Node[key] = function (node, parent) {
|
||||
var n = new Node(node, parent);
|
||||
|
||||
var args = _.toArray(arguments).slice(2);
|
||||
return n[key].apply(n, args);
|
||||
};
|
||||
});
|
||||
90
lib/6to5/generation/node/index.js
Normal file
90
lib/6to5/generation/node/index.js
Normal file
@@ -0,0 +1,90 @@
|
||||
module.exports = Node;
|
||||
|
||||
var whitespace = require("./whitespace");
|
||||
var parens = require("./parentheses");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var find = function (obj, node, parent) {
|
||||
var result;
|
||||
|
||||
_.each(obj, function (fn, type) {
|
||||
if (t["is" + type](node)) {
|
||||
result = fn(node, parent);
|
||||
if (result != null) return false;
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
function Node(node, parent) {
|
||||
this.parent = parent;
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
Node.prototype.isUserWhitespacable = function () {
|
||||
//var parent = this.parent;
|
||||
var node = this.node;
|
||||
|
||||
if (t.isUserWhitespacable(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//if (t.isArrayExpression(parent)) {
|
||||
// return true;
|
||||
//}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
Node.prototype.needsWhitespace = function (type) {
|
||||
var parent = this.parent;
|
||||
var node = this.node;
|
||||
if (!node) return 0;
|
||||
|
||||
if (t.isExpressionStatement(node)) {
|
||||
node = node.expression;
|
||||
}
|
||||
|
||||
var lines = find(whitespace[type].nodes, node, parent);
|
||||
if (lines) return lines;
|
||||
|
||||
_.each(find(whitespace[type].list, node, parent), function (expr) {
|
||||
lines = Node.needsWhitespace(expr, node, type);
|
||||
if (lines) return false;
|
||||
});
|
||||
return lines || 0;
|
||||
};
|
||||
|
||||
Node.prototype.needsWhitespaceBefore = function () {
|
||||
return this.needsWhitespace("before");
|
||||
};
|
||||
|
||||
Node.prototype.needsWhitespaceAfter = function () {
|
||||
return this.needsWhitespace("after");
|
||||
};
|
||||
|
||||
Node.prototype.needsParens = function () {
|
||||
var parent = this.parent;
|
||||
var node = this.node;
|
||||
|
||||
if (!parent) return false;
|
||||
|
||||
if (t.isNewExpression(parent) && parent.callee === node) {
|
||||
return t.isCallExpression(node) || _.some(node, function (val) {
|
||||
return t.isCallExpression(val);
|
||||
});
|
||||
}
|
||||
|
||||
return find(parens, node, parent);
|
||||
};
|
||||
|
||||
_.each(Node.prototype, function (fn, key) {
|
||||
Node[key] = function (node, parent) {
|
||||
var n = new Node(node, parent);
|
||||
|
||||
var args = _.toArray(arguments).slice(2);
|
||||
return n[key].apply(n, args);
|
||||
};
|
||||
});
|
||||
150
lib/6to5/generation/node/parentheses.js
Normal file
150
lib/6to5/generation/node/parentheses.js
Normal file
@@ -0,0 +1,150 @@
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var PRECEDENCE = {};
|
||||
|
||||
_.each([
|
||||
["||"],
|
||||
["&&"],
|
||||
["|"],
|
||||
["^"],
|
||||
["&"],
|
||||
["==", "===", "!=", "!=="],
|
||||
["<", ">", "<=", ">=", "in", "instanceof"],
|
||||
[">>", "<<", ">>>"],
|
||||
["+", "-"],
|
||||
["*", "/", "%"]
|
||||
], function (tier, i) {
|
||||
_.each(tier, function (op) {
|
||||
PRECEDENCE[op] = i;
|
||||
});
|
||||
});
|
||||
|
||||
exports.Binary = function (node, parent) {
|
||||
if (t.isCallExpression(parent) && parent.callee === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isUnaryLike(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isMemberExpression(parent) && parent.object === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isBinary(parent)) {
|
||||
var parentOp = parent.operator;
|
||||
var parentPos = PRECEDENCE[parentOp];
|
||||
|
||||
var nodeOp = node.operator;
|
||||
var nodePos = PRECEDENCE[nodeOp];
|
||||
|
||||
if (parentPos > nodePos) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (parentPos === nodePos && parent.right === node) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.BinaryExpression = function (node, parent) {
|
||||
if (node.operator === "in") {
|
||||
// var i = (1 in []);
|
||||
if (t.isVariableDeclarator(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// for ((1 in []);;);
|
||||
if (t.isFor(parent)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.SequenceExpression = function (node, parent) {
|
||||
if (t.isForStatement(parent)) {
|
||||
// Although parentheses wouldn't hurt around sequence
|
||||
// expressions in the head of for loops, traditional style
|
||||
// dictates that e.g. i++, j++ should not be wrapped with
|
||||
// parentheses.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (t.isExpressionStatement(parent) && parent.expression === node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise err on the side of overparenthesization, adding
|
||||
// explicit exceptions above if this proves overzealous.
|
||||
return true;
|
||||
};
|
||||
|
||||
exports.YieldExpression = function (node, parent) {
|
||||
return t.isBinary(parent) ||
|
||||
t.isUnaryLike(parent) ||
|
||||
t.isCallExpression(parent) ||
|
||||
t.isMemberExpression(parent) ||
|
||||
t.isNewExpression(parent) ||
|
||||
t.isConditionalExpression(parent) ||
|
||||
t.isYieldExpression(parent);
|
||||
};
|
||||
|
||||
exports.Literal = function (node, parent) {
|
||||
// (1).valueOf()
|
||||
if (_.isNumber(node.value) && t.isMemberExpression(parent) && parent.object === node) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
exports.ClassExpression = function (node, parent) {
|
||||
return t.isExpressionStatement(parent);
|
||||
};
|
||||
|
||||
exports.UnaryLike = function (node, parent) {
|
||||
return t.isMemberExpression(parent) && parent.object === node;
|
||||
};
|
||||
|
||||
exports.FunctionExpression = function (node, parent) {
|
||||
// function () {};
|
||||
if (t.isExpressionStatement(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// (function test() {}).name;
|
||||
if (t.isMemberExpression(parent) && parent.object === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// (function () {})();
|
||||
if (t.isCallExpression(parent) && parent.callee === node) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
exports.AssignmentExpression =
|
||||
exports.ConditionalExpression = function (node, parent) {
|
||||
if (t.isUnaryLike(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isBinary(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isCallExpression(parent) && parent.callee === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isConditionalExpression(parent) && parent.test === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isMemberExpression(parent) && parent.object === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
60
lib/6to5/generation/node/whitespace.js
Normal file
60
lib/6to5/generation/node/whitespace.js
Normal file
@@ -0,0 +1,60 @@
|
||||
var _ = require("lodash");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.before = {
|
||||
nodes: {
|
||||
Property: function (node, parent) {
|
||||
if (parent.properties[0] === node) {
|
||||
return 1;
|
||||
}
|
||||
},
|
||||
|
||||
SwitchCase: function (node, parent) {
|
||||
if (parent.cases[0] === node) {
|
||||
return 1;
|
||||
}
|
||||
},
|
||||
|
||||
CallExpression: function (node) {
|
||||
if (t.isFunction(node.callee)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.after = {
|
||||
nodes: {},
|
||||
|
||||
list: {
|
||||
VariableDeclaration: function (node) {
|
||||
return _.map(node.declarations, "init");
|
||||
},
|
||||
|
||||
ArrayExpression: function (node) {
|
||||
return node.elements;
|
||||
},
|
||||
|
||||
ObjectExpression: function (node) {
|
||||
return node.properties;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_.each({
|
||||
Function: 1,
|
||||
Class: 1,
|
||||
For: 1,
|
||||
SwitchStatement: 1,
|
||||
IfStatement: { before: 1 },
|
||||
CallExpression: { after: 1 },
|
||||
Literal: { after: 1 }
|
||||
}, function (amounts, type) {
|
||||
if (_.isNumber(amounts)) amounts = { after: amounts, before: amounts };
|
||||
|
||||
_.each(amounts, function (amount, key) {
|
||||
exports[key].nodes[type] = function () {
|
||||
return amount;
|
||||
};
|
||||
});
|
||||
});
|
||||
@@ -14,10 +14,9 @@ var go = function (getBody, node, file, scope) {
|
||||
};
|
||||
|
||||
// traverse the function and find all alias functions so we can alias
|
||||
// arguments and this if necessary
|
||||
// `arguments` and `this` if necessary
|
||||
traverse(node, function (node) {
|
||||
var _aliasFunction = node._aliasFunction;
|
||||
if (!_aliasFunction) {
|
||||
if (!node._aliasFunction) {
|
||||
if (t.isFunction(node)) {
|
||||
// stop traversal of this node as it'll be hit again by this transformer
|
||||
return false;
|
||||
@@ -26,12 +25,10 @@ var go = function (getBody, node, file, scope) {
|
||||
}
|
||||
}
|
||||
|
||||
// traverse all child nodes of this function and find arguments and this
|
||||
// traverse all child nodes of this function and find `arguments` and `this`
|
||||
traverse(node, function (node, parent) {
|
||||
if (_aliasFunction === "arrows") {
|
||||
if (t.isFunction(node) && node._aliasFunction !== "arrows") {
|
||||
return false;
|
||||
}
|
||||
if (t.isFunction(node) && !node._aliasFunction) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (node._ignoreAliasFunctions) return;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var singleArrayExpression = function (node) {
|
||||
var block = node.blocks[0];
|
||||
@@ -13,7 +14,13 @@ var singleArrayExpression = function (node) {
|
||||
ARRAY: block.right,
|
||||
KEY: block.left
|
||||
});
|
||||
result._aliasFunction = true;
|
||||
|
||||
_.each([result.callee.object, result], function (call) {
|
||||
if (t.isCallExpression(call)) {
|
||||
call.arguments[0]._aliasFunction = true;
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
@@ -23,7 +30,7 @@ var multiple = function (node, file) {
|
||||
var container = util.template("array-comprehension-container", {
|
||||
KEY: uid
|
||||
});
|
||||
container._aliasFunction = true;
|
||||
container.callee.expression._aliasFunction = true;
|
||||
|
||||
var block = container.callee.expression.body;
|
||||
var body = block.body;
|
||||
|
||||
@@ -3,7 +3,7 @@ var t = require("../../types");
|
||||
exports.ArrowFunctionExpression = function (node) {
|
||||
t.ensureBlock(node);
|
||||
|
||||
node._aliasFunction = "arrows";
|
||||
node._aliasFunction = true;
|
||||
node.expression = false;
|
||||
node.type = "FunctionExpression";
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ exports.ObjectExpression = function (node, parent, file) {
|
||||
var containerCallee = container.callee.expression;
|
||||
var containerBody = containerCallee.body.body;
|
||||
|
||||
containerCallee._aliasFunction = "arrows";
|
||||
containerCallee._aliasFunction = true;
|
||||
|
||||
_.each(computed, function (prop) {
|
||||
containerBody.unshift(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "6to5",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "1.12.0",
|
||||
"version": "1.12.1",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://github.com/6to5/6to5",
|
||||
"repository": {
|
||||
|
||||
@@ -149,7 +149,3 @@ _.each(fs.readdirSync(fixtureLoc), function (binName) {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
after(function () {
|
||||
rimraf.sync(tmpLoc);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user