Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f0b7683a1 | ||
|
|
f0d2cbb055 | ||
|
|
602c5e0ca0 | ||
|
|
2a2dff0eaf | ||
|
|
e1151e08c9 | ||
|
|
84f54ca3c7 | ||
|
|
5fb793b75f | ||
|
|
1adc9bfc70 | ||
|
|
3649fad485 | ||
|
|
0e1743738e | ||
|
|
6ad16302cd | ||
|
|
4b6b7af332 | ||
|
|
55dfb423ee | ||
|
|
9d1bc4817d | ||
|
|
fc8666e7a4 | ||
|
|
07b6881d67 |
16
CHANGELOG.md
16
CHANGELOG.md
@@ -11,10 +11,26 @@
|
||||
|
||||
_Note: Gaps between patch versions are faulty/broken releases._
|
||||
|
||||
## 3.6.5
|
||||
|
||||
* **Internal**
|
||||
* Upgrade `core-js`.
|
||||
* **Bug Fix**
|
||||
* Fix block scoping leaking variables in IIFE mode.
|
||||
* Fix tail call transformer exploding on return statements as the consequent of an if statement.
|
||||
* **New Feature**
|
||||
* Add `validation.react` transformer.
|
||||
|
||||
## 3.6.4
|
||||
|
||||
* **New Feature**
|
||||
* Add support for flow type casts and module types.
|
||||
|
||||
## 3.6.3
|
||||
|
||||
* **Internal**
|
||||
* Upgrade `acorn-6to5`.
|
||||
* Use `default` property on `6to5-runtime`.
|
||||
|
||||
## 3.6.2
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ commander.option("-c, --remove-comments", "Remove comments from the compiled cod
|
||||
commander.option("-M, --module-ids", "Insert module id in modules", false);
|
||||
commander.option("-R, --react-compat", "Makes the react transformer produce pre-v0.12 code");
|
||||
commander.option("--keep-module-id-extensions", "Keep extensions when generating module ids", false);
|
||||
commander.option("-a, --auxilary-comment [comment]", "Comment text to prepend to all auxilary code");
|
||||
|
||||
commander.on("--help", function () {
|
||||
var outKeys = function (title, obj) {
|
||||
@@ -99,6 +100,7 @@ if (errors.length) {
|
||||
|
||||
exports.opts = {
|
||||
keepModuleIdExtensions: commander.keepModuleIdExtensions,
|
||||
auxilaryComment: commander.auxilaryComment,
|
||||
sourceMapName: commander.outFile,
|
||||
experimental: commander.experimental,
|
||||
reactCompat: commander.reactCompat,
|
||||
|
||||
@@ -30,6 +30,7 @@ exports.ObjectTypeIndexer =
|
||||
exports.ObjectTypeProperty =
|
||||
exports.QualifiedTypeIdentifier =
|
||||
exports.UnionTypeAnnotation =
|
||||
exports.TypeCastExpression =
|
||||
exports.VoidTypeAnnotation = function () {
|
||||
// todo: implement these once we have a `--keep-types` option
|
||||
};
|
||||
|
||||
@@ -82,7 +82,7 @@ Whitespace.prototype.getNewlinesAfter = function (node) {
|
||||
}
|
||||
}
|
||||
|
||||
if (endToken.type.type === "eof") {
|
||||
if (endToken && endToken.type.type === "eof") {
|
||||
return 1;
|
||||
} else {
|
||||
var lines = this.getNewlinesBetween(startToken, endToken);
|
||||
@@ -96,6 +96,8 @@ Whitespace.prototype.getNewlinesAfter = function (node) {
|
||||
};
|
||||
|
||||
Whitespace.prototype.getNewlinesBetween = function (startToken, endToken) {
|
||||
if (!endToken || !endToken.loc) return 0;
|
||||
|
||||
var start = startToken ? startToken.loc.end.line : 1;
|
||||
var end = endToken.loc.start.line;
|
||||
var lines = 0;
|
||||
|
||||
@@ -15,7 +15,8 @@ exports.messages = {
|
||||
invalidParentForThisNode: "We don't know how to handle this node within the current parent - please open an issue",
|
||||
readOnly: "$1 is read-only",
|
||||
modulesIllegalExportName: "Illegal export $1",
|
||||
unknownForHead: "Unknown node type $1 in ForStatement"
|
||||
unknownForHead: "Unknown node type $1 in ForStatement",
|
||||
didYouMean: "Did you mean $1?"
|
||||
};
|
||||
|
||||
exports.get = function (key) {
|
||||
|
||||
@@ -86,6 +86,7 @@ File.validOptions = [
|
||||
"experimental",
|
||||
"resolveModuleSource",
|
||||
"runtime",
|
||||
"auxilaryComment",
|
||||
|
||||
// these are used by plugins
|
||||
"ignore",
|
||||
@@ -106,6 +107,7 @@ File.prototype.normalizeOptions = function (opts) {
|
||||
defaults(opts, {
|
||||
keepModuleIdExtensions: false,
|
||||
resolveModuleSource: null,
|
||||
auxilaryComment: "",
|
||||
experimental: false,
|
||||
reactCompat: false,
|
||||
playground: false,
|
||||
@@ -298,6 +300,18 @@ File.prototype.isConsequenceExpressionStatement = function (node) {
|
||||
return t.isExpressionStatement(node) && this.lastStatements.indexOf(node) >= 0;
|
||||
};
|
||||
|
||||
File.prototype.attachAuxilaryComment = function (node) {
|
||||
var comment = this.opts.auxilaryComment;
|
||||
if (comment) {
|
||||
node.leadingComments = node.leadingComments || [];
|
||||
node.leadingComments.push({
|
||||
type: "Line",
|
||||
value: " " + comment
|
||||
});
|
||||
}
|
||||
return node;
|
||||
};
|
||||
|
||||
File.prototype.addHelper = function (name) {
|
||||
if (!includes(File.helpers, name)) {
|
||||
throw new ReferenceError("Unknown helper " + name);
|
||||
|
||||
@@ -124,7 +124,7 @@ BlockScoping.prototype.run = function () {
|
||||
if (!this.hasLetReferences) return;
|
||||
|
||||
if (needsClosure) {
|
||||
this.needsClosure();
|
||||
this.wrapClosure();
|
||||
} else {
|
||||
this.remap();
|
||||
}
|
||||
@@ -205,9 +205,28 @@ BlockScoping.prototype.remap = function () {
|
||||
* Description
|
||||
*/
|
||||
|
||||
BlockScoping.prototype.needsClosure = function () {
|
||||
BlockScoping.prototype.wrapClosure = function () {
|
||||
var block = this.block;
|
||||
|
||||
var outsideRefs = this.outsideLetReferences;
|
||||
|
||||
// remap loop heads with colliding variables
|
||||
if (this.loopParent) {
|
||||
for (var name in outsideRefs) {
|
||||
var id = outsideRefs[name];
|
||||
|
||||
if (this.scope.hasGlobal(id.name)) {
|
||||
delete outsideRefs[id.name];
|
||||
delete this.letReferences[id.name];
|
||||
|
||||
this.scope.rename(id.name);
|
||||
|
||||
this.letReferences[id.name] = id;
|
||||
outsideRefs[id.name] = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we're inside of a for loop then we search to see if there are any
|
||||
// `break`s, `continue`s, `return`s etc
|
||||
this.has = this.checkLoop();
|
||||
@@ -216,7 +235,7 @@ BlockScoping.prototype.needsClosure = function () {
|
||||
this.hoistVarDeclarations();
|
||||
|
||||
// turn outsideLetReferences into an array
|
||||
var params = values(this.outsideLetReferences);
|
||||
var params = values(outsideRefs);
|
||||
|
||||
// build the closure that we're going to wrap the block with
|
||||
var fn = t.functionExpression(null, params, t.blockStatement(block.body));
|
||||
|
||||
@@ -294,7 +294,15 @@ TailCallTransformer.prototype.subTransformCallExpression = function (node) {
|
||||
// looks for and replaces tail recursion calls
|
||||
var firstPass = {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (t.isReturnStatement(node)) {
|
||||
if (t.isIfStatement(node)) {
|
||||
if (t.isReturnStatement(node.alternate)) {
|
||||
t.ensureBlock(node, "alternate");
|
||||
}
|
||||
|
||||
if (t.isReturnStatement(node.consequent)) {
|
||||
t.ensureBlock(node, "consequent");
|
||||
}
|
||||
} else if (t.isReturnStatement(node)) {
|
||||
this.skip();
|
||||
return state.subTransform(node.argument);
|
||||
} else if (t.isTryStatement(parent)) {
|
||||
|
||||
@@ -4,6 +4,7 @@ module.exports = {
|
||||
"validation.undeclaredVariableCheck": require("./validation/undeclared-variable-check"),
|
||||
"validation.noForInOfAssignment": require("./validation/no-for-in-of-assignment"),
|
||||
"validation.setters": require("./validation/setters"),
|
||||
"validation.react": require("./validation/react"),
|
||||
"spec.blockScopedFunctions": require("./spec/block-scoped-functions"),
|
||||
|
||||
"playground.malletOperator": require("./playground/mallet-operator"),
|
||||
@@ -12,6 +13,7 @@ module.exports = {
|
||||
"playground.objectGetterMemoization": require("./playground/object-getter-memoization"),
|
||||
|
||||
reactCompat: require("./other/react-compat"),
|
||||
flow: require("./other/flow"),
|
||||
react: require("./other/react"),
|
||||
|
||||
_modules: require("./internal/modules"),
|
||||
|
||||
@@ -6,7 +6,7 @@ var t = require("../../../types");
|
||||
exports.secondPass = true;
|
||||
|
||||
exports.BlockStatement =
|
||||
exports.Program = function (node) {
|
||||
exports.Program = function (node, parent, scope, file) {
|
||||
if (!node._declarations) return;
|
||||
|
||||
var kinds = {};
|
||||
@@ -19,16 +19,16 @@ exports.Program = function (node) {
|
||||
kind = declar.kind || "var";
|
||||
var declarNode = t.variableDeclarator(declar.id, declar.init);
|
||||
|
||||
if (!declar.init) {
|
||||
if (declar.init) {
|
||||
node.body.unshift(file.attachAuxilaryComment(t.variableDeclaration(kind, [declarNode])));
|
||||
} else {
|
||||
kinds[kind] = kinds[kind] || [];
|
||||
kinds[kind].push(declarNode);
|
||||
} else {
|
||||
node.body.unshift(t.variableDeclaration(kind, [declarNode]));
|
||||
}
|
||||
}
|
||||
|
||||
for (kind in kinds) {
|
||||
node.body.unshift(t.variableDeclaration(kind, kinds[kind]));
|
||||
node.body.unshift(file.attachAuxilaryComment(t.variableDeclaration(kind, kinds[kind])));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
13
lib/6to5/transformation/transformers/other/flow.js
Normal file
13
lib/6to5/transformation/transformers/other/flow.js
Normal file
@@ -0,0 +1,13 @@
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.TypeCastExpression = function (node) {
|
||||
return node.expression;
|
||||
};
|
||||
|
||||
exports.ImportDeclaration = function (node) {
|
||||
if (node.isType) this.remove();
|
||||
};
|
||||
|
||||
exports.ExportDeclaration = function (node) {
|
||||
if (t.isTypeAlias(node.declaration)) this.remove();
|
||||
};
|
||||
@@ -1,10 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
var includes = require("lodash/collection/includes");
|
||||
var util = require("../../../util");
|
||||
var core = require("core-js/library");
|
||||
var t = require("../../../types");
|
||||
var has = require("lodash/object/has");
|
||||
var includes = require("lodash/collection/includes");
|
||||
var t = require("../../../types");
|
||||
|
||||
var isSymboliterator = t.buildMatchMemberExpression("Symbol.iterator");
|
||||
|
||||
var coreHas = function (node) {
|
||||
return node.name !== "_" && has(core, node.name);
|
||||
@@ -47,8 +49,7 @@ var astVisitor = {
|
||||
if (!callee.computed) return false;
|
||||
|
||||
prop = callee.property;
|
||||
if (!t.isIdentifier(prop.object, { name: "Symbol" })) return false;
|
||||
if (!t.isIdentifier(prop.property, { name: "iterator" })) return false;
|
||||
if (!isSymboliterator(prop)) return false;
|
||||
|
||||
return util.template("corejs-iterator", {
|
||||
CORE_ID: file.get("coreIdentifier"),
|
||||
@@ -60,9 +61,7 @@ var astVisitor = {
|
||||
if (node.operator !== "in") return;
|
||||
|
||||
var left = node.left;
|
||||
if (!t.isMemberExpression(left)) return;
|
||||
if (!t.isIdentifier(left.object, { name: "Symbol" })) return;
|
||||
if (!t.isIdentifier(left.property, { name: "iterator" })) return;
|
||||
if (!isSymboliterator(left)) return;
|
||||
|
||||
return util.template("corejs-is-iterator", {
|
||||
CORE_ID: file.get("coreIdentifier"),
|
||||
|
||||
25
lib/6to5/transformation/transformers/validation/react.js
vendored
Normal file
25
lib/6to5/transformation/transformers/validation/react.js
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
var messages = require("../../../messages");
|
||||
var t = require("../../../types");
|
||||
|
||||
// check if the input Literal `source` is an alternate casing of "react"
|
||||
var check = function (source, file) {
|
||||
if (t.isLiteral(source)) {
|
||||
var name = source.value;
|
||||
var lower = name.toLowerCase();
|
||||
|
||||
if (lower === "react" && name !== lower) {
|
||||
throw file.errorWithNode(source, messages.get("didYouMean", "react"));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.CallExpression = function (node, parent, scope, file) {
|
||||
if (t.isIdentifier(node.callee, { name: "require" }) && node.arguments.length === 1) {
|
||||
check(node.arguments[0], file);
|
||||
}
|
||||
};
|
||||
|
||||
exports.ImportDeclaration =
|
||||
exports.ExportDeclaration = function (node, parent, scope, file) {
|
||||
check(node.source, file);
|
||||
};
|
||||
@@ -33,7 +33,7 @@ function Scope(block, parentBlock, parent, file) {
|
||||
this.crawl();
|
||||
}
|
||||
|
||||
Scope.defaultDeclarations = flatten([globals.builtin, globals.browser, globals.node].map(Object.keys));
|
||||
Scope.globals = flatten([globals.builtin, globals.browser, globals.node].map(Object.keys));
|
||||
|
||||
/**
|
||||
* Description
|
||||
@@ -637,7 +637,7 @@ Scope.prototype.hasBinding = function (name) {
|
||||
if (!name) return false;
|
||||
if (this.hasOwnBinding(name)) return true;
|
||||
if (this.parentHasBinding(name)) return true;
|
||||
if (includes(Scope.defaultDeclarations, name)) return true;
|
||||
if (includes(Scope.globals, name)) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
"TypeofTypeAnnotation": [],
|
||||
"TypeAlias": [],
|
||||
"TypeAnnotation": [],
|
||||
"TypeCastExpression": ["expression"],
|
||||
"TypeParameterDeclaration": [],
|
||||
"TypeParameterInstantiation": [],
|
||||
"ObjectTypeAnnotation": [],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "6to5",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "3.6.3",
|
||||
"version": "3.6.5",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://6to5.org/",
|
||||
"repository": "6to5/6to5",
|
||||
@@ -38,7 +38,7 @@
|
||||
"chalk": "^0.5.1",
|
||||
"chokidar": "0.12.6",
|
||||
"commander": "2.6.0",
|
||||
"core-js": "^0.5.2",
|
||||
"core-js": "^0.5.3",
|
||||
"debug": "^2.1.1",
|
||||
"detect-indent": "3.0.0",
|
||||
"estraverse": "1.9.1",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "6to5-runtime",
|
||||
"description": "6to5 selfContained runtime",
|
||||
"version": "3.6.2",
|
||||
"version": "3.6.4",
|
||||
"repository": "6to5/6to5",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>"
|
||||
}
|
||||
9
test/fixtures/transformation/es6-block-scoping-exec/closure-wrap-collision.js
vendored
Normal file
9
test/fixtures/transformation/es6-block-scoping-exec/closure-wrap-collision.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
for (let i = 1; i < 3; i += 1) {
|
||||
(function () {
|
||||
i;
|
||||
})();
|
||||
}
|
||||
|
||||
assert.throws(function () {
|
||||
i;
|
||||
}, ReferenceError);
|
||||
4
test/fixtures/transformation/es6-tail-call/expression-consequent/actual.js
vendored
Normal file
4
test/fixtures/transformation/es6-tail-call/expression-consequent/actual.js
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
function f() {
|
||||
if (true) {}
|
||||
else return f()
|
||||
}
|
||||
9
test/fixtures/transformation/es6-tail-call/expression-consequent/expected.js
vendored
Normal file
9
test/fixtures/transformation/es6-tail-call/expression-consequent/expected.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
function f() {
|
||||
_function: while (true) {
|
||||
if (true) {} else {
|
||||
continue _function;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user