Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50dee1a754 | ||
|
|
f80f860bbc | ||
|
|
7fc2fe41af | ||
|
|
a884a26402 | ||
|
|
81ec1e1f42 | ||
|
|
1a27970376 | ||
|
|
6822c854d4 | ||
|
|
8f4c4be821 | ||
|
|
5fca095149 | ||
|
|
34599a21cb | ||
|
|
d9d84c60b5 | ||
|
|
221d78d2e2 | ||
|
|
fa46f60655 | ||
|
|
03ce52fb7c | ||
|
|
0df0c696a9 | ||
|
|
21b7f4120e | ||
|
|
f43a3dec4b | ||
|
|
cacee5c625 | ||
|
|
553c90ae75 | ||
|
|
bc3502d695 | ||
|
|
6ae03a5dce | ||
|
|
68ef2d545e | ||
|
|
861b9e68d3 | ||
|
|
a0eb108cd4 | ||
|
|
756aef6adc | ||
|
|
7b74c1c8ec | ||
|
|
8e115ef3ed | ||
|
|
b9a6cf35b7 | ||
|
|
2e22de71b4 |
11
CHANGELOG.md
11
CHANGELOG.md
@@ -1,10 +1,17 @@
|
||||
# 1.12.21
|
||||
|
||||
* Fix unneccesary let scoping replacement.
|
||||
* Add `commonInterop` module formatter. Thanks [@Naddiseo](https://github.com/Naddiseo).
|
||||
* Fix `return` outside of function body bug. Thanks [@brentburg](https://github.com/brentburg).
|
||||
* Add more flexible option types.
|
||||
|
||||
# 1.12.20
|
||||
|
||||
* Append `sourceMappingURL` when using `bin/6to5` and output sourcemaps.
|
||||
|
||||
# 1.12.19
|
||||
|
||||
* Add `comments` option and `--remove-comments` flag. Thanks @[webpro](htps://github.com/webpro)!
|
||||
* Add `comments` option and `--remove-comments` flag. Thanks [@webpro](htps://github.com/webpro).
|
||||
* Embed `regenerator`.
|
||||
|
||||
# 1.12.18
|
||||
@@ -13,7 +20,7 @@
|
||||
|
||||
# 1.12.17
|
||||
|
||||
* Add `moduleName`, `sourceRoot` and `filenameRelative` options - thanks @[darvelo](https://github.com/darvelo)!
|
||||
* Add `moduleName`, `sourceRoot` and `filenameRelative` options. Thanks [@darvelo](https://github.com/darvelo).
|
||||
* Traversal optimisations.
|
||||
|
||||
# 1.12.16
|
||||
|
||||
@@ -56,31 +56,42 @@ better suited if you'd like a full ES6 environment with polyfills and all.
|
||||
|
||||
## Comparison to other transpilers
|
||||
|
||||
| | 6to5 | Traceur | esnext | es6now | es6-transpiler | jstransform |
|
||||
| ---------------------------- | ---- | ------- | ------ | ------ | -------------- | ----------- |
|
||||
| No runtime | ✓ | | | | ✓ | ✓ |
|
||||
| Source maps | ✓ | ✓ | ✓ | | ✓ | ✓ |
|
||||
| No compiler global pollution | ✓ | | ✓ | | ✓ | ✓ |
|
||||
| Browser support | ✓ | ✓ | ✓ | | | |
|
||||
| Array comprehension | ✓ | ✓ | | | ✓ | |
|
||||
| Arrow functions | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Async functions | ✓ | ✓ | ✓ | | | |
|
||||
| Classes | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Computed property names | ✓ | ✓ | ✓ | ✓ | ✓ | |
|
||||
| Constants | ✓ | ✓ | | | ✓ | |
|
||||
| Default parameters | ✓ | ✓ | ✓ | ✓ | ✓ | |
|
||||
| Destructuring | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| For-of | ✓ | ✓ | ✓ | ✓ | ✓ | |
|
||||
| Generators | ✓ | ✓ | ✓ | | | |
|
||||
| Generator comprehension | ✓ | ✓ | | | | |
|
||||
| Let scoping | ✓ | ✓ | | | ✓ | |
|
||||
| Modules | ✓ | ✓ | | ✓ | | |
|
||||
| Property method assignment | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Property name shorthand | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Rest parameters | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Spread | ✓ | ✓ | ✓ | ✓ | ✓ | |
|
||||
| Template literals | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Unicode regex | ✓ | ✓ | | | ✓ | |
|
||||
### Features
|
||||
|
||||
| | 6to5 | Traceur | es6-transpiler | esnext | es6now | jstransform |
|
||||
| ---------------------------- | ---- | ------- | -------------- | ------ | ------ | ----------- |
|
||||
| Source maps | ✓ | ✓ | ✓ | ✓ | | ✓ |
|
||||
| No compiler global pollution | ✓ | | ✓ | ✓ | | ✓ |
|
||||
| No runtime | ✓ | | ✓ | | | ✓ |
|
||||
| Browser support | ✓ | ✓ | | ✓ | | |
|
||||
|
||||
### Language Support
|
||||
|
||||
| | 6to5 | Traceur | es6-transpiler | esnext | es6now | jstransform |
|
||||
| ---------------------------- | ----- | ------- | -------------- | ------ | ------ | ----------- |
|
||||
| Array comprehension | ✓ | ✓ | ✓ | | | |
|
||||
| Arrow functions | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Async functions | ✓ | ✓ | | ✓ | | |
|
||||
| Classes | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Computed property names | ✓ | ✓ | ✓ | ✓ | ✓ | |
|
||||
| Constants | ✓ | ✓ | ✓ | | | |
|
||||
| Default parameters | ✓ | ✓ | ✓ | ✓ | ✓ | |
|
||||
| Destructuring | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| For-of | ✓ | ✓ | ✓ | ✓ | ✓ | |
|
||||
| Generators | ✓ | ✓ | | ✓ | | |
|
||||
| Generator comprehension | ✓ | ✓ | | | | |
|
||||
| Let scoping | ✓ | ✓ | ✓ | | | |
|
||||
| Modules | ✓ | ✓ | | | ✓ | |
|
||||
| Property method assignment | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Property name shorthand | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Rest parameters | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Spread | ✓ | ✓ | ✓ | ✓ | ✓ | |
|
||||
| Template literals | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Unicode regex | ✓ | ✓ | ✓ | | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### [Traceur](https://github.com/google/traceur-compiler)
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ function File(opts) {
|
||||
}
|
||||
|
||||
File.declarations = ["extends", "class-props", "slice", "apply-constructor",
|
||||
"tagged-template-literal"];
|
||||
"tagged-template-literal", "interop-require"];
|
||||
|
||||
File.normaliseOptions = function (opts) {
|
||||
opts = _.cloneDeep(opts || {});
|
||||
@@ -39,6 +39,17 @@ File.normaliseOptions = function (opts) {
|
||||
// normalise windows path separators to unix
|
||||
opts.filename = opts.filename.replace(/\\/g, "/");
|
||||
|
||||
opts.blacklist = util.arrayify(opts.blacklist);
|
||||
opts.whitelist = util.arrayify(opts.whitelist);
|
||||
|
||||
_.defaults(opts, {
|
||||
moduleRoot: opts.sourceRoot
|
||||
});
|
||||
|
||||
_.defaults(opts, {
|
||||
sourceRoot: opts.moduleRoot
|
||||
});
|
||||
|
||||
_.defaults(opts, {
|
||||
filenameRelative: opts.filename
|
||||
});
|
||||
@@ -59,7 +70,7 @@ File.normaliseOptions = function (opts) {
|
||||
};
|
||||
|
||||
File.prototype.getModuleFormatter = function (type) {
|
||||
var ModuleFormatter = transform.moduleFormatters[type];
|
||||
var ModuleFormatter = _.isFunction(type) ? type : transform.moduleFormatters[type];
|
||||
|
||||
if (!ModuleFormatter) {
|
||||
var loc = util.resolve(type);
|
||||
|
||||
@@ -165,6 +165,8 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.printJoin = function (print, nodes, opts) {
|
||||
if (!nodes || !nodes.length) return;
|
||||
|
||||
opts = opts || {};
|
||||
|
||||
var self = this;
|
||||
|
||||
@@ -17,6 +17,9 @@ exports.polyfill = function () {
|
||||
|
||||
exports.canCompile = util.canCompile;
|
||||
|
||||
// do not use this - this is for use by official maintained 6to5 plugins
|
||||
exports._util = util;
|
||||
|
||||
exports.transform = transform;
|
||||
|
||||
exports.transformFile = function (filename, opts, callback) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
require("./polyfill");
|
||||
|
||||
var sourceMapSupport = require("source-map-support");
|
||||
var util = require("./util");
|
||||
var to5 = require("./index");
|
||||
var _ = require("lodash");
|
||||
|
||||
@@ -71,7 +72,8 @@ var loader = function (m, filename) {
|
||||
var result = to5.transformFileSync(filename, {
|
||||
whitelist: whitelist,
|
||||
blacklist: blacklist,
|
||||
sourceMap: true
|
||||
sourceMap: true,
|
||||
modules: "commonInterop"
|
||||
});
|
||||
|
||||
maps[filename] = result.map;
|
||||
@@ -100,11 +102,11 @@ module.exports = function (opts) {
|
||||
if (_.isRegExp(opts)) opts = { ignore: opts };
|
||||
if (opts.ignoreRegex != null) opts.ignore = opts.ignoreRegex;
|
||||
|
||||
if (opts.only != null) onlyRegex = opts.only;
|
||||
if (opts.ignore != null) ignoreRegex = opts.ignore;
|
||||
if (opts.only != null) onlyRegex = util.regexify(opts.only);
|
||||
if (opts.ignore != null) ignoreRegex = util.regexify(opts.ignore);
|
||||
|
||||
if (opts.extensions) hookExtensions(opts.extensions);
|
||||
if (opts.extensions) hookExtensions(util.arrayify(opts.extensions));
|
||||
|
||||
if (opts.blacklist) blacklist = opts.blacklist;
|
||||
if (opts.whitelist) whitelist = opts.whitelist;
|
||||
if (opts.blacklist) blacklist = util.arrayify(opts.blacklist);
|
||||
if (opts.whitelist) whitelist = util.arrayify(opts.whitelist);
|
||||
};
|
||||
|
||||
3
lib/6to5/templates/interop-require.js
Normal file
3
lib/6to5/templates/interop-require.js
Normal file
@@ -0,0 +1,3 @@
|
||||
(function (obj) {
|
||||
return obj && (obj["default"] || obj);
|
||||
})
|
||||
29
lib/6to5/transformation/modules/common-interop.js
Normal file
29
lib/6to5/transformation/modules/common-interop.js
Normal file
@@ -0,0 +1,29 @@
|
||||
module.exports = CommonJSInteropFormatter;
|
||||
|
||||
var CommonJSFormatter = require("./common");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
function CommonJSInteropFormatter(file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
util.inherits(CommonJSInteropFormatter, CommonJSFormatter);
|
||||
|
||||
CommonJSInteropFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
|
||||
var variableName = t.getSpecifierName(specifier);
|
||||
|
||||
// import foo from "foo";
|
||||
if (specifier.default) {
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(variableName,
|
||||
t.callExpression(this.file.addDeclaration("interop-require"), [util.template("require", {
|
||||
MODULE_NAME: node.source.raw
|
||||
})])
|
||||
)
|
||||
]));
|
||||
return;
|
||||
}
|
||||
|
||||
CommonJSFormatter.prototype.importSpecifier.apply(this, arguments);
|
||||
};
|
||||
@@ -20,10 +20,11 @@ transform._ensureTransformerNames = function (type, keys) {
|
||||
transform.transformers = {};
|
||||
|
||||
transform.moduleFormatters = {
|
||||
common: require("./modules/common"),
|
||||
ignore: require("./modules/ignore"),
|
||||
amd: require("./modules/amd"),
|
||||
umd: require("./modules/umd")
|
||||
common: require("./modules/common"),
|
||||
commonInterop: require("./modules/common-interop"),
|
||||
ignore: require("./modules/ignore"),
|
||||
amd: require("./modules/amd"),
|
||||
umd: require("./modules/umd")
|
||||
};
|
||||
|
||||
_.each({
|
||||
|
||||
@@ -8,70 +8,63 @@
|
||||
* the same directory.
|
||||
*/
|
||||
|
||||
var assert = require("assert");
|
||||
var types = require("ast-types");
|
||||
var b = types.builders;
|
||||
var n = types.namedTypes;
|
||||
var leap = require("./leap");
|
||||
var meta = require("./meta");
|
||||
exports.Emitter = Emitter;
|
||||
|
||||
var runtimeProperty = require("./util").runtimeProperty;
|
||||
var assert = require("assert");
|
||||
var types = require("ast-types");
|
||||
var leap = require("./leap");
|
||||
var meta = require("./meta");
|
||||
var t = require("../../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var runtimeKeysMethod = runtimeProperty("keys");
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
var n = types.namedTypes;
|
||||
|
||||
function Emitter(contextId) {
|
||||
assert.ok(this instanceof Emitter);
|
||||
n.Identifier.assert(contextId);
|
||||
t.assertIdentifier(contextId);
|
||||
|
||||
Object.defineProperties(this, {
|
||||
// In order to make sure the context object does not collide with
|
||||
// anything in the local scope, we might have to rename it, so we
|
||||
// refer to it symbolically instead of just assuming that it will be
|
||||
// called "context".
|
||||
contextId: { value: contextId },
|
||||
// In order to make sure the context object does not collide with
|
||||
// anything in the local scope, we might have to rename it, so we
|
||||
// refer to it symbolically instead of just assuming that it will be
|
||||
// called "context".
|
||||
this.contextId = contextId;
|
||||
|
||||
// An append-only list of Statements that grows each time this.emit is
|
||||
// called.
|
||||
listing: { value: [] },
|
||||
// An append-only list of Statements that grows each time this.emit is
|
||||
// called.
|
||||
this.listing = [];
|
||||
|
||||
// A sparse array whose keys correspond to locations in this.listing
|
||||
// that have been marked as branch/jump targets.
|
||||
marked: { value: [true] },
|
||||
// A sparse array whose keys correspond to locations in this.listing
|
||||
// that have been marked as branch/jump targets.
|
||||
this.marked = [true];
|
||||
|
||||
// The last location will be marked when this.getDispatchLoop is
|
||||
// called.
|
||||
finalLoc: { value: loc() },
|
||||
// The last location will be marked when this.getDispatchLoop is
|
||||
// called.
|
||||
this.finalLoc = loc();
|
||||
|
||||
// A list of all leap.TryEntry statements emitted.
|
||||
tryEntries: { value: [] }
|
||||
});
|
||||
// A list of all leap.TryEntry statements emitted.
|
||||
this.tryEntries = [];
|
||||
|
||||
// The .leapManager property needs to be defined by a separate
|
||||
// defineProperties call so that .finalLoc will be visible to the
|
||||
// leap.LeapManager constructor.
|
||||
Object.defineProperties(this, {
|
||||
// Each time we evaluate the body of a loop, we tell this.leapManager
|
||||
// to enter a nested loop context that determines the meaning of break
|
||||
// and continue statements therein.
|
||||
leapManager: { value: new leap.LeapManager(this) }
|
||||
});
|
||||
// Each time we evaluate the body of a loop, we tell this.leapManager
|
||||
// to enter a nested loop context that determines the meaning of break
|
||||
// and continue statements therein.
|
||||
this.leapManager = new leap.LeapManager(this);
|
||||
}
|
||||
|
||||
var Ep = Emitter.prototype;
|
||||
exports.Emitter = Emitter;
|
||||
|
||||
// Offsets into this.listing that could be used as targets for branches or
|
||||
// jumps are represented as numeric Literal nodes. This representation has
|
||||
// the amazingly convenient benefit of allowing the exact value of the
|
||||
// location to be determined at any time, even after generating code that
|
||||
// refers to the location.
|
||||
function loc() {
|
||||
return b.literal(-1);
|
||||
return t.literal(-1);
|
||||
}
|
||||
|
||||
// Sets the exact value of the given location to the offset of the next
|
||||
// Statement emitted.
|
||||
Ep.mark = function(loc) {
|
||||
n.Literal.assert(loc);
|
||||
Emitter.prototype.mark = function(loc) {
|
||||
t.assertLiteral(loc);
|
||||
var index = this.listing.length;
|
||||
if (loc.value === -1) {
|
||||
loc.value = index;
|
||||
@@ -84,32 +77,31 @@ Ep.mark = function(loc) {
|
||||
return loc;
|
||||
};
|
||||
|
||||
Ep.emit = function(node) {
|
||||
if (n.Expression.check(node))
|
||||
node = b.expressionStatement(node);
|
||||
n.Statement.assert(node);
|
||||
Emitter.prototype.emit = function(node) {
|
||||
if (t.isExpression(node)) node = t.expressionStatement(node);
|
||||
t.assertStatement(node);
|
||||
this.listing.push(node);
|
||||
};
|
||||
|
||||
// Shorthand for emitting assignment statements. This will come in handy
|
||||
// for assignments to temporary variables.
|
||||
Ep.emitAssign = function(lhs, rhs) {
|
||||
Emitter.prototype.emitAssign = function(lhs, rhs) {
|
||||
this.emit(this.assign(lhs, rhs));
|
||||
return lhs;
|
||||
};
|
||||
|
||||
// Shorthand for an assignment statement.
|
||||
Ep.assign = function(lhs, rhs) {
|
||||
return b.expressionStatement(
|
||||
b.assignmentExpression("=", lhs, rhs));
|
||||
Emitter.prototype.assign = function(lhs, rhs) {
|
||||
return t.expressionStatement(
|
||||
t.assignmentExpression("=", lhs, rhs));
|
||||
};
|
||||
|
||||
// Convenience function for generating expressions like context.next,
|
||||
// context.sent, and context.rval.
|
||||
Ep.contextProperty = function(name, computed) {
|
||||
return b.memberExpression(
|
||||
Emitter.prototype.contextProperty = function(name, computed) {
|
||||
return t.memberExpression(
|
||||
this.contextId,
|
||||
computed ? b.literal(name) : b.identifier(name),
|
||||
computed ? t.literal(name) : t.identifier(name),
|
||||
!!computed
|
||||
);
|
||||
};
|
||||
@@ -124,19 +116,18 @@ var volatileContextPropertyNames = {
|
||||
// A "volatile" context property is a MemberExpression like context.sent
|
||||
// that should probably be stored in a temporary variable when there's a
|
||||
// possibility the property will get overwritten.
|
||||
Ep.isVolatileContextProperty = function(expr) {
|
||||
if (n.MemberExpression.check(expr)) {
|
||||
Emitter.prototype.isVolatileContextProperty = function(expr) {
|
||||
if (t.isMemberExpression(expr)) {
|
||||
if (expr.computed) {
|
||||
// If it's a computed property such as context[couldBeAnything],
|
||||
// assume the worst in terms of volatility.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (n.Identifier.check(expr.object) &&
|
||||
n.Identifier.check(expr.property) &&
|
||||
if (t.isIdentifier(expr.object) &&
|
||||
t.isIdentifier(expr.property) &&
|
||||
expr.object.name === this.contextId.name &&
|
||||
hasOwn.call(volatileContextPropertyNames,
|
||||
expr.property.name)) {
|
||||
_.has(volatileContextPropertyNames, expr.property.name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -145,7 +136,7 @@ Ep.isVolatileContextProperty = function(expr) {
|
||||
};
|
||||
|
||||
// Shorthand for setting context.rval and jumping to `context.stop()`.
|
||||
Ep.stop = function(rval) {
|
||||
Emitter.prototype.stop = function(rval) {
|
||||
if (rval) {
|
||||
this.setReturnValue(rval);
|
||||
}
|
||||
@@ -153,8 +144,8 @@ Ep.stop = function(rval) {
|
||||
this.jump(this.finalLoc);
|
||||
};
|
||||
|
||||
Ep.setReturnValue = function(valuePath) {
|
||||
n.Expression.assert(valuePath.value);
|
||||
Emitter.prototype.setReturnValue = function(valuePath) {
|
||||
t.assertExpression(valuePath.value);
|
||||
|
||||
this.emitAssign(
|
||||
this.contextProperty("rval"),
|
||||
@@ -162,10 +153,10 @@ Ep.setReturnValue = function(valuePath) {
|
||||
);
|
||||
};
|
||||
|
||||
Ep.clearPendingException = function(tryLoc, assignee) {
|
||||
n.Literal.assert(tryLoc);
|
||||
Emitter.prototype.clearPendingException = function(tryLoc, assignee) {
|
||||
t.assertLiteral(tryLoc);
|
||||
|
||||
var catchCall = b.callExpression(
|
||||
var catchCall = t.callExpression(
|
||||
this.contextProperty("catch", true),
|
||||
[tryLoc]
|
||||
);
|
||||
@@ -179,44 +170,43 @@ Ep.clearPendingException = function(tryLoc, assignee) {
|
||||
|
||||
// Emits code for an unconditional jump to the given location, even if the
|
||||
// exact value of the location is not yet known.
|
||||
Ep.jump = function(toLoc) {
|
||||
Emitter.prototype.jump = function(toLoc) {
|
||||
this.emitAssign(this.contextProperty("next"), toLoc);
|
||||
this.emit(b.breakStatement());
|
||||
this.emit(t.breakStatement());
|
||||
};
|
||||
|
||||
// Conditional jump.
|
||||
Ep.jumpIf = function(test, toLoc) {
|
||||
n.Expression.assert(test);
|
||||
n.Literal.assert(toLoc);
|
||||
Emitter.prototype.jumpIf = function(test, toLoc) {
|
||||
t.assertExpression(test);
|
||||
t.assertLiteral(toLoc);
|
||||
|
||||
this.emit(b.ifStatement(
|
||||
this.emit(t.ifStatement(
|
||||
test,
|
||||
b.blockStatement([
|
||||
t.blockStatement([
|
||||
this.assign(this.contextProperty("next"), toLoc),
|
||||
b.breakStatement()
|
||||
t.breakStatement()
|
||||
])
|
||||
));
|
||||
};
|
||||
|
||||
// Conditional jump, with the condition negated.
|
||||
Ep.jumpIfNot = function(test, toLoc) {
|
||||
n.Expression.assert(test);
|
||||
n.Literal.assert(toLoc);
|
||||
Emitter.prototype.jumpIfNot = function(test, toLoc) {
|
||||
t.assertExpression(test);
|
||||
t.assertLiteral(toLoc);
|
||||
|
||||
var negatedTest;
|
||||
if (n.UnaryExpression.check(test) &&
|
||||
test.operator === "!") {
|
||||
if (t.isUnaryExpression(test) && test.operator === "!") {
|
||||
// Avoid double negation.
|
||||
negatedTest = test.argument;
|
||||
} else {
|
||||
negatedTest = b.unaryExpression("!", test);
|
||||
negatedTest = t.unaryExpression("!", test);
|
||||
}
|
||||
|
||||
this.emit(b.ifStatement(
|
||||
this.emit(t.ifStatement(
|
||||
negatedTest,
|
||||
b.blockStatement([
|
||||
t.blockStatement([
|
||||
this.assign(this.contextProperty("next"), toLoc),
|
||||
b.breakStatement()
|
||||
t.breakStatement()
|
||||
])
|
||||
));
|
||||
};
|
||||
@@ -227,15 +217,15 @@ Ep.jumpIfNot = function(test, toLoc) {
|
||||
// other local variables, and since we just increment `nextTempId`
|
||||
// monotonically, uniqueness is assured.
|
||||
var nextTempId = 0;
|
||||
Ep.makeTempVar = function() {
|
||||
Emitter.prototype.makeTempVar = function() {
|
||||
return this.contextProperty("t" + nextTempId++);
|
||||
};
|
||||
|
||||
Ep.getContextFunction = function(id) {
|
||||
var node = b.functionExpression(
|
||||
id || null/*Anonymous*/,
|
||||
Emitter.prototype.getContextFunction = function(id) {
|
||||
var node = t.functionExpression(
|
||||
id || null,
|
||||
[this.contextId],
|
||||
b.blockStatement([this.getDispatchLoop()]),
|
||||
t.blockStatement([this.getDispatchLoop()]),
|
||||
false, // Not a generator anymore!
|
||||
false // Nor an expression.
|
||||
);
|
||||
@@ -254,7 +244,7 @@ Ep.getContextFunction = function(id) {
|
||||
//
|
||||
// Each marked location in this.listing will correspond to one generated
|
||||
// case statement.
|
||||
Ep.getDispatchLoop = function() {
|
||||
Emitter.prototype.getDispatchLoop = function() {
|
||||
var self = this;
|
||||
var cases = [];
|
||||
var current;
|
||||
@@ -265,9 +255,7 @@ Ep.getDispatchLoop = function() {
|
||||
|
||||
self.listing.forEach(function(stmt, i) {
|
||||
if (self.marked.hasOwnProperty(i)) {
|
||||
cases.push(b.switchCase(
|
||||
b.literal(i),
|
||||
current = []));
|
||||
cases.push(t.switchCase(t.literal(i), current = []));
|
||||
alreadyEnded = false;
|
||||
}
|
||||
|
||||
@@ -283,24 +271,24 @@ Ep.getDispatchLoop = function() {
|
||||
this.finalLoc.value = this.listing.length;
|
||||
|
||||
cases.push(
|
||||
b.switchCase(this.finalLoc, [
|
||||
t.switchCase(this.finalLoc, [
|
||||
// Intentionally fall through to the "end" case...
|
||||
]),
|
||||
|
||||
// So that the runtime can jump to the final location without having
|
||||
// to know its offset, we provide the "end" case as a synonym.
|
||||
b.switchCase(b.literal("end"), [
|
||||
t.switchCase(t.literal("end"), [
|
||||
// This will check/clear both context.thrown and context.rval.
|
||||
b.returnStatement(
|
||||
b.callExpression(this.contextProperty("stop"), [])
|
||||
t.returnStatement(
|
||||
t.callExpression(this.contextProperty("stop"), [])
|
||||
)
|
||||
])
|
||||
);
|
||||
|
||||
return b.whileStatement(
|
||||
b.literal(true),
|
||||
b.switchStatement(
|
||||
b.assignmentExpression(
|
||||
return t.whileStatement(
|
||||
t.literal(true),
|
||||
t.switchStatement(
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
this.contextProperty("prev"),
|
||||
this.contextProperty("next")
|
||||
@@ -312,13 +300,13 @@ Ep.getDispatchLoop = function() {
|
||||
|
||||
// See comment above re: alreadyEnded.
|
||||
function isSwitchCaseEnder(stmt) {
|
||||
return n.BreakStatement.check(stmt) ||
|
||||
n.ContinueStatement.check(stmt) ||
|
||||
n.ReturnStatement.check(stmt) ||
|
||||
n.ThrowStatement.check(stmt);
|
||||
return t.isBreakStatement(stmt) ||
|
||||
t.isContinueStatement(stmt) ||
|
||||
t.isReturnStatement(stmt) ||
|
||||
t.isThrowStatement(stmt);
|
||||
}
|
||||
|
||||
Ep.getTryEntryList = function() {
|
||||
Emitter.prototype.getTryEntryList = function() {
|
||||
if (this.tryEntries.length === 0) {
|
||||
// To avoid adding a needless [] to the majority of runtime.wrap
|
||||
// argument lists, force the caller to handle this case specially.
|
||||
@@ -327,7 +315,7 @@ Ep.getTryEntryList = function() {
|
||||
|
||||
var lastLocValue = 0;
|
||||
|
||||
return b.arrayExpression(
|
||||
return t.arrayExpression(
|
||||
this.tryEntries.map(function(tryEntry) {
|
||||
var thisLocValue = tryEntry.firstLoc.value;
|
||||
assert.ok(thisLocValue >= lastLocValue, "try entries out of order");
|
||||
@@ -346,7 +334,7 @@ Ep.getTryEntryList = function() {
|
||||
triple[2] = fe.firstLoc;
|
||||
}
|
||||
|
||||
return b.arrayExpression(triple);
|
||||
return t.arrayExpression(triple);
|
||||
})
|
||||
);
|
||||
};
|
||||
@@ -358,29 +346,26 @@ Ep.getTryEntryList = function() {
|
||||
|
||||
// No destructive modification of AST nodes.
|
||||
|
||||
Ep.explode = function(path, ignoreResult) {
|
||||
Emitter.prototype.explode = function(path, ignoreResult) {
|
||||
assert.ok(path instanceof types.NodePath);
|
||||
|
||||
var node = path.value;
|
||||
var self = this;
|
||||
|
||||
n.Node.assert(node);
|
||||
n.Node.check(node);
|
||||
|
||||
if (n.Statement.check(node))
|
||||
if (t.isStatement(node))
|
||||
return self.explodeStatement(path);
|
||||
|
||||
if (n.Expression.check(node))
|
||||
if (t.isExpression(node))
|
||||
return self.explodeExpression(path, ignoreResult);
|
||||
|
||||
if (n.Declaration.check(node))
|
||||
if (t.isDeclaration(node))
|
||||
throw getDeclError(node);
|
||||
|
||||
switch (node.type) {
|
||||
case "Program":
|
||||
return path.get("body").map(
|
||||
self.explodeStatement,
|
||||
self
|
||||
);
|
||||
return path.get("body").map(self.explodeStatement, self);
|
||||
|
||||
case "VariableDeclarator":
|
||||
throw getDeclError(node);
|
||||
@@ -390,13 +375,10 @@ Ep.explode = function(path, ignoreResult) {
|
||||
case "Property":
|
||||
case "SwitchCase":
|
||||
case "CatchClause":
|
||||
throw new Error(
|
||||
node.type + " nodes should be handled by their parents");
|
||||
throw new Error(node.type + " nodes should be handled by their parents");
|
||||
|
||||
default:
|
||||
throw new Error(
|
||||
"unknown Node of type " +
|
||||
JSON.stringify(node.type));
|
||||
throw new Error("unknown Node of type " + JSON.stringify(node.type));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -407,24 +389,24 @@ function getDeclError(node) {
|
||||
JSON.stringify(node));
|
||||
}
|
||||
|
||||
Ep.explodeStatement = function(path, labelId) {
|
||||
Emitter.prototype.explodeStatement = function(path, labelId) {
|
||||
assert.ok(path instanceof types.NodePath);
|
||||
|
||||
var stmt = path.value;
|
||||
var self = this;
|
||||
var after, head;
|
||||
|
||||
n.Statement.assert(stmt);
|
||||
t.assertStatement(stmt);
|
||||
|
||||
if (labelId) {
|
||||
n.Identifier.assert(labelId);
|
||||
t.assertIdentifier(labelId);
|
||||
} else {
|
||||
labelId = null;
|
||||
}
|
||||
|
||||
// Explode BlockStatement nodes even if they do not contain a yield,
|
||||
// because we don't want or need the curly braces.
|
||||
if (n.BlockStatement.check(stmt)) {
|
||||
if (t.isBlockStatement(stmt)) {
|
||||
return path.get("body").each(
|
||||
self.explodeStatement,
|
||||
self
|
||||
@@ -520,7 +502,7 @@ Ep.explodeStatement = function(path, labelId) {
|
||||
break;
|
||||
|
||||
case "ForInStatement":
|
||||
n.Identifier.assert(stmt.left);
|
||||
t.assertIdentifier(stmt.left);
|
||||
|
||||
head = loc();
|
||||
after = loc();
|
||||
@@ -528,7 +510,7 @@ Ep.explodeStatement = function(path, labelId) {
|
||||
var keyIterNextFn = self.makeTempVar();
|
||||
self.emitAssign(
|
||||
keyIterNextFn,
|
||||
b.callExpression(
|
||||
t.callExpression(
|
||||
runtimeKeysMethod,
|
||||
[self.explodeExpression(path.get("right"))]
|
||||
)
|
||||
@@ -538,13 +520,13 @@ Ep.explodeStatement = function(path, labelId) {
|
||||
|
||||
var keyInfoTmpVar = self.makeTempVar();
|
||||
self.jumpIf(
|
||||
b.memberExpression(
|
||||
b.assignmentExpression(
|
||||
t.memberExpression(
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
keyInfoTmpVar,
|
||||
b.callExpression(keyIterNextFn, [])
|
||||
t.callExpression(keyIterNextFn, [])
|
||||
),
|
||||
b.identifier("done"),
|
||||
t.identifier("done"),
|
||||
false
|
||||
),
|
||||
after
|
||||
@@ -552,9 +534,9 @@ Ep.explodeStatement = function(path, labelId) {
|
||||
|
||||
self.emitAssign(
|
||||
stmt.left,
|
||||
b.memberExpression(
|
||||
t.memberExpression(
|
||||
keyInfoTmpVar,
|
||||
b.identifier("value"),
|
||||
t.identifier("value"),
|
||||
false
|
||||
)
|
||||
);
|
||||
@@ -604,11 +586,11 @@ Ep.explodeStatement = function(path, labelId) {
|
||||
|
||||
for (var i = cases.length - 1; i >= 0; --i) {
|
||||
var c = cases[i];
|
||||
n.SwitchCase.assert(c);
|
||||
t.assertSwitchCase(c);
|
||||
|
||||
if (c.test) {
|
||||
condition = b.conditionalExpression(
|
||||
b.binaryExpression("===", disc, c.test),
|
||||
condition = t.conditionalExpression(
|
||||
t.binaryExpression("===", disc, c.test),
|
||||
caseLocs[i] = loc(),
|
||||
condition
|
||||
);
|
||||
@@ -724,7 +706,7 @@ Ep.explodeStatement = function(path, labelId) {
|
||||
|
||||
var catchScope = bodyPath.scope;
|
||||
var catchParamName = handler.param.name;
|
||||
n.CatchClause.assert(catchScope.node);
|
||||
t.assertCatchClause(catchScope.node);
|
||||
assert.strictEqual(catchScope.lookup(catchParamName), catchScope);
|
||||
|
||||
types.visit(bodyPath, {
|
||||
@@ -749,7 +731,7 @@ Ep.explodeStatement = function(path, labelId) {
|
||||
self.explodeStatement(path.get("finalizer"));
|
||||
});
|
||||
|
||||
self.emit(b.callExpression(
|
||||
self.emit(t.callExpression(
|
||||
self.contextProperty("finish"),
|
||||
[finallyEntry.firstLoc]
|
||||
));
|
||||
@@ -761,25 +743,22 @@ Ep.explodeStatement = function(path, labelId) {
|
||||
break;
|
||||
|
||||
case "ThrowStatement":
|
||||
self.emit(b.throwStatement(
|
||||
self.emit(t.throwStatement(
|
||||
self.explodeExpression(path.get("argument"))
|
||||
));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(
|
||||
"unknown Statement of type " +
|
||||
JSON.stringify(stmt.type));
|
||||
throw new Error("unknown Statement of type " + JSON.stringify(stmt.type));
|
||||
}
|
||||
};
|
||||
|
||||
Ep.emitAbruptCompletion = function(record) {
|
||||
Emitter.prototype.emitAbruptCompletion = function(record) {
|
||||
if (!isValidCompletion(record)) {
|
||||
assert.ok(
|
||||
false,
|
||||
"invalid completion record: " +
|
||||
JSON.stringify(record)
|
||||
"invalid completion record: " + JSON.stringify(record)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -788,23 +767,21 @@ Ep.emitAbruptCompletion = function(record) {
|
||||
"normal completions are not abrupt"
|
||||
);
|
||||
|
||||
var abruptArgs = [b.literal(record.type)];
|
||||
var abruptArgs = [t.literal(record.type)];
|
||||
|
||||
if (record.type === "break" ||
|
||||
record.type === "continue") {
|
||||
n.Literal.assert(record.target);
|
||||
if (record.type === "break" || record.type === "continue") {
|
||||
t.assertLiteral(record.target);
|
||||
abruptArgs[1] = record.target;
|
||||
} else if (record.type === "return" ||
|
||||
record.type === "throw") {
|
||||
} else if (record.type === "return" || record.type === "throw") {
|
||||
if (record.value) {
|
||||
n.Expression.assert(record.value);
|
||||
t.assertExpression(record.value);
|
||||
abruptArgs[1] = record.value;
|
||||
}
|
||||
}
|
||||
|
||||
this.emit(
|
||||
b.returnStatement(
|
||||
b.callExpression(
|
||||
t.returnStatement(
|
||||
t.callExpression(
|
||||
this.contextProperty("abrupt"),
|
||||
abruptArgs
|
||||
)
|
||||
@@ -816,21 +793,20 @@ function isValidCompletion(record) {
|
||||
var type = record.type;
|
||||
|
||||
if (type === "normal") {
|
||||
return !hasOwn.call(record, "target");
|
||||
return !_.has(record, "target");
|
||||
}
|
||||
|
||||
if (type === "break" || type === "continue") {
|
||||
return !hasOwn.call(record, "value") && n.Literal.check(record.target);
|
||||
return !_.has(record, "value") && t.isLiteral(record.target);
|
||||
}
|
||||
|
||||
if (type === "return" || type === "throw") {
|
||||
return hasOwn.call(record, "value") && !hasOwn.call(record, "target");
|
||||
return _.has(record, "value") && !_.has(record, "target");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Not all offsets into emitter.listing are potential jump targets. For
|
||||
// example, execution typically falls into the beginning of a try block
|
||||
// without jumping directly there. This method returns the current offset
|
||||
@@ -840,8 +816,8 @@ function isValidCompletion(record) {
|
||||
// statements). There's no logical harm in marking such locations as jump
|
||||
// targets, but minimizing the number of switch cases keeps the generated
|
||||
// code shorter.
|
||||
Ep.getUnmarkedCurrentLoc = function() {
|
||||
return b.literal(this.listing.length);
|
||||
Emitter.prototype.getUnmarkedCurrentLoc = function() {
|
||||
return t.literal(this.listing.length);
|
||||
};
|
||||
|
||||
// The context.prev property takes the value of context.next whenever we
|
||||
@@ -854,9 +830,9 @@ Ep.getUnmarkedCurrentLoc = function() {
|
||||
// would know the location of the current instruction with complete
|
||||
// precision at all times, but we don't have that luxury here, as it would
|
||||
// be costly and verbose to set context.prev before every statement.
|
||||
Ep.updateContextPrevLoc = function(loc) {
|
||||
Emitter.prototype.updateContextPrevLoc = function(loc) {
|
||||
if (loc) {
|
||||
n.Literal.assert(loc);
|
||||
t.assertLiteral(loc);
|
||||
|
||||
if (loc.value === -1) {
|
||||
// If an uninitialized location literal was passed in, set its value
|
||||
@@ -877,12 +853,12 @@ Ep.updateContextPrevLoc = function(loc) {
|
||||
this.emitAssign(this.contextProperty("prev"), loc);
|
||||
};
|
||||
|
||||
Ep.explodeExpression = function(path, ignoreResult) {
|
||||
Emitter.prototype.explodeExpression = function(path, ignoreResult) {
|
||||
assert.ok(path instanceof types.NodePath);
|
||||
|
||||
var expr = path.value;
|
||||
if (expr) {
|
||||
n.Expression.assert(expr);
|
||||
t.assertExpression(expr);
|
||||
} else {
|
||||
return expr;
|
||||
}
|
||||
@@ -891,7 +867,7 @@ Ep.explodeExpression = function(path, ignoreResult) {
|
||||
var result, after; // Used optionally by several cases below.
|
||||
|
||||
function finish(expr) {
|
||||
n.Expression.assert(expr);
|
||||
t.assertExpression(expr);
|
||||
if (ignoreResult) {
|
||||
self.emit(expr);
|
||||
} else {
|
||||
@@ -963,7 +939,7 @@ Ep.explodeExpression = function(path, ignoreResult) {
|
||||
return finish(self.explodeExpression(path.get("expression")));
|
||||
|
||||
case "MemberExpression":
|
||||
return finish(b.memberExpression(
|
||||
return finish(t.memberExpression(
|
||||
self.explodeExpression(path.get("object")),
|
||||
expr.computed ? explodeViaTempVar(null, path.get("property")) : expr.property,
|
||||
expr.computed
|
||||
@@ -979,15 +955,14 @@ Ep.explodeExpression = function(path, ignoreResult) {
|
||||
// MemberExpression, then we need to force it to be unqualified by
|
||||
// using the (0, object.property)(...) trick; otherwise, it will
|
||||
// receive the object of the MemberExpression as its `this` object.
|
||||
if (!n.MemberExpression.check(oldCalleePath.node) &&
|
||||
n.MemberExpression.check(newCallee)) {
|
||||
newCallee = b.sequenceExpression([
|
||||
b.literal(0),
|
||||
if (!t.isMemberExpression(oldCalleePath.node) && t.isMemberExpression(newCallee)) {
|
||||
newCallee = t.sequenceExpression([
|
||||
t.literal(0),
|
||||
newCallee
|
||||
]);
|
||||
}
|
||||
|
||||
return finish(b.callExpression(
|
||||
return finish(t.callExpression(
|
||||
newCallee,
|
||||
path.get("arguments").map(function(argPath) {
|
||||
return explodeViaTempVar(null, argPath);
|
||||
@@ -995,7 +970,7 @@ Ep.explodeExpression = function(path, ignoreResult) {
|
||||
));
|
||||
|
||||
case "NewExpression":
|
||||
return finish(b.newExpression(
|
||||
return finish(t.newExpression(
|
||||
explodeViaTempVar(null, path.get("callee")),
|
||||
path.get("arguments").map(function(argPath) {
|
||||
return explodeViaTempVar(null, argPath);
|
||||
@@ -1003,9 +978,9 @@ Ep.explodeExpression = function(path, ignoreResult) {
|
||||
));
|
||||
|
||||
case "ObjectExpression":
|
||||
return finish(b.objectExpression(
|
||||
return finish(t.objectExpression(
|
||||
path.get("properties").map(function(propPath) {
|
||||
return b.property(
|
||||
return t.property(
|
||||
propPath.value.kind,
|
||||
propPath.value.key,
|
||||
explodeViaTempVar(null, propPath.get("value"))
|
||||
@@ -1014,7 +989,7 @@ Ep.explodeExpression = function(path, ignoreResult) {
|
||||
));
|
||||
|
||||
case "ArrayExpression":
|
||||
return finish(b.arrayExpression(
|
||||
return finish(t.arrayExpression(
|
||||
path.get("elements").map(function(elemPath) {
|
||||
return explodeViaTempVar(null, elemPath);
|
||||
})
|
||||
@@ -1077,7 +1052,7 @@ Ep.explodeExpression = function(path, ignoreResult) {
|
||||
return result;
|
||||
|
||||
case "UnaryExpression":
|
||||
return finish(b.unaryExpression(
|
||||
return finish(t.unaryExpression(
|
||||
expr.operator,
|
||||
// Can't (and don't need to) break up the syntax of the argument.
|
||||
// Think about delete a[b].
|
||||
@@ -1086,21 +1061,21 @@ Ep.explodeExpression = function(path, ignoreResult) {
|
||||
));
|
||||
|
||||
case "BinaryExpression":
|
||||
return finish(b.binaryExpression(
|
||||
return finish(t.binaryExpression(
|
||||
expr.operator,
|
||||
explodeViaTempVar(null, path.get("left")),
|
||||
explodeViaTempVar(null, path.get("right"))
|
||||
));
|
||||
|
||||
case "AssignmentExpression":
|
||||
return finish(b.assignmentExpression(
|
||||
return finish(t.assignmentExpression(
|
||||
expr.operator,
|
||||
self.explodeExpression(path.get("left")),
|
||||
self.explodeExpression(path.get("right"))
|
||||
));
|
||||
|
||||
case "UpdateExpression":
|
||||
return finish(b.updateExpression(
|
||||
return finish(t.updateExpression(
|
||||
expr.operator,
|
||||
self.explodeExpression(path.get("argument")),
|
||||
expr.prefix
|
||||
@@ -1113,10 +1088,10 @@ Ep.explodeExpression = function(path, ignoreResult) {
|
||||
if (arg && expr.delegate) {
|
||||
result = self.makeTempVar();
|
||||
|
||||
self.emit(b.returnStatement(b.callExpression(
|
||||
self.emit(t.returnStatement(t.callExpression(
|
||||
self.contextProperty("delegateYield"), [
|
||||
arg,
|
||||
b.literal(result.property.name),
|
||||
t.literal(result.property.name),
|
||||
after
|
||||
]
|
||||
)));
|
||||
@@ -1127,7 +1102,7 @@ Ep.explodeExpression = function(path, ignoreResult) {
|
||||
}
|
||||
|
||||
self.emitAssign(self.contextProperty("next"), after);
|
||||
self.emit(b.returnStatement(arg || null));
|
||||
self.emit(t.returnStatement(arg || null));
|
||||
self.mark(after);
|
||||
|
||||
return self.contextProperty("sent");
|
||||
|
||||
@@ -3,16 +3,15 @@
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* https://raw.github.com/facebook/regenerator/master/LICENSE file. An
|
||||
* https://raw.githut.com/facebook/regenerator/master/LICENSE file. An
|
||||
* additional grant of patent rights can be found in the PATENTS file in
|
||||
* the same directory.
|
||||
*/
|
||||
|
||||
var assert = require("assert");
|
||||
var types = require("ast-types");
|
||||
var n = types.namedTypes;
|
||||
var b = types.builders;
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
var types = require("ast-types");
|
||||
var t = require("../../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
// The hoist function takes a FunctionExpression or FunctionDeclaration
|
||||
// and replaces any Declaration nodes in its body with assignments, then
|
||||
@@ -20,19 +19,19 @@ var hasOwn = Object.prototype.hasOwnProperty;
|
||||
// declarations.
|
||||
exports.hoist = function(funPath) {
|
||||
assert.ok(funPath instanceof types.NodePath);
|
||||
n.Function.assert(funPath.value);
|
||||
t.assertFunction(funPath.value);
|
||||
|
||||
var vars = {};
|
||||
|
||||
function varDeclToExpr(vdec, includeIdentifiers) {
|
||||
n.VariableDeclaration.assert(vdec);
|
||||
t.assertVariableDeclaration(vdec);
|
||||
var exprs = [];
|
||||
|
||||
vdec.declarations.forEach(function(dec) {
|
||||
vars[dec.id.name] = dec.id;
|
||||
|
||||
if (dec.init) {
|
||||
exprs.push(b.assignmentExpression(
|
||||
exprs.push(t.assignmentExpression(
|
||||
"=", dec.id, dec.init
|
||||
));
|
||||
} else if (includeIdentifiers) {
|
||||
@@ -46,7 +45,7 @@ exports.hoist = function(funPath) {
|
||||
if (exprs.length === 1)
|
||||
return exprs[0];
|
||||
|
||||
return b.sequenceExpression(exprs);
|
||||
return t.sequenceExpression(exprs);
|
||||
}
|
||||
|
||||
types.visit(funPath.get("body"), {
|
||||
@@ -57,7 +56,7 @@ exports.hoist = function(funPath) {
|
||||
} else {
|
||||
// We don't need to traverse this expression any further because
|
||||
// there can't be any new declarations inside an expression.
|
||||
return b.expressionStatement(expr);
|
||||
return t.expressionStatement(expr);
|
||||
}
|
||||
|
||||
// Since the original node has been either removed or replaced,
|
||||
@@ -67,7 +66,7 @@ exports.hoist = function(funPath) {
|
||||
|
||||
visitForStatement: function(path) {
|
||||
var init = path.value.init;
|
||||
if (n.VariableDeclaration.check(init)) {
|
||||
if (t.isVariableDeclaration(init)) {
|
||||
path.get("init").replace(varDeclToExpr(init, false));
|
||||
}
|
||||
this.traverse(path);
|
||||
@@ -75,7 +74,7 @@ exports.hoist = function(funPath) {
|
||||
|
||||
visitForInStatement: function(path) {
|
||||
var left = path.value.left;
|
||||
if (n.VariableDeclaration.check(left)) {
|
||||
if (t.isVariableDeclaration(left)) {
|
||||
path.get("left").replace(varDeclToExpr(left, true));
|
||||
}
|
||||
this.traverse(path);
|
||||
@@ -85,11 +84,11 @@ exports.hoist = function(funPath) {
|
||||
var node = path.value;
|
||||
vars[node.id.name] = node.id;
|
||||
|
||||
var assignment = b.expressionStatement(
|
||||
b.assignmentExpression(
|
||||
var assignment = t.expressionStatement(
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
node.id,
|
||||
b.functionExpression(
|
||||
t.functionExpression(
|
||||
node.id,
|
||||
node.params,
|
||||
node.body,
|
||||
@@ -99,7 +98,7 @@ exports.hoist = function(funPath) {
|
||||
)
|
||||
);
|
||||
|
||||
if (n.BlockStatement.check(path.parent.node)) {
|
||||
if (t.isBlockStatement(path.parent.node)) {
|
||||
// Insert the assignment form before the first statement in the
|
||||
// enclosing block.
|
||||
path.parent.get("body").unshift(assignment);
|
||||
@@ -128,7 +127,7 @@ exports.hoist = function(funPath) {
|
||||
var paramNames = {};
|
||||
funPath.get("params").each(function(paramPath) {
|
||||
var param = paramPath.value;
|
||||
if (n.Identifier.check(param)) {
|
||||
if (t.isIdentifier(param)) {
|
||||
paramNames[param.name] = param;
|
||||
} else {
|
||||
// Variables declared by destructuring parameter patterns will be
|
||||
@@ -139,8 +138,8 @@ exports.hoist = function(funPath) {
|
||||
var declarations = [];
|
||||
|
||||
Object.keys(vars).forEach(function(name) {
|
||||
if (!hasOwn.call(paramNames, name)) {
|
||||
declarations.push(b.variableDeclarator(vars[name], null));
|
||||
if (!_.has(paramNames, name)) {
|
||||
declarations.push(t.variableDeclarator(vars[name], null));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -148,5 +147,5 @@ exports.hoist = function(funPath) {
|
||||
return null; // Be sure to handle this case!
|
||||
}
|
||||
|
||||
return b.variableDeclaration("var", declarations);
|
||||
return t.variableDeclaration("var", declarations);
|
||||
};
|
||||
|
||||
@@ -8,10 +8,19 @@
|
||||
* the same directory.
|
||||
*/
|
||||
|
||||
exports.FunctionEntry = FunctionEntry;
|
||||
exports.FinallyEntry = FinallyEntry;
|
||||
exports.SwitchEntry = SwitchEntry;
|
||||
exports.LeapManager = LeapManager;
|
||||
exports.CatchEntry = CatchEntry;
|
||||
exports.LoopEntry = LoopEntry;
|
||||
exports.TryEntry = TryEntry;
|
||||
|
||||
var assert = require("assert");
|
||||
var types = require("ast-types");
|
||||
var n = types.namedTypes;
|
||||
var inherits = require("util").inherits;
|
||||
var util = require("util");
|
||||
var t = require("../../../types");
|
||||
|
||||
var inherits = util.inherits;
|
||||
|
||||
function Entry() {
|
||||
assert.ok(this instanceof Entry);
|
||||
@@ -20,55 +29,46 @@ function Entry() {
|
||||
function FunctionEntry(returnLoc) {
|
||||
Entry.call(this);
|
||||
|
||||
n.Literal.assert(returnLoc);
|
||||
t.assertLiteral(returnLoc);
|
||||
|
||||
Object.defineProperties(this, {
|
||||
returnLoc: { value: returnLoc }
|
||||
});
|
||||
this.returnLoc = returnLoc;
|
||||
}
|
||||
|
||||
inherits(FunctionEntry, Entry);
|
||||
exports.FunctionEntry = FunctionEntry;
|
||||
|
||||
function LoopEntry(breakLoc, continueLoc, label) {
|
||||
Entry.call(this);
|
||||
|
||||
n.Literal.assert(breakLoc);
|
||||
n.Literal.assert(continueLoc);
|
||||
t.assertLiteral(breakLoc);
|
||||
t.assertLiteral(continueLoc);
|
||||
|
||||
if (label) {
|
||||
n.Identifier.assert(label);
|
||||
t.assertIdentifier(label);
|
||||
} else {
|
||||
label = null;
|
||||
}
|
||||
|
||||
Object.defineProperties(this, {
|
||||
breakLoc: { value: breakLoc },
|
||||
continueLoc: { value: continueLoc },
|
||||
label: { value: label }
|
||||
});
|
||||
this.breakLoc = breakLoc;
|
||||
this.continueLoc = continueLoc;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
inherits(LoopEntry, Entry);
|
||||
exports.LoopEntry = LoopEntry;
|
||||
|
||||
function SwitchEntry(breakLoc) {
|
||||
Entry.call(this);
|
||||
|
||||
n.Literal.assert(breakLoc);
|
||||
t.assertLiteral(breakLoc);
|
||||
|
||||
Object.defineProperties(this, {
|
||||
breakLoc: { value: breakLoc }
|
||||
});
|
||||
this.breakLoc = breakLoc;
|
||||
}
|
||||
|
||||
inherits(SwitchEntry, Entry);
|
||||
exports.SwitchEntry = SwitchEntry;
|
||||
|
||||
function TryEntry(firstLoc, catchEntry, finallyEntry) {
|
||||
Entry.call(this);
|
||||
|
||||
n.Literal.assert(firstLoc);
|
||||
t.assertLiteral(firstLoc);
|
||||
|
||||
if (catchEntry) {
|
||||
assert.ok(catchEntry instanceof CatchEntry);
|
||||
@@ -85,43 +85,34 @@ function TryEntry(firstLoc, catchEntry, finallyEntry) {
|
||||
// Have to have one or the other (or both).
|
||||
assert.ok(catchEntry || finallyEntry);
|
||||
|
||||
Object.defineProperties(this, {
|
||||
firstLoc: { value: firstLoc },
|
||||
catchEntry: { value: catchEntry },
|
||||
finallyEntry: { value: finallyEntry }
|
||||
});
|
||||
this.firstLoc = firstLoc;
|
||||
this.catchEntry = catchEntry;
|
||||
this.finallyEntry = finallyEntry;
|
||||
}
|
||||
|
||||
inherits(TryEntry, Entry);
|
||||
exports.TryEntry = TryEntry;
|
||||
|
||||
function CatchEntry(firstLoc, paramId) {
|
||||
Entry.call(this);
|
||||
|
||||
n.Literal.assert(firstLoc);
|
||||
n.Identifier.assert(paramId);
|
||||
t.assertLiteral(firstLoc);
|
||||
t.assertIdentifier(paramId);
|
||||
|
||||
Object.defineProperties(this, {
|
||||
firstLoc: { value: firstLoc },
|
||||
paramId: { value: paramId }
|
||||
});
|
||||
this.firstLoc = firstLoc;
|
||||
this.paramId = paramId;
|
||||
}
|
||||
|
||||
inherits(CatchEntry, Entry);
|
||||
exports.CatchEntry = CatchEntry;
|
||||
|
||||
function FinallyEntry(firstLoc) {
|
||||
Entry.call(this);
|
||||
|
||||
n.Literal.assert(firstLoc);
|
||||
t.assertLiteral(firstLoc);
|
||||
|
||||
Object.defineProperties(this, {
|
||||
firstLoc: { value: firstLoc }
|
||||
});
|
||||
this.firstLoc = firstLoc;
|
||||
}
|
||||
|
||||
inherits(FinallyEntry, Entry);
|
||||
exports.FinallyEntry = FinallyEntry;
|
||||
|
||||
function LeapManager(emitter) {
|
||||
assert.ok(this instanceof LeapManager);
|
||||
@@ -129,18 +120,11 @@ function LeapManager(emitter) {
|
||||
var Emitter = require("./emit").Emitter;
|
||||
assert.ok(emitter instanceof Emitter);
|
||||
|
||||
Object.defineProperties(this, {
|
||||
emitter: { value: emitter },
|
||||
entryStack: {
|
||||
value: [new FunctionEntry(emitter.finalLoc)]
|
||||
}
|
||||
});
|
||||
this.emitter = emitter;
|
||||
this.entryStack = [new FunctionEntry(emitter.finalLoc)];
|
||||
}
|
||||
|
||||
var LMp = LeapManager.prototype;
|
||||
exports.LeapManager = LeapManager;
|
||||
|
||||
LMp.withEntry = function(entry, callback) {
|
||||
LeapManager.prototype.withEntry = function(entry, callback) {
|
||||
assert.ok(entry instanceof Entry);
|
||||
this.entryStack.push(entry);
|
||||
try {
|
||||
@@ -151,7 +135,7 @@ LMp.withEntry = function(entry, callback) {
|
||||
}
|
||||
};
|
||||
|
||||
LMp._findLeapLocation = function(property, label) {
|
||||
LeapManager.prototype._findLeapLocation = function(property, label) {
|
||||
for (var i = this.entryStack.length - 1; i >= 0; --i) {
|
||||
var entry = this.entryStack[i];
|
||||
var loc = entry[property];
|
||||
@@ -170,10 +154,10 @@ LMp._findLeapLocation = function(property, label) {
|
||||
return null;
|
||||
};
|
||||
|
||||
LMp.getBreakLoc = function(label) {
|
||||
LeapManager.prototype.getBreakLoc = function(label) {
|
||||
return this._findLeapLocation("breakLoc", label);
|
||||
};
|
||||
|
||||
LMp.getContinueLoc = function(label) {
|
||||
LeapManager.prototype.getContinueLoc = function(label) {
|
||||
return this._findLeapLocation("continueLoc", label);
|
||||
};
|
||||
|
||||
@@ -9,15 +9,16 @@
|
||||
*/
|
||||
|
||||
var assert = require("assert");
|
||||
var types = require("ast-types");
|
||||
var m = require("private").makeAccessor();
|
||||
var types = require("ast-types");
|
||||
var m = require("private").makeAccessor();
|
||||
var _ = require("lodash");
|
||||
|
||||
var isArray = types.builtInTypes.array;
|
||||
var n = types.namedTypes;
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
var n = types.namedTypes;
|
||||
|
||||
function makePredicate(propertyName, knownTypes) {
|
||||
function onlyChildren(node) {
|
||||
n.Node.assert(node);
|
||||
n.Node.check(node);
|
||||
|
||||
// Assume no side effects until we find out otherwise.
|
||||
var result = false;
|
||||
@@ -42,19 +43,16 @@ function makePredicate(propertyName, knownTypes) {
|
||||
}
|
||||
|
||||
function predicate(node) {
|
||||
n.Node.assert(node);
|
||||
n.Node.check(node);
|
||||
|
||||
var meta = m(node);
|
||||
if (hasOwn.call(meta, propertyName))
|
||||
return meta[propertyName];
|
||||
if (_.has(meta, propertyName)) return meta[propertyName];
|
||||
|
||||
// Certain types are "opaque," which means they have no side
|
||||
// effects or leaps and we don't care about their subexpressions.
|
||||
if (hasOwn.call(opaqueTypes, node.type))
|
||||
return meta[propertyName] = false;
|
||||
if (_.has(opaqueTypes, node.type)) return meta[propertyName] = false;
|
||||
|
||||
if (hasOwn.call(knownTypes, node.type))
|
||||
return meta[propertyName] = true;
|
||||
if (_.has(knownTypes, node.type)) return meta[propertyName] = true;
|
||||
|
||||
return meta[propertyName] = onlyChildren(node);
|
||||
}
|
||||
@@ -91,7 +89,7 @@ var leapTypes = {
|
||||
|
||||
// All leap types are also side effect types.
|
||||
for (var type in leapTypes) {
|
||||
if (hasOwn.call(leapTypes, type)) {
|
||||
if (_.has(leapTypes, type)) {
|
||||
sideEffectTypes[type] = leapTypes[type];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,9 @@
|
||||
* the same directory.
|
||||
*/
|
||||
|
||||
if (typeof global.regeneratorRuntime === "object") {
|
||||
return;
|
||||
}
|
||||
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
var iteratorSymbol = typeof Symbol === "function" && Symbol.iterator || "@@iterator";
|
||||
var runtime = global.regeneratorRuntime = exports;
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
|
||||
var wrap = runtime.wrap = function wrap(innerFn, outerFn, self, tryList) {
|
||||
return new Generator(innerFn, outerFn, self || null, tryList || []);
|
||||
@@ -412,8 +408,7 @@ Context.prototype = {
|
||||
throw record.arg;
|
||||
}
|
||||
|
||||
if (record.type === "break" ||
|
||||
record.type === "continue") {
|
||||
if (record.type === "break" || record.type === "continue") {
|
||||
this.next = record.arg;
|
||||
} else if (record.type === "return") {
|
||||
this.rval = record.arg;
|
||||
|
||||
@@ -8,30 +8,11 @@
|
||||
* the same directory.
|
||||
*/
|
||||
|
||||
var b = require("ast-types").builders;
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.defaults = function(obj) {
|
||||
var len = arguments.length;
|
||||
var extension;
|
||||
|
||||
for (var i = 1; i < len; ++i) {
|
||||
if ((extension = arguments[i])) {
|
||||
for (var key in extension) {
|
||||
if (hasOwn.call(extension, key) && !hasOwn.call(obj, key)) {
|
||||
obj[key] = extension[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
exports.runtimeProperty = function(name) {
|
||||
return b.memberExpression(
|
||||
b.identifier("regeneratorRuntime"),
|
||||
b.identifier(name),
|
||||
false
|
||||
exports.runtimeProperty = function (name) {
|
||||
return t.memberExpression(
|
||||
t.identifier("regeneratorRuntime"),
|
||||
t.identifier(name)
|
||||
);
|
||||
};
|
||||
|
||||
@@ -3,20 +3,20 @@
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* https://raw.github.com/facebook/regenerator/master/LICENSE file. An
|
||||
* https://raw.githut.com/facebook/regenerator/master/LICENSE file. An
|
||||
* additional grant of patent rights can be found in the PATENTS file in
|
||||
* the same directory.
|
||||
*/
|
||||
|
||||
var types = require("ast-types");
|
||||
var n = types.namedTypes;
|
||||
var b = types.builders;
|
||||
var hoist = require("./hoist").hoist;
|
||||
var Emitter = require("./emit").Emitter;
|
||||
var runtimeProperty = require("./util").runtimeProperty;
|
||||
var runtimeWrapMethod = runtimeProperty("wrap");
|
||||
var runtimeMarkMethod = runtimeProperty("mark");
|
||||
var Emitter = require("./emit").Emitter;
|
||||
var hoist = require("./hoist").hoist;
|
||||
var types = require("ast-types");
|
||||
var t = require("../../../types");
|
||||
|
||||
var runtimeAsyncMethod = runtimeProperty("async");
|
||||
var runtimeWrapMethod = runtimeProperty("wrap");
|
||||
var runtimeMarkMethod = runtimeProperty("mark");
|
||||
|
||||
exports.transform = function transform(node) {
|
||||
return types.visit(node, visitor);
|
||||
@@ -38,8 +38,8 @@ var visitor = types.PathVisitor.fromMethodsObject({
|
||||
if (node.expression) {
|
||||
// Transform expression lambdas into normal functions.
|
||||
node.expression = false;
|
||||
node.body = b.blockStatement([
|
||||
b.returnStatement(node.body)
|
||||
node.body = t.blockStatement([
|
||||
t.returnStatement(node.body)
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ var visitor = types.PathVisitor.fromMethodsObject({
|
||||
node.id = path.scope.parent.declareTemporary("callee$")
|
||||
);
|
||||
|
||||
var innerFnId = b.identifier(node.id.name + "$");
|
||||
var innerFnId = t.identifier(node.id.name + "$");
|
||||
var contextId = path.scope.declareTemporary("context$");
|
||||
var vars = hoist(path);
|
||||
|
||||
@@ -68,8 +68,8 @@ var visitor = types.PathVisitor.fromMethodsObject({
|
||||
emitter.getContextFunction(innerFnId),
|
||||
// Async functions don't care about the outer function because they
|
||||
// don't need it to be marked and don't inherit from its .prototype.
|
||||
node.async ? b.literal(null) : outerFnId,
|
||||
b.thisExpression()
|
||||
node.async ? t.literal(null) : outerFnId,
|
||||
t.thisExpression()
|
||||
];
|
||||
|
||||
var tryEntryList = emitter.getTryEntryList();
|
||||
@@ -77,24 +77,23 @@ var visitor = types.PathVisitor.fromMethodsObject({
|
||||
wrapArgs.push(tryEntryList);
|
||||
}
|
||||
|
||||
var wrapCall = b.callExpression(
|
||||
var wrapCall = t.callExpression(
|
||||
node.async ? runtimeAsyncMethod : runtimeWrapMethod,
|
||||
wrapArgs
|
||||
);
|
||||
|
||||
outerBody.push(b.returnStatement(wrapCall));
|
||||
node.body = b.blockStatement(outerBody);
|
||||
outerBody.push(t.returnStatement(wrapCall));
|
||||
node.body = t.blockStatement(outerBody);
|
||||
|
||||
if (node.async) {
|
||||
node.async = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (n.FunctionDeclaration.check(node)) {
|
||||
if (t.isFunctionDeclaration(node)) {
|
||||
var pp = path.parent;
|
||||
|
||||
while (pp && !(n.BlockStatement.check(pp.value) ||
|
||||
n.Program.check(pp.value))) {
|
||||
while (pp && !(t.isBlockStatement(pp.value) || t.isProgram(pp.value))) {
|
||||
pp = pp.parent;
|
||||
}
|
||||
|
||||
@@ -150,10 +149,10 @@ var visitor = types.PathVisitor.fromMethodsObject({
|
||||
// declaration. Note that all the other fields are the same.
|
||||
node.type = "FunctionExpression";
|
||||
|
||||
var varDecl = b.variableDeclaration("var", [
|
||||
b.variableDeclarator(
|
||||
var varDecl = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(
|
||||
node.id,
|
||||
b.callExpression(runtimeMarkMethod, [node])
|
||||
t.callExpression(runtimeMarkMethod, [node])
|
||||
)
|
||||
]);
|
||||
|
||||
@@ -178,30 +177,28 @@ var visitor = types.PathVisitor.fromMethodsObject({
|
||||
bodyPath.push(varDecl);
|
||||
|
||||
} else {
|
||||
n.FunctionExpression.assert(node);
|
||||
return b.callExpression(runtimeMarkMethod, [node]);
|
||||
t.assertFunctionExpression(node);
|
||||
return t.callExpression(runtimeMarkMethod, [node]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function shouldNotHoistAbove(stmtPath) {
|
||||
var value = stmtPath.value;
|
||||
n.Statement.assert(value);
|
||||
t.assertStatement(value);
|
||||
|
||||
// If the first statement is a "use strict" declaration, make sure to
|
||||
// insert hoisted declarations afterwards.
|
||||
if (n.ExpressionStatement.check(value) &&
|
||||
n.Literal.check(value.expression) &&
|
||||
if (t.isExpressionStatement(value) &&
|
||||
t.isLiteral(value.expression) &&
|
||||
value.expression.value === "use strict") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (n.VariableDeclaration.check(value)) {
|
||||
if (t.isVariableDeclaration(value)) {
|
||||
for (var i = 0; i < value.declarations.length; ++i) {
|
||||
var decl = value.declarations[i];
|
||||
if (n.CallExpression.check(decl.init) &&
|
||||
types.astNodesAreEquivalent(decl.init.callee,
|
||||
runtimeMarkMethod)) {
|
||||
if (t.isCallExpression(decl.init) && types.astNodesAreEquivalent(decl.init.callee, runtimeMarkMethod)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -217,6 +214,6 @@ var awaitVisitor = types.PathVisitor.fromMethodsObject({
|
||||
|
||||
visitAwaitExpression: function(path) {
|
||||
// Convert await expressions to yield expressions.
|
||||
return b.yieldExpression(path.value.argument, false);
|
||||
return t.yieldExpression(path.value.argument, false);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -88,6 +88,9 @@ LetScoping.prototype.run = function () {
|
||||
|
||||
this.info = this.getInfo();
|
||||
|
||||
// remap all let references that exist in upper scopes to their uid
|
||||
this.remap();
|
||||
|
||||
// this is a block within a `Function` so we can safely leave it be
|
||||
if (t.isFunction(this.parent)) return this.noClosure();
|
||||
|
||||
@@ -138,23 +141,29 @@ LetScoping.prototype.run = function () {
|
||||
};
|
||||
|
||||
/**
|
||||
* There are no let references accessed within a closure so we can just traverse
|
||||
* through this block and replace all references that exist in a higher scope to
|
||||
* their uids.
|
||||
* There are no let references accessed within a closure so we can just turn the
|
||||
* lets into vars.
|
||||
*/
|
||||
|
||||
LetScoping.prototype.noClosure = function () {
|
||||
var replacements = this.info.duplicates;
|
||||
var declarators = this.info.declarators;
|
||||
var block = this.block;
|
||||
standardiseLets(this.info.declarators);
|
||||
};
|
||||
|
||||
standardiseLets(declarators);
|
||||
/**
|
||||
* Traverse through block and replace all references that exist in a higher
|
||||
* scope to their uids.
|
||||
*/
|
||||
|
||||
LetScoping.prototype.remap = function () {
|
||||
var replacements = this.info.duplicates;
|
||||
var block = this.block;
|
||||
|
||||
if (_.isEmpty(replacements)) return;
|
||||
|
||||
var replace = function (node, parent) {
|
||||
var replace = function (node, parent, scope) {
|
||||
if (!t.isIdentifier(node)) return;
|
||||
if (!t.isReferenced(node, parent)) return;
|
||||
if (scope && scope.hasOwn(node.name)) return;
|
||||
node.name = replacements[node.name] || node.name;
|
||||
};
|
||||
|
||||
@@ -260,7 +269,7 @@ LetScoping.prototype.checkFor = function () {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (forParent && !node.label) {
|
||||
if (forParent && node && !node.label) {
|
||||
if (t.isBreakStatement(node)) {
|
||||
has.hasBreak = true;
|
||||
replace = t.returnStatement(t.literal("break"));
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"Property": ["kind", "key", "value", "computed"],
|
||||
"ReturnStatement": ["argument"],
|
||||
"SequenceExpression": ["expressions"],
|
||||
"ThrowExpression": ["argument"],
|
||||
"UnaryExpression": ["operator", "argument", "prefix"],
|
||||
"VariableDeclaration": ["kind", "declarations"],
|
||||
"VariableDeclarator": ["id", "init"],
|
||||
|
||||
@@ -2,14 +2,25 @@ var _ = require("lodash");
|
||||
|
||||
var t = exports;
|
||||
|
||||
var addAssert = function (type, is) {
|
||||
t["assert" + type] = function (node, opts) {
|
||||
opts = opts || {};
|
||||
if (!is(node, opts)) {
|
||||
throw new Error("Expected type " + JSON.stringify(type) + " with option " + JSON.stringify(opts));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
t.VISITOR_KEYS = require("./visitor-keys");
|
||||
|
||||
_.each(t.VISITOR_KEYS, function (keys, type) {
|
||||
t["is" + type] = function (node, opts) {
|
||||
var is = t["is" + type] = function (node, opts) {
|
||||
return node && node.type === type && t.shallowEqual(node, opts);
|
||||
};
|
||||
|
||||
addAssert(type, is);
|
||||
});
|
||||
|
||||
//
|
||||
@@ -43,13 +54,23 @@ _.each(t.ALIAS_KEYS, function (aliases, type) {
|
||||
_.each(_aliases, function (types, type) {
|
||||
t[type.toUpperCase() + "_TYPES"] = types;
|
||||
|
||||
t["is" + type] = function (node, opts) {
|
||||
var is = t["is" + type] = function (node, opts) {
|
||||
return node && _.contains(types, node.type) && t.shallowEqual(node, opts);
|
||||
};
|
||||
|
||||
addAssert(type, is);
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
t.isExpression = function (node) {
|
||||
return !t.isStatement(node);
|
||||
};
|
||||
|
||||
addAssert("Expression", t.isExpression);
|
||||
|
||||
//
|
||||
|
||||
t.shallowEqual = function (actual, expected) {
|
||||
var same = true;
|
||||
|
||||
|
||||
@@ -37,6 +37,21 @@ exports.list = function (val) {
|
||||
return val ? val.split(",") : [];
|
||||
};
|
||||
|
||||
exports.regexify = function (val) {
|
||||
if (!val) return new RegExp;
|
||||
if (_.isArray(val)) val = val.join("|");
|
||||
if (_.isString(val)) return new RegExp(val || "");
|
||||
if (_.isRegExp(val)) return val;
|
||||
throw new TypeError("illegal type for regexify");
|
||||
};
|
||||
|
||||
exports.arrayify = function (val) {
|
||||
if (!val) return [];
|
||||
if (_.isString(val)) return exports.list(val);
|
||||
if (_.isArray(val)) return val;
|
||||
throw new TypeError("illegal type for arrayify");
|
||||
};
|
||||
|
||||
exports.getUid = function (parent, file) {
|
||||
var node;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "6to5",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "1.12.20",
|
||||
"version": "1.12.21",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://github.com/6to5/6to5",
|
||||
"repository": {
|
||||
@@ -47,7 +47,7 @@
|
||||
"chokidar": "0.10.5",
|
||||
"source-map-support": "0.2.8",
|
||||
"esutils": "1.1.4",
|
||||
"acorn-6to5": "https://github.com/6to5/acorn-6to5/archive/74d8e9bed20ba302d3504f53d0b1c649968959e1.tar.gz",
|
||||
"acorn-6to5": "0.9.1-2",
|
||||
"estraverse": "^1.7.0",
|
||||
"private": "^0.1.6"
|
||||
},
|
||||
|
||||
@@ -2,5 +2,12 @@ let x = 1;
|
||||
{
|
||||
let x = 2;
|
||||
assert.equal(x, 2);
|
||||
{
|
||||
let x = 3;
|
||||
assert.equal(x, 3);
|
||||
|
||||
x++;
|
||||
assert.equal(x, 4);
|
||||
}
|
||||
}
|
||||
assert.equal(x, 1);
|
||||
|
||||
8
test/fixtures/transformation/modules-common-interop/exports-default/actual.js
vendored
Normal file
8
test/fixtures/transformation/modules-common-interop/exports-default/actual.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
export default 42;
|
||||
export default {};
|
||||
export default [];
|
||||
export default foo;
|
||||
export default function () {}
|
||||
export default class {}
|
||||
export default function foo () {}
|
||||
export default class Foo {}
|
||||
13
test/fixtures/transformation/modules-common-interop/exports-default/expected.js
vendored
Normal file
13
test/fixtures/transformation/modules-common-interop/exports-default/expected.js
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
exports["default"] = 42;
|
||||
exports["default"] = {};
|
||||
exports["default"] = [];
|
||||
exports["default"] = foo;
|
||||
exports["default"] = function () {};
|
||||
exports["default"] = function () {};
|
||||
function foo() {}
|
||||
exports["default"] = foo;
|
||||
var Foo = function Foo() {};
|
||||
|
||||
exports["default"] = Foo;
|
||||
6
test/fixtures/transformation/modules-common-interop/exports-from/actual.js
vendored
Normal file
6
test/fixtures/transformation/modules-common-interop/exports-from/actual.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
export * from "foo";
|
||||
export {foo} from "foo";
|
||||
export {foo, bar} from "foo";
|
||||
export {foo as bar} from "foo";
|
||||
export {foo as default} from "foo";
|
||||
export {foo as default, bar} from "foo";
|
||||
15
test/fixtures/transformation/modules-common-interop/exports-from/expected.js
vendored
Normal file
15
test/fixtures/transformation/modules-common-interop/exports-from/expected.js
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
"use strict";
|
||||
|
||||
(function (obj) {
|
||||
for (var i in obj) {
|
||||
exports[i] = obj[i];
|
||||
}
|
||||
})(require("foo"));
|
||||
|
||||
exports.foo = require("foo").foo;
|
||||
exports.foo = require("foo").foo;
|
||||
exports.bar = require("foo").bar;
|
||||
exports.bar = require("foo").foo;
|
||||
exports["default"] = require("foo").foo;
|
||||
exports["default"] = require("foo").foo;
|
||||
exports.bar = require("foo").bar;
|
||||
5
test/fixtures/transformation/modules-common-interop/exports-named/actual.js
vendored
Normal file
5
test/fixtures/transformation/modules-common-interop/exports-named/actual.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
export {foo};
|
||||
export {foo, bar};
|
||||
export {foo as bar};
|
||||
export {foo as default};
|
||||
export {foo as default, bar};
|
||||
9
test/fixtures/transformation/modules-common-interop/exports-named/expected.js
vendored
Normal file
9
test/fixtures/transformation/modules-common-interop/exports-named/expected.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
exports.foo = foo;
|
||||
exports.foo = foo;
|
||||
exports.bar = bar;
|
||||
exports.bar = foo;
|
||||
exports["default"] = foo;
|
||||
exports["default"] = foo;
|
||||
exports.bar = bar;
|
||||
8
test/fixtures/transformation/modules-common-interop/exports-variable/actual.js
vendored
Normal file
8
test/fixtures/transformation/modules-common-interop/exports-variable/actual.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
export var foo = 1;
|
||||
export var foo2 = function () {};
|
||||
export var foo3;
|
||||
export let foo4 = 2;
|
||||
export let foo5;
|
||||
export const foo6 = 3;
|
||||
export function foo7 () {}
|
||||
export class foo8 {}
|
||||
13
test/fixtures/transformation/modules-common-interop/exports-variable/expected.js
vendored
Normal file
13
test/fixtures/transformation/modules-common-interop/exports-variable/expected.js
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
exports.foo7 = foo7;
|
||||
var foo = exports.foo = 1;
|
||||
var foo2 = exports.foo2 = function () {};
|
||||
var foo3;
|
||||
var foo4 = exports.foo4 = 2;
|
||||
var foo5;
|
||||
var foo6 = exports.foo6 = 3;
|
||||
function foo7() {}
|
||||
var foo8 = function foo8() {};
|
||||
|
||||
exports.foo8 = foo8;
|
||||
11
test/fixtures/transformation/modules-common-interop/hoist-function-exports/actual.js
vendored
Normal file
11
test/fixtures/transformation/modules-common-interop/hoist-function-exports/actual.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import { isEven } from "./evens";
|
||||
|
||||
export function nextOdd(n) {
|
||||
return isEven(n) ? n + 1 : n + 2;
|
||||
}
|
||||
|
||||
export var isOdd = (function (isEven) {
|
||||
return function (n) {
|
||||
return !isEven(n);
|
||||
};
|
||||
})(isEven);
|
||||
13
test/fixtures/transformation/modules-common-interop/hoist-function-exports/expected.js
vendored
Normal file
13
test/fixtures/transformation/modules-common-interop/hoist-function-exports/expected.js
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
exports.nextOdd = nextOdd;
|
||||
var isEven = require("./evens").isEven;
|
||||
function nextOdd(n) {
|
||||
return isEven(n) ? n + 1 : n + 2;
|
||||
}
|
||||
|
||||
var isOdd = exports.isOdd = (function (isEven) {
|
||||
return function (n) {
|
||||
return !isEven(n);
|
||||
};
|
||||
})(isEven);
|
||||
2
test/fixtures/transformation/modules-common-interop/imports-default/actual.js
vendored
Normal file
2
test/fixtures/transformation/modules-common-interop/imports-default/actual.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import foo from "foo";
|
||||
import {default as foo} from "foo";
|
||||
9
test/fixtures/transformation/modules-common-interop/imports-default/expected.js
vendored
Normal file
9
test/fixtures/transformation/modules-common-interop/imports-default/expected.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) {
|
||||
return obj && (obj["default"] || obj);
|
||||
};
|
||||
|
||||
var foo = _interopRequire(require("foo"));
|
||||
|
||||
var foo = require("foo")["default"];
|
||||
1
test/fixtures/transformation/modules-common-interop/imports-glob/actual.js
vendored
Normal file
1
test/fixtures/transformation/modules-common-interop/imports-glob/actual.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import * as foo from "foo";
|
||||
3
test/fixtures/transformation/modules-common-interop/imports-glob/expected.js
vendored
Normal file
3
test/fixtures/transformation/modules-common-interop/imports-glob/expected.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var foo = require("foo");
|
||||
1
test/fixtures/transformation/modules-common-interop/imports-mixing/actual.js
vendored
Normal file
1
test/fixtures/transformation/modules-common-interop/imports-mixing/actual.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import foo, {baz as xyz} from "foo";
|
||||
9
test/fixtures/transformation/modules-common-interop/imports-mixing/expected.js
vendored
Normal file
9
test/fixtures/transformation/modules-common-interop/imports-mixing/expected.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) {
|
||||
return obj && (obj["default"] || obj);
|
||||
};
|
||||
|
||||
var foo = _interopRequire(require("foo"));
|
||||
|
||||
var xyz = require("foo").baz;
|
||||
4
test/fixtures/transformation/modules-common-interop/imports-named/actual.js
vendored
Normal file
4
test/fixtures/transformation/modules-common-interop/imports-named/actual.js
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import {bar} from "foo";
|
||||
import {bar, baz} from "foo";
|
||||
import {bar as baz} from "foo";
|
||||
import {bar as baz, xyz} from "foo";
|
||||
8
test/fixtures/transformation/modules-common-interop/imports-named/expected.js
vendored
Normal file
8
test/fixtures/transformation/modules-common-interop/imports-named/expected.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
var bar = require("foo").bar;
|
||||
var bar = require("foo").bar;
|
||||
var baz = require("foo").baz;
|
||||
var baz = require("foo").bar;
|
||||
var baz = require("foo").bar;
|
||||
var xyz = require("foo").xyz;
|
||||
3
test/fixtures/transformation/modules-common-interop/imports/actual.js
vendored
Normal file
3
test/fixtures/transformation/modules-common-interop/imports/actual.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import "foo";
|
||||
import "foo-bar";
|
||||
import "./directory/foo-bar";
|
||||
7
test/fixtures/transformation/modules-common-interop/imports/expected.js
vendored
Normal file
7
test/fixtures/transformation/modules-common-interop/imports/expected.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
require("foo");
|
||||
|
||||
require("foo-bar");
|
||||
|
||||
require("./directory/foo-bar");
|
||||
3
test/fixtures/transformation/modules-common-interop/options.json
vendored
Normal file
3
test/fixtures/transformation/modules-common-interop/options.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"modules": "commonInterop"
|
||||
}
|
||||
12
test/fixtures/transformation/modules-common-interop/overview/actual.js
vendored
Normal file
12
test/fixtures/transformation/modules-common-interop/overview/actual.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import "foo";
|
||||
import "foo-bar";
|
||||
import "./directory/foo-bar";
|
||||
import foo from "foo";
|
||||
import * as foo from "foo";
|
||||
import {bar} from "foo";
|
||||
import {foo as bar} from "foo";
|
||||
|
||||
export {test};
|
||||
export var test = 5;
|
||||
|
||||
export default test;
|
||||
22
test/fixtures/transformation/modules-common-interop/overview/expected.js
vendored
Normal file
22
test/fixtures/transformation/modules-common-interop/overview/expected.js
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) {
|
||||
return obj && (obj["default"] || obj);
|
||||
};
|
||||
|
||||
require("foo");
|
||||
|
||||
require("foo-bar");
|
||||
|
||||
require("./directory/foo-bar");
|
||||
|
||||
var foo = _interopRequire(require("foo"));
|
||||
|
||||
var foo = require("foo");
|
||||
|
||||
var bar = require("foo").bar;
|
||||
var bar = require("foo").foo;
|
||||
exports.test = test;
|
||||
var test = exports.test = 5;
|
||||
|
||||
exports["default"] = test;
|
||||
Reference in New Issue
Block a user