Compare commits

...

29 Commits

Author SHA1 Message Date
Sebastian McKenzie
50dee1a754 v1.12.21 2014-11-19 13:49:35 +11:00
Sebastian McKenzie
f80f860bbc changelog for 1.12.21 2014-11-19 13:48:09 +11:00
Sebastian McKenzie
7fc2fe41af fix bug in let scoping resulting in unneccesary replacement - closes #193, closes #185 2014-11-19 13:46:00 +11:00
Sebastian McKenzie
a884a26402 revert acorn-6to5 2014-11-19 13:28:01 +11:00
Sebastian McKenzie
81ec1e1f42 remove unused variable in generators/meta 2014-11-19 12:54:54 +11:00
Sebastian McKenzie
1a27970376 publish acorn-6to5 as an npm package - fixes #187 2014-11-19 12:51:14 +11:00
Sebastian McKenzie
6822c854d4 add interop-require declaration 2014-11-19 12:40:44 +11:00
Sebastian McKenzie
8f4c4be821 generator: add existence check to printJoin 2014-11-19 12:40:35 +11:00
Sebastian McKenzie
5fca095149 use commonInterop module formatter in 6to5/register 2014-11-19 12:40:23 +11:00
Sebastian McKenzie
34599a21cb clean up common-interop module formatter 2014-11-19 12:40:10 +11:00
Sebastian McKenzie
d9d84c60b5 check for existence of node before checking it in let scoping 2014-11-19 12:13:00 +11:00
Sebastian McKenzie
221d78d2e2 arrayify whitelist and blacklist, inherit moduleRoot from sourceRoot and vice versa 2014-11-19 12:13:00 +11:00
Sebastian McKenzie
fa46f60655 expose util as _util 2014-11-19 12:13:00 +11:00
Sebastian McKenzie
03ce52fb7c use regexify and arrayify in register options 2014-11-19 12:13:00 +11:00
Sebastian McKenzie
0df0c696a9 add util.arrayify and util.regexify 2014-11-19 12:12:59 +11:00
Sebastian McKenzie
21b7f4120e add assertion checks into types 2014-11-19 12:12:59 +11:00
Sebastian McKenzie
f43a3dec4b more regenerator spring cleaning 2014-11-19 12:12:59 +11:00
Sebastian McKenzie
cacee5c625 Merge pull request #191 from Naddiseo/commonjs-interop
Added an interop commonjs loader.
2014-11-19 12:09:00 +11:00
Sebastian McKenzie
553c90ae75 Merge pull request #192 from Naddiseo/function-modules
Allow module transformers to be directly passed into opts.
2014-11-19 12:06:02 +11:00
Richard Eames
bc3502d695 Allow module transformers to be directly passed into opts. 2014-11-18 15:29:59 -07:00
Richard Eames
6ae03a5dce Added an interop commonjs loader. 2014-11-18 15:25:12 -07:00
Sebastian McKenzie
68ef2d545e Merge pull request #188 from brentburg/webpack-return
Webpack doesn't like return outside of a function in a module
2014-11-19 01:14:07 +11:00
Brent Burgoyne
861b9e68d3 Deleted uneeded _runtime.js 2014-11-18 07:13:12 -07:00
Brent Burgoyne
a0eb108cd4 Remove global existence check 2014-11-18 07:10:47 -07:00
Brent Burgoyne
756aef6adc Instead of returning early, conditionally require actual runtime (./_runtime.js)
Fix this error with webpack:

ERROR in ./~/6to5/lib/6to5/transformation/transformers/generators/runtime.js
Module parse failed: /[...]/node_modules/6to5/lib/6to5/transformation/transformers/generators/runtime.js Line 12: Illegal return statement
You may need an appropriate loader to handle this file type.
|
| if (typeof global.regeneratorRuntime === "object") {
  |   return;
  |
}
|
 @ ./~/6to5/lib/6to5/polyfill.js 6:0-59
2014-11-18 06:55:39 -07:00
Sebastian McKenzie
7b74c1c8ec more generator spring cleaning 2014-11-17 17:30:41 +11:00
Sebastian McKenzie
8e115ef3ed regenerator spring cleaning 2014-11-17 17:04:04 +11:00
Sebastian McKenzie
b9a6cf35b7 Merge pull request #184 from thejameskyle/support-table
Sort comparison table by most es6 support and split into two groups
2014-11-17 16:50:24 +11:00
James Kyle
2e22de71b4 Sort comparison table by most es6 support and split into two groups 2014-11-16 21:49:19 -08:00
45 changed files with 618 additions and 382 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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);

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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);
};

View File

@@ -0,0 +1,3 @@
(function (obj) {
return obj && (obj["default"] || obj);
})

View 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);
};

View File

@@ -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({

View File

@@ -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");

View File

@@ -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);
};

View File

@@ -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);
};

View File

@@ -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];
}
}

View File

@@ -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;

View File

@@ -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)
);
};

View File

@@ -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);
}
});

View File

@@ -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"));

View File

@@ -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"],

View File

@@ -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;

View File

@@ -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;

View File

@@ -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"
},

View File

@@ -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);

View 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 {}

View 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;

View 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";

View 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;

View File

@@ -0,0 +1,5 @@
export {foo};
export {foo, bar};
export {foo as bar};
export {foo as default};
export {foo as default, bar};

View 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;

View 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 {}

View 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;

View 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);

View 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);

View File

@@ -0,0 +1,2 @@
import foo from "foo";
import {default as foo} from "foo";

View 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"];

View File

@@ -0,0 +1 @@
import * as foo from "foo";

View File

@@ -0,0 +1,3 @@
"use strict";
var foo = require("foo");

View File

@@ -0,0 +1 @@
import foo, {baz as xyz} from "foo";

View 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;

View 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";

View 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;

View File

@@ -0,0 +1,3 @@
import "foo";
import "foo-bar";
import "./directory/foo-bar";

View File

@@ -0,0 +1,7 @@
"use strict";
require("foo");
require("foo-bar");
require("./directory/foo-bar");

View File

@@ -0,0 +1,3 @@
{
"modules": "commonInterop"
}

View 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;

View 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;