Compare commits
75 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31e6b18346 | ||
|
|
d17ac92a3f | ||
|
|
188bcb70f7 | ||
|
|
b8bd11a0e7 | ||
|
|
45bc74efe7 | ||
|
|
7eb169a894 | ||
|
|
eed4f312d8 | ||
|
|
44e4dc970f | ||
|
|
5d32432e67 | ||
|
|
9c9af6dbbd | ||
|
|
70cd650e10 | ||
|
|
c7bb00d58d | ||
|
|
623be068c4 | ||
|
|
71f5c9791d | ||
|
|
3e6e86d073 | ||
|
|
a0fb398ca2 | ||
|
|
71b9f19e6a | ||
|
|
c45ce58f0c | ||
|
|
d32f587e3c | ||
|
|
9e1874ba89 | ||
|
|
35fdc5c5d8 | ||
|
|
a4035fc257 | ||
|
|
42e3dc7a70 | ||
|
|
cdccf24515 | ||
|
|
c8cd5c108b | ||
|
|
2b95b876e1 | ||
|
|
f801772fc2 | ||
|
|
8ad678e5bc | ||
|
|
35c49dbef7 | ||
|
|
119314df74 | ||
|
|
51e336b037 | ||
|
|
7d446807a9 | ||
|
|
8afdeaf557 | ||
|
|
4df50954a2 | ||
|
|
70b6317865 | ||
|
|
5ebdc44297 | ||
|
|
a4659fd239 | ||
|
|
19bfa4a35b | ||
|
|
f7fff7d35e | ||
|
|
130e0ebe6b | ||
|
|
69c836fc8d | ||
|
|
f62a3ef394 | ||
|
|
7a6e568940 | ||
|
|
65998c3437 | ||
|
|
160de340b0 | ||
|
|
76ca40f698 | ||
|
|
01ed824b5c | ||
|
|
6b0dbc4486 | ||
|
|
2648268f30 | ||
|
|
8cf5bf7037 | ||
|
|
60961bc3ff | ||
|
|
df16bc17e7 | ||
|
|
5337ab5a08 | ||
|
|
2eaeebcce4 | ||
|
|
ad71010144 | ||
|
|
864169c1eb | ||
|
|
930d7f9aa6 | ||
|
|
ed40ec03d1 | ||
|
|
73062ae240 | ||
|
|
bafa3e0d4c | ||
|
|
f3d2b2bb81 | ||
|
|
a74b67d4eb | ||
|
|
625416862f | ||
|
|
8dda8838ba | ||
|
|
96d3a25213 | ||
|
|
727208f376 | ||
|
|
1b046a6ecb | ||
|
|
3b8ed0d401 | ||
|
|
d4c98d7738 | ||
|
|
4e44af819f | ||
|
|
a65acd73ca | ||
|
|
b7cb2bcb7b | ||
|
|
5ac4dc0541 | ||
|
|
99ddd02b0a | ||
|
|
19cfee14fd |
44
CHANGELOG.md
44
CHANGELOG.md
@@ -13,6 +13,50 @@ _Note: Gaps between patch versions are faulty/broken releases._
|
||||
|
||||
See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
|
||||
|
||||
## 4.7.2
|
||||
|
||||
* **New Feature**
|
||||
* `"both"` option for `sourceMap`.
|
||||
* Add output types to external helpers. Thanks [@neVERberleRfellerER](https://github.com/neVERberleRfellerER)!
|
||||
* **Bug Fix**
|
||||
* Fix node duplication sometimes resulting in a recursion error.
|
||||
* Ignore `break`s within cases inside `for...of`.
|
||||
* **Polish**
|
||||
* Split up variable declarations and export declarations to allow easier transformation.
|
||||
|
||||
## 4.7.0
|
||||
|
||||
* **Bug Fix**
|
||||
* Add `alternate` to list of `STATEMENT_OR_BLOCK` keys.
|
||||
* Add support for module specifiers to `t.isReferenced`.
|
||||
* **New Feature**
|
||||
* Add `inputSourceMap` option.
|
||||
* **Polish**
|
||||
* Throw an error on different `babel` and `babel-runtime` versions.
|
||||
* Replicate module environment for `babel-node` eval.
|
||||
* Clean up classes output.
|
||||
* **Spec Compliancy**
|
||||
* Make it illegal to use a rest parameter on a setter.
|
||||
|
||||
## 4.6.6
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix incorrect method call in `utility.deadCodeElimination` transformer.
|
||||
* Fix `es6.blockScopingTDZ` transformer duplicating binding nodes.
|
||||
|
||||
## 4.6.5
|
||||
|
||||
* **Internal**
|
||||
* `useStrict` transformer has been renamed to `strict`.
|
||||
|
||||
## 4.6.4
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix `ForOfStatement` not proplery inheriting labels.
|
||||
* When in closure mode in block scoping transformer, properly check for variable shadowing.
|
||||
* **New Feature**
|
||||
* New `utility.inlineEnvironmentVariables` and `utility.inlineExpression` transformers.
|
||||
|
||||
## 4.6.3
|
||||
|
||||
* **Bug Fix**
|
||||
|
||||
@@ -53,7 +53,6 @@ $ mocha test/transformation.js
|
||||
#### Code Standards
|
||||
|
||||
* **General**
|
||||
* No ES6 syntax features or methods, exclusively ES5.
|
||||
* Max of five arguments for functions
|
||||
* Max depth of four nested blocks
|
||||
* 2-spaced soft tabs
|
||||
|
||||
@@ -60,7 +60,18 @@ if (program.eval || program.print) {
|
||||
var code = program.eval;
|
||||
if (!code || code === true) code = program.print;
|
||||
|
||||
var result = _eval(code, "eval");
|
||||
global.__filename = "[eval]";
|
||||
global.__dirname = process.cwd();
|
||||
|
||||
var module = new Module(global.__filename);
|
||||
module.filename = global.__filename;
|
||||
module.paths = Module._nodeModulePaths(global.__dirname);
|
||||
|
||||
global.exports = module.exports;
|
||||
global.module = module;
|
||||
global.require = module.require.bind(module);
|
||||
|
||||
var result = _eval(code, global.__filename);
|
||||
if (program.print) console.log(result);
|
||||
} else {
|
||||
if (program.args.length) {
|
||||
@@ -88,7 +99,7 @@ if (program.eval || program.print) {
|
||||
args = args.slice(i);
|
||||
|
||||
// make the filename absolute
|
||||
var filename = args[0]
|
||||
var filename = args[0];
|
||||
if (!pathIsAbsolute(filename)) args[0] = path.join(process.cwd(), filename);
|
||||
|
||||
// add back on node and concat the sliced args
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var commander = require("commander");
|
||||
var util = require("../lib/babel/util");
|
||||
var runtime = require("../lib/babel/build-external-helpers");
|
||||
console.log(runtime());
|
||||
|
||||
commander.option("-l, --whitelist [whitelist]", "Whitelist of helpers to ONLY include", util.list);
|
||||
commander.option("-t, --output-type [type]", "Type of output (global|umd|var)", "global");
|
||||
|
||||
commander.usage("[options]");
|
||||
commander.parse(process.argv);
|
||||
|
||||
console.log(runtime(commander.whitelist, commander.outputType));
|
||||
|
||||
@@ -7,7 +7,17 @@
|
||||
|
||||
var args = [__dirname + "/_babel-node"];
|
||||
|
||||
process.argv.slice(2).forEach(function(arg){
|
||||
var babelArgs = process.argv.slice(2);
|
||||
var userArgs;
|
||||
|
||||
// separate node arguments from script arguments
|
||||
var argSeparator = babelArgs.indexOf("--");
|
||||
if (argSeparator > -1) {
|
||||
userArgs = babelArgs.slice(argSeparator); // including the --
|
||||
babelArgs = babelArgs.slice(0, argSeparator);
|
||||
}
|
||||
|
||||
babelArgs.forEach(function(arg){
|
||||
var flag = arg.split("=")[0];
|
||||
|
||||
switch (flag) {
|
||||
@@ -49,6 +59,11 @@ process.argv.slice(2).forEach(function(arg){
|
||||
}
|
||||
});
|
||||
|
||||
// append arguments passed after --
|
||||
if (argSeparator > -1) {
|
||||
args = args.concat(userArgs);
|
||||
}
|
||||
|
||||
try {
|
||||
var kexec = require("kexec");
|
||||
kexec(process.argv[0], args);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
var sourceMapToComment = require("source-map-to-comment");
|
||||
var sourceMap = require("source-map");
|
||||
var chokidar = require("chokidar");
|
||||
var path = require("path");
|
||||
var util = require("./util");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
var convertSourceMap = require("convert-source-map");
|
||||
var sourceMap = require("source-map");
|
||||
var chokidar = require("chokidar");
|
||||
var path = require("path");
|
||||
var util = require("./util");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
|
||||
module.exports = function (commander, filenames) {
|
||||
var results = [];
|
||||
@@ -42,7 +42,7 @@ module.exports = function (commander, filenames) {
|
||||
});
|
||||
|
||||
if (commander.sourceMapsInline || (!commander.outFile && commander.sourceMaps)) {
|
||||
code += "\n" + sourceMapToComment(map);
|
||||
code += "\n" + convertSourceMap.fromObject(map).toComment();
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "babel",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "4.6.4",
|
||||
"version": "4.7.2",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
"repository": "babel/babel",
|
||||
@@ -37,10 +37,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"acorn-babel": "0.11.1-37",
|
||||
"ast-types": "~0.6.1",
|
||||
"ast-types": "~0.7.0",
|
||||
"chalk": "^1.0.0",
|
||||
"chokidar": "^0.12.6",
|
||||
"commander": "^2.6.0",
|
||||
"convert-source-map": "^0.5.0",
|
||||
"core-js": "^0.6.1",
|
||||
"debug": "^2.1.1",
|
||||
"detect-indent": "^3.0.0",
|
||||
@@ -56,14 +57,14 @@
|
||||
"output-file-sync": "^1.1.0",
|
||||
"path-is-absolute": "^1.0.0",
|
||||
"private": "^0.1.6",
|
||||
"regenerator-babel": "0.8.13-1",
|
||||
"regenerator-babel": "0.8.13-2",
|
||||
"regexpu": "^1.1.2",
|
||||
"repeating": "^1.1.2",
|
||||
"shebang-regex": "^1.0.0",
|
||||
"slash": "^1.0.0",
|
||||
"source-map": "^0.4.0",
|
||||
"source-map-support": "^0.2.9",
|
||||
"source-map-to-comment": "^1.0.0",
|
||||
"to-fast-properties": "^1.0.0",
|
||||
"trim-right": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "babel-runtime",
|
||||
"description": "babel selfContained runtime",
|
||||
"version": "4.6.3",
|
||||
"version": "4.7.1",
|
||||
"repository": "babel/babel",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>"
|
||||
}
|
||||
@@ -25,7 +25,7 @@ transform.load = function (url, callback, opts = {}, hold) {
|
||||
if (!hold) transform.run.apply(transform, param);
|
||||
if (callback) callback(param);
|
||||
} else {
|
||||
throw new Error("Could not load " + url);
|
||||
throw new Error(`Could not load ${url}`);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ var compile = function (filename) {
|
||||
var opts = extend({}, transformOpts);
|
||||
resolveRc(filename, opts);
|
||||
|
||||
var cacheKey = filename + ":" + JSON.stringify(opts);
|
||||
var cacheKey = `${filename}:${JSON.stringify(opts)}`;
|
||||
|
||||
if (cache) {
|
||||
var cached = cache[cacheKey];
|
||||
@@ -57,7 +57,7 @@ var compile = function (filename) {
|
||||
|
||||
if (!result) {
|
||||
result = babel.transformFileSync(filename, extend(opts, {
|
||||
sourceMap: true,
|
||||
sourceMap: "both",
|
||||
ast: false
|
||||
}));
|
||||
}
|
||||
@@ -153,3 +153,16 @@ export default function (opts = {}) {
|
||||
|
||||
extend(transformOpts, opts);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
try {
|
||||
var runtimePackage = require("babel-runtime/package");
|
||||
var version = require("../../package").version;
|
||||
if (runtimePackage.version !== version) {
|
||||
throw new ReferenceError(`The verison of babel-runtime of ${runtimePackage.runtime} that you have installed does not match the babel verison of ${version}`);
|
||||
}
|
||||
} catch (err) {
|
||||
if (err.code !== "MODULE_NOT_FOUND") throw err;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ export default function (loc, opts = {}) {
|
||||
try {
|
||||
json = JSON.parse(content);
|
||||
} catch (err) {
|
||||
err.message = file + ": " + err.message;
|
||||
err.message = `${file}: ${err.message}`;
|
||||
throw err;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import buildHelpers from "./build-helpers";
|
||||
import generator from "./generation";
|
||||
import * as messages from "./messages";
|
||||
import * as util from "./util";
|
||||
import t from "./types";
|
||||
|
||||
export default function (whitelist) {
|
||||
var namespace = t.identifier("babelHelpers");
|
||||
|
||||
function buildGlobal(namespace, builder) {
|
||||
var body = [];
|
||||
var container = t.functionExpression(null, [t.identifier("global")], t.blockStatement(body));
|
||||
var tree = t.program([t.expressionStatement(t.callExpression(container, [util.template("self-global")]))]);
|
||||
@@ -17,7 +16,58 @@ export default function (whitelist) {
|
||||
)
|
||||
]));
|
||||
|
||||
buildHelpers(body, namespace, whitelist);
|
||||
builder(body);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
function buildUmd(namespace, builder) {
|
||||
var body = [];
|
||||
body.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(namespace, t.identifier("global"))
|
||||
]));
|
||||
|
||||
builder(body);
|
||||
|
||||
var container = util.template("umd-commonjs-strict", {
|
||||
FACTORY_PARAMETERS: t.identifier("global"),
|
||||
BROWSER_ARGUMENTS: t.assignmentExpression("=", t.memberExpression(t.identifier("root"), namespace), t.objectExpression({})),
|
||||
COMMON_ARGUMENTS: t.identifier("exports"),
|
||||
AMD_ARGUMENTS: t.arrayExpression([t.literal("exports")]),
|
||||
FACTORY_BODY: body,
|
||||
UMD_ROOT: t.identifier("this")
|
||||
});
|
||||
return t.program([container]);
|
||||
}
|
||||
|
||||
function buildVar(namespace, builder) {
|
||||
var body = [];
|
||||
body.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(namespace, t.objectExpression({}))
|
||||
]));
|
||||
builder(body);
|
||||
return t.program(body);
|
||||
}
|
||||
|
||||
export default function (whitelist, outputType = "global") {
|
||||
var namespace = t.identifier("babelHelpers");
|
||||
var builder = function (body) {
|
||||
return buildHelpers(body, namespace, whitelist);
|
||||
};
|
||||
|
||||
var tree;
|
||||
|
||||
var build = {
|
||||
global: buildGlobal,
|
||||
umd: buildUmd,
|
||||
var: buildVar
|
||||
}[outputType];
|
||||
|
||||
if (build) {
|
||||
tree = build(namespace, builder);
|
||||
} else {
|
||||
throw new Error(messages.get("unsupportedOutputType", outputType));
|
||||
}
|
||||
|
||||
return generator(tree).code;
|
||||
};
|
||||
|
||||
@@ -140,7 +140,7 @@ export default class Buffer {
|
||||
var indent = this.getIndent();
|
||||
|
||||
// replace all newlines with newlines with the indentation
|
||||
str = str.replace(/\n/g, "\n" + indent);
|
||||
str = str.replace(/\n/g, `\n${indent}`);
|
||||
|
||||
// we've got a newline before us so prepend on the indentation
|
||||
if (this.isLast("\n")) this._push(indent);
|
||||
|
||||
@@ -109,16 +109,19 @@ export function ExpressionStatement(node, print) {
|
||||
this.semicolon();
|
||||
}
|
||||
|
||||
exports.BinaryExpression =
|
||||
exports.LogicalExpression =
|
||||
exports.AssignmentPattern =
|
||||
exports.AssignmentExpression = function (node, print) {
|
||||
export function AssignmentExpression(node, print) {
|
||||
// todo: add cases where the spaces can be dropped when in compact mode
|
||||
print(node.left);
|
||||
this.push(" ");
|
||||
this.push(node.operator);
|
||||
this.push(" ");
|
||||
print(node.right);
|
||||
}
|
||||
|
||||
export {
|
||||
AssignmentExpression as BinaryExpression,
|
||||
AssignmentExpression as LogicalExpression,
|
||||
AssignmentExpression as AssignmentPattern
|
||||
};
|
||||
|
||||
var SCIENTIFIC_NOTATION = /e/i;
|
||||
|
||||
@@ -44,8 +44,7 @@ export function _method(node, print) {
|
||||
print(value.body);
|
||||
}
|
||||
|
||||
exports.FunctionDeclaration =
|
||||
exports.FunctionExpression = function (node, print) {
|
||||
export function FunctionExpression(node, print) {
|
||||
if (node.async) this.push("async ");
|
||||
this.push("function");
|
||||
if (node.generator) this.push("*");
|
||||
@@ -60,7 +59,9 @@ exports.FunctionExpression = function (node, print) {
|
||||
this._params(node, print);
|
||||
this.space();
|
||||
print(node.body);
|
||||
};
|
||||
}
|
||||
|
||||
export { FunctionExpression as FunctionDeclaration };
|
||||
|
||||
export function ArrowFunctionExpression(node, print) {
|
||||
if (node.async) this.push("async ");
|
||||
|
||||
@@ -5,7 +5,7 @@ export function ImportSpecifier(node, print) {
|
||||
if (t.isSpecifierDefault(node)) {
|
||||
print(t.getSpecifierName(node));
|
||||
} else {
|
||||
return exports.ExportSpecifier.apply(this, arguments);
|
||||
return ExportSpecifier.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,6 @@ import each from "lodash/collection/each";
|
||||
|
||||
each(["BindMemberExpression", "BindFunctionExpression"], function (type) {
|
||||
exports[type] = function () {
|
||||
throw new ReferenceError("Trying to render non-standard playground node " + JSON.stringify(type));
|
||||
throw new ReferenceError(`Trying to render non-standard playground node ${JSON.stringify(type)}`);
|
||||
};
|
||||
});
|
||||
|
||||
@@ -60,7 +60,7 @@ var buildForXStatement = function (op) {
|
||||
this.keyword("for");
|
||||
this.push("(");
|
||||
print(node.left);
|
||||
this.push(" " + op + " ");
|
||||
this.push(` ${op} `);
|
||||
print(node.right);
|
||||
this.push(")");
|
||||
print.block(node.body);
|
||||
@@ -192,7 +192,7 @@ export function VariableDeclaration(node, print, parent) {
|
||||
|
||||
var sep = ",";
|
||||
if (!this.format.compact && hasInits) {
|
||||
sep += "\n" + repeating(" ", node.kind.length + 1);
|
||||
sep += `\n${repeating(" ", node.kind.length + 1)}`;
|
||||
} else {
|
||||
sep += " ";
|
||||
}
|
||||
|
||||
@@ -4,12 +4,12 @@ export function Identifier(node) {
|
||||
this.push(node.name);
|
||||
}
|
||||
|
||||
exports.RestElement =
|
||||
exports.SpreadElement =
|
||||
exports.SpreadProperty = function (node, print) {
|
||||
export function RestElement(node, print) {
|
||||
this.push("...");
|
||||
print(node.argument);
|
||||
};
|
||||
}
|
||||
|
||||
export { RestElement as SpreadElement, RestElement as SpreadProperty };
|
||||
|
||||
export function VirtualPropertyExpression(node, print) {
|
||||
print(node.object);
|
||||
@@ -17,8 +17,7 @@ export function VirtualPropertyExpression(node, print) {
|
||||
print(node.property);
|
||||
}
|
||||
|
||||
exports.ObjectExpression =
|
||||
exports.ObjectPattern = function (node, print) {
|
||||
export function ObjectExpression(node, print) {
|
||||
var props = node.properties;
|
||||
|
||||
if (props.length) {
|
||||
@@ -32,7 +31,9 @@ exports.ObjectPattern = function (node, print) {
|
||||
} else {
|
||||
this.push("{}");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export { ObjectExpression as ObjectPattern };
|
||||
|
||||
export function Property(node, print) {
|
||||
if (node.method || node.kind === "get" || node.kind === "set") {
|
||||
@@ -53,8 +54,7 @@ export function Property(node, print) {
|
||||
}
|
||||
}
|
||||
|
||||
exports.ArrayExpression =
|
||||
exports.ArrayPattern = function (node, print) {
|
||||
export function ArrayExpression(node, print) {
|
||||
var elems = node.elements;
|
||||
var len = elems.length;
|
||||
|
||||
@@ -76,7 +76,9 @@ exports.ArrayPattern = function (node, print) {
|
||||
});
|
||||
|
||||
this.push("]");
|
||||
};
|
||||
}
|
||||
|
||||
export { ArrayExpression as ArrayPattern };
|
||||
|
||||
export function Literal(node) {
|
||||
var val = node.value;
|
||||
@@ -89,7 +91,7 @@ export function Literal(node) {
|
||||
} else if (type === "boolean") {
|
||||
this.push(val ? "true" : "false");
|
||||
} else if (node.regex) {
|
||||
this.push("/" + node.regex.pattern + "/" + node.regex.flags);
|
||||
this.push(`/${node.regex.pattern}/${node.regex.flags}`);
|
||||
} else if (val === null) {
|
||||
this.push("null");
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ class CodeGenerator {
|
||||
|
||||
this.printTrailingComments(node, parent);
|
||||
} else {
|
||||
throw new ReferenceError("unknown node of type " + JSON.stringify(node.type) + " with constructor " + JSON.stringify(node && node.constructor.name));
|
||||
throw new ReferenceError(`unknown node of type ${JSON.stringify(node.type)} with constructor ${JSON.stringify(node && node.constructor.name)}`);
|
||||
}
|
||||
|
||||
this.format.concise = oldConcise;
|
||||
@@ -238,9 +238,9 @@ class CodeGenerator {
|
||||
generateComment(comment) {
|
||||
var val = comment.value;
|
||||
if (comment.type === "Line") {
|
||||
val = "//" + val;
|
||||
val = `//${val}`;
|
||||
} else {
|
||||
val = "/*" + val + "*/";
|
||||
val = `/*${val}*/`;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
@@ -319,7 +319,7 @@ class CodeGenerator {
|
||||
}
|
||||
|
||||
var indent = Math.max(this.indentSize(), column);
|
||||
val = val.replace(/\n/g, "\n" + repeating(" ", indent));
|
||||
val = val.replace(/\n/g, `\n${repeating(" ", indent)}`);
|
||||
}
|
||||
|
||||
if (column === 0) {
|
||||
|
||||
@@ -55,7 +55,7 @@ var highlight = function (text) {
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = function (lines, lineNumber, colNumber) {
|
||||
export default function (lines, lineNumber, colNumber) {
|
||||
colNumber = Math.max(colNumber, 0);
|
||||
|
||||
if (chalk.supportsColor) {
|
||||
@@ -81,8 +81,7 @@ module.exports = function (lines, lineNumber, colNumber) {
|
||||
return;
|
||||
}
|
||||
if (colNumber) {
|
||||
params.line += "\n" + params.before + repeating(" ", params.width) +
|
||||
params.after + repeating(" ", colNumber - 1) + "^";
|
||||
params.line += `\n${params.before}${repeating(" ", params.width)}${params.after}${repeating(" ", colNumber - 1)}^`;
|
||||
}
|
||||
params.before = params.before.replace(/^./, ">");
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import t from "../types";
|
||||
|
||||
module.exports = function (ast, comments, tokens) {
|
||||
export default function (ast, comments, tokens) {
|
||||
if (ast && ast.type === "Program") {
|
||||
return t.file(ast, comments || [], tokens || []);
|
||||
} else {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
module.exports = function () {
|
||||
export default function () {
|
||||
return Object.create(null);
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@ import estraverse from "estraverse";
|
||||
import codeFrame from "./code-frame";
|
||||
import acorn from "acorn-babel";
|
||||
|
||||
module.exports = function (opts, code, callback) {
|
||||
export default function (opts, code, callback) {
|
||||
try {
|
||||
var comments = [];
|
||||
var tokens = [];
|
||||
@@ -32,7 +32,7 @@ module.exports = function (opts, code, callback) {
|
||||
} catch (err) {
|
||||
if (!err._babel) {
|
||||
err._babel = true;
|
||||
var message = opts.filename + ": " + err.message;
|
||||
var message = `${opts.filename}: ${err.message}`;
|
||||
|
||||
var loc = err.loc;
|
||||
if (loc) {
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
/**
|
||||
* A trick from Bluebird to force V8 to use fast properties for an object.
|
||||
* Read more: http://stackoverflow.com/questions/24987896/
|
||||
*
|
||||
* Use %HasFastProperties(obj) and --allow-natives-syntax to check whether
|
||||
* a particular object already has fast properties.
|
||||
*/
|
||||
|
||||
module.exports = function toFastProperties(obj) {
|
||||
/*jshint -W027*/
|
||||
function f() {}
|
||||
f.prototype = obj;
|
||||
return f;
|
||||
eval(obj);
|
||||
};
|
||||
@@ -10,6 +10,7 @@ export var messages = {
|
||||
undeclaredVariable: "Reference to undeclared variable $1",
|
||||
undeclaredVariableSuggestion: "Reference to undeclared variable $1 - did you mean $2?",
|
||||
settersInvalidParamLength: "Setters must have exactly one parameter",
|
||||
settersNoRest: "Setters aren't allowed to have a rest",
|
||||
noAssignmentsInForHead: "No assignments allowed in for-in/of head",
|
||||
expectedMemberExpressionOrIdentifier: "Expected type MemeberExpression or Identifier",
|
||||
invalidParentForThisNode: "We don't know how to handle this node within the current parent - please open an issue",
|
||||
@@ -18,18 +19,20 @@ export var messages = {
|
||||
unknownForHead: "Unknown node type $1 in ForStatement",
|
||||
didYouMean: "Did you mean $1?",
|
||||
evalInStrictMode: "eval is not allowed in strict mode",
|
||||
codeGeneratorDeopt: "Note: The code generator has deoptimised the styling of $1 as it exceeds the max of $2."
|
||||
codeGeneratorDeopt: "Note: The code generator has deoptimised the styling of $1 as it exceeds the max of $2.",
|
||||
missingTemplatesDirectory: "no templates directory - this is most likely the result of a broken `npm publish`. Please report to https://github.com/babel/babel/issues",
|
||||
unsupportedOutputType: "Unsupported output type $1"
|
||||
};
|
||||
|
||||
export function get(key) {
|
||||
var msg = exports.messages[key];
|
||||
if (!msg) throw new ReferenceError("Unknown message `" + key + "`");
|
||||
var msg = messages[key];
|
||||
if (!msg) throw new ReferenceError(`Unknown message ${JSON.stringify(key)}`);
|
||||
|
||||
var args = [];
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
args = exports.parseArgs(args);
|
||||
args = parseArgs(args);
|
||||
|
||||
return msg.replace(/\$(\d+)/g, function (str, i) {
|
||||
return args[--i];
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import sourceMapToComment from "source-map-to-comment";
|
||||
import convertSourceMap from "convert-source-map";
|
||||
import shebangRegex from "shebang-regex";
|
||||
import isFunction from "lodash/lang/isFunction";
|
||||
import sourceMap from "source-map";
|
||||
import transform from "./index";
|
||||
import generate from "../generation";
|
||||
import defaults from "lodash/object/defaults";
|
||||
@@ -48,7 +49,7 @@ export default class File {
|
||||
static helpers = [
|
||||
"inherits",
|
||||
"defaults",
|
||||
"prototype-properties",
|
||||
"create-class",
|
||||
"apply-constructor",
|
||||
"tagged-template-literal",
|
||||
"tagged-template-literal-loose",
|
||||
@@ -77,34 +78,41 @@ export default class File {
|
||||
static validOptions = [
|
||||
"filename",
|
||||
"filenameRelative",
|
||||
|
||||
"blacklist",
|
||||
"whitelist",
|
||||
"loose",
|
||||
"optional",
|
||||
|
||||
"loose",
|
||||
"playground",
|
||||
"experimental",
|
||||
|
||||
"modules",
|
||||
"moduleIds",
|
||||
"moduleId",
|
||||
"resolveModuleSource",
|
||||
"keepModuleIdExtensions",
|
||||
|
||||
"code",
|
||||
"ast",
|
||||
|
||||
"comments",
|
||||
"compact",
|
||||
|
||||
"auxiliaryComment",
|
||||
"externalHelpers",
|
||||
"returnUsedHelpers",
|
||||
|
||||
"inputSourceMap",
|
||||
"sourceMap",
|
||||
"sourceMapName",
|
||||
"sourceFileName",
|
||||
"sourceRoot",
|
||||
"moduleRoot",
|
||||
"moduleIds",
|
||||
"comments",
|
||||
"reactCompat",
|
||||
"keepModuleIdExtensions",
|
||||
"code",
|
||||
"ast",
|
||||
"playground",
|
||||
"experimental",
|
||||
"externalHelpers",
|
||||
"auxiliaryComment",
|
||||
"compact",
|
||||
"returnUsedHelpers",
|
||||
|
||||
"resolveModuleSource",
|
||||
"moduleId",
|
||||
|
||||
// legacy
|
||||
"format",
|
||||
"reactCompat",
|
||||
|
||||
// these are used by plugins
|
||||
"ignore",
|
||||
@@ -118,7 +126,7 @@ export default class File {
|
||||
|
||||
for (var key in opts) {
|
||||
if (key[0] !== "_" && File.validOptions.indexOf(key) < 0) {
|
||||
throw new ReferenceError("Unknown option: " + key);
|
||||
throw new ReferenceError(`Unknown option: ${key}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +136,7 @@ export default class File {
|
||||
returnUsedHelpers: false,
|
||||
externalHelpers: false,
|
||||
auxilaryComment: "",
|
||||
inputSourceMap: false,
|
||||
experimental: false,
|
||||
reactCompat: false,
|
||||
playground: false,
|
||||
@@ -145,6 +154,10 @@ export default class File {
|
||||
ast: true
|
||||
});
|
||||
|
||||
if (opts.inputSourceMap) {
|
||||
opts.sourceMap = true;
|
||||
}
|
||||
|
||||
// normalize windows path separators to unix
|
||||
opts.filename = slash(opts.filename);
|
||||
if (opts.sourceRoot) {
|
||||
@@ -248,7 +261,7 @@ export default class File {
|
||||
|
||||
debug(msg) {
|
||||
var parts = this.opts.filename;
|
||||
if (msg) parts += ": " + msg;
|
||||
if (msg) parts += `: ${msg}`;
|
||||
util.debug(parts);
|
||||
}
|
||||
|
||||
@@ -261,12 +274,24 @@ export default class File {
|
||||
}
|
||||
|
||||
if (!ModuleFormatter) {
|
||||
throw new ReferenceError("Unknown module formatter type " + JSON.stringify(type));
|
||||
throw new ReferenceError(`Unknown module formatter type ${JSON.stringify(type)}`);
|
||||
}
|
||||
|
||||
return new ModuleFormatter(this);
|
||||
}
|
||||
|
||||
parseInputSourceMap(code) {
|
||||
var opts = this.opts;
|
||||
|
||||
var inputMap = convertSourceMap.fromSource(code);
|
||||
if (inputMap) {
|
||||
opts.inputSourceMap = inputMap.toObject();
|
||||
code = convertSourceMap.removeComments(code);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
parseShebang(code) {
|
||||
var shebangMatch = shebangRegex.exec(code);
|
||||
|
||||
@@ -314,7 +339,11 @@ export default class File {
|
||||
this.dynamicImported.push(declar);
|
||||
if (noDefault) this.dynamicImportedNoDefault.push(declar);
|
||||
|
||||
this.moduleFormatter.importSpecifier(specifiers[0], declar, this.dynamicImports);
|
||||
if (this.transformers["es6.modules"].canRun()) {
|
||||
this.moduleFormatter.importSpecifier(specifiers[0], declar, this.dynamicImports);
|
||||
} else {
|
||||
this.dynamicImports.push(declar);
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
@@ -338,7 +367,7 @@ export default class File {
|
||||
|
||||
addHelper(name) {
|
||||
if (!includes(File.helpers, name)) {
|
||||
throw new ReferenceError("Unknown helper " + name);
|
||||
throw new ReferenceError(`Unknown helper ${name}`);
|
||||
}
|
||||
|
||||
var program = this.ast.program;
|
||||
@@ -371,13 +400,14 @@ export default class File {
|
||||
|
||||
errorWithNode(node, msg, Error = SyntaxError) {
|
||||
var loc = node.loc.start;
|
||||
var err = new Error("Line " + loc.line + ": " + msg);
|
||||
var err = new Error(`Line ${loc.line}: ${msg}`);
|
||||
err.loc = loc;
|
||||
return err;
|
||||
}
|
||||
|
||||
addCode(code) {
|
||||
code = (code || "") + "";
|
||||
code = this.parseInputSourceMap(code);
|
||||
this.code = code;
|
||||
return this.parseShebang(code);
|
||||
}
|
||||
@@ -388,7 +418,7 @@ export default class File {
|
||||
var opts = this.opts;
|
||||
|
||||
opts.allowImportExportEverywhere = this.isLoose("es6.modules");
|
||||
opts.strictMode = this.transformers.useStrict.canRun();
|
||||
opts.strictMode = this.transformers.strict.canRun();
|
||||
|
||||
return parse(opts, code, (tree) => {
|
||||
this.transform(tree);
|
||||
@@ -430,6 +460,13 @@ export default class File {
|
||||
}
|
||||
|
||||
checkNode(node, scope) {
|
||||
if (Array.isArray(node)) {
|
||||
for (var i = 0; i < node.length; i++) {
|
||||
this.checkNode(node[i], scope);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var stack = this.transformerStack;
|
||||
scope ||= this.scope;
|
||||
|
||||
@@ -440,6 +477,28 @@ export default class File {
|
||||
});
|
||||
}
|
||||
|
||||
mergeSourceMap(map) {
|
||||
var opts = this.opts;
|
||||
|
||||
var inputMap = opts.inputSourceMap;
|
||||
|
||||
if (inputMap) {
|
||||
map.sources[0] = inputMap.file;
|
||||
|
||||
var inputMapConsumer = new sourceMap.SourceMapConsumer(inputMap);
|
||||
var outputMapConsumer = new sourceMap.SourceMapConsumer(map);
|
||||
var outputMapGenerator = sourceMap.SourceMapGenerator.fromSourceMap(outputMapConsumer);
|
||||
outputMapGenerator.applySourceMap(inputMapConsumer);
|
||||
|
||||
var mergedMap = outputMapGenerator.toJSON();
|
||||
mergedMap.sources = inputMap.sources
|
||||
mergedMap.file = inputMap.file;
|
||||
return mergedMap;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
generate() {
|
||||
var opts = this.opts;
|
||||
var ast = this.ast;
|
||||
@@ -463,11 +522,16 @@ export default class File {
|
||||
|
||||
if (this.shebang) {
|
||||
// add back shebang
|
||||
result.code = this.shebang + "\n" + result.code;
|
||||
result.code = `${this.shebang}\n${result.code}`;
|
||||
}
|
||||
|
||||
if (opts.sourceMap === "inline") {
|
||||
result.code += "\n" + sourceMapToComment(result.map);
|
||||
result.map = this.mergeSourceMap(result.map);
|
||||
|
||||
if (opts.sourceMap === "inline" || opts.sourceMap === "both") {
|
||||
result.code += "\n" + convertSourceMap.fromObject(result.map).toComment();
|
||||
}
|
||||
|
||||
if (opts.sourceMap === "both") {
|
||||
result.map = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import explode from "./explode-assignable-expression";
|
||||
import t from "../../types";
|
||||
|
||||
module.exports = function (exports, opts) {
|
||||
export default function (exports, opts) {
|
||||
var isAssignment = function (node) {
|
||||
return node.operator === opts.operator + "=";
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import t from "../../types";
|
||||
|
||||
module.exports = function build(node, buildBody) {
|
||||
export default function build(node, buildBody) {
|
||||
var self = node.blocks.shift();
|
||||
if (!self) return;
|
||||
|
||||
@@ -20,4 +20,4 @@ module.exports = function build(node, buildBody) {
|
||||
self.right,
|
||||
t.blockStatement([child])
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import explode from "./explode-assignable-expression";
|
||||
import t from "../../types";
|
||||
|
||||
module.exports = function (exports, opts) {
|
||||
export default function (exports, opts) {
|
||||
var buildAssignment = function (left, right) {
|
||||
return t.assignmentExpression("=", left, right);
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ import esutils from "esutils";
|
||||
import * as react from "./react";
|
||||
import t from "../../types";
|
||||
|
||||
module.exports = function (exports, opts) {
|
||||
export default function (exports, opts) {
|
||||
exports.check = function (node) {
|
||||
if (t.isJSX(node)) return true;
|
||||
if (react.isCreateClass(node)) return true;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import cloneDeep from "lodash/lang/cloneDeep";
|
||||
import traverse from "../../traversal";
|
||||
import clone from "lodash/lang/clone";
|
||||
import each from "lodash/collection/each";
|
||||
import has from "lodash/object/has";
|
||||
import t from "../../types";
|
||||
@@ -10,11 +9,11 @@ export function push(mutatorMap, key, kind, computed, value) {
|
||||
|
||||
if (t.isIdentifier(key)) {
|
||||
alias = key.name;
|
||||
if (computed) alias = "computed:" + alias;
|
||||
if (computed) alias = `computed:${alias}`;
|
||||
} else if (t.isLiteral(key)) {
|
||||
alias = String(key.value);
|
||||
} else {
|
||||
alias = JSON.stringify(traverse.removeProperties(cloneDeep(key)));
|
||||
alias = JSON.stringify(traverse.removeProperties(t.cloneDeep(key)));
|
||||
}
|
||||
|
||||
var map;
|
||||
@@ -33,7 +32,7 @@ export function push(mutatorMap, key, kind, computed, value) {
|
||||
map[kind] = value;
|
||||
}
|
||||
|
||||
export function build(mutatorMap) {
|
||||
export function toClassObject(mutatorMap) {
|
||||
var objExpr = t.objectExpression([]);
|
||||
|
||||
each(mutatorMap, function (map) {
|
||||
@@ -41,22 +40,43 @@ export function build(mutatorMap) {
|
||||
|
||||
var propNode = t.property("init", map._key, mapNode, map._computed);
|
||||
|
||||
if (!map.get && !map.set) {
|
||||
map.writable = t.literal(true);
|
||||
}
|
||||
|
||||
if (map.enumerable === false) {
|
||||
delete map.enumerable;
|
||||
} else {
|
||||
map.enumerable = t.literal(true);
|
||||
}
|
||||
|
||||
map.configurable = t.literal(true);
|
||||
|
||||
each(map, function (node, key) {
|
||||
if (key[0] === "_") return;
|
||||
|
||||
node = clone(node);
|
||||
var inheritNode = node;
|
||||
if (t.isMethodDefinition(node)) node = node.value;
|
||||
|
||||
var prop = t.property("init", t.identifier(key), node);
|
||||
t.inheritsComments(prop, inheritNode);
|
||||
t.removeComments(inheritNode);
|
||||
mapNode.properties.push(prop);
|
||||
});
|
||||
|
||||
objExpr.properties.push(propNode);
|
||||
});
|
||||
|
||||
return objExpr;
|
||||
}
|
||||
|
||||
export function toDefineObject(mutatorMap) {
|
||||
var objExpr = t.objectExpression([]);
|
||||
|
||||
each(mutatorMap, function (map) {
|
||||
var mapNode = t.objectExpression([]);
|
||||
|
||||
var propNode = t.property("init", map._key, mapNode, map._computed);
|
||||
|
||||
if (map.value) {
|
||||
map.writable = t.literal(true);
|
||||
}
|
||||
|
||||
map.configurable = t.literal(true);
|
||||
map.enumerable = t.literal(true);
|
||||
|
||||
each(map, function (node, key) {
|
||||
if (key[0] === "_") return;
|
||||
|
||||
node = t.clone(node);
|
||||
var inheritNode = node;
|
||||
if (t.isMethodDefinition(node)) node = node.value;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ var getObjRef = function (node, nodes, file, scope) {
|
||||
return ref;
|
||||
}
|
||||
} else {
|
||||
throw new Error("We can't explode this node type " + node.type);
|
||||
throw new Error(`We can't explode this node type ${node.type}`);
|
||||
}
|
||||
|
||||
var temp = scope.generateUidBasedOnNode(ref);
|
||||
@@ -45,7 +45,7 @@ var getPropRef = function (node, nodes, file, scope) {
|
||||
return temp;
|
||||
};
|
||||
|
||||
module.exports = function (node, nodes, file, scope, allowedSingleIdent) {
|
||||
export default function (node, nodes, file, scope, allowedSingleIdent) {
|
||||
var obj;
|
||||
if (t.isIdentifier(node) && allowedSingleIdent) {
|
||||
obj = node;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import t from "../../types";
|
||||
|
||||
module.exports = function (node) {
|
||||
export default function (node) {
|
||||
var lastNonDefault = 0;
|
||||
for (var i = 0; i < node.params.length; i++) {
|
||||
if (!t.isAssignmentPattern(node.params[i])) lastNonDefault = i + 1;
|
||||
|
||||
@@ -6,7 +6,7 @@ var visitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
// check if this node is a referenced identifier that matches the same as our
|
||||
// function id
|
||||
if (!t.isReferencedIdentifier(node, parent, { name: state.name })) return;
|
||||
if (!this.isReferencedIdentifier({ name: state.name })) return;
|
||||
|
||||
// check that we don't have a local variable declared as that removes the need
|
||||
// for the wrapper
|
||||
@@ -89,6 +89,11 @@ var visit = function (node, name, scope) {
|
||||
return state;
|
||||
};
|
||||
|
||||
export function custom(node, id, scope) {
|
||||
var state = visit(node, id.name, scope);
|
||||
return wrap(state, node, id, scope);
|
||||
}
|
||||
|
||||
export function property(node, file, scope) {
|
||||
var key = t.toComputedKey(node, node.key);
|
||||
if (!t.isLiteral(key)) return node; // we can't set a function id with this
|
||||
@@ -103,7 +108,7 @@ export function property(node, file, scope) {
|
||||
|
||||
export function bare(node, parent, scope) {
|
||||
// has an `id` so we don't need to infer one
|
||||
if (node.id) return;
|
||||
if (node.id) return node;
|
||||
|
||||
var id;
|
||||
if (t.isProperty(parent) && parent.kind === "init" && !parent.computed) {
|
||||
@@ -113,10 +118,10 @@ export function bare(node, parent, scope) {
|
||||
// var foo = function () {};
|
||||
id = parent.id;
|
||||
} else {
|
||||
return;
|
||||
return node;
|
||||
}
|
||||
|
||||
if (!t.isIdentifier(id)) return;
|
||||
if (!t.isIdentifier(id)) return node;
|
||||
|
||||
var name = t.toIdentifier(id.name);
|
||||
id = t.identifier(name);
|
||||
|
||||
@@ -16,7 +16,7 @@ var visitor = {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = function (node, callId, scope) {
|
||||
export default function (node, callId, scope) {
|
||||
node.async = false;
|
||||
node.generator = true;
|
||||
|
||||
@@ -24,7 +24,7 @@ module.exports = function (node, callId, scope) {
|
||||
|
||||
var call = t.callExpression(callId, [node]);
|
||||
var id = node.id;
|
||||
delete node.id;
|
||||
node.id = null;
|
||||
|
||||
if (t.isFunctionDeclaration(node)) {
|
||||
var declar = t.variableDeclaration("let", [
|
||||
|
||||
@@ -55,14 +55,18 @@ export default class ReplaceSupers {
|
||||
constructor(opts, inClass) {
|
||||
this.topLevelThisReference = opts.topLevelThisReference;
|
||||
this.methodNode = opts.methodNode;
|
||||
this.className = opts.className;
|
||||
this.superName = opts.superName;
|
||||
this.superRef = opts.superRef;
|
||||
this.isStatic = opts.isStatic;
|
||||
this.hasSuper = false;
|
||||
this.inClass = inClass;
|
||||
this.isLoose = opts.isLoose;
|
||||
this.scope = opts.scope;
|
||||
this.file = opts.file;
|
||||
this.opts = opts;
|
||||
}
|
||||
|
||||
getObjectRef() {
|
||||
return this.opts.objectRef || this.opts.getObjectRef();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,7 +91,7 @@ export default class ReplaceSupers {
|
||||
t.callExpression(
|
||||
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
|
||||
[
|
||||
this.isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
|
||||
this.isStatic ? this.getObjectRef() : t.memberExpression(this.getObjectRef(), t.identifier("prototype"))
|
||||
]
|
||||
),
|
||||
isComputed ? property : t.literal(property.name),
|
||||
@@ -118,7 +122,7 @@ export default class ReplaceSupers {
|
||||
t.callExpression(
|
||||
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
|
||||
[
|
||||
this.isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
|
||||
this.isStatic ? this.getObjectRef() : t.memberExpression(this.getObjectRef(), t.identifier("prototype"))
|
||||
]
|
||||
),
|
||||
isComputed ? property : t.literal(property.name),
|
||||
@@ -175,19 +179,19 @@ export default class ReplaceSupers {
|
||||
getLooseSuperProperty(id, parent) {
|
||||
var methodNode = this.methodNode;
|
||||
var methodName = methodNode.key;
|
||||
var superName = this.superName || t.identifier("Function");
|
||||
var superRef = this.superRef || t.identifier("Function");
|
||||
|
||||
if (parent.property === id) {
|
||||
return;
|
||||
} else if (t.isCallExpression(parent, { callee: id })) {
|
||||
// super(); -> ClassName.prototype.MethodName.call(this);
|
||||
// super(); -> objectRef.prototype.MethodName.call(this);
|
||||
parent.arguments.unshift(t.thisExpression());
|
||||
|
||||
if (methodName.name === "constructor") {
|
||||
// constructor() { super(); }
|
||||
return t.memberExpression(superName, t.identifier("call"));
|
||||
return t.memberExpression(superRef, t.identifier("call"));
|
||||
} else {
|
||||
id = superName;
|
||||
id = superRef;
|
||||
|
||||
// foo() { super(); }
|
||||
if (!methodNode.static) {
|
||||
@@ -198,10 +202,10 @@ export default class ReplaceSupers {
|
||||
return t.memberExpression(id, t.identifier("call"));
|
||||
}
|
||||
} else if (t.isMemberExpression(parent) && !methodNode.static) {
|
||||
// super.test -> ClassName.prototype.test
|
||||
return t.memberExpression(superName, t.identifier("prototype"));
|
||||
// super.test -> objectRef.prototype.test
|
||||
return t.memberExpression(superRef, t.identifier("prototype"));
|
||||
} else {
|
||||
return superName;
|
||||
return superRef;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +226,7 @@ export default class ReplaceSupers {
|
||||
if (!t.isMemberExpression(callee)) return;
|
||||
if (callee.object.name !== "super") return;
|
||||
|
||||
// super.test(); -> ClassName.prototype.MethodName.call(this);
|
||||
// super.test(); -> objectRef.prototype.MethodName.call(this);
|
||||
this.hasSuper = true;
|
||||
t.appendToMemberExpression(callee, t.identifier("call"));
|
||||
node.arguments.unshift(getThisReference());
|
||||
@@ -251,7 +255,7 @@ export default class ReplaceSupers {
|
||||
if (t.isCallExpression(node)) {
|
||||
var callee = node.callee;
|
||||
if (isSuper(callee, node)) {
|
||||
// super(); -> _get(Object.getPrototypeOf(ClassName), "MethodName", this).call(this);
|
||||
// super(); -> _get(Object.getPrototypeOf(objectRef), "MethodName", this).call(this);
|
||||
property = methodNode.key;
|
||||
computed = methodNode.computed;
|
||||
args = node.arguments;
|
||||
@@ -264,17 +268,17 @@ export default class ReplaceSupers {
|
||||
throw this.file.errorWithNode(node, messages.get("classesIllegalSuperCall", methodName));
|
||||
}
|
||||
} else if (t.isMemberExpression(callee) && isSuper(callee.object, callee)) {
|
||||
// super.test(); -> _get(Object.getPrototypeOf(ClassName.prototype), "test", this).call(this);
|
||||
// super.test(); -> _get(Object.getPrototypeOf(objectRef.prototype), "test", this).call(this);
|
||||
property = callee.property;
|
||||
computed = callee.computed;
|
||||
args = node.arguments;
|
||||
}
|
||||
} else if (t.isMemberExpression(node) && isSuper(node.object, node)) {
|
||||
// super.name; -> _get(Object.getPrototypeOf(ClassName.prototype), "name", this);
|
||||
// super.name; -> _get(Object.getPrototypeOf(objectRef.prototype), "name", this);
|
||||
property = node.property;
|
||||
computed = node.computed;
|
||||
} else if (t.isAssignmentExpression(node) && isSuper(node.left.object, node.left) && methodNode.kind === "set") {
|
||||
// super.name = "val"; -> _set(Object.getPrototypeOf(ClassName.prototype), "name", this);
|
||||
// super.name = "val"; -> _set(Object.getPrototypeOf(objectRef.prototype), "name", this);
|
||||
this.hasSuper = true;
|
||||
return this.setSuperProperty(node.left.property, node.right, node.left.computed, getThisReference());
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ export function has(node) {
|
||||
|
||||
export function wrap(node, callback) {
|
||||
var useStrictNode;
|
||||
if (exports.has(node)) {
|
||||
if (has(node)) {
|
||||
useStrictNode = node.body.shift();
|
||||
}
|
||||
|
||||
@@ -25,9 +25,12 @@ transform._ensureTransformerNames = function (type, rawKeys) {
|
||||
var key = rawKeys[i];
|
||||
|
||||
var deprecatedKey = transform.deprecatedTransformerMap[key];
|
||||
if (deprecatedKey) {
|
||||
var aliasKey = transform.aliasTransformerMap[key];
|
||||
if (aliasKey) {
|
||||
keys.push(aliasKey);
|
||||
} else if (deprecatedKey) {
|
||||
// deprecated key, remap it to the new one
|
||||
console.error("The transformer " + key + " has been renamed to " + deprecatedKey);
|
||||
console.error(`The transformer ${key} has been renamed to ${deprecatedKey}`);
|
||||
rawKeys.push(deprecatedKey);
|
||||
} else if (transform.transformers[key]) {
|
||||
// valid key
|
||||
@@ -37,7 +40,7 @@ transform._ensureTransformerNames = function (type, rawKeys) {
|
||||
keys = keys.concat(transform.namespaces[key]);
|
||||
} else {
|
||||
// invalid key
|
||||
throw new ReferenceError("Unknown transformer " + key + " specified in " + type);
|
||||
throw new ReferenceError(`Unknown transformer ${key} specified in ${type}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +52,7 @@ transform.transformers = object();
|
||||
transform.namespaces = object();
|
||||
|
||||
transform.deprecatedTransformerMap = require("./transformers/deprecated");
|
||||
transform.aliasTransformerMap = require("./transformers/aliases");
|
||||
transform.moduleFormatters = require("./modules");
|
||||
|
||||
import rawTransformers from "./transformers";
|
||||
|
||||
@@ -42,8 +42,8 @@ var remapVisitor = {
|
||||
};
|
||||
|
||||
var importsVisitor = {
|
||||
enter(node, parent, scope, formatter) {
|
||||
if (t.isImportDeclaration(node)) {
|
||||
ImportDeclaration: {
|
||||
enter(node, parent, scope, formatter) {
|
||||
formatter.hasLocalImports = true;
|
||||
extend(formatter.localImports, t.getBindingIdentifiers(node));
|
||||
formatter.bumpImportOccurences(node);
|
||||
@@ -52,9 +52,9 @@ var importsVisitor = {
|
||||
};
|
||||
|
||||
var exportsVisitor = {
|
||||
enter(node, parent, scope, formatter) {
|
||||
var declar = node && node.declaration;
|
||||
if (t.isExportDeclaration(node)) {
|
||||
ExportDeclaration: {
|
||||
enter(node, parent, scope, formatter) {
|
||||
var declar = node.declaration;
|
||||
formatter.hasLocalImports = true;
|
||||
|
||||
if (declar && t.isStatement(declar)) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
module.exports = {
|
||||
export default {
|
||||
commonStrict: require("./common-strict"),
|
||||
amdStrict: require("./amd-strict"),
|
||||
umdStrict: require("./umd-strict"),
|
||||
|
||||
@@ -142,9 +142,9 @@ export default class SystemFormatter extends AMDFormatter {
|
||||
|
||||
return t.arrayExpression(map(this.ids, function (uid, source) {
|
||||
var state = {
|
||||
hoistDeclarators: hoistDeclarators,
|
||||
source: source,
|
||||
nodes: [],
|
||||
hoistDeclarators: hoistDeclarators
|
||||
nodes: []
|
||||
};
|
||||
|
||||
scope.traverse(block, runnerSettersVisitor, state);
|
||||
@@ -161,11 +161,11 @@ export default class SystemFormatter extends AMDFormatter {
|
||||
var block = t.blockStatement(program.body);
|
||||
|
||||
var runner = util.template("system", {
|
||||
MODULE_NAME: moduleNameLiteral,
|
||||
MODULE_DEPENDENCIES: t.arrayExpression(this.buildDependencyLiterals()),
|
||||
EXPORT_IDENTIFIER: this.exportIdentifier,
|
||||
SETTERS: this.buildRunnerSetters(block, hoistDeclarators),
|
||||
EXECUTE: t.functionExpression(null, [], block)
|
||||
EXPORT_IDENTIFIER: this.exportIdentifier,
|
||||
MODULE_NAME: moduleNameLiteral,
|
||||
SETTERS: this.buildRunnerSetters(block, hoistDeclarators),
|
||||
EXECUTE: t.functionExpression(null, [], block)
|
||||
}, true);
|
||||
|
||||
var handlerBody = runner.expression.arguments[2].body.body;
|
||||
|
||||
16
src/babel/transformation/templates/create-class.js
Normal file
16
src/babel/transformation/templates/create-class.js
Normal file
@@ -0,0 +1,16 @@
|
||||
(function() {
|
||||
function defineProperties(target, props) {
|
||||
for (var key in props) {
|
||||
var prop = props[key];
|
||||
prop.configurable = true;
|
||||
if (prop.value) prop.writable = true;
|
||||
}
|
||||
Object.defineProperties(target, props);
|
||||
}
|
||||
|
||||
return function (Constructor, protoProps, staticProps) {
|
||||
if (protoProps) defineProperties(Constructor.prototype, protoProps);
|
||||
if (staticProps) defineProperties(Constructor, staticProps);
|
||||
return Constructor;
|
||||
};
|
||||
})()
|
||||
@@ -1,4 +0,0 @@
|
||||
(function (child, staticProps, instanceProps) {
|
||||
if (staticProps) Object.defineProperties(child, staticProps);
|
||||
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
|
||||
})
|
||||
11
src/babel/transformation/templates/umd-commonjs-strict.js
Normal file
11
src/babel/transformation/templates/umd-commonjs-strict.js
Normal file
@@ -0,0 +1,11 @@
|
||||
(function (root, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define(AMD_ARGUMENTS, factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
factory(COMMON_ARGUMENTS);
|
||||
} else {
|
||||
factory(BROWSER_ARGUMENTS);
|
||||
}
|
||||
})(UMD_ROOT, function (FACTORY_PARAMETERS) {
|
||||
FACTORY_BODY
|
||||
});
|
||||
@@ -56,7 +56,7 @@ export default class TransformerPass {
|
||||
|
||||
var file = this.file;
|
||||
|
||||
file.debug("Running transformer " + this.transformer.key);
|
||||
file.debug(`Running transformer ${this.transformer.key}`);
|
||||
|
||||
file.scope.traverse(file.ast, this.handlers, file);
|
||||
}
|
||||
|
||||
3
src/babel/transformation/transformers/aliases.json
Normal file
3
src/babel/transformation/transformers/aliases.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"useStrict": "strict"
|
||||
}
|
||||
@@ -23,6 +23,6 @@ export function ObjectExpression(node) {
|
||||
|
||||
return t.callExpression(
|
||||
t.memberExpression(t.identifier("Object"), t.identifier("defineProperties")),
|
||||
[node, defineMap.build(mutatorMap)]
|
||||
[node, defineMap.toDefineObject(mutatorMap)]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import t from "../../../types";
|
||||
|
||||
var visitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (!t.isReferencedIdentifier(node, parent)) return;
|
||||
if (!this.isReferencedIdentifier()) return;
|
||||
|
||||
var declared = state.letRefs[node.name];
|
||||
if (!declared) return;
|
||||
@@ -32,12 +32,10 @@ export function BlockStatement(node, parent, scope, file) {
|
||||
var letRefs = node._letReferences;
|
||||
if (!letRefs) return;
|
||||
|
||||
var state = {
|
||||
scope.traverse(node, visitor, {
|
||||
letRefs: letRefs,
|
||||
file: file
|
||||
};
|
||||
|
||||
scope.traverse(node, visitor, state);
|
||||
});
|
||||
}
|
||||
|
||||
export { BlockStatement as Program, BlockStatement as Loop };
|
||||
|
||||
@@ -109,7 +109,7 @@ function traverseReplace(node, parent, scope, remaps) {
|
||||
|
||||
var letReferenceBlockVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (t.isFunction(node)) {
|
||||
if (this.isFunction()) {
|
||||
scope.traverse(node, letReferenceFunctionVisitor, state);
|
||||
return this.skip();
|
||||
}
|
||||
@@ -119,7 +119,7 @@ var letReferenceBlockVisitor = {
|
||||
var letReferenceFunctionVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
// not a direct reference
|
||||
if (!t.isReferencedIdentifier(node, parent)) return;
|
||||
if (!this.isReferencedIdentifier()) return;
|
||||
|
||||
// this scope has a variable with the same name so it couldn't belong
|
||||
// to our let scope
|
||||
@@ -134,17 +134,17 @@ var letReferenceFunctionVisitor = {
|
||||
|
||||
var hoistVarDeclarationsVisitor = {
|
||||
enter(node, parent, scope, self) {
|
||||
if (t.isForStatement(node)) {
|
||||
if (this.isForStatement()) {
|
||||
if (isVar(node.init, node)) {
|
||||
node.init = t.sequenceExpression(self.pushDeclar(node.init));
|
||||
}
|
||||
} else if (t.isFor(node)) {
|
||||
} else if (this.isFor()) {
|
||||
if (isVar(node.left, node)) {
|
||||
node.left = node.left.declarations[0].id;
|
||||
}
|
||||
} else if (isVar(node, parent)) {
|
||||
return self.pushDeclar(node).map(t.expressionStatement);
|
||||
} else if (t.isFunction(node)) {
|
||||
} else if (this.isFunction()) {
|
||||
return this.skip();
|
||||
}
|
||||
}
|
||||
@@ -152,7 +152,7 @@ var hoistVarDeclarationsVisitor = {
|
||||
|
||||
var loopLabelVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (t.isLabeledStatement(node)) {
|
||||
if (this.isLabeledStatement()) {
|
||||
state.innerLabels.push(node.label.name);
|
||||
}
|
||||
}
|
||||
@@ -170,13 +170,13 @@ var loopVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
var replace;
|
||||
|
||||
if (t.isLoop(node)) {
|
||||
if (this.isLoop()) {
|
||||
state.ignoreLabeless = true;
|
||||
scope.traverse(node, loopVisitor, state);
|
||||
state.ignoreLabeless = false;
|
||||
}
|
||||
|
||||
if (t.isFunction(node) || t.isLoop(node)) {
|
||||
if (this.isFunction() || this.isLoop()) {
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ var loopVisitor = {
|
||||
return;
|
||||
}
|
||||
|
||||
loopText = loopText + "|" + node.label.name;
|
||||
loopText = `${loopText}|${node.label.name}`;
|
||||
} else {
|
||||
// we shouldn't be transforming these statements because
|
||||
// they don't refer to the actual loop we're scopifying
|
||||
@@ -204,7 +204,7 @@ var loopVisitor = {
|
||||
replace = t.literal(loopText);
|
||||
}
|
||||
|
||||
if (t.isReturnStatement(node)) {
|
||||
if (this.isReturnStatement()) {
|
||||
state.hasReturn = true;
|
||||
replace = t.objectExpression([
|
||||
t.property("init", t.identifier("v"), node.argument || t.identifier("undefined"))
|
||||
|
||||
@@ -3,29 +3,54 @@ import * as nameMethod from "../../helpers/name-method";
|
||||
import * as defineMap from "../../helpers/define-map";
|
||||
import * as messages from "../../../messages";
|
||||
import * as util from "../../../util";
|
||||
import traverse from "../../../traversal";
|
||||
import t from "../../../types";
|
||||
|
||||
export var check = t.isClass;
|
||||
|
||||
export function ClassDeclaration(node, parent, scope, file) {
|
||||
return new ClassTransformer(node, file, scope, true).run();
|
||||
return t.variableDeclaration("let", [
|
||||
t.variableDeclarator(node.id, t.toExpression(node))
|
||||
]);
|
||||
}
|
||||
|
||||
export function ClassExpression(node, parent, scope, file) {
|
||||
if (!node.id) {
|
||||
if (t.isProperty(parent) && parent.value === node && !parent.computed && t.isIdentifier(parent.key)) {
|
||||
// var o = { foo: class {} };
|
||||
node.id = parent.key;
|
||||
}
|
||||
return new ClassTransformer(node, parent, scope, file).run();
|
||||
}
|
||||
|
||||
if (t.isVariableDeclarator(parent) && t.isIdentifier(parent.id)) {
|
||||
// var foo = class {};
|
||||
node.id = parent.id;
|
||||
var verifyConstructorVisitor = traverse.explode({
|
||||
MethodDefinition: {
|
||||
enter() {
|
||||
this.skip();
|
||||
}
|
||||
},
|
||||
|
||||
Property: {
|
||||
enter(node) {
|
||||
if (node.method) this.skip();
|
||||
}
|
||||
},
|
||||
|
||||
CallExpression: {
|
||||
enter(node, parent, scope, state) {
|
||||
if (t.isIdentifier(node.callee, { name: "super" })) {
|
||||
state.hasBareSuper = true;
|
||||
|
||||
if (!state.hasSuper) {
|
||||
throw state.file.errorWithNode(node, "super call is only allowed in derived constructor");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
ThisExpression: {
|
||||
enter(node, parent, scope, state) {
|
||||
if (state.hasSuper && !state.hasBareSuper) {
|
||||
throw state.file.errorWithNode(node, "'this' is not allowed before super()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new ClassTransformer(node, file, scope, false).run();
|
||||
}
|
||||
});
|
||||
|
||||
class ClassTransformer {
|
||||
|
||||
@@ -33,27 +58,31 @@ class ClassTransformer {
|
||||
* Description
|
||||
*
|
||||
* @param {Node} node
|
||||
* @param {File} file
|
||||
* @param {Node} parent
|
||||
* @param {Scope} scope
|
||||
* @param {Boolean} isStatement
|
||||
* @param {File} file
|
||||
*/
|
||||
|
||||
constructor(node, file, scope, isStatement) {
|
||||
this.isStatement = isStatement;
|
||||
this.scope = scope;
|
||||
this.node = node;
|
||||
this.file = file;
|
||||
constructor(node, parent, scope, file) {
|
||||
this.parent = parent;
|
||||
this.scope = scope;
|
||||
this.node = node;
|
||||
this.file = file;
|
||||
|
||||
this.hasInstanceMutators = false;
|
||||
this.hasStaticMutators = false;
|
||||
|
||||
this.instanceMutatorMap = {};
|
||||
this.staticMutatorMap = {};
|
||||
this.hasConstructor = false;
|
||||
this.className = node.id || scope.generateUidIdentifier("class");
|
||||
this.superName = node.superClass || t.identifier("Function");
|
||||
this.hasSuper = !!node.superClass;
|
||||
this.isLoose = file.isLoose("es6.classes");
|
||||
|
||||
this.hasConstructor = false;
|
||||
this.className = node.id;
|
||||
this.classRef = node.id || scope.generateUidIdentifier("class");
|
||||
|
||||
this.superName = node.superClass || t.identifier("Function");
|
||||
this.hasSuper = !!node.superClass;
|
||||
|
||||
this.isLoose = file.isLoose("es6.classes");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,39 +95,35 @@ class ClassTransformer {
|
||||
var superName = this.superName;
|
||||
var className = this.className;
|
||||
var classBody = this.node.body.body;
|
||||
var classRef = this.classRef;
|
||||
var file = this.file;
|
||||
|
||||
//
|
||||
|
||||
var body = this.body = [];
|
||||
|
||||
//
|
||||
|
||||
var constructorBody = t.blockStatement([
|
||||
t.expressionStatement(t.callExpression(file.addHelper("class-call-check"), [
|
||||
t.thisExpression(),
|
||||
className
|
||||
classRef
|
||||
]))
|
||||
]);
|
||||
|
||||
var constructor;
|
||||
if (this.node.id) {
|
||||
constructor = t.functionDeclaration(className, [], constructorBody);
|
||||
|
||||
if (this.className) {
|
||||
constructor = t.functionDeclaration(this.className, [], constructorBody);
|
||||
body.push(constructor);
|
||||
} else {
|
||||
var constructorName = null;
|
||||
// when a class has no parent and there is only a constructor or no body
|
||||
// then the constructor is not wrapped in a closure and needs to be named
|
||||
var containsOnlyConstructor = classBody.length === 1 && classBody[0].key.name === "constructor";
|
||||
if (!this.hasSuper && (classBody.length === 0 || containsOnlyConstructor)) {
|
||||
constructorName = className;
|
||||
}
|
||||
|
||||
constructor = t.functionExpression(constructorName, [], constructorBody);
|
||||
body.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(className, constructor)
|
||||
]));
|
||||
constructor = t.functionExpression(null, [], constructorBody);
|
||||
}
|
||||
|
||||
this.constructor = constructor;
|
||||
|
||||
//
|
||||
|
||||
var closureParams = [];
|
||||
var closureArgs = [];
|
||||
|
||||
@@ -107,40 +132,40 @@ class ClassTransformer {
|
||||
if (this.hasSuper) {
|
||||
closureArgs.push(superName);
|
||||
|
||||
if (!t.isIdentifier(superName)) {
|
||||
superName = this.scope.generateUidBasedOnNode(superName, this.file);
|
||||
}
|
||||
|
||||
superName = this.scope.generateUidBasedOnNode(superName, this.file);
|
||||
closureParams.push(superName);
|
||||
|
||||
this.superName = superName;
|
||||
body.push(t.expressionStatement(t.callExpression(file.addHelper("inherits"), [className, superName])));
|
||||
body.push(t.expressionStatement(t.callExpression(file.addHelper("inherits"), [classRef, superName])));
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
this.buildBody();
|
||||
|
||||
t.inheritsComments(body[0], this.node);
|
||||
|
||||
var init;
|
||||
|
||||
if (body.length === 1) {
|
||||
// only a constructor so no need for a closure container
|
||||
init = t.toExpression(constructor);
|
||||
if (this.className) {
|
||||
// named class with only a constructor
|
||||
if (body.length === 1) return t.toExpression(body[0]);
|
||||
} else {
|
||||
body.push(t.returnStatement(className));
|
||||
init = t.callExpression(
|
||||
t.functionExpression(null, closureParams, t.blockStatement(body)),
|
||||
closureArgs
|
||||
);
|
||||
// infer class name if this is a nameless class expression
|
||||
constructor = nameMethod.bare(constructor, this.parent, this.scope);
|
||||
|
||||
body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(classRef, constructor)
|
||||
]));
|
||||
|
||||
t.inheritsComments(body[0], this.node);
|
||||
}
|
||||
|
||||
if (this.isStatement) {
|
||||
return t.variableDeclaration("let", [
|
||||
t.variableDeclarator(className, init)
|
||||
]);
|
||||
} else {
|
||||
return init;
|
||||
}
|
||||
//
|
||||
|
||||
body.push(t.returnStatement(classRef));
|
||||
|
||||
return t.callExpression(
|
||||
t.functionExpression(null, closureParams, t.blockStatement(body)),
|
||||
closureArgs
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,18 +182,22 @@ class ClassTransformer {
|
||||
for (var i = 0; i < classBody.length; i++) {
|
||||
var node = classBody[i];
|
||||
if (t.isMethodDefinition(node)) {
|
||||
var isConstructor = (!node.computed && t.isIdentifier(node.key, { name: "constructor" })) || t.isLiteral(node.key, { value: "constructor" });
|
||||
if (isConstructor) this.verifyConstructor(node);
|
||||
|
||||
var replaceSupers = new ReplaceSupers({
|
||||
methodNode: node,
|
||||
className: this.className,
|
||||
superName: this.superName,
|
||||
objectRef: this.classRef,
|
||||
superRef: this.superName,
|
||||
isStatic: node.static,
|
||||
isLoose: this.isLoose,
|
||||
scope: this.scope,
|
||||
file: this.file
|
||||
}, true);
|
||||
|
||||
replaceSupers.replace();
|
||||
|
||||
if ((!node.computed && t.isIdentifier(node.key, { name: "constructor" })) || t.isLiteral(node.key, { value: "constructor" })) {
|
||||
if (isConstructor) {
|
||||
this.pushConstructor(node);
|
||||
} else {
|
||||
this.pushMethod(node);
|
||||
@@ -182,7 +211,7 @@ class ClassTransformer {
|
||||
}
|
||||
|
||||
// we have no constructor, we have a super, and the super doesn't appear to be falsy
|
||||
if (!this.hasConstructor && this.hasSuper && t.evaluateTruthy(superName) !== false) {
|
||||
if (!this.hasConstructor && this.hasSuper && t.evaluateTruthy(superName, this.scope) !== false) {
|
||||
var helperName = "class-super-constructor-call";
|
||||
if (this.isLoose) helperName += "-loose";
|
||||
constructor.body.body.push(util.template(helperName, {
|
||||
@@ -195,25 +224,47 @@ class ClassTransformer {
|
||||
var staticProps;
|
||||
|
||||
if (this.hasInstanceMutators) {
|
||||
instanceProps = defineMap.build(this.instanceMutatorMap);
|
||||
instanceProps = defineMap.toClassObject(this.instanceMutatorMap);
|
||||
}
|
||||
|
||||
if (this.hasStaticMutators) {
|
||||
staticProps = defineMap.build(this.staticMutatorMap);
|
||||
staticProps = defineMap.toClassObject(this.staticMutatorMap);
|
||||
}
|
||||
|
||||
if (instanceProps || staticProps) {
|
||||
staticProps ||= t.literal(null);
|
||||
instanceProps ||= t.literal(null);
|
||||
|
||||
var args = [className, staticProps];
|
||||
if (instanceProps) args.push(instanceProps);
|
||||
var args = [this.classRef, instanceProps];
|
||||
if (staticProps) args.push(staticProps);
|
||||
|
||||
body.push(t.expressionStatement(
|
||||
t.callExpression(this.file.addHelper("prototype-properties"), args)
|
||||
t.callExpression(this.file.addHelper("create-class"), args)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Node} node
|
||||
*/
|
||||
|
||||
verifyConstructor(node) {
|
||||
return; // enable this for the next major
|
||||
|
||||
var state = {
|
||||
hasBareSuper: false,
|
||||
hasSuper: this.hasSuper,
|
||||
file: this.file
|
||||
};
|
||||
|
||||
traverse(node, verifyConstructorVisitor, this.scope, state);
|
||||
|
||||
if (!state.hasBareSuper && this.hasSuper) {
|
||||
throw this.file.errorWithNode(node, "Derived constructor must call super()");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a method to its respective mutatorMap.
|
||||
*
|
||||
@@ -231,9 +282,9 @@ class ClassTransformer {
|
||||
if (this.isLoose) {
|
||||
// use assignments instead of define properties for loose classes
|
||||
|
||||
var className = this.className;
|
||||
if (!node.static) className = t.memberExpression(className, t.identifier("prototype"));
|
||||
methodName = t.memberExpression(className, methodName, node.computed);
|
||||
var classRef = this.classRef;
|
||||
if (!node.static) classRef = t.memberExpression(classRef, t.identifier("prototype"));
|
||||
methodName = t.memberExpression(classRef, methodName, node.computed);
|
||||
|
||||
var expr = t.expressionStatement(t.assignmentExpression("=", methodName, node.value));
|
||||
t.inheritsComments(expr, node);
|
||||
@@ -253,7 +304,6 @@ class ClassTransformer {
|
||||
}
|
||||
|
||||
defineMap.push(mutatorMap, methodName, kind, node.computed, node);
|
||||
defineMap.push(mutatorMap, methodName, "enumerable", node.computed, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -268,7 +318,7 @@ class ClassTransformer {
|
||||
var key;
|
||||
|
||||
if (node.static) {
|
||||
key = t.memberExpression(this.className, node.key);
|
||||
key = t.memberExpression(this.classRef, node.key);
|
||||
this.body.push(
|
||||
t.expressionStatement(t.assignmentExpression("=", key, node.value))
|
||||
);
|
||||
@@ -301,6 +351,8 @@ class ClassTransformer {
|
||||
|
||||
construct._ignoreUserWhitespace = true;
|
||||
construct.params = fn.params;
|
||||
construct.body.body = construct.body.body.concat(fn.body.body);
|
||||
|
||||
t.inherits(construct.body, fn.body);
|
||||
construct.body.body = construct.body.body.concat(fn.body.body);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ export function check(node) {
|
||||
|
||||
var visitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (t.isAssignmentExpression(node) || t.isUpdateExpression(node)) {
|
||||
var ids = t.getBindingIdentifiers(node);
|
||||
if (this.isAssignmentExpression() || this.isUpdateExpression()) {
|
||||
var ids = this.getBindingIdentifiers();
|
||||
|
||||
for (var name in ids) {
|
||||
var id = ids[name];
|
||||
@@ -30,7 +30,7 @@ var visitor = {
|
||||
|
||||
throw state.file.errorWithNode(id, messages.get("readOnly", name));
|
||||
}
|
||||
} else if (t.isScope(node, parent)) {
|
||||
} else if (this.isScope()) {
|
||||
this.skip();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,12 +56,12 @@ export { ForOfStatement as ForInStatement };
|
||||
exports.Function = function (node, parent, scope, file) {
|
||||
var nodes = [];
|
||||
|
||||
var hasDestructuringTransformer = false;
|
||||
var hasDestructuring = false;
|
||||
|
||||
node.params = node.params.map(function (pattern, i) {
|
||||
if (!t.isPattern(pattern)) return pattern;
|
||||
|
||||
hasDestructuringTransformer = true;
|
||||
hasDestructuring = true;
|
||||
var ref = scope.generateUidIdentifier("ref");
|
||||
|
||||
var destructuring = new DestructuringTransformer({
|
||||
@@ -69,15 +69,16 @@ exports.Function = function (node, parent, scope, file) {
|
||||
nodes: nodes,
|
||||
scope: scope,
|
||||
file: file,
|
||||
kind: "var",
|
||||
kind: "let"
|
||||
});
|
||||
destructuring.init(pattern, ref);
|
||||
|
||||
return ref;
|
||||
});
|
||||
|
||||
if (!hasDestructuringTransformer) return;
|
||||
if (!hasDestructuring) return;
|
||||
|
||||
file.checkNode(nodes);
|
||||
t.ensureBlock(node);
|
||||
|
||||
var block = node.body;
|
||||
@@ -218,7 +219,7 @@ export function VariableDeclaration(node, parent, scope, file) {
|
||||
}
|
||||
|
||||
return nodes;
|
||||
};
|
||||
}
|
||||
|
||||
var hasRest = function (pattern) {
|
||||
for (var i = 0; i < pattern.elements.length; i++) {
|
||||
|
||||
@@ -41,17 +41,20 @@ export function ForOfStatement(node, parent, scope, file) {
|
||||
|
||||
var breakVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (t.isLoop(node)) {
|
||||
if (this.isLoop()) {
|
||||
state.ignoreLabeless = true;
|
||||
scope.traverse(node, breakVisitor, state);
|
||||
state.ignoreLabeless = false;
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
if (t.isBreakStatement(node)) {
|
||||
if (this.isBreakStatement()) {
|
||||
if (!node.label && state.ignoreLabeless) return;
|
||||
if (node.label && node.label.name !== state.label) return;
|
||||
|
||||
// break statements mean something different in this context
|
||||
if (t.isSwitchCase(parent)) return;
|
||||
|
||||
var ret = t.expressionStatement(
|
||||
t.callExpression(t.memberExpression(state.iteratorKey, t.identifier("return")), [])
|
||||
);
|
||||
@@ -103,7 +106,7 @@ var loose = function (node, parent, scope, file) {
|
||||
iteratorKey: iteratorKey,
|
||||
label: t.isLabeledStatement(parent) && parent.label.name,
|
||||
|
||||
wrapReturn: function (node) {
|
||||
wrapReturn(node) {
|
||||
return t.ifStatement(
|
||||
t.logicalExpression(
|
||||
"&&",
|
||||
@@ -124,8 +127,6 @@ var loose = function (node, parent, scope, file) {
|
||||
};
|
||||
|
||||
var spec = function (node, parent, scope, file) {
|
||||
|
||||
|
||||
var left = node.left;
|
||||
var declar;
|
||||
|
||||
@@ -173,7 +174,7 @@ var spec = function (node, parent, scope, file) {
|
||||
iteratorKey: iteratorKey,
|
||||
label: isLabeledParent && parent.label.name,
|
||||
|
||||
wrapReturn: function (node) {
|
||||
wrapReturn(node) {
|
||||
return t.ifStatement(t.memberExpression(iteratorKey, t.identifier("return")), node);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@ export function check(node) {
|
||||
return t.isIdentifier(node, { name: "super" });
|
||||
}
|
||||
|
||||
export function Property(node, parent, scope, file) {
|
||||
function Property(node, scope, getObjectRef, file) {
|
||||
if (!node.method) return;
|
||||
|
||||
var value = node.value;
|
||||
@@ -13,8 +13,8 @@ export function Property(node, parent, scope, file) {
|
||||
|
||||
var replaceSupers = new ReplaceSupers({
|
||||
topLevelThisReference: thisExpr,
|
||||
getObjectRef: getObjectRef,
|
||||
methodNode: node,
|
||||
className: thisExpr,
|
||||
isStatic: true,
|
||||
scope: scope,
|
||||
file: file
|
||||
@@ -30,3 +30,20 @@ export function Property(node, parent, scope, file) {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function ObjectExpression(node, parent, scope, file) {
|
||||
var objectRef;
|
||||
var getObjectRef = () => objectRef ||= scope.generateUidIdentifier("obj");
|
||||
|
||||
for (var i = 0; i < node.properties.length; i++) {
|
||||
Property(node.properties[i], scope, getObjectRef, file);
|
||||
}
|
||||
|
||||
if (objectRef) {
|
||||
scope.push({
|
||||
id: objectRef
|
||||
});
|
||||
|
||||
return t.assignmentExpression("=", objectRef, node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ var hasDefaults = function (node) {
|
||||
|
||||
var iifeVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (!t.isReferencedIdentifier(node, parent)) return;
|
||||
if (!this.isReferencedIdentifier()) return;
|
||||
if (!state.scope.hasOwnBinding(node.name)) return;
|
||||
if (state.scope.bindingIdentifierEquals(node.name, node)) return;
|
||||
|
||||
@@ -61,7 +61,7 @@ exports.Function = function (node, parent, scope, file) {
|
||||
scope.traverse(param, iifeVisitor, state);
|
||||
}
|
||||
|
||||
if (file.transformers["es6.blockScopingTDZ"].canRun()) {
|
||||
if (file.transformers["es6.blockScopingTDZ"].canRun() && t.isIdentifier(param)) {
|
||||
pushDefNode(param, t.identifier("undefined"), i);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,13 +7,13 @@ export var check = t.isRestElement;
|
||||
var memberExpressionOptimisationVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
// check if this scope has a local binding that will shadow the rest parameter
|
||||
if (t.isScope(node, parent) && !scope.bindingIdentifierEquals(state.name, state.outerBinding)) {
|
||||
if (this.isScope() && !scope.bindingIdentifierEquals(state.name, state.outerBinding)) {
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
// skip over functions as whatever `arguments` we reference inside will refer
|
||||
// to the wrong function
|
||||
if (t.isFunctionDeclaration(node) || t.isFunctionExpression(node)) {
|
||||
if (this.isFunctionDeclaration() || this.isFunctionExpression()) {
|
||||
state.noOptimise = true;
|
||||
scope.traverse(node, memberExpressionOptimisationVisitor, state);
|
||||
state.noOptimise = false;
|
||||
@@ -21,7 +21,7 @@ var memberExpressionOptimisationVisitor = {
|
||||
}
|
||||
|
||||
// is this a referenced identifier and is it referencing the rest parameter?
|
||||
if (!t.isReferencedIdentifier(node, parent, { name: state.name })) return;
|
||||
if (!this.isReferencedIdentifier({ name: state.name })) return;
|
||||
|
||||
if (!state.noOptimise && t.isMemberExpression(parent) && parent.computed) {
|
||||
// if we know that this member expression is referencing a number then we can safely
|
||||
@@ -55,7 +55,7 @@ var hasRest = function (node) {
|
||||
return t.isRestElement(node.params[node.params.length - 1]);
|
||||
};
|
||||
|
||||
exports.Function = function (node, parent, scope) {
|
||||
exports.Function = function (node, parent, scope, file) {
|
||||
if (!hasRest(node)) return;
|
||||
|
||||
var rest = node.params.pop().argument;
|
||||
@@ -69,10 +69,12 @@ exports.Function = function (node, parent, scope) {
|
||||
if (t.isPattern(rest)) {
|
||||
var pattern = rest;
|
||||
rest = scope.generateUidIdentifier("ref");
|
||||
var declar = t.variableDeclaration("var", pattern.elements.map(function (elem, index) {
|
||||
|
||||
var declar = t.variableDeclaration("let", pattern.elements.map(function (elem, index) {
|
||||
var accessExpr = t.memberExpression(rest, t.literal(index), true);
|
||||
return t.variableDeclarator(elem, accessExpr);
|
||||
}));
|
||||
file.checkNode(declar);
|
||||
node.body.body.unshift(declar);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import clone from "lodash/lang/clone";
|
||||
import t from "../../../types";
|
||||
|
||||
export function check(node) {
|
||||
@@ -12,6 +11,6 @@ export function Property(node) {
|
||||
|
||||
if (node.shorthand) {
|
||||
node.shorthand = false;
|
||||
node.key = t.removeComments(clone(node.key));
|
||||
node.key = t.removeComments(t.clone(node.key));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ function returnBlock(expr) {
|
||||
// looks for and replaces tail recursion calls
|
||||
var firstPass = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (t.isIfStatement(node)) {
|
||||
if (this.isIfStatement()) {
|
||||
if (t.isReturnStatement(node.alternate)) {
|
||||
t.ensureBlock(node, "alternate");
|
||||
}
|
||||
@@ -25,7 +25,7 @@ var firstPass = {
|
||||
if (t.isReturnStatement(node.consequent)) {
|
||||
t.ensureBlock(node, "consequent");
|
||||
}
|
||||
} else if (t.isReturnStatement(node)) {
|
||||
} else if (this.isReturnStatement()) {
|
||||
this.skip();
|
||||
return state.subTransform(node.argument);
|
||||
} else if (t.isTryStatement(parent)) {
|
||||
@@ -34,9 +34,9 @@ var firstPass = {
|
||||
} else if (parent.finalizer && node !== parent.finalizer) {
|
||||
this.skip();
|
||||
}
|
||||
} else if (t.isFunction(node)) {
|
||||
} else if (this.isFunction()) {
|
||||
this.skip();
|
||||
} else if (t.isVariableDeclaration(node)) {
|
||||
} else if (this.isVariableDeclaration()) {
|
||||
this.skip();
|
||||
state.vars.push(node);
|
||||
}
|
||||
@@ -47,15 +47,15 @@ var firstPass = {
|
||||
// them as needed
|
||||
var secondPass = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (t.isThisExpression(node)) {
|
||||
if (this.isThisExpression()) {
|
||||
state.needsThis = true;
|
||||
return state.getThisId();
|
||||
} else if (t.isReferencedIdentifier(node, parent, { name: "arguments" })) {
|
||||
} else if (this.isReferencedIdentifier({ name: "arguments" })) {
|
||||
state.needsArguments = true;
|
||||
return state.getArgumentsId();
|
||||
} else if (t.isFunction(node)) {
|
||||
} else if (this.isFunction()) {
|
||||
this.skip();
|
||||
if (t.isFunctionDeclaration(node)) {
|
||||
if (this.isFunctionDeclaration()) {
|
||||
node = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(node.id, t.toExpression(node))
|
||||
]);
|
||||
@@ -69,7 +69,7 @@ var secondPass = {
|
||||
// optimizes recursion by removing `this` and `arguments` if they aren't used
|
||||
var thirdPass = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (!t.isExpressionStatement(node)) return;
|
||||
if (!this.isExpressionStatement()) return;
|
||||
|
||||
var expr = node.expression;
|
||||
if (!t.isAssignmentExpression(expr)) return;
|
||||
@@ -229,7 +229,7 @@ class TailCallTransformer {
|
||||
subTransform(node) {
|
||||
if (!node) return;
|
||||
|
||||
var handler = this["subTransform" + node.type];
|
||||
var handler = this[`subTransform${node.type}`];
|
||||
if (handler) return handler.call(this, node);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
export default {
|
||||
useStrict: require("./other/use-strict"),
|
||||
strict: require("./other/strict"),
|
||||
|
||||
_validation: require("./internal/validation"),
|
||||
|
||||
"validation.undeclaredVariableCheck": require("./validation/undeclared-variable-check"),
|
||||
"validation.noForInOfAssignment": require("./validation/no-for-in-of-assignment"),
|
||||
"validation.setters": require("./validation/setters"),
|
||||
"validation.react": require("./validation/react"),
|
||||
|
||||
// this goes at the start so we only transform the original user code
|
||||
@@ -97,7 +97,7 @@ export default {
|
||||
"spec.typeofSymbol": require("./spec/typeof-symbol"),
|
||||
"spec.undefinedToVoid": require("./spec/undefined-to-void"),
|
||||
|
||||
_useStrict: require("./internal/use-strict"),
|
||||
_strict: require("./internal/strict"),
|
||||
_moduleFormatter: require("./internal/module-formatter"),
|
||||
|
||||
"es3.propertyLiterals": require("./es3/property-literals"),
|
||||
|
||||
@@ -2,7 +2,7 @@ import t from "../../../types";
|
||||
|
||||
var functionChildrenVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (t.isFunction(node) && !node._aliasFunction) {
|
||||
if (this.isFunction() && !node._aliasFunction) {
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
@@ -10,22 +10,22 @@ var functionChildrenVisitor = {
|
||||
|
||||
var getId;
|
||||
|
||||
if (t.isIdentifier(node) && node.name === "arguments") {
|
||||
if (this.isIdentifier() && node.name === "arguments") {
|
||||
getId = state.getArgumentsId;
|
||||
} else if (t.isThisExpression(node)) {
|
||||
} else if (this.isThisExpression()) {
|
||||
getId = state.getThisId;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (t.isReferenced(node, parent)) return getId();
|
||||
if (this.isReferenced()) return getId();
|
||||
}
|
||||
};
|
||||
|
||||
var functionVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (!node._aliasFunction) {
|
||||
if (t.isFunction(node)) {
|
||||
if (this.isFunction()) {
|
||||
// stop traversal of this node as it'll be hit again by this transformer
|
||||
return this.skip();
|
||||
} else {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as useStrict from "../../helpers/use-strict";
|
||||
import * as strict from "../../helpers/strict";
|
||||
import t from "../../../types";
|
||||
|
||||
export var secondPass = true;
|
||||
@@ -6,7 +6,7 @@ export var secondPass = true;
|
||||
export function BlockStatement(node, parent, scope, file) {
|
||||
if (!node._declarations) return;
|
||||
|
||||
useStrict.wrap(node, function () {
|
||||
strict.wrap(node, function () {
|
||||
var kinds = {};
|
||||
var kind;
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import * as useStrict from "../../helpers/use-strict";
|
||||
import * as strict from "../../helpers/strict";
|
||||
|
||||
export function Program(program, parent, scope, file) {
|
||||
if (!file.transformers["es6.modules"].canRun()) return;
|
||||
|
||||
useStrict.wrap(program, function () {
|
||||
strict.wrap(program, function () {
|
||||
program.body = file.dynamicImports.concat(program.body);
|
||||
});
|
||||
|
||||
if (!file.transformers["es6.modules"].canRun()) return;
|
||||
|
||||
if (file.moduleFormatter.transform) {
|
||||
file.moduleFormatter.transform(program);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ export function check(node) {
|
||||
export function ImportDeclaration(node, parent, scope, file) {
|
||||
var resolveModuleSource = file.opts.resolveModuleSource;
|
||||
if (node.source && resolveModuleSource) {
|
||||
node.source.value = resolveModuleSource(node.source.value);
|
||||
node.source.value = resolveModuleSource(node.source.value, file.opts.filename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,16 @@ export function ExportDeclaration(node, parent, scope) {
|
||||
node.declaration = null;
|
||||
node._blockHoist = 2;
|
||||
return [getDeclar(), node];
|
||||
} else if (t.isVariableDeclaration(declar)) {
|
||||
var specifiers = [];
|
||||
|
||||
var bindings = t.getBindingIdentifiers(declar);
|
||||
for (var key in bindings) {
|
||||
var id = bindings[key];
|
||||
specifiers.push(t.exportSpecifier(id, id));
|
||||
}
|
||||
|
||||
return [declar, t.exportDeclaration(null, specifiers)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import t from "../../../types";
|
||||
|
||||
export function Program(program, parent, scope, file) {
|
||||
if (file.transformers.useStrict.canRun()) {
|
||||
if (file.transformers.strict.canRun()) {
|
||||
program.body.unshift(t.expressionStatement(t.literal("use strict")));
|
||||
}
|
||||
}
|
||||
27
src/babel/transformation/transformers/internal/validation.js
Normal file
27
src/babel/transformation/transformers/internal/validation.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import * as messages from "../../../messages";
|
||||
import t from "../../../types";
|
||||
|
||||
export function ForOfStatement(node, parent, scope, file) {
|
||||
var left = node.left;
|
||||
if (t.isVariableDeclaration(left)) {
|
||||
var declar = left.declarations[0];
|
||||
if (declar.init) throw file.errorWithNode(declar, messages.get("noAssignmentsInForHead"));
|
||||
}
|
||||
}
|
||||
|
||||
export { ForOfStatement as ForInStatement };
|
||||
|
||||
export function Property(node, parent, scope, file) {
|
||||
if (node.kind === "set") {
|
||||
if (node.value.params.length !== 1) {
|
||||
throw file.errorWithNode(node.value, messages.get("settersInvalidParamLength"));
|
||||
}
|
||||
|
||||
var first = node.value.params[0];
|
||||
if (t.isRestElement(first)) {
|
||||
throw file.errorWithNode(first, messages.get("settersNoRest"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { Property as MethodDefinition };
|
||||
@@ -13,12 +13,12 @@ export function Class(node) {
|
||||
node.implements = null;
|
||||
}
|
||||
|
||||
export function Function(node) {
|
||||
exports.Function = function (node) {
|
||||
for (var i = 0; i < node.params.length; i++) {
|
||||
var param = node.params[i];
|
||||
param.optional = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export function TypeCastExpression(node) {
|
||||
return node.expression;
|
||||
|
||||
@@ -16,14 +16,15 @@ var ALIASABLE_CONSTRUCTORS = [
|
||||
"Map",
|
||||
"WeakMap",
|
||||
"Set",
|
||||
"WeakSet"
|
||||
"WeakSet",
|
||||
"Number"
|
||||
];
|
||||
|
||||
var astVisitor = {
|
||||
enter(node, parent, scope, file) {
|
||||
var prop;
|
||||
|
||||
if (t.isMemberExpression(node) && t.isReferenced(node, parent)) {
|
||||
if (this.isMemberExpression() && this.isReferenced()) {
|
||||
// Array.from -> _core.Array.from
|
||||
var obj = node.object;
|
||||
prop = node.property;
|
||||
@@ -34,10 +35,10 @@ var astVisitor = {
|
||||
this.skip();
|
||||
return t.prependToMemberExpression(node, file.get("coreIdentifier"));
|
||||
}
|
||||
} else if (t.isReferencedIdentifier(node, parent) && !t.isMemberExpression(parent) && includes(ALIASABLE_CONSTRUCTORS, node.name) && !scope.getBindingIdentifier(node.name)) {
|
||||
} else if (this.isReferencedIdentifier() && !t.isMemberExpression(parent) && includes(ALIASABLE_CONSTRUCTORS, node.name) && !scope.getBindingIdentifier(node.name)) {
|
||||
// Symbol() -> _core.Symbol(); new Promise -> new _core.Promise
|
||||
return t.memberExpression(file.get("coreIdentifier"), node);
|
||||
} else if (t.isCallExpression(node)) {
|
||||
} else if (this.isCallExpression()) {
|
||||
// arr[Symbol.iterator]() -> _core.$for.getIterator(arr)
|
||||
|
||||
var callee = node.callee;
|
||||
@@ -53,7 +54,7 @@ var astVisitor = {
|
||||
CORE_ID: file.get("coreIdentifier"),
|
||||
VALUE: callee.object
|
||||
});
|
||||
} else if (t.isBinaryExpression(node)) {
|
||||
} else if (this.isBinaryExpression()) {
|
||||
// Symbol.iterator in arr -> core.$for.isIterable(arr)
|
||||
|
||||
if (node.operator !== "in") return;
|
||||
@@ -94,7 +95,7 @@ export function pre(file) {
|
||||
}
|
||||
|
||||
export function Identifier(node, parent, scope, file) {
|
||||
if (t.isReferencedIdentifier(node, parent, { name: "regeneratorRuntime" })) {
|
||||
if (this.isReferencedIdentifier({ name: "regeneratorRuntime" })) {
|
||||
return file.get("regeneratorIdentifier");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,7 @@ export var playground = true;
|
||||
|
||||
build(exports, {
|
||||
is(node, file) {
|
||||
var is = t.isAssignmentExpression(node) && node.operator === "||=";
|
||||
if (is) {
|
||||
if (t.isAssignmentExpression(node, { operator: "||=" })) {
|
||||
var left = node.left;
|
||||
if (!t.isMemberExpression(left) && !t.isIdentifier(left)) {
|
||||
throw file.errorWithNode(left, messages.get("expectedMemberExpressionOrIdentifier"));
|
||||
|
||||
@@ -5,7 +5,7 @@ export var playground = true;
|
||||
|
||||
build(exports, {
|
||||
is(node) {
|
||||
var is = t.isAssignmentExpression(node) && node.operator === "?=";
|
||||
var is = t.isAssignmentExpression(node, { operator: "?=" });
|
||||
if (is) t.assertMemberExpression(node.left);
|
||||
return is;
|
||||
},
|
||||
|
||||
@@ -4,9 +4,9 @@ export var playground = true;
|
||||
|
||||
var visitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (t.isFunction(node)) return this.skip();
|
||||
if (this.isFunction()) return this.skip();
|
||||
|
||||
if (t.isReturnStatement(node) && node.argument) {
|
||||
if (this.isReturnStatement() && node.argument) {
|
||||
node.argument = t.memberExpression(t.callExpression(state.file.addHelper("define-property"), [
|
||||
t.thisExpression(),
|
||||
state.key,
|
||||
|
||||
@@ -3,7 +3,7 @@ import t from "../../../types";
|
||||
export var optional = true;
|
||||
|
||||
export function Identifier(node, parent) {
|
||||
if (node.name === "undefined" && t.isReferenced(node, parent)) {
|
||||
if (node.name === "undefined" && this.isReferenced()) {
|
||||
return t.unaryExpression("void", t.literal(0), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ function toStatements(node) {
|
||||
|
||||
export var optional = true;
|
||||
|
||||
export function ConditionalExpression(node) {
|
||||
var evaluateTest = t.evaluateTruthy(node.test);
|
||||
export function ConditionalExpression(node, parent, scope) {
|
||||
var evaluateTest = t.evaluateTruthy(node.test, scope);
|
||||
if (evaluateTest === true) {
|
||||
return node.consequent;
|
||||
} else if (evaluateTest === false) {
|
||||
@@ -29,12 +29,12 @@ export function ConditionalExpression(node) {
|
||||
}
|
||||
|
||||
export var IfStatement = {
|
||||
exit(node) {
|
||||
exit(node, parent, scope) {
|
||||
var consequent = node.consequent;
|
||||
var alternate = node.alternate;
|
||||
var test = node.test;
|
||||
|
||||
var evaluateTest = t.evaluateTruthy(test);
|
||||
var evaluateTest = t.evaluateTruthy(test, scope);
|
||||
|
||||
// we can check if a test will be truthy 100% and if so then we can inline
|
||||
// the consequent and completely ignore the alternate
|
||||
@@ -77,7 +77,7 @@ export var IfStatement = {
|
||||
// if (foo) {} else { bar; } -> if (!foo) { bar; }
|
||||
//
|
||||
|
||||
if (t.blockStatement(consequent) && !consequent.body.length && t.isBlockStatement(alternate) && alternate.body.length) {
|
||||
if (t.isBlockStatement(consequent) && !consequent.body.length && t.isBlockStatement(alternate) && alternate.body.length) {
|
||||
node.consequent = node.alternate;
|
||||
node.alternate = null;
|
||||
node.test = t.unaryExpression("!", test, true);
|
||||
|
||||
@@ -2,7 +2,11 @@ import t from "../../../types";
|
||||
|
||||
export var optional = true;
|
||||
|
||||
export function Expression(node) {
|
||||
var res = t.evaluate(node);
|
||||
export function Expression(node, parent, scope) {
|
||||
var res = t.evaluate(node, scope);
|
||||
if (res.confident) return t.valueToNode(res.value);
|
||||
}
|
||||
|
||||
export function Identifier() {
|
||||
// override Expression
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import t from "../../../types";
|
||||
export var optional = true;
|
||||
|
||||
export function ExpressionStatement(node) {
|
||||
if (t.isIdentifier(node.expression, { name: "debugger" })) {
|
||||
if (this.get("expression").isIdentifier({ name: "debugger" })) {
|
||||
this.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import * as messages from "../../../messages";
|
||||
import t from "../../../types";
|
||||
|
||||
export { isFor as check } from "../../../types";
|
||||
|
||||
export function ForOfStatement(node, parent, scope, file) {
|
||||
var left = node.left;
|
||||
if (t.isVariableDeclaration(left)) {
|
||||
var declar = left.declarations[0];
|
||||
if (declar.init) throw file.errorWithNode(declar, messages.get("noAssignmentsInForHead"));
|
||||
}
|
||||
}
|
||||
|
||||
export { ForOfStatement as ForInStatement };
|
||||
@@ -2,7 +2,7 @@ import * as messages from "../../../messages";
|
||||
import t from "../../../types";
|
||||
|
||||
// check if the input Literal `source` is an alternate casing of "react"
|
||||
var check = function (source, file) {
|
||||
function check(source, file) {
|
||||
if (t.isLiteral(source)) {
|
||||
var name = source.value;
|
||||
var lower = name.toLowerCase();
|
||||
@@ -11,7 +11,7 @@ var check = function (source, file) {
|
||||
throw file.errorWithNode(source, messages.get("didYouMean", "react"));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function CallExpression(node, parent, scope, file) {
|
||||
if (t.isIdentifier(node.callee, { name: "require" }) && node.arguments.length === 1) {
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import * as messages from "../../../messages";
|
||||
|
||||
export function check(node) {
|
||||
return node.kind === "set";
|
||||
}
|
||||
|
||||
export function Property(node, parent, scope, file) {
|
||||
if (node.kind === "set" && node.value.params.length !== 1) {
|
||||
throw file.errorWithNode(node.value, messages.get("settersInvalidParamLength"));
|
||||
}
|
||||
}
|
||||
|
||||
export { Property as MethodDefinition };
|
||||
@@ -1,11 +1,10 @@
|
||||
import levenshtein from "leven";
|
||||
import * as messages from "../../../messages";
|
||||
import t from "../../../types";
|
||||
|
||||
export var optional = true;
|
||||
|
||||
export function Identifier(node, parent, scope, file) {
|
||||
if (!t.isReferenced(node, parent)) return;
|
||||
if (!this.isReferenced()) return;
|
||||
if (scope.hasBinding(node.name)) return;
|
||||
|
||||
// get the closest declaration to offer as a suggestion
|
||||
|
||||
@@ -2,14 +2,13 @@ import TraversalPath from "./path";
|
||||
import flatten from "lodash/array/flatten";
|
||||
import compact from "lodash/array/compact";
|
||||
|
||||
export default class TraversalConext {
|
||||
export default class TraversalContext {
|
||||
constructor(scope, opts, state, parentPath) {
|
||||
this.shouldFlatten = false;
|
||||
this.parentPath = parentPath;
|
||||
|
||||
this.scope = scope;
|
||||
this.state = state;
|
||||
this.opts = opts;
|
||||
this.scope = scope;
|
||||
this.state = state;
|
||||
this.opts = opts;
|
||||
}
|
||||
|
||||
flatten() {
|
||||
@@ -17,7 +16,7 @@ export default class TraversalConext {
|
||||
}
|
||||
|
||||
visitNode(node, obj, key) {
|
||||
var iteration = new TraversalPath(this, node, obj, key);
|
||||
var iteration = TraversalPath.get(this.parentPath, this, node, obj, key);
|
||||
return iteration.visit();
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ function traverse(parent, opts, scope, state) {
|
||||
|
||||
if (!opts.noScope && !scope) {
|
||||
if (parent.type !== "Program" && parent.type !== "File") {
|
||||
throw new Error("Must pass a scope unless traversing a Program/File got a " + parent.type + " node");
|
||||
throw new Error(`Must pass a scope unless traversing a Program/File got a ${parent.type} node`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,13 +42,14 @@ traverse.node = function (node, opts, scope, state, parentPath) {
|
||||
function clearNode(node) {
|
||||
node._declarations = null;
|
||||
node.extendedRange = null;
|
||||
node._scopeInfo = null;
|
||||
node.tokens = null;
|
||||
node.range = null;
|
||||
node.start = null;
|
||||
node.end = null;
|
||||
node.loc = null;
|
||||
node.raw = null;
|
||||
node._scopeInfo = null;
|
||||
node._paths = null;
|
||||
node.tokens = null;
|
||||
node.range = null;
|
||||
node.start = null;
|
||||
node.end = null;
|
||||
node.loc = null;
|
||||
node.raw = null;
|
||||
|
||||
if (Array.isArray(node.trailingComments)) {
|
||||
clearComments(node.trailingComments);
|
||||
@@ -57,11 +58,18 @@ function clearNode(node) {
|
||||
if (Array.isArray(node.leadingComments)) {
|
||||
clearComments(node.leadingComments);
|
||||
}
|
||||
|
||||
for (var key in node) {
|
||||
var val = node[key];
|
||||
if (Array.isArray(val)) {
|
||||
delete val._paths;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var clearVisitor = {
|
||||
noScope: true,
|
||||
enter: clearNode
|
||||
exit: clearNode
|
||||
};
|
||||
|
||||
function clearComments(comments) {
|
||||
@@ -71,8 +79,8 @@ function clearComments(comments) {
|
||||
}
|
||||
|
||||
traverse.removeProperties = function (tree) {
|
||||
clearNode(tree);
|
||||
traverse(tree, clearVisitor);
|
||||
clearNode(tree);
|
||||
|
||||
return tree;
|
||||
};
|
||||
|
||||
@@ -4,23 +4,33 @@ import Scope from "./scope";
|
||||
import t from "../types";
|
||||
|
||||
export default class TraversalPath {
|
||||
constructor(context, parent, container, key) {
|
||||
this.shouldRemove = false;
|
||||
this.shouldSkip = false;
|
||||
this.shouldStop = false;
|
||||
|
||||
this.parentPath = context.parentPath;
|
||||
this.context = context;
|
||||
this.state = this.context.state;
|
||||
this.opts = this.context.opts;
|
||||
|
||||
constructor(parent, container) {
|
||||
this.container = container;
|
||||
this.key = key;
|
||||
this.parent = parent;
|
||||
this.data = {};
|
||||
}
|
||||
|
||||
this.parent = parent;
|
||||
this.state = context.state;
|
||||
static get(parentPath, context, parent, container, key) {
|
||||
var targetNode = container[key];
|
||||
var paths = container._paths ||= [];
|
||||
var path;
|
||||
|
||||
this.setScope();
|
||||
for (var i = 0; i < paths.length; i++) {
|
||||
var pathCheck = paths[i];
|
||||
if (pathCheck.node === targetNode) {
|
||||
path = pathCheck;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!path) {
|
||||
path = new TraversalPath(parent, container);
|
||||
paths.push(path);
|
||||
}
|
||||
|
||||
path.setContext(parentPath, context, key);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static getScope(node, parent, scope) {
|
||||
@@ -34,10 +44,32 @@ export default class TraversalPath {
|
||||
return ourScope;
|
||||
}
|
||||
|
||||
setData(key, val) {
|
||||
return this.data[key] = val;
|
||||
}
|
||||
|
||||
getData(key) {
|
||||
return this.data[key];
|
||||
}
|
||||
|
||||
setScope() {
|
||||
this.scope = TraversalPath.getScope(this.node, this.parent, this.context.scope);
|
||||
}
|
||||
|
||||
setContext(parentPath, context, key) {
|
||||
this.shouldRemove = false;
|
||||
this.shouldSkip = false;
|
||||
this.shouldStop = false;
|
||||
|
||||
this.parentPath = parentPath;
|
||||
this.context = context;
|
||||
this.state = context.state;
|
||||
this.opts = context.opts;
|
||||
this.key = key;
|
||||
|
||||
this.setScope();
|
||||
}
|
||||
|
||||
remove() {
|
||||
this.shouldRemove = true;
|
||||
this.shouldSkip = true;
|
||||
@@ -114,14 +146,13 @@ export default class TraversalPath {
|
||||
}
|
||||
}
|
||||
|
||||
visit() {
|
||||
var opts = this.opts;
|
||||
var node = this.node;
|
||||
isBlacklisted() {
|
||||
var blacklist = this.opts.blacklist;
|
||||
return blacklist && blacklist.indexOf(this.node.type) > -1;
|
||||
}
|
||||
|
||||
// type is blacklisted
|
||||
if (opts.blacklist && opts.blacklist.indexOf(node.type) > -1) {
|
||||
return false;
|
||||
}
|
||||
visit() {
|
||||
if (this.isBlacklisted()) return false;
|
||||
|
||||
this.call("enter");
|
||||
|
||||
@@ -129,7 +160,8 @@ export default class TraversalPath {
|
||||
return this.shouldStop;
|
||||
}
|
||||
|
||||
node = this.node;
|
||||
var node = this.node;
|
||||
var opts = this.opts;
|
||||
|
||||
if (Array.isArray(node)) {
|
||||
// traverse over these replacement nodes we purposely don't call exitNode
|
||||
@@ -139,13 +171,38 @@ export default class TraversalPath {
|
||||
}
|
||||
} else {
|
||||
traverse.node(node, opts, this.scope, this.state, this);
|
||||
|
||||
this.call("exit");
|
||||
}
|
||||
|
||||
return this.shouldStop;
|
||||
}
|
||||
|
||||
isReferencedIdentifier() {
|
||||
return t.isReferencedIdentifier(this.node);
|
||||
get(key) {
|
||||
return TraversalPath.get(this, this.context, this.node, this.node, key);
|
||||
}
|
||||
|
||||
isReferencedIdentifier(opts) {
|
||||
return t.isReferencedIdentifier(this.node, this.parent, opts);
|
||||
}
|
||||
|
||||
isReferenced() {
|
||||
return t.isReferenced(this.node, this.parent);
|
||||
}
|
||||
|
||||
isScope() {
|
||||
return t.isScope(this.node, this.parent);
|
||||
}
|
||||
|
||||
getBindingIdentifiers() {
|
||||
return t.getBindingIdentifiers(this.node);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < t.TYPES.length; i++) {
|
||||
let type = t.TYPES[i];
|
||||
let typeKey = `is${type}`;
|
||||
TraversalPath.prototype[typeKey] = function (opts) {
|
||||
return t[typeKey](this.node, opts);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ export default class Scope {
|
||||
}
|
||||
|
||||
static globals = flatten([globals.builtin, globals.browser, globals.node].map(Object.keys));
|
||||
static contextVariables = ["this", "arguments"];
|
||||
|
||||
/**
|
||||
* Description
|
||||
@@ -143,7 +144,7 @@ export default class Scope {
|
||||
_generateUid(name, i) {
|
||||
var id = name;
|
||||
if (i > 1) id += i;
|
||||
return "_" + id;
|
||||
return `_${id}`;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -415,7 +416,7 @@ export default class Scope {
|
||||
registerVariableDeclaration(declar) {
|
||||
var declars = declar.declarations;
|
||||
for (var i = 0; i < declars.length; i++) {
|
||||
this.registerBinding(declars[i], declar.kind);
|
||||
this.registerBinding(declar.kind, declars[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,12 +534,12 @@ export default class Scope {
|
||||
if (t.isBlockStatement(block) || t.isProgram(block)) {
|
||||
block._declarations ||= {};
|
||||
block._declarations[opts.key] = {
|
||||
kind: opts.kind,
|
||||
kind: opts.kind || "var",
|
||||
id: opts.id,
|
||||
init: opts.init
|
||||
};
|
||||
} else {
|
||||
throw new TypeError("cannot add a declaration here in node type " + block.type);
|
||||
throw new TypeError(`cannot add a declaration here in node type ${block.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,6 +627,37 @@ export default class Scope {
|
||||
return binding && binding.identifier;
|
||||
}
|
||||
|
||||
|
||||
getOwnImmutableBindingValue(name) {
|
||||
return this._immutableBindingInfoToValue(this.getOwnBindingInfo(name));
|
||||
}
|
||||
|
||||
getImmutableBindingValue(name) {
|
||||
return this._immutableBindingInfoToValue(this.getBindingInfo(name));
|
||||
}
|
||||
|
||||
_immutableBindingInfoToValue(info) {
|
||||
if (!info) return;
|
||||
|
||||
// can't guarantee this value is the same
|
||||
if (info.reassigned) return;
|
||||
|
||||
var node = info.node;
|
||||
if (t.isVariableDeclarator(node)) {
|
||||
if (t.isIdentifier(node.id)) {
|
||||
node = node.init;
|
||||
} else {
|
||||
// otherwise it's probably a destructuring like:
|
||||
// var { foo } = "foo";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isImmutable(node)) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
// has
|
||||
|
||||
hasOwnBinding(name) {
|
||||
@@ -637,6 +669,7 @@ export default class Scope {
|
||||
if (this.hasOwnBinding(name)) return true;
|
||||
if (this.parentHasBinding(name)) return true;
|
||||
if (includes(Scope.globals, name)) return true;
|
||||
if (includes(Scope.contextVariables, name)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import toFastProperties from "../helpers/to-fast-properties";
|
||||
import toFastProperties from "to-fast-properties";
|
||||
import isPlainObject from "lodash/lang/isPlainObject";
|
||||
import isNumber from "lodash/lang/isNumber";
|
||||
import isRegExp from "lodash/lang/isRegExp";
|
||||
@@ -6,6 +6,7 @@ import isString from "lodash/lang/isString";
|
||||
import compact from "lodash/array/compact";
|
||||
import esutils from "esutils";
|
||||
import object from "../helpers/object";
|
||||
import clone from "lodash/lang/clone";
|
||||
import each from "lodash/collection/each";
|
||||
import uniq from "lodash/array/uniq";
|
||||
|
||||
@@ -21,19 +22,19 @@ export default t;
|
||||
*/
|
||||
|
||||
function registerType(type, skipAliasCheck) {
|
||||
var is = t["is" + type] = function (node, opts) {
|
||||
var is = t[`is${type}`] = function (node, opts) {
|
||||
return t.is(type, node, opts, skipAliasCheck);
|
||||
};
|
||||
|
||||
t["assert" + type] = function (node, opts) {
|
||||
t[`assert${type}`] = function (node, opts) {
|
||||
opts ||= {};
|
||||
if (!is(node, opts)) {
|
||||
throw new Error("Expected type " + JSON.stringify(type) + " with option " + JSON.stringify(opts));
|
||||
throw new Error(`Expected type ${JSON.stringify(type)} with option ${JSON.stringify(opts)}`);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
t.STATEMENT_OR_BLOCK_KEYS = ["consequent", "body"];
|
||||
t.STATEMENT_OR_BLOCK_KEYS = ["consequent", "body", "alternate"];
|
||||
t.NATIVE_TYPE_NAMES = ["Array", "Object", "Number", "Boolean", "Date", "Array", "String"];
|
||||
t.FOR_INIT_KEYS = ["left", "init"];
|
||||
|
||||
@@ -48,7 +49,7 @@ each(t.VISITOR_KEYS, function (keys, type) {
|
||||
|
||||
each(t.ALIAS_KEYS, function (aliases, type) {
|
||||
each(aliases, function (alias) {
|
||||
var types = t.FLIPPED_ALIAS_KEYS[alias] = t.FLIPPED_ALIAS_KEYS[alias] || [];
|
||||
var types = t.FLIPPED_ALIAS_KEYS[alias] ||= [];
|
||||
types.push(type);
|
||||
});
|
||||
});
|
||||
@@ -58,6 +59,8 @@ each(t.FLIPPED_ALIAS_KEYS, function (types, type) {
|
||||
registerType(type, false);
|
||||
});
|
||||
|
||||
t.TYPES = Object.keys(t.VISITOR_KEYS).concat(Object.keys(t.FLIPPED_ALIAS_KEYS));
|
||||
|
||||
/**
|
||||
* Returns whether `node` is of given `type`.
|
||||
*
|
||||
@@ -141,22 +144,6 @@ t.toComputedKey = function (node, key) {
|
||||
return key;
|
||||
};
|
||||
|
||||
/*
|
||||
* Shallowly checks to see if the passed `node` is falsy.
|
||||
*
|
||||
* @param {Object} node
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
t.isFalsyExpression = function (node) {
|
||||
if (t.isLiteral(node)) {
|
||||
return !node.value;
|
||||
} else if (t.isIdentifier(node)) {
|
||||
return node.name === "undefined";
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Turn an array of statement `nodes` into a `SequenceExpression`.
|
||||
*
|
||||
@@ -292,6 +279,16 @@ t.isReferenced = function (node, parent) {
|
||||
return parent.id !== node;
|
||||
}
|
||||
|
||||
// no: export { foo as NODE };
|
||||
if (t.isExportSpecifier(parent, { name: node })) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// no: import { NODE as foo } from "foo";
|
||||
if (t.isImportSpecifier(parent, { id: node })) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// no: class NODE {}
|
||||
if (t.isClass(parent)) {
|
||||
return parent.id !== node;
|
||||
@@ -395,7 +392,7 @@ t.toIdentifier = function (name) {
|
||||
});
|
||||
|
||||
if (!t.isValidIdentifier(name)) {
|
||||
name = "_" + name;
|
||||
name = `_${name}`;
|
||||
}
|
||||
|
||||
return name || "_";
|
||||
@@ -413,6 +410,51 @@ t.ensureBlock = function (node, key) {
|
||||
return node[key] = t.toBlock(node[key], node);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Object} node
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
t.clone = function (node) {
|
||||
var newNode = {};
|
||||
for (var key in node) {
|
||||
if (key[0] === "_") continue;
|
||||
newNode[key] = node[key];
|
||||
}
|
||||
return newNode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Object} node
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
t.cloneDeep = function (node) {
|
||||
var newNode = {};
|
||||
|
||||
for (var key in node) {
|
||||
if (key[0] === "_") continue;
|
||||
|
||||
var val = node[key];
|
||||
|
||||
if (val) {
|
||||
if (val.type) {
|
||||
val = t.cloneDeep(val);
|
||||
} else if (Array.isArray(val)) {
|
||||
val = val.map(t.cloneDeep);
|
||||
}
|
||||
}
|
||||
|
||||
newNode[key] = val;
|
||||
}
|
||||
|
||||
return newNode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Build a function that when called will return whether or not the
|
||||
* input `node` `MemberExpression` matches the input `match`.
|
||||
@@ -506,7 +548,7 @@ t.toStatement = function (node, ignore) {
|
||||
if (ignore) {
|
||||
return false;
|
||||
} else {
|
||||
throw new Error("cannot turn " + node.type + " to a statement");
|
||||
throw new Error(`cannot turn ${node.type} to a statement`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,7 +578,7 @@ t.toExpression = function (node) {
|
||||
if (t.isExpression(node)) {
|
||||
return node;
|
||||
} else {
|
||||
throw new Error("cannot turn " + node.type + " to an expression");
|
||||
throw new Error(`cannot turn ${node.type} to an expression`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -807,6 +849,35 @@ t.isScope = function (node, parent) {
|
||||
return t.isScopable(node);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Node} node
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
t.isImmutable = function (node) {
|
||||
if (t.isLiteral(node)) {
|
||||
if (node.regex) {
|
||||
// regexes are mutable
|
||||
return false;
|
||||
} else {
|
||||
// immutable!
|
||||
return true;
|
||||
}
|
||||
} else if (t.isIdentifier(node)) {
|
||||
if (node.name === "undefined") {
|
||||
// immutable!
|
||||
return true;
|
||||
} else {
|
||||
// no idea...
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Walk the input `node` and statically evaluate if it's truthy.
|
||||
*
|
||||
@@ -824,11 +895,12 @@ t.isScope = function (node, parent) {
|
||||
* if (!t.evaluateTruthy(node)) falsyLogic();
|
||||
*
|
||||
* @param {Node} node
|
||||
* @param {Scope} scope
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
t.evaluateTruthy = function (node) {
|
||||
var res = t.evaluate(node);
|
||||
t.evaluateTruthy = function (node, scope) {
|
||||
var res = t.evaluate(node, scope);
|
||||
if (res.confident) return !!res.value;
|
||||
};
|
||||
|
||||
@@ -846,10 +918,11 @@ t.evaluateTruthy = function (node) {
|
||||
* t.evaluate(parse("foo + foo")) // { confident: false, value: undefined }
|
||||
*
|
||||
* @param {Node} node
|
||||
* @param {Scope} scope
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
t.evaluate = function (node) {
|
||||
t.evaluate = function (node, scope) {
|
||||
var confident = true;
|
||||
|
||||
var value = evaluate(node);
|
||||
@@ -882,30 +955,26 @@ t.evaluate = function (node) {
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isIdentifier(node, { name: "undefined" })) {
|
||||
return undefined;
|
||||
if (t.isIdentifier(node)) {
|
||||
if (node.name === "undefined") {
|
||||
return undefined;
|
||||
} else {
|
||||
return evaluate(scope.getImmutableBindingValue(node.name));
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isUnaryExpression(node, { prefix: true })) {
|
||||
var arg = evaluate(node.argument);
|
||||
switch (node.operator) {
|
||||
case "void": return undefined;
|
||||
case "!": return !evaluate(node.argument);
|
||||
case "+": return +evaluate(node.argument);
|
||||
case "-": return -evaluate(node.argument);
|
||||
case "!": return !arg;
|
||||
case "+": return +arg;
|
||||
case "-": return -arg;
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isArrayExpression(node)) {
|
||||
// possible perf issues - could deopt on X elements
|
||||
var values = [];
|
||||
for (var i = 0; i < node.elements.length; i++) {
|
||||
values.push(evaluate(node.elements[i]));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
if (t.isObjectExpression(node)) {
|
||||
// todo: deopt on mutable computed property keys etc
|
||||
if (t.isArrayExpression(node) || t.isObjectExpression(node)) {
|
||||
// we could evaluate these but it's probably impractical and not very useful
|
||||
}
|
||||
|
||||
if (t.isLogicalExpression(node)) {
|
||||
|
||||
@@ -3,6 +3,7 @@ import "./patch";
|
||||
import buildDebug from "debug/node";
|
||||
import cloneDeep from "lodash/lang/cloneDeep";
|
||||
import isBoolean from "lodash/lang/isBoolean";
|
||||
import * as messages from "./messages";
|
||||
import contains from "lodash/collection/contains";
|
||||
import traverse from "./traversal";
|
||||
import isString from "lodash/lang/isString";
|
||||
@@ -20,7 +21,7 @@ export { inherits, inspect } from "util";
|
||||
export var debug = buildDebug("babel");
|
||||
|
||||
export function canCompile(filename, altExts) {
|
||||
var exts = altExts || exports.canCompile.EXTENSIONS;
|
||||
var exts = altExts || canCompile.EXTENSIONS;
|
||||
var ext = path.extname(filename);
|
||||
return contains(exts, ext);
|
||||
}
|
||||
@@ -50,7 +51,7 @@ export function regexify(val) {
|
||||
export function arrayify(val) {
|
||||
if (!val) return [];
|
||||
if (isBoolean(val)) return [val];
|
||||
if (isString(val)) return exports.list(val);
|
||||
if (isString(val)) return list(val);
|
||||
if (Array.isArray(val)) return val;
|
||||
throw new TypeError("illegal type for arrayify");
|
||||
}
|
||||
@@ -71,11 +72,13 @@ var templateVisitor = {
|
||||
return nodes[node.name];
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
export function template(name, nodes, keepExpression) {
|
||||
var ast = exports.templates[name];
|
||||
if (!ast) throw new ReferenceError("unknown template " + name);
|
||||
if (!ast) throw new ReferenceError(`unknown template ${name}`);
|
||||
|
||||
if (nodes === true) {
|
||||
keepExpression = true;
|
||||
@@ -101,7 +104,8 @@ export function template(name, nodes, keepExpression) {
|
||||
|
||||
export function parseTemplate(loc, code) {
|
||||
var ast = parse({ filename: loc }, code).program;
|
||||
return traverse.removeProperties(ast);
|
||||
ast = traverse.removeProperties(ast);
|
||||
return ast;
|
||||
}
|
||||
|
||||
function loadTemplates() {
|
||||
@@ -109,9 +113,7 @@ function loadTemplates() {
|
||||
|
||||
var templatesLoc = path.join(__dirname, "transformation/templates");
|
||||
if (!fs.existsSync(templatesLoc)) {
|
||||
throw new Error("no templates directory - this is most likely the " +
|
||||
"result of a broken `npm publish`. Please report to " +
|
||||
"https://github.com/babel/babel/issues");
|
||||
throw new ReferenceError(messages.get("missingTemplatesDirectory"));
|
||||
}
|
||||
|
||||
each(fs.readdirSync(templatesLoc), function (name) {
|
||||
@@ -131,6 +133,5 @@ try {
|
||||
exports.templates = require("../../templates.json");
|
||||
} catch (err) {
|
||||
if (err.code !== "MODULE_NOT_FOUND") throw err;
|
||||
|
||||
exports.templates = loadTemplates();
|
||||
}
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
var genHelpers = require("./_generator-helpers");
|
||||
var transform = require("../lib/babel/transformation");
|
||||
var sourceMap = require("source-map");
|
||||
var codeFrame = require("../lib/babel/helpers/code-frame");
|
||||
var Module = require("module");
|
||||
var helper = require("./_helper");
|
||||
var assert = require("assert");
|
||||
var chai = require("chai");
|
||||
var path = require("path");
|
||||
var util = require("../lib/babel/util");
|
||||
var _ = require("lodash");
|
||||
var genHelpers = require("./_generator-helpers");
|
||||
var transform = require("../lib/babel/transformation");
|
||||
var buildExernalHelpers = require("../lib/babel/build-external-helpers");
|
||||
var sourceMap = require("source-map");
|
||||
var codeFrame = require("../lib/babel/helpers/code-frame");
|
||||
var Module = require("module");
|
||||
var helper = require("./_helper");
|
||||
var assert = require("assert");
|
||||
var chai = require("chai");
|
||||
var path = require("path");
|
||||
var util = require("../lib/babel/util");
|
||||
var _ = require("lodash");
|
||||
|
||||
require("../lib/babel/polyfill");
|
||||
|
||||
eval(buildExernalHelpers());
|
||||
|
||||
global.assertNoOwnProperties = function (obj) {
|
||||
assert.equal(Object.getOwnPropertyNames(obj).length, 0);
|
||||
};
|
||||
@@ -83,8 +86,8 @@ var run = function (task, done) {
|
||||
}
|
||||
};
|
||||
|
||||
var fn = new Function("require", "done", execCode);
|
||||
fn.call(global, fakeRequire, chai.assert, done);
|
||||
var fn = new Function("require", "done", "exports", execCode);
|
||||
fn.call(global, fakeRequire, chai.assert, {}, done);
|
||||
} catch (err) {
|
||||
err.message = exec.loc + ": " + err.message;
|
||||
err.message += codeFrame(execCode);
|
||||
|
||||
@@ -1,25 +1,16 @@
|
||||
"use strict";
|
||||
|
||||
var _asyncToGenerator = function (fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { var callNext = step.bind(null, "next"); var callThrow = step.bind(null, "throw"); function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(callNext, callThrow); } } callNext(); }); }; };
|
||||
|
||||
var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); };
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
|
||||
|
||||
var Foo = (function () {
|
||||
function Foo() {
|
||||
_classCallCheck(this, Foo);
|
||||
babelHelpers.classCallCheck(this, Foo);
|
||||
}
|
||||
|
||||
_prototypeProperties(Foo, null, {
|
||||
babelHelpers.createClass(Foo, {
|
||||
foo: {
|
||||
value: _asyncToGenerator(function* () {
|
||||
value: babelHelpers.asyncToGenerator(function* () {
|
||||
var wat = yield bar();
|
||||
}),
|
||||
writable: true,
|
||||
configurable: true
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
return Foo;
|
||||
})();
|
||||
@@ -1,7 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var _asyncToGenerator = function (fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { var callNext = step.bind(null, "next"); var callThrow = step.bind(null, "throw"); function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(callNext, callThrow); } } callNext(); }); }; };
|
||||
|
||||
var foo = _asyncToGenerator(function* () {
|
||||
var foo = babelHelpers.asyncToGenerator(function* () {
|
||||
var wat = yield bar();
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"externalHelpers": true,
|
||||
"noCheckAst": true,
|
||||
"optional": ["asyncToGenerator"]
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var _asyncToGenerator = function (fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { var callNext = step.bind(null, "next"); var callThrow = step.bind(null, "throw"); function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(callNext, callThrow); } } callNext(); }); }; };
|
||||
|
||||
var foo = _asyncToGenerator(function* () {
|
||||
var foo = babelHelpers.asyncToGenerator(function* () {
|
||||
var wat = yield bar();
|
||||
});
|
||||
});
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
var _bluebird = require("bluebird");
|
||||
|
||||
var _prototypeProperties = function (child, staticProps, instanceProps) { if (staticProps) Object.defineProperties(child, staticProps); if (instanceProps) Object.defineProperties(child.prototype, instanceProps); };
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||
|
||||
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
|
||||
|
||||
@@ -11,13 +11,11 @@ var Foo = (function () {
|
||||
_classCallCheck(this, Foo);
|
||||
}
|
||||
|
||||
_prototypeProperties(Foo, null, {
|
||||
_createClass(Foo, {
|
||||
foo: {
|
||||
value: _bluebird.coroutine(function* () {
|
||||
var wat = yield bar();
|
||||
}),
|
||||
writable: true,
|
||||
configurable: true
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -4,4 +4,4 @@ var _bluebird = require("bluebird");
|
||||
|
||||
var foo = _bluebird.coroutine(function* () {
|
||||
var wat = yield bar();
|
||||
});
|
||||
});
|
||||
@@ -4,4 +4,4 @@ var _bluebird = require("bluebird");
|
||||
|
||||
var foo = _bluebird.coroutine(function* () {
|
||||
var wat = yield bar();
|
||||
});
|
||||
});
|
||||
@@ -8,7 +8,7 @@ var obj = Object.defineProperties({}, {
|
||||
set: function (value) {
|
||||
this._foo = value;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
configurable: true,
|
||||
enumerable: true
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -5,7 +5,7 @@ var obj = Object.defineProperties({}, {
|
||||
get: function () {
|
||||
return 5 + 5;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
configurable: true,
|
||||
enumerable: true
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -5,7 +5,7 @@ var obj = Object.defineProperties({}, {
|
||||
set: function (value) {
|
||||
this._foo = value;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
configurable: true,
|
||||
enumerable: true
|
||||
}
|
||||
});
|
||||
});
|
||||
9
test/fixtures/transformation/es6-block-scoping-tdz-fail/destructuring.js
vendored
Normal file
9
test/fixtures/transformation/es6-block-scoping-tdz-fail/destructuring.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
function foo(
|
||||
{ x: { y: { z: a = b } = {}, w: b = 20 }, a: c = 30 }
|
||||
) {
|
||||
assert.equal(a, 10);
|
||||
assert.equal(b, 20);
|
||||
assert.equal(c, 30);
|
||||
}
|
||||
|
||||
foo({ x: {} });
|
||||
2
test/fixtures/transformation/es6-block-scoping-tdz-fail/export.js
vendored
Normal file
2
test/fixtures/transformation/es6-block-scoping-tdz-fail/export.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
a;
|
||||
export const a = 1;
|
||||
9
test/fixtures/transformation/es6-block-scoping-tdz-pass/destructuring.js
vendored
Normal file
9
test/fixtures/transformation/es6-block-scoping-tdz-pass/destructuring.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
function foo(
|
||||
{ x: { y: { z: a = 10 } = {}, w: b = 20 }, a: c = 30 }
|
||||
) {
|
||||
assert.equal(a, 10);
|
||||
assert.equal(b, 20);
|
||||
assert.equal(c, 30);
|
||||
}
|
||||
|
||||
foo({ x: {} });
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user