Compare commits

...

116 Commits

Author SHA1 Message Date
Sebastian McKenzie
db36c3a7c2 v3.6.1 2015-02-13 20:50:37 +11:00
Sebastian McKenzie
e841b88cbc fix 6to5-node test collisions 2015-02-13 20:48:52 +11:00
Sebastian McKenzie
3d874f2479 update sliceToArray helper, again... 2015-02-13 20:45:43 +11:00
Sebastian McKenzie
228719102a update sliceToArray tests 2015-02-13 20:39:37 +11:00
Sebastian McKenzie
c6ce1a248c better slicedToArray helper 2015-02-13 20:38:28 +11:00
Sebastian McKenzie
ba9b85f64b only use functions returnType if it hasn't been reassigned 2015-02-13 20:36:43 +11:00
Sebastian McKenzie
56c868efee fix incorrect generateUid references in File 2015-02-13 18:27:53 +11:00
Sebastian McKenzie
1f3c3832ba fix linting errors 2015-02-13 18:25:34 +11:00
Sebastian McKenzie
3b04a8c648 fix linting errors 2015-02-13 18:24:24 +11:00
Sebastian McKenzie
2270057b54 add 3.6.1 changelog 2015-02-13 18:23:46 +11:00
Sebastian McKenzie
c3206aa9a4 move File::generateUid to Scope and add return type inferrence 2015-02-13 18:21:28 +11:00
Sebastian McKenzie
1912d1b26a remove ExportSpecifier from t.getBindingIdentifiers as it has none 2015-02-13 18:19:27 +11:00
Sebastian McKenzie
9208e7e594 update common standard import test 2015-02-13 17:47:46 +11:00
Sebastian McKenzie
ce332b3384 fix module binding resolution - fixes #762 2015-02-13 17:37:35 +11:00
Sebastian McKenzie
a567531f77 ignore member expressions in constants transformer - fixes #770 2015-02-13 17:18:42 +11:00
Sebastian McKenzie
9cce72def0 update tests that use the toSlicedArray helper 2015-02-13 17:04:18 +11:00
Sebastian McKenzie
2d8581c6dc Merge branch 'master' of github.com:6to5/6to5
Conflicts:
	lib/6to5/transformation/transformers/minification/dead-code-elimination.js
2015-02-13 16:54:09 +11:00
Sebastian McKenzie
14a000396a add error message to the sliced-to-array helper on a non-iterable param - fixes #766 2015-02-13 16:50:03 +11:00
Sebastian McKenzie
4c41f5a22f bump acorn-6to5 and 6to5 devDependency 2015-02-13 15:09:28 +11:00
Sebastian McKenzie
6be2a6e02a add extra note to minification dead code elimination transformer 2015-02-13 15:09:17 +11:00
Sebastian McKenzie
0a4fc16ca0 add type inferrence that expires when a binding is reassigned 2015-02-13 15:08:58 +11:00
Sebastian McKenzie
25d8377411 normalise JSX attribute strings 2015-02-13 15:08:39 +11:00
Brian Donovan
14267a788d Fix a typo. 2015-02-12 19:12:09 -08:00
Sebastian McKenzie
ba5c5760b1 Merge pull request #769 from 6to5/if-truthy-minification-returns-consequent
Return the consequent if the test is truthy.
2015-02-13 14:08:32 +11:00
Brian Donovan
49904b3ab3 Fix a small grammar issue. 2015-02-12 19:07:54 -08:00
Brian Donovan
a212f035e4 Return the consequent if the test is truthy. 2015-02-12 19:06:06 -08:00
Brian Donovan
ea471a6a17 Fix a few typos. 2015-02-12 18:47:08 -08:00
Brian Donovan
f5bae0b696 Remove redundant variable. 2015-02-12 18:46:53 -08:00
Brian Donovan
9ec9e13aeb Update the jsdoc to indicate that key is optional. 2015-02-12 18:36:36 -08:00
Brian Donovan
0b042b2681 Use the posessive form of "its", not a contraction of "it is". 2015-02-12 18:36:02 -08:00
Brian Donovan
83b4d12884 Correct a jsdoc comment parameter name. 2015-02-12 18:35:35 -08:00
Brian Donovan
98d555498d Remove unused variable. 2015-02-12 18:29:14 -08:00
Sebastian McKenzie
fdc05cb977 Merge pull request #767 from 6to5/templates-should-not-recurse
Ensure that templates do not recurse.
2015-02-13 11:13:30 +11:00
Brian Donovan
928ebda5bc Ensure that templates do not recurse.
Closes #765.
2015-02-12 16:10:13 -08:00
Sebastian McKenzie
0a2003af66 3.6.0 2015-02-12 21:59:37 +11:00
Sebastian McKenzie
02392635ef v3.6.0 2015-02-12 21:57:18 +11:00
Sebastian McKenzie
298cfac7f4 fix linting errors 2015-02-12 21:55:31 +11:00
Sebastian McKenzie
476b683f0f upgrade core-js 2015-02-12 21:53:51 +11:00
Sebastian McKenzie
5c5b66df54 add 3.6.0 changelog 2015-02-12 21:53:45 +11:00
Sebastian McKenzie
e7f6572a3b track arrays to avoid turning something into an array multiple times - closes #757 2015-02-12 21:30:48 +11:00
Sebastian McKenzie
e9cfd2df3e fix toConsumableArray helper 2015-02-12 16:53:00 +11:00
Sebastian McKenzie
a425136680 allow loose = true as an alias for loose = "all" 2015-02-12 16:36:17 +11:00
Sebastian McKenzie
8d06a4301c pdate tests to reflect toConsumableArray updates 2015-02-12 16:35:55 +11:00
Sebastian McKenzie
1909a16dc7 copy over files that we can't compile when specifying a directory in bin/6to5 2015-02-12 16:35:41 +11:00
Sebastian McKenzie
3bfa1f610c add bootstrapping base 2015-02-12 16:35:04 +11:00
Sebastian McKenzie
4faf2b7730 fix namespace name 2015-02-12 16:00:54 +11:00
Sebastian McKenzie
4e5d6ee976 rice up toConsumableArray helper 2015-02-12 16:00:43 +11:00
Sebastian McKenzie
afb1ee79a1 fix autoenabling of playground/experimental when used in whitelist/optional 2015-02-12 16:00:26 +11:00
Sebastian McKenzie
efe3f30741 make minification.renameLocalVariables work 2015-02-12 07:46:34 +11:00
Sebastian McKenzie
5ff0285ba7 use space helper instead of pushing a space in IfStatement generation 2015-02-12 07:46:21 +11:00
Sebastian McKenzie
d7bea2f325 remove legacy jshint comment 2015-02-12 07:46:03 +11:00
Sebastian McKenzie
32316ad942 clean up t.is 2015-02-12 07:45:55 +11:00
Sebastian McKenzie
7953eb560e force experimental and playground flag when whitelisting/optionalising transformers 2015-02-12 07:45:50 +11:00
Sebastian McKenzie
faa10df84c add toConsumableArray helper for spread - fixes #757 2015-02-12 07:37:40 +11:00
Sebastian McKenzie
ae344aa23e recurse over and duplicate array in toArray in order to handle sparse arrays - fixes #754 2015-02-12 00:33:04 +11:00
Sebastian McKenzie
e0bfc72700 fix tail call deopt check 2015-02-11 20:16:50 +11:00
Sebastian McKenzie
bf8f80faf7 add general support for declarations to Scope::rename - closes #751 2015-02-11 20:14:41 +11:00
Sebastian McKenzie
77fa8bf01c fix isReferenced on AssignmentPattern 2015-02-11 20:14:21 +11:00
Sebastian McKenzie
34ca1ac04f delay binding reassignment to after reference replacements - #751 2015-02-11 19:48:54 +11:00
Sebastian McKenzie
85d33536e0 add deopt logging to tail call transformer 2015-02-11 15:59:15 +11:00
Sebastian McKenzie
a4932e0e0f add messages to make it easier to make error messages 2015-02-11 15:57:30 +11:00
Sebastian McKenzie
4ebd0a1e8a upgrade regenerator-6to5 2015-02-11 12:12:43 +11:00
Sebastian McKenzie
14e92e9e3f remove kexec from optionalDependencies 2015-02-11 12:00:38 +11:00
Sebastian McKenzie
13687d98ed bump regenerator-6to5 2015-02-11 11:52:16 +11:00
Sebastian McKenzie
db93c52182 opt out of tail recursion optimisation if the owner id has been reassigned - fixes #744 2015-02-11 11:27:50 +11:00
Sebastian McKenzie
56a953df64 add basic support for class property initializers - #619 2015-02-11 10:59:44 +11:00
Sebastian McKenzie
c38edbbb42 Merge branch 'master' of github.com:6to5/6to5 2015-02-11 08:29:08 +11:00
Sebastian McKenzie
017bb6427a Merge pull request #743 from chicoxyzzy/master
optimise lodash usage
2015-02-11 08:28:58 +11:00
Sebastian McKenzie
714ad40cb0 update contributing guide 2015-02-11 08:28:47 +11:00
Ingvar Stepanyan
904a72fb3a Fix rename not establishing binding. 2015-02-10 17:18:46 +02:00
chico
146835e0f1 fix broken code, lint and codestyle fixes 2015-02-10 18:16:54 +03:00
chico
79ba97872c optimise lodash usage; change contains function to includes for convenience 2015-02-10 17:40:53 +03:00
Sebastian McKenzie
897566ccb3 more reliable scope construction 2015-02-11 00:38:59 +11:00
Sebastian McKenzie
4df1b6700b remove acorn node patching 2015-02-11 00:37:59 +11:00
Sebastian McKenzie
50f903caf7 proper optional builder keys 2015-02-11 00:13:27 +11:00
Sebastian McKenzie
7b8118d8bd default newName in scope.rename to a new uid 2015-02-11 00:13:21 +11:00
Sebastian McKenzie
0c1e1e757c default optional builder keys to false 2015-02-11 00:02:51 +11:00
Sebastian McKenzie
62fa583fc1 fix linting errors 2015-02-10 23:55:11 +11:00
Sebastian McKenzie
8598000a69 restructure Scope API and internal data structure 2015-02-10 23:52:23 +11:00
Sebastian McKenzie
edc8bee38e test for falsy nodes in tail call transformer subtransform 2015-02-10 22:39:46 +11:00
Sebastian McKenzie
45b70d7fba fix bad ctrl+f Class -> ClassTransformer replacement 2015-02-10 22:39:21 +11:00
Sebastian McKenzie
49a53b26bb add scope renaming helper method - fixes #645 - @RReverser 2015-02-10 22:39:07 +11:00
Sebastian McKenzie
329b4e9d21 append Transformer to the end of transformer classes 2015-02-10 22:12:36 +11:00
Sebastian McKenzie
f1bca0013e refactor tail call transformer into a class - @RReverser 2015-02-10 22:11:22 +11:00
Sebastian McKenzie
87af83f1cb Merge pull request #742 from douglasduteil/patch-1
chore(travis): run tests on nodejs 0.12 too
2015-02-10 20:30:30 +11:00
Douglas Duteil
5156574bf2 chore(travis): run tests on nodejs 0.12 too 2015-02-10 10:29:05 +01:00
Sebastian McKenzie
ac098255be fix allowPartial in t.buildMatchMemberExpression 2015-02-10 18:34:16 +11:00
Sebastian McKenzie
47b803ef24 remove old tail call transformer 2015-02-10 18:33:51 +11:00
Sebastian McKenzie
7f61c8b65e add descriptor falsy check to defaults helper - #739 2015-02-10 18:33:29 +11:00
Sebastian McKenzie
4fa9aa63a3 Merge branch 'better-tail-recursion' 2015-02-10 18:04:05 +11:00
Sebastian McKenzie
d582c7c93a Merge pull request #739 from lukescott/defaults-fix
fix defaults helper in strict mode - #738
2015-02-10 18:00:26 +11:00
Sebastian McKenzie
6266f5b924 finish minification.removeConsoleCall transformer #740 2015-02-10 17:56:31 +11:00
Luke Scott
c6920a0e60 fix defaults helper in strict mode - #738 2015-02-09 20:38:57 -08:00
Sebastian McKenzie
825d84ba52 fix defaults helper iteration - #738 2015-02-10 13:20:19 +11:00
Sebastian McKenzie
94a0eb5b06 copy over descriptors and handle non-enumerable properties in defaults helper - fixes #738 2015-02-10 13:06:26 +11:00
Sebastian McKenzie
b6d708caf2 add SpreadProperty to t.getBindingIdentifiers - fixes #734 2015-02-10 09:04:27 +11:00
Ingvar Stepanyan
0d542b61d3 Performance improvements for TCO.
http://jsperf.com/tco/17
2015-02-09 19:00:31 +02:00
Ingvar Stepanyan
5a842ab623 Fix statement substitution in templates. 2015-02-09 17:34:59 +02:00
Sebastian McKenzie
26d4b5f2cf normalise opts.sourceRoot path - 6to5/karma-6to5-preprocessor#5 2015-02-09 23:38:54 +11:00
Sebastian McKenzie
ba0dfac53d add uid scope kind 2015-02-09 21:28:51 +11:00
Sebastian McKenzie
8a4296a948 remove binding kind from pushing bindings to the function scope, better block scoped collision logic, and track label ids as references 2015-02-09 21:21:25 +11:00
Sebastian McKenzie
478f9e028f put function params into the param kind 2015-02-09 20:16:38 +11:00
Sebastian McKenzie
c4e56894d9 ignore hoisted kind when checking for block scoped collisions 2015-02-09 20:03:59 +11:00
Sebastian McKenzie
c6f13844ed move FunctionDeclarations into a hoisted kind 2015-02-09 19:53:46 +11:00
Sebastian McKenzie
5e81653680 change function params binding kind to let 2015-02-09 19:45:03 +11:00
Sebastian McKenzie
8e2df3f1f9 add kinds to binding registration and rename declaration scope methods to bindings 2015-02-09 19:42:52 +11:00
Sebastian McKenzie
a2cc384172 move rest parameters transformer above default parameters 2015-02-09 10:59:31 +11:00
Sebastian McKenzie
d37bf292a1 rename declarationKinds to bindingKinds in scope tracker 2015-02-09 10:59:20 +11:00
Sebastian McKenzie
70eb641530 fix element name in default parameters 2015-02-09 08:46:06 +11:00
Sebastian McKenzie
f845a9b2c4 ignore binding elements when finding the last non-default param - fixes #723 2015-02-09 08:25:58 +11:00
Sebastian McKenzie
ee5cb8d9ed clean up tail call transformer 2015-02-08 22:47:50 +11:00
Sebastian McKenzie
9020a21ba2 3.5.3 2015-02-08 22:17:36 +11:00
Sebastian McKenzie
fdda013d07 v3.5.3 2015-02-08 22:17:05 +11:00
Sebastian McKenzie
64477d934d add 3.5.3 changelog 2015-02-08 22:10:00 +11:00
Sebastian McKenzie
45c507056a add back old tail call implementation 2015-02-08 22:09:41 +11:00
Sebastian McKenzie
730b96c195 3.5.2 2015-02-08 21:23:55 +11:00
146 changed files with 1549 additions and 741 deletions

5
.6to5rc Normal file
View File

@@ -0,0 +1,5 @@
{
"experimental": true,
"playground": true,
"loose": true
}

View File

@@ -3,6 +3,7 @@ language: node_js
node_js:
- "0.10"
- "0.11"
- "0.12"
branches:
except:

View File

@@ -11,6 +11,33 @@
_Note: Gaps between patch versions are faulty/broken releases._
## 3.6.1
* **Bug Fix**
* Multiline JSX string literals are now supported.
* Fix scope tracking import specifiers incorrectly.
* Fix templates incorrectly recursing into their replacements.
* **Internal**
* Type inferrence now extends to function return types.
* Upgrade `acorn-6to5`.
## 3.6.0
* **New Feature**
* Add playground class property initializers.
* **Polish**
* Completely reimplemented scope tracking, can now track types and optimise certain helpers based on it.
* Extremely fast tail recursion optimisation implementation. Thanks [@RReverser](https://github.com/RReverser)!
* **Internal**
* `kexec` has been removed as an optional dependency and must be user installed.
* Upgrade `regenerator-6to5`.
* Upgrade `acorn-6to5`.
* Upgrade `core-js`.
## 3.5.3
* Enable `es6.tailCall` transformer with the first implementation that only works with self referencing calls until we can implement nested tail calls elegantly.
## 3.5.2
* Disable `es6.tailCall` temporairly after reports of it breaking.

View File

@@ -1,6 +1,12 @@
# Contributing
Contributions are always welcome, no matter how large or small. Before contributing, please read the [code of conduct](https://github.com/6to5/6to5/blob/master/CODE_OF_CONDUCT.md).
Contributions are always welcome, no matter how large or small. Before
contributing, please read the
[code of conduct](https://github.com/6to5/6to5/blob/master/CODE_OF_CONDUCT.md).
**NOTE:** Please do not send pull requests that fix linting issues. It's highly
likely that they've already been fixed by the time it's submitted and it just
pollutes the git tree.
## Developing
@@ -12,7 +18,8 @@ Contributions are always welcome, no matter how large or small. Before contribut
* Link your forked clone (`npm link`)
* Develop your changes ensuring you're fetching updates from upstream often
* Ensure the test are passing (`make test`)
* Create new pull request explaining your proposed change or reference an issue in your commit message
* Create new pull request explaining your proposed change or reference an issue
in your commit message
#### Code Standards

View File

@@ -5,10 +5,17 @@ UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs
JSHINT_CMD = node_modules/jshint/bin/jshint
MOCHA_CMD = node_modules/mocha/bin/_mocha
JSCS_CMD = node_modules/jscs/bin/jscs
6TO5_CMD = node_modules/6to5/bin/6to5
export NODE_ENV = test
.PHONY: clean test test-cov test-clean lint test-travis test-simple test-all test-browser publish build bootstrap publish-core publish-runtime
.PHONY: clean test test-cov test-clean lint test-travis test-simple test-all test-browser publish build bootstrap publish-core publish-runtime build-core watch-core
build-core:
#node $(6TO5_CMD) src --out-dir lib
watch-core:
#node $(6TO5_CMD) src --out-dir lib --watch
build:
mkdir -p dist
@@ -55,7 +62,7 @@ test-cov:
export SIMPLE_6TO5_TESTS=1; \
node $(ISTANBUL_CMD) $(MOCHA_CMD) --
test-travis: bootstrap
test-travis: build-core bootstrap
node $(ISTANBUL_CMD) $(MOCHA_CMD) --
if test -n "$$CODECLIMATE_REPO_TOKEN"; then codeclimate < coverage/lcov.info; fi

View File

@@ -1,17 +0,0 @@
environment:
matrix:
- nodejs_version: "0.10"
- nodejs_version: "0.11"
install:
- "npm install"
- "cinst make"
test_script:
- "node --version"
- "npm --version"
- "make test-spec"
build: "off"
version: "{build}"

View File

@@ -37,8 +37,13 @@ module.exports = function (commander, filenames, opts) {
if (stat.isDirectory(filename)) {
var dirname = filename;
_.each(util.readdirFilter(dirname), function (filename) {
write(path.join(dirname, filename), filename);
_.each(util.readdir(dirname), function (filename) {
var src = path.join(dirname, filename);
if (util.canCompile(filename)) {
write(src, filename);
} else {
outputFileSync(path.join(commander.outDir, filename), fs.readFileSync(src));
}
});
} else {
write(filename, filename);

View File

@@ -12,6 +12,10 @@ exports.readdirFilter = function (filename) {
});
};
exports.readdir = readdir;
exports.canCompile = util.canCompile;
exports.addSourceMappingUrl = function (code, loc) {
return code + "\n//# sourceMappingURL=" + path.basename(loc);
};

View File

@@ -1,5 +1,5 @@
var t = require("../types");
var _ = require("lodash");
var includes = require("lodash/collection/includes");
exports.AssignmentExpression = function (node, parent, detected) {
if (node.operator === "**=") {
@@ -38,7 +38,7 @@ exports.Property = function (node, parent, detected) {
};
exports.AssignmentPattern = function (node, parent, detected) {
if (t.isFunction(parent) && _.contains(parent.params, node)) {
if (t.isFunction(parent) && includes(parent.params, node)) {
detected("es6.parameters.default");
}
};

View File

@@ -3,7 +3,7 @@
module.exports = Buffer;
var isBoolean = require("lodash/lang/isBoolean");
var contains = require("lodash/collection/contains");
var includes = require("lodash/collection/includes");
var isNumber = require("lodash/lang/isNumber");
var util = require("../util");
@@ -159,7 +159,7 @@ Buffer.prototype.isLast = function (cha, trimRight) {
var last = buf[buf.length - 1];
if (Array.isArray(cha)) {
return contains(cha, last);
return includes(cha, last);
} else {
return cha === last;
}

View File

@@ -21,7 +21,7 @@ exports.IfStatement = function (node, print) {
print.indentOnComments(node.consequent);
if (node.alternate) {
if (this.isLast("}")) this.push(" ");
if (this.isLast("}")) this.space();
this.keyword("else");
if (this.format.format && !t.isBlockStatement(node.alternate)) {

48
lib/6to5/messages.js Normal file
View File

@@ -0,0 +1,48 @@
var util = require("util");
exports.messages = {
tailCallReassignmentDeopt: "Function reference has been reassigned so it's probably be dereferenced so we can't optimise this with confidence",
JSXNamespacedTags: "Namespace tags are not supported. ReactJSX is not XML.",
classesIllegalBareSuper: "Illegal use of bare super",
classesIllegalSuperCall: "Direct super call is illegal in non-constructor, use super.$1() instead",
classesIllegalConstructorKind: "Illegal kind for constructor method",
scopeDuplicateDeclaration: "Duplicate declaration $1",
undeclaredVariable: "Reference to undeclared variable $1",
undeclaredVariableSuggestion: "Reference to undeclared variable $1 - did you mean $2?",
settersInvalidParamLength: "Setters must have only one parameter",
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",
readOnly: "$1 is read-only",
modulesIllegalExportName: "Illegal export $1",
unknownForHead: "Unknown node type $1 in ForStatement"
};
exports.get = function (key) {
var msg = exports.messages[key];
if (!msg) throw new ReferenceError("Unknown message `" + key + "`");
var args = [];
for (var i = 1; i < arguments.length; i++) {
args.push(arguments[i]);
}
args = exports.parseArgs(args);
return msg.replace(/\$(\d+)/g, function (str, i) {
return args[--i];
});
};
exports.parseArgs = function (args) {
return args.map(function (val) {
if (val != null && val.inspect) {
return val.inspect();
} else {
try {
return JSON.stringify(val) || val + "";
} catch (e) {
return util.inspect(val);
}
}
});
};

View File

@@ -3,8 +3,6 @@
var extend = require("lodash/object/extend");
var t = require("./types");
require("./types/node");
// estraverse
var estraverse = require("estraverse");

View File

@@ -8,7 +8,7 @@ var isFunction = require("lodash/lang/isFunction");
var transform = require("./index");
var generate = require("../generation");
var defaults = require("lodash/object/defaults");
var contains = require("lodash/collection/contains");
var includes = require("lodash/collection/includes");
var clone = require("../helpers/clone");
var parse = require("../helpers/parse");
var Scope = require("../traversal/scope");
@@ -41,6 +41,7 @@ File.helpers = [
"tagged-template-literal-loose",
"interop-require",
"to-array",
"to-consumable-array",
"sliced-to-array",
"object-without-properties",
"has-own",
@@ -123,7 +124,10 @@ File.prototype.normalizeOptions = function (opts) {
});
// normalize windows path separators to unix
opts.filename = opts.filename.replace(/\\/g, "/");
opts.filename = util.normalisePathSeparator(opts.filename);
if (opts.sourceRoot) {
opts.sourceRoot = util.normalisePathSeparator(opts.sourceRoot);
}
opts.basename = path.basename(opts.filename, path.extname(opts.filename));
@@ -132,7 +136,7 @@ File.prototype.normalizeOptions = function (opts) {
opts.optional = util.arrayify(opts.optional);
opts.loose = util.arrayify(opts.loose);
if (contains(opts.loose, "all")) {
if (includes(opts.loose, "all") || includes(opts.loose, true)) {
opts.loose = Object.keys(transform.transformers);
}
@@ -172,11 +176,20 @@ File.prototype.normalizeOptions = function (opts) {
"`reactCompat` - backwards compatibility will be removed in v4.0.0");
}
var ensureEnabled = function (key) {
var namespace = transform.transformerNamespaces[key];
if (namespace === "es7") opts.experimental = true;
if (namespace === "playground") opts.playground = true;
};
each(opts.whitelist, ensureEnabled);
each(opts.optional, ensureEnabled);
return opts;
};
File.prototype.isLoose = function (key) {
return contains(this.opts.loose, key);
return includes(this.opts.loose, key);
};
File.prototype.buildTransformers = function () {
@@ -213,22 +226,6 @@ File.prototype.debug = function (msg) {
util.debug(parts);
};
File.prototype.toArray = function (node, i) {
if (t.isArrayExpression(node)) {
return node;
} else if (t.isIdentifier(node) && node.name === "arguments") {
return t.callExpression(t.memberExpression(this.addHelper("slice"), t.identifier("call")), [node]);
} else {
var declarationName = "to-array";
var args = [node];
if (i) {
args.push(t.literal(i));
declarationName = "sliced-to-array";
}
return t.callExpression(this.addHelper(declarationName), args);
}
};
File.prototype.getModuleFormatter = function (type) {
var ModuleFormatter = isFunction(type) ? type : transform.moduleFormatters[type];
@@ -281,7 +278,7 @@ File.prototype.addImport = function (source, name) {
var id = this.dynamicImportIds[name];
if (!id) {
id = this.dynamicImportIds[name] = this.generateUidIdentifier(name);
id = this.dynamicImportIds[name] = this.scope.generateUidIdentifier(name);
var specifiers = [t.importSpecifier(t.identifier("default"), id)];
var declar = t.importDeclaration(specifiers, t.literal(source));
@@ -299,7 +296,7 @@ File.prototype.isConsequenceExpressionStatement = function (node) {
};
File.prototype.addHelper = function (name) {
if (!contains(File.helpers, name)) {
if (!includes(File.helpers, name)) {
throw new ReferenceError("Unknown helper " + name);
}
@@ -315,7 +312,7 @@ File.prototype.addHelper = function (name) {
} else {
var ref = util.template(name);
ref._compact = true;
var uid = this.generateUidIdentifier(name);
var uid = this.scope.generateUidIdentifier(name);
this.scope.push({
key: name,
id: uid,
@@ -325,6 +322,10 @@ File.prototype.addHelper = function (name) {
}
};
File.prototype.logDeopt = function () {
// todo, (node, msg)
};
File.prototype.errorWithNode = function (node, msg, Error) {
Error = Error || SyntaxError;
@@ -442,30 +443,3 @@ File.prototype.generate = function () {
return result;
};
File.prototype.generateUid = function (name, scope) {
name = t.toIdentifier(name).replace(/^_+/, "");
scope = scope || this.scope;
var uid;
var i = 0;
do {
uid = this._generateUid(name, i);
i++;
} while (scope.hasReference(uid));
return uid;
};
File.prototype.generateUidIdentifier = function (name, scope) {
scope = scope || this.scope;
var id = t.identifier(this.generateUid(name, scope));
scope.addDeclarationToFunctionScope("var", id);
return id;
};
File.prototype._generateUid = function (name, i) {
var id = name;
if (i > 1) id += i;
return "_" + id;
};

View File

@@ -6,6 +6,7 @@
// jsx
var isString = require("lodash/lang/isString");
var messages = require("../../messages");
var esutils = require("esutils");
var react = require("./react");
var t = require("../../types");
@@ -28,7 +29,7 @@ module.exports = function (exports, opts) {
};
exports.JSXNamespacedName = function (node, parent, scope, file) {
throw file.errorWithNode(node, "Namespace tags are not supported. ReactJSX is not XML.");
throw file.errorWithNode(node, messages.get("JSXNamespacedTags"));
};
exports.JSXMemberExpression = {
@@ -45,6 +46,11 @@ module.exports = function (exports, opts) {
exports.JSXAttribute = {
exit: function (node) {
var value = node.value || t.literal(true);
if (t.isLiteral(value) && isString(value.value)) {
value.value = value.value.replace(/\n\s+/g, " ");
}
return t.inherits(t.property("init", node.name, value), node);
}
};

View File

@@ -18,7 +18,7 @@ var getObjRef = function (node, nodes, file, scope) {
} else if (t.isMemberExpression(node)) {
ref = node.object;
if (t.isIdentifier(ref) && scope.hasReference(ref.name)) {
if (t.isIdentifier(ref) && scope.hasGlobal(ref.name)) {
// the object reference that we need to save is locally declared
// so as per the previous comment we can be 100% sure evaluating
// it multiple times will be safe

View File

@@ -13,7 +13,7 @@ var visitor = {
// check that we don't have a local variable declared as that removes the need
// for the wrapper
var localDeclar = scope.getBinding(state.id);
var localDeclar = scope.getBindingIdentifier(state.id);
if (localDeclar !== state.outerDeclar) return;
state.selfReference = true;
@@ -31,7 +31,7 @@ exports.property = function (node, file, scope) {
var state = {
id: id,
selfReference: false,
outerDeclar: scope.getBinding(id),
outerDeclar: scope.getBindingIdentifier(id),
};
scope.traverse(node, visitor, state);

View File

@@ -2,7 +2,8 @@
module.exports = ReplaceSupers;
var t = require("../../types");
var messages = require("../../messages");
var t = require("../../types");
/**
* Description
@@ -142,7 +143,7 @@ ReplaceSupers.prototype.getThisReference = function () {
if (this.topLevelThisReference) {
return this.topLevelThisReference;
} else {
var ref = this.topLevelThisReference = this.file.generateUidIdentifier("this");
var ref = this.topLevelThisReference = this.scope.generateUidIdentifier("this");
this.methodNode.value.body.body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(this.topLevelThisReference, t.thisExpression())
]));
@@ -232,7 +233,7 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
var thisReference;
if (isIllegalBareSuper(node, parent)) {
throw this.file.errorWithNode(node, "Illegal use of bare super");
throw this.file.errorWithNode(node, messages.get("classesIllegalBareSuper"));
}
if (t.isCallExpression(node)) {
@@ -248,7 +249,7 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
// - https://twitter.com/wycats/status/544553184396836864
if (methodNode.key.name !== "constructor" || !this.inClass) {
var methodName = methodNode.key.name || "METHOD_NAME";
throw this.file.errorWithNode(node, "Direct super call is illegal in non-constructor, use super." + methodName + "() instead");
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);

View File

@@ -56,8 +56,9 @@ transform._ensureTransformerNames = function (type, rawKeys) {
return keys;
};
transform.transformers = object();
transform.namespaces = object();
transform.transformerNamespaces = object();
transform.transformers = object();
transform.namespaces = object();
transform.deprecatedTransformerMap = require("./transformers/deprecated");
transform.moduleFormatters = require("./modules");
@@ -66,8 +67,10 @@ var rawTransformers = require("./transformers");
each(rawTransformers, function (transformer, key) {
var namespace = key.split(".")[0];
transform.namespaces[namespace] = transform.namespaces[namespace] || [];
transform.namespaces[namespace].push(key);
transform.transformerNamespaces[key] = namespace;
transform.transformers[key] = new Transformer(key, transformer);
});

View File

@@ -2,14 +2,16 @@
module.exports = DefaultFormatter;
var messages = require("../../messages");
var extend = require("lodash/object/extend");
var object = require("../../helpers/object");
var util = require("../../util");
var t = require("../../types");
var extend = require("lodash/object/extend");
function DefaultFormatter(file) {
this.file = file;
this.ids = object();
this.scope = file.scope;
this.file = file;
this.ids = object();
this.hasNonDefaultExports = false;
@@ -124,13 +126,6 @@ DefaultFormatter.prototype.isLocalReference = function (node) {
return t.isIdentifier(node) && localImports[node.name] && localImports[node.name] !== node;
};
DefaultFormatter.prototype.checkLocalReference = function (node) {
var file = this.file;
if (this.isLocalReference(node)) {
throw file.errorWithNode(node, "Illegal assignment of module import");
}
};
DefaultFormatter.prototype.remapExportAssignment = function (node) {
return t.assignmentExpression(
"=",
@@ -146,7 +141,7 @@ DefaultFormatter.prototype.remapExportAssignment = function (node) {
DefaultFormatter.prototype.isLocalReference = function (node, scope) {
var localExports = this.localExports;
var name = node.name;
return t.isIdentifier(node) && localExports[name] && localExports[name] === scope.getBinding(name);
return t.isIdentifier(node) && localExports[name] && localExports[name] === scope.getBindingIdentifier(name);
};
DefaultFormatter.prototype.getModuleName = function () {
@@ -213,14 +208,11 @@ DefaultFormatter.prototype.getExternalReference = function (node, nodes) {
DefaultFormatter.prototype.checkExportIdentifier = function (node) {
if (t.isIdentifier(node, { name: "__esModule" })) {
throw this.file.errorWithNode(node, "Illegal export __esModule - this is used internally for CommonJS interop");
throw this.file.errorWithNode(node, messages.get("modulesIllegalExportName", node.name));
}
};
DefaultFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
var inherits = false;
if (node.specifiers.length === 1) inherits = node;
if (node.source) {
var ref = this.getExternalReference(node, nodes);

View File

@@ -6,7 +6,7 @@ var DefaultFormatter = require("./_default");
var CommonFormatter = require("./common");
var util = require("../../util");
var t = require("../../types");
var contains = require("lodash/collection/contains");
var includes = require("lodash/collection/includes");
var values = require("lodash/object/values");
function AMDFormatter() {
@@ -70,7 +70,7 @@ AMDFormatter.prototype.getModuleName = function () {
};
AMDFormatter.prototype._getExternalReference = function (node) {
return this.file.generateUidIdentifier(node.source.value);
return this.scope.generateUidIdentifier(node.source.value);
};
AMDFormatter.prototype.importDeclaration = function (node) {
@@ -81,7 +81,7 @@ AMDFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
var key = t.getSpecifierName(specifier);
var ref = this.getExternalReference(node);
if (contains(this.file.dynamicImported, node)) {
if (includes(this.file.dynamicImported, node)) {
// Prevent unnecessary renaming of dynamic imports.
this.ids[node.source.value] = ref;
} else if (t.isImportBatchSpecifier(specifier)) {

View File

@@ -3,7 +3,7 @@
module.exports = CommonJSFormatter;
var DefaultFormatter = require("./_default");
var contains = require("lodash/collection/contains");
var includes = require("lodash/collection/includes");
var util = require("../../util");
var t = require("../../types");
@@ -14,8 +14,13 @@ function CommonJSFormatter() {
util.inherits(CommonJSFormatter, DefaultFormatter);
CommonJSFormatter.prototype.init = function () {
var file = this.file;
var scope = file.scope;
scope.rename("module");
if (!this.noInteropRequireImport && this.hasNonDefaultExports) {
this.file.ast.program.body.push(util.template("exports-module-declaration", true));
file.ast.program.body.push(util.template("exports-module-declaration", true));
}
};
@@ -26,7 +31,7 @@ CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes)
// import foo from "foo";
if (t.isSpecifierDefault(specifier)) {
if (!contains(this.file.dynamicImported, node)) {
if (!includes(this.file.dynamicImported, node)) {
if (this.noInteropRequireImport) {
ref = t.memberExpression(ref, t.identifier("default"));
} else {
@@ -88,7 +93,7 @@ CommonJSFormatter.prototype._getExternalReference = function (node, nodes) {
var call = t.callExpression(t.identifier("require"), [node.source]);
if (this.localImportOccurences[source] > 1) {
var uid = this.file.generateUidIdentifier(source);
var uid = this.scope.generateUidIdentifier(source);
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(uid, call)
]));

View File

@@ -12,7 +12,7 @@ var each = require("lodash/collection/each");
var map = require("lodash/collection/map");
function SystemFormatter(file) {
this.exportIdentifier = file.generateUidIdentifier("export");
this.exportIdentifier = file.scope.generateUidIdentifier("export");
this.noInteropRequireExport = true;
this.noInteropRequireImport = true;
@@ -29,7 +29,7 @@ SystemFormatter.prototype._addImportSource = function (node, exportNode) {
};
SystemFormatter.prototype.buildExportsWildcard = function (objectIdentifier, node) {
var leftIdentifier = this.file.generateUidIdentifier("key");
var leftIdentifier = this.scope.generateUidIdentifier("key");
var valIdentifier = t.memberExpression(objectIdentifier, leftIdentifier, true);
var left = t.variableDeclaration("var", [

View File

@@ -0,0 +1,3 @@
{
"blacklist": ["useStrict"]
}

View File

@@ -1,7 +1,10 @@
(function (obj, defaults) {
for (var key in defaults) {
if (obj[key] === undefined) {
obj[key] = defaults[key];
var keys = Object.getOwnPropertyNames(defaults);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
var value = Object.getOwnPropertyDescriptor(defaults, key);
if (value && value.configurable && obj[key] === undefined) {
Object.defineProperty(obj, key, value);
}
}
return obj;

View File

@@ -1,5 +1,7 @@
(function (arr, i) {
if (Array.isArray(arr)) {
if (!arr || !arr[Symbol.iterator]) {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
} else if (Array.isArray(arr)) {
return arr;
} else {
var _arr = [];

View File

@@ -0,0 +1,3 @@
{
FUNCTION_ID:while (true) BLOCK
}

View File

@@ -0,0 +1,8 @@
(function (arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
} else {
return Array.from(arr);
}
});

View File

@@ -1,6 +1,6 @@
module.exports = TransformerPass;
var contains = require("lodash/collection/contains");
var includes = require("lodash/collection/includes");
/**
* This class is responsible for traversing over the provided `File`s
@@ -25,14 +25,14 @@ TransformerPass.prototype.canRun = function () {
// blacklist
var blacklist = opts.blacklist;
if (blacklist.length && contains(blacklist, key)) return false;
if (blacklist.length && includes(blacklist, key)) return false;
// whitelist
var whitelist = opts.whitelist;
if (whitelist.length) return contains(whitelist, key);
if (whitelist.length) return includes(whitelist, key);
// optional
if (transformer.optional && !contains(opts.optional, key)) return false;
if (transformer.optional && !includes(opts.optional, key)) return false;
// experimental
if (transformer.experimental && !opts.experimental) return false;

View File

@@ -10,7 +10,7 @@ var visitor = {
if (!declared) return;
// declared node is different in this scope
if (scope.getBinding(node.name) !== declared) return;
if (scope.getBindingIdentifier(node.name) !== declared) return;
var assert = t.callExpression(
state.file.addHelper("temporal-assert-defined"),

View File

@@ -136,7 +136,7 @@ function replace(node, parent, scope, remaps) {
var remap = remaps[node.name];
if (!remap) return;
var ownBinding = scope.getBinding(node.name);
var ownBinding = scope.getBindingIdentifier(node.name);
if (ownBinding === remap.binding) {
node.name = remap.uid;
} else {
@@ -175,7 +175,7 @@ BlockScoping.prototype.remap = function () {
// this is the defining identifier of a declaration
var ref = letRefs[key];
if (scope.parentHasReference(key)) {
if (scope.parentHasBinding(key) || scope.hasGlobal(key)) {
var uid = scope.generateUidIdentifier(ref.name).name;
ref.name = uid;

View File

@@ -3,13 +3,14 @@
var ReplaceSupers = require("../../helpers/replace-supers");
var nameMethod = require("../../helpers/name-method");
var defineMap = require("../../helpers/define-map");
var messages = require("../../../messages");
var util = require("../../../util");
var t = require("../../../types");
exports.check = t.isClass;
exports.ClassDeclaration = function (node, parent, scope, file) {
return new Class(node, file, scope, true).run();
return new ClassTransformer(node, file, scope, true).run();
};
exports.ClassExpression = function (node, parent, scope, file) {
@@ -25,7 +26,7 @@ exports.ClassExpression = function (node, parent, scope, file) {
}
}
return new Class(node, file, scope, false).run();
return new ClassTransformer(node, file, scope, false).run();
};
/**
@@ -34,10 +35,10 @@ exports.ClassExpression = function (node, parent, scope, file) {
* @param {Node} node
* @param {File} file
* @param {Scope} scope
* @param {Boolean} closure
* @param {Boolean} isStatement
*/
function Class(node, file, scope, isStatement) {
function ClassTransformer(node, file, scope, isStatement) {
this.isStatement = isStatement;
this.scope = scope;
this.node = node;
@@ -61,7 +62,7 @@ function Class(node, file, scope, isStatement) {
* @returns {Array}
*/
Class.prototype.run = function () {
ClassTransformer.prototype.run = function () {
var superName = this.superName;
var className = this.className;
var file = this.file;
@@ -98,8 +99,7 @@ Class.prototype.run = function () {
closureArgs.push(superName);
if (!t.isIdentifier(superName)) {
var superRef = this.scope.generateUidBasedOnNode(superName, this.file);
superName = superRef;
superName = this.scope.generateUidBasedOnNode(superName, this.file);
}
closureParams.push(superName);
@@ -138,7 +138,7 @@ Class.prototype.run = function () {
* Description
*/
Class.prototype.buildBody = function () {
ClassTransformer.prototype.buildBody = function () {
var constructor = this.constructor;
var className = this.className;
var superName = this.superName;
@@ -167,6 +167,8 @@ Class.prototype.buildBody = function () {
} else if (t.isPrivateDeclaration(node)) {
this.closure = true;
body.unshift(node);
} else if (t.isClassProperty(node)) {
this.pushProperty(node);
}
}
@@ -204,12 +206,12 @@ Class.prototype.buildBody = function () {
};
/**
* Push a method to it's respective mutatorMap.
* Push a method to its respective mutatorMap.
*
* @param {Node} node MethodDefinition
*/
Class.prototype.pushMethod = function (node) {
ClassTransformer.prototype.pushMethod = function (node) {
var methodName = node.key;
var kind = node.kind;
@@ -245,15 +247,39 @@ Class.prototype.pushMethod = function (node) {
defineMap.push(mutatorMap, methodName, "enumerable", node.computed, false);
};
/**
* Description
*
* @param {Node} node
*/
ClassTransformer.prototype.pushProperty = function (node) {
if (!node.value) return;
var key;
if (node.static) {
key = t.memberExpression(this.className, node.key);
this.body.push(
t.expressionStatement(t.assignmentExpression("=", key, node.value))
);
} else {
key = t.memberExpression(t.thisExpression(), node.key);
this.constructor.body.body.unshift(
t.expressionStatement(t.assignmentExpression("=", key, node.value))
);
}
};
/**
* Replace the constructor body of our class.
*
* @param {Node} method MethodDefinition
*/
Class.prototype.pushConstructor = function (method) {
ClassTransformer.prototype.pushConstructor = function (method) {
if (method.kind) {
throw this.file.errorWithNode(method, "illegal kind for constructor method");
throw this.file.errorWithNode(method, messages.get("classesIllegalConstructorKind"));
}
var construct = this.constructor;

View File

@@ -1,6 +1,7 @@
"use strict";
var t = require("../../../types");
var messages = require("../../../messages");
var t = require("../../../types");
exports.check = function (node) {
return t.isVariableDeclaration(node, { kind: "const" });
@@ -9,35 +10,39 @@ exports.check = function (node) {
var visitor = {
enter: function (node, parent, scope, state) {
if (t.isAssignmentExpression(node) || t.isUpdateExpression(node)) {
if (t.isMemberExpression(node.left || node.argument)) return;
var ids = t.getBindingIdentifiers(node);
for (var key in ids) {
var id = ids[key];
for (var name in ids) {
var id = ids[name];
var constant = state.constants[key];
var constant = state.constants[name];
// no constant exists
if (!constant) continue;
var constantIdentifier = constant.identifier;
// check if the assignment id matches the constant declaration id
// if it does then it was the id used to initially declare the
// constant so we can just ignore it
if (id === constant) continue;
if (id === constantIdentifier) continue;
// check if there's been a local binding that shadows this constant
if (!scope.bindingEquals(key, constant)) continue;
if (!scope.bindingIdentifierEquals(name, constantIdentifier)) continue;
throw state.file.errorWithNode(id, key + " is read-only");
throw state.file.errorWithNode(id, messages.get("readOnly", name));
}
} else if (t.isScope(node)) {
} else if (t.isScope(node, parent)) {
this.skip();
}
}
};
exports.Scope = function (node, parent, scope, file) {
exports.Scopable = function (node, parent, scope, file) {
scope.traverse(node, visitor, {
constants: scope.getAllDeclarationsOfKind("const"),
constants: scope.getAllBindingsOfKind("const"),
file: file
});
};

View File

@@ -1,10 +1,11 @@
"use strict";
var t = require("../../../types");
var messages = require("../../../messages");
var t = require("../../../types");
exports.check = t.isPattern;
function Destructuring(opts) {
function DestructuringTransformer(opts) {
this.blockHoist = opts.blockHoist;
this.operator = opts.operator;
this.nodes = opts.nodes;
@@ -13,7 +14,7 @@ function Destructuring(opts) {
this.kind = opts.kind;
}
Destructuring.prototype.buildVariableAssignment = function (id, init) {
DestructuringTransformer.prototype.buildVariableAssignment = function (id, init) {
var op = this.operator;
if (t.isMemberExpression(id)) op = "=";
@@ -32,7 +33,7 @@ Destructuring.prototype.buildVariableAssignment = function (id, init) {
return node;
};
Destructuring.prototype.buildVariableDeclaration = function (id, init) {
DestructuringTransformer.prototype.buildVariableDeclaration = function (id, init) {
var declar = t.variableDeclaration("var", [
t.variableDeclarator(id, init)
]);
@@ -40,7 +41,7 @@ Destructuring.prototype.buildVariableDeclaration = function (id, init) {
return declar;
};
Destructuring.prototype.push = function (elem, parentId) {
DestructuringTransformer.prototype.push = function (elem, parentId) {
if (t.isObjectPattern(elem)) {
this.pushObjectPattern(elem, parentId);
} else if (t.isArrayPattern(elem)) {
@@ -52,7 +53,7 @@ Destructuring.prototype.push = function (elem, parentId) {
}
};
Destructuring.prototype.pushAssignmentPattern = function (pattern, parentId) {
DestructuringTransformer.prototype.pushAssignmentPattern = function (pattern, parentId) {
var tempParentId = this.scope.generateUidBasedOnNode(parentId);
var declar = t.variableDeclaration("var", [
@@ -71,7 +72,7 @@ Destructuring.prototype.pushAssignmentPattern = function (pattern, parentId) {
));
};
Destructuring.prototype.pushObjectSpread = function (pattern, parentId, prop, i) {
DestructuringTransformer.prototype.pushObjectSpread = function (pattern, parentId, prop, i) {
// get all the keys that appear in this object before the current spread
var keys = [];
for (var i2 = 0; i2 < pattern.properties.length; i2++) {
@@ -92,7 +93,7 @@ Destructuring.prototype.pushObjectSpread = function (pattern, parentId, prop, i)
this.nodes.push(this.buildVariableAssignment(prop.argument, value));
};
Destructuring.prototype.pushObjectProperty = function (prop, parentId) {
DestructuringTransformer.prototype.pushObjectProperty = function (prop, parentId) {
if (t.isLiteral(prop.key)) prop.computed = true;
var pattern2 = prop.value;
@@ -105,7 +106,7 @@ Destructuring.prototype.pushObjectProperty = function (prop, parentId) {
}
};
Destructuring.prototype.pushObjectPattern = function (pattern, parentId) {
DestructuringTransformer.prototype.pushObjectPattern = function (pattern, parentId) {
if (!pattern.properties.length) {
this.nodes.push(t.expressionStatement(
t.callExpression(this.file.addHelper("object-destructuring-empty"), [parentId])
@@ -137,18 +138,20 @@ var hasRest = function (pattern) {
return false;
};
Destructuring.prototype.pushArrayPattern = function (pattern, parentId) {
DestructuringTransformer.prototype.pushArrayPattern = function (pattern, parentId) {
if (!pattern.elements) return;
// if we have a rest then we need all the elements
var count = !hasRest(pattern) && pattern.elements.length;
var toArray = this.file.toArray(parentId, count);
var toArray = this.scope.toArray(parentId, count);
var _parentId = this.scope.generateUidBasedOnNode(parentId, this.file);
var _parentId = this.scope.generateUidBasedOnNode(parentId);
this.nodes.push(this.buildVariableDeclaration(_parentId, toArray));
parentId = _parentId;
this.scope.assignTypeGeneric(parentId.name, "Array");
for (var i = 0; i < pattern.elements.length; i++) {
var elem = pattern.elements[i];
@@ -158,7 +161,7 @@ Destructuring.prototype.pushArrayPattern = function (pattern, parentId) {
var newPatternId;
if (t.isRestElement(elem)) {
newPatternId = this.file.toArray(parentId);
newPatternId = this.scope.toArray(parentId);
if (i > 0) {
newPatternId = t.callExpression(t.memberExpression(newPatternId, t.identifier("slice")), [t.literal(i)]);
@@ -173,7 +176,7 @@ Destructuring.prototype.pushArrayPattern = function (pattern, parentId) {
}
};
Destructuring.prototype.init = function (pattern, parentId) {
DestructuringTransformer.prototype.init = function (pattern, parentId) {
if (!t.isArrayExpression(parentId) && !t.isMemberExpression(parentId) && !t.isIdentifier(parentId)) {
var key = this.scope.generateUidBasedOnNode(parentId);
this.nodes.push(this.buildVariableDeclaration(key, parentId));
@@ -217,7 +220,7 @@ exports.ForOfStatement = function (node, parent, scope, file) {
var nodes = [];
var destructuring = new Destructuring({
var destructuring = new DestructuringTransformer({
kind: left.kind,
file: file,
scope: scope,
@@ -235,15 +238,15 @@ exports.ForOfStatement = function (node, parent, scope, file) {
exports.Function = function (node, parent, scope, file) {
var nodes = [];
var hasDestructuring = false;
var hasDestructuringTransformer = false;
node.params = node.params.map(function (pattern, i) {
if (!t.isPattern(pattern)) return pattern;
hasDestructuring = true;
hasDestructuringTransformer = true;
var parentId = scope.generateUidIdentifier("ref");
var destructuring = new Destructuring({
var destructuring = new DestructuringTransformer({
blockHoist: node.params.length - i,
nodes: nodes,
scope: scope,
@@ -255,7 +258,7 @@ exports.Function = function (node, parent, scope, file) {
return parentId;
});
if (!hasDestructuring) return;
if (!hasDestructuringTransformer) return;
t.ensureBlock(node);
@@ -272,7 +275,7 @@ exports.CatchClause = function (node, parent, scope, file) {
var nodes = [];
var destructuring = new Destructuring({
var destructuring = new DestructuringTransformer({
kind: "let",
file: file,
scope: scope,
@@ -298,7 +301,7 @@ exports.ExpressionStatement = function (node, parent, scope, file) {
t.variableDeclarator(ref, expr.right)
]));
var destructuring = new Destructuring({
var destructuring = new DestructuringTransformer({
operator: expr.operator,
file: file,
scope: scope,
@@ -321,7 +324,7 @@ exports.AssignmentExpression = function (node, parent, scope, file) {
var nodes = [];
nodes.push(t.assignmentExpression("=", ref, node.right));
var destructuring = new Destructuring({
var destructuring = new DestructuringTransformer({
operator: node.operator,
file: file,
scope: scope,
@@ -356,7 +359,7 @@ exports.VariableDeclaration = function (node, parent, scope, file) {
var patternId = declar.init;
var pattern = declar.id;
var destructuring = new Destructuring({
var destructuring = new DestructuringTransformer({
nodes: nodes,
scope: scope,
kind: node.kind,
@@ -387,7 +390,7 @@ exports.VariableDeclaration = function (node, parent, scope, file) {
declar = declar || t.variableDeclaration(node.kind, []);
if (!t.isVariableDeclaration(node) && declar.kind !== node.kind) {
throw file.errorWithNode(node, "Cannot use this node within the current parent");
throw file.errorWithNode(node, messages.get("invalidParentForThisNode"));
}
declar.declarations = declar.declarations.concat(node.declarations);

View File

@@ -1,7 +1,8 @@
"use strict";
var util = require("../../../util");
var t = require("../../../types");
var messages = require("../../../messages");
var util = require("../../../util");
var t = require("../../../types");
exports.check = t.isForOfStatement;
@@ -17,7 +18,7 @@ exports.ForOfStatement = function (node, parent, scope, file) {
// inherit comments from the original loop
t.inheritsComments(loop, node);
// ensure that it's a block so we can take all it's statemetns
// ensure that it's a block so we can take all its statements
t.ensureBlock(node);
// add the value declaration to the new loop body
@@ -50,7 +51,7 @@ var loose = function (node, parent, scope, file) {
t.variableDeclarator(left.declarations[0].id, id)
]);
} else {
throw file.errorWithNode(left, "Unknown node type " + left.type + " in ForOfStatement");
throw file.errorWithNode(left, messages.get("unknownForHead", left.type));
}
var loop = util.template("for-of-loose", {
@@ -89,7 +90,7 @@ var spec = function (node, parent, scope, file) {
t.variableDeclarator(left.declarations[0].id, stepValue)
]);
} else {
throw file.errorWithNode(left, "Unknown node type " + left.type + " in ForOfStatement");
throw file.errorWithNode(left, messages.get("unknownForHead", left.type));
}
var loop = util.template("for-of", {

View File

@@ -18,7 +18,7 @@ var iifeVisitor = {
enter: function (node, parent, scope, state) {
if (!t.isReferencedIdentifier(node, parent)) return;
if (!state.scope.hasOwnBinding(node.name)) return;
if (state.scope.bindingEquals(node.name, node)) return;
if (state.scope.bindingIdentifierEquals(node.name, node)) return;
state.iife = true;
this.stop();
@@ -55,7 +55,9 @@ exports.Function = function (node, parent, scope, file) {
var param = node.params[i];
if (!t.isAssignmentPattern(param)) {
lastNonDefaultParam = i + 1;
if (!t.isRestElement(param)) {
lastNonDefaultParam = i + 1;
}
if (!t.isIdentifier(param)) {
scope.traverse(param, iifeVisitor, state);
@@ -71,10 +73,12 @@ exports.Function = function (node, parent, scope, file) {
var left = param.left;
var right = param.right;
node.params[i] = scope.generateUidIdentifier("x");
var placeholder = scope.generateUidIdentifier("x");
placeholder._isDefaultPlaceholder = true;
node.params[i] = placeholder;
if (!state.iife) {
if (t.isIdentifier(right) && scope.hasOwnReference(right.name)) {
if (t.isIdentifier(right) && scope.hasOwnBinding(right.name)) {
state.iife = true;
} else {
scope.traverse(right, iifeVisitor, state);

View File

@@ -60,6 +60,8 @@ exports.Function = function (node, parent, scope) {
node.body.body.unshift(restDeclar);
}
scope.assignTypeGeneric(rest.name, "Array");
var loop = util.template("rest", {
ARGUMENTS: argsId,
ARRAY_KEY: arrKey,

View File

@@ -1,12 +1,12 @@
"use strict";
var contains = require("lodash/collection/contains");
var includes = require("lodash/collection/includes");
var t = require("../../../types");
exports.check = t.isSpreadElement;
var getSpreadLiteral = function (spread, file) {
return file.toArray(spread.argument);
var getSpreadLiteral = function (spread, scope) {
return scope.toArray(spread.argument, true);
};
var hasSpread = function (nodes) {
@@ -18,7 +18,7 @@ var hasSpread = function (nodes) {
return false;
};
var build = function (props, file) {
var build = function (props, scope) {
var nodes = [];
var _props = [];
@@ -33,7 +33,7 @@ var build = function (props, file) {
var prop = props[i];
if (t.isSpreadElement(prop)) {
push();
nodes.push(getSpreadLiteral(prop, file));
nodes.push(getSpreadLiteral(prop, scope));
} else {
_props.push(prop);
}
@@ -44,11 +44,11 @@ var build = function (props, file) {
return nodes;
};
exports.ArrayExpression = function (node, parent, scope, file) {
exports.ArrayExpression = function (node, parent, scope) {
var elements = node.elements;
if (!hasSpread(elements)) return;
var nodes = build(elements, file);
var nodes = build(elements, scope);
var first = nodes.shift();
if (!t.isArrayExpression(first)) {
@@ -59,7 +59,7 @@ exports.ArrayExpression = function (node, parent, scope, file) {
return t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes);
};
exports.CallExpression = function (node, parent, scope, file) {
exports.CallExpression = function (node, parent, scope) {
var args = node.arguments;
if (!hasSpread(args)) return;
@@ -71,7 +71,7 @@ exports.CallExpression = function (node, parent, scope, file) {
if (args.length === 1 && args[0].argument.name === "arguments") {
nodes = [args[0].argument];
} else {
nodes = build(args, file);
nodes = build(args, scope);
}
var first = nodes.shift();
@@ -103,9 +103,9 @@ exports.NewExpression = function (node, parent, scope, file) {
var args = node.arguments;
if (!hasSpread(args)) return;
var nativeType = t.isIdentifier(node.callee) && contains(t.NATIVE_TYPE_NAMES, node.callee.name);
var nativeType = t.isIdentifier(node.callee) && includes(t.NATIVE_TYPE_NAMES, node.callee.name);
var nodes = build(args, file);
var nodes = build(args, scope);
if (nativeType) {
nodes.unshift(t.arrayExpression([t.literal(null)]));

View File

@@ -1,118 +1,359 @@
"use strict";
/*
var t = require("../../../types");
var reduceRight = require("lodash/collection/reduceRight");
var messages = require("../../../messages");
var flatten = require("lodash/array/flatten");
var util = require("../../../util");
var map = require("lodash/collection/map");
var t = require("../../../types");
function transformExpression(node, scope, state) {
if (!node) return;
return (function subTransform(node) {
switch (node.type) {
case "ConditionalExpression":
// any value of ternary operator can be final one
subTransform(node.consequent);
subTransform(node.alternate);
break;
case "LogicalExpression":
// only right expression can be final and so optimized
subTransform(node.right);
break;
case "SequenceExpression":
// only last element of sequence can be optimized
var seq = node.expressions;
subTransform(seq[seq.length - 1]);
break;
case "CallExpression":
var callee = node.callee, thisBinding;
var args = [callee];
// bind `this` to object in member expressions
if (t.isMemberExpression(callee)) {
var object = state.wrapSideEffect(callee.object);
callee.object = object.expr;
thisBinding = object.ref;
}
if (node.arguments.length > 0 || thisBinding) {
args.push(t.arrayExpression(node.arguments));
}
if (thisBinding) {
args.push(thisBinding);
}
node.callee = state.getHelperRef();
node.arguments = args;
break;
}
})(node);
function returnBlock(expr) {
return t.blockStatement([t.returnStatement(expr)]);
}
var functionChildrenVisitor = {
enter: function (node, parent, scope, state) {
if (t.isReturnStatement(node)) {
// prevent entrance by current visitor
this.skip();
// transform return argument into statement if
// it contains tail recursion
transformExpression(node.argument, scope, state);
} else if (t.isFunction(node)) {
// inner function's bodies are irrelevant
this.skip();
} else if (t.isTryStatement(parent)) {
if (node === parent.block) {
// `try`-blocks can't be optimized
this.skip();
} else if (parent.finalizer && node !== parent.finalizer) {
// `catch` clause followed by `finally` can't be optimized
this.skip();
function TailCallTransformer(node, scope, file) {
this.hasTailRecursion = false;
this.needsArguments = false;
this.setsArguments = false;
this.needsThis = false;
this.ownerId = node.id;
this.vars = [];
this.scope = scope;
this.file = file;
this.node = node;
}
TailCallTransformer.prototype.getArgumentsId = function () {
return this.argumentsId = this.argumentsId || this.scope.generateUidIdentifier("arguments");
};
TailCallTransformer.prototype.getThisId = function () {
return this.thisId = this.thisId || this.scope.generateUidIdentifier("this");
};
TailCallTransformer.prototype.getLeftId = function () {
return this.leftId = this.leftId || this.scope.generateUidIdentifier("left");
};
TailCallTransformer.prototype.getFunctionId = function () {
return this.functionId = this.functionId || this.scope.generateUidIdentifier("function");
};
TailCallTransformer.prototype.getParams = function () {
var params = this.params;
if (!params) {
params = this.node.params;
this.paramDecls = [];
for (var i = 0; i < params.length; i++) {
var param = params[i];
if (!param._isDefaultPlaceholder) {
this.paramDecls.push(t.variableDeclarator(
param,
params[i] = this.scope.generateUidIdentifier("x")
));
}
}
}
return this.params = params;
};
var functionVisitor = {
enter: function (node, parent, scope, state) {
// traverse all child nodes of this function and find `arguments` and `this`
scope.traverse(node, functionChildrenVisitor, state);
return this.skip();
}
TailCallTransformer.prototype.hasDeopt = function () {
// check if the ownerId has been reassigned, if it has then it's not safe to
// perform optimisations
var ownerIdInfo = this.scope.getBindingInfo(this.ownerId.name);
return ownerIdInfo && ownerIdInfo.reassigned;
};
exports.FunctionDeclaration =
exports.FunctionExpression = function (node, parent, scope, file) {
var tempId, helperRef;
TailCallTransformer.prototype.run = function () {
var scope = this.scope;
var node = this.node;
var state = {
ownerId: node.id,
getHelperRef: function () {
return helperRef = helperRef || file.addHelper("tail-call");
},
wrapSideEffect: function (node) {
if (t.isIdentifier(node) || t.isLiteral(node)) {
return {expr: node, ref: node};
}
tempId = tempId || scope.generateUidIdentifier("temp");
return {
expr: t.assignmentExpression("=", tempId, node),
ref: tempId
};
}
};
// only tail recursion can be optimized as for now, so we can skip anonymous
// functions entirely
var ownerId = this.ownerId;
if (!ownerId) return;
// traverse the function and look for tail recursion
scope.traverse(node, functionVisitor, state);
scope.traverse(node, firstPass, this);
if (tempId) {
t.ensureBlock(node).body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(tempId)
]));
if (!this.hasTailRecursion) return;
if (this.hasDeopt()) {
this.file.logDeopt(node, messages.get("tailCallReassignmentDeopt"));
return;
}
//
scope.traverse(node, secondPass, this);
if (!this.needsThis || !this.needsArguments) {
scope.traverse(node, thirdPass, this);
}
var body = t.ensureBlock(node).body;
if (this.vars.length > 0) {
var declarations = flatten(map(this.vars, function (decl) {
return decl.declarations;
}, this));
var statement = reduceRight(declarations, function (expr, decl) {
return t.assignmentExpression("=", decl.id, expr);
}, t.identifier("undefined"));
body.unshift(t.expressionStatement(statement));
}
var paramDecls = this.paramDecls;
if (paramDecls.length > 0) {
body.unshift(t.variableDeclaration("var", paramDecls));
}
node.body = util.template("tail-call-body", {
THIS_ID: this.thisId,
ARGUMENTS_ID: this.argumentsId,
FUNCTION_ID: this.getFunctionId(),
BLOCK: node.body
});
var topVars = [];
if (this.needsThis) {
topVars.push(t.variableDeclarator(this.getThisId(), t.thisExpression()));
}
if (this.needsArguments || this.setsArguments) {
var decl = t.variableDeclarator(this.getArgumentsId());
if (this.needsArguments) {
decl.init = t.identifier("arguments");
}
topVars.push(decl);
}
var leftId = this.leftId;
if (leftId) {
topVars.push(t.variableDeclarator(leftId));
}
if (topVars.length > 0) {
node.body.body.unshift(t.variableDeclaration("var", topVars));
}
};
*/
TailCallTransformer.prototype.subTransform = function (node) {
if (!node) return;
var handler = this["subTransform" + node.type];
if (handler) return handler.call(this, node);
};
TailCallTransformer.prototype.subTransformConditionalExpression = function (node) {
var callConsequent = this.subTransform(node.consequent);
var callAlternate = this.subTransform(node.alternate);
if (!callConsequent && !callAlternate) {
return;
}
// if ternary operator had tail recursion in value, convert to optimized if-statement
node.type = "IfStatement";
node.consequent = callConsequent ? t.toBlock(callConsequent) : returnBlock(node.consequent);
if (callAlternate) {
node.alternate = t.isIfStatement(callAlternate) ? callAlternate : t.toBlock(callAlternate);
} else {
node.alternate = returnBlock(node.alternate);
}
return [node];
};
TailCallTransformer.prototype.subTransformLogicalExpression = function (node) {
// only call in right-value of can be optimized
var callRight = this.subTransform(node.right);
if (!callRight) return;
// cache left value as it might have side-effects
var leftId = this.getLeftId();
var testExpr = t.assignmentExpression(
"=",
leftId,
node.left
);
if (node.operator === "&&") {
testExpr = t.unaryExpression("!", testExpr);
}
return [t.ifStatement(testExpr, returnBlock(leftId))].concat(callRight);
};
TailCallTransformer.prototype.subTransformSequenceExpression = function (node) {
var seq = node.expressions;
// only last element can be optimized
var lastCall = this.subTransform(seq[seq.length - 1]);
if (!lastCall) {
return;
}
// remove converted expression from sequence
// and convert to regular expression if needed
if (--seq.length === 1) {
node = seq[0];
}
return [t.expressionStatement(node)].concat(lastCall);
};
TailCallTransformer.prototype.subTransformCallExpression = function (node) {
var callee = node.callee, thisBinding, args;
if (t.isMemberExpression(callee, { computed: false }) && t.isIdentifier(callee.property)) {
switch (callee.property.name) {
case "call":
args = t.arrayExpression(node.arguments.slice(1));
break;
case "apply":
args = node.arguments[1] || t.identifier("undefined");
break;
default:
return;
}
thisBinding = node.arguments[0];
callee = callee.object;
}
// only tail recursion can be optimized as for now
if (!t.isIdentifier(callee) || !this.scope.bindingIdentifierEquals(callee.name, this.ownerId)) {
return;
}
this.hasTailRecursion = true;
if (this.hasDeopt()) return;
var body = [];
if (!t.isThisExpression(thisBinding)) {
body.push(t.expressionStatement(t.assignmentExpression(
"=",
this.getThisId(),
thisBinding || t.identifier("undefined")
)));
}
if (!args) {
args = t.arrayExpression(node.arguments);
}
var argumentsId = this.getArgumentsId();
var params = this.getParams();
body.push(t.expressionStatement(t.assignmentExpression(
"=",
argumentsId,
args
)));
var i, param;
if (t.isArrayExpression(args)) {
var elems = args.elements;
for (i = 0; i < elems.length && i < params.length; i++) {
param = params[i];
var elem = elems[i] || (elems[i] = t.identifier("undefined"));
if (!param._isDefaultPlaceholder) {
elems[i] = t.assignmentExpression("=", param, elem);
}
}
} else {
this.setsArguments = true;
for (i = 0; i < params.length; i++) {
param = params[i];
if (!param._isDefaultPlaceholder) {
body.push(t.expressionStatement(t.assignmentExpression(
"=",
param,
t.memberExpression(argumentsId, t.literal(i), true)
)));
}
}
}
body.push(t.continueStatement(this.getFunctionId()));
return body;
};
// looks for and replaces tail recursion calls
var firstPass = {
enter: function (node, parent, scope, state) {
if (t.isReturnStatement(node)) {
this.skip();
return state.subTransform(node.argument);
} else if (t.isTryStatement(parent)) {
if (node === parent.block) {
this.skip();
} else if (parent.finalizer && node !== parent.finalizer) {
this.skip();
}
} else if (t.isFunction(node)) {
this.skip();
} else if (t.isVariableDeclaration(node)) {
this.skip();
state.vars.push(node);
}
}
};
// hoists up function declarations, replaces `this` and `arguments` and marks
// them as needed
var secondPass = {
enter: function (node, parent, scope, state) {
if (t.isThisExpression(node)) {
state.needsThis = true;
return state.getThisId();
} else if (t.isReferencedIdentifier(node, parent, { name: "arguments" })) {
state.needsArguments = true;
return state.getArgumentsId();
} else if (t.isFunction(node)) {
this.skip();
if (t.isFunctionDeclaration(node)) {
node = t.variableDeclaration("var", [
t.variableDeclarator(node.id, t.toExpression(node))
]);
node._blockHoist = 2;
return node;
}
}
}
};
// optimizes recursion by removing `this` and `arguments` if they aren't used
var thirdPass = {
enter: function (node, parent, scope, state) {
if (!t.isExpressionStatement(node)) return;
var expr = node.expression;
if (!t.isAssignmentExpression(expr)) return;
if (!state.needsThis && expr.left === state.getThisId()) {
this.remove();
} else if (!state.needsArguments && expr.left === state.getArgumentsId() && t.isArrayExpression(expr.right)) {
return map(expr.right.elements, function (elem) {
return t.expressionStatement(elem);
});
}
}
};
exports.Function = function (node, parent, scope, file) {
var tailCall = new TailCallTransformer(node, scope, file);
tailCall.run();
};

View File

@@ -31,7 +31,6 @@ module.exports = {
"es6.objectSuper": require("./es6/object-super"),
"es7.objectRestSpread": require("./es7/object-rest-spread"),
"es7.exponentiationOperator": require("./es7/exponentiation-operator"),
"es6.spread": require("./es6/spread"),
"es6.templateLiterals": require("./es6/template-literals"),
"es5.properties.mutators": require("./es5/properties.mutators"),
@@ -47,11 +46,15 @@ module.exports = {
"es6.constants": require("./es6/constants"),
// needs to be before `es6.parameters.default` as default parameters will destroy the rest param
"es6.parameters.rest": require("./es6/parameters.rest"),
// needs to be after `es6.parameters.rest` as we use `toArray` and avoid turning an already known array into one
"es6.spread": require("./es6/spread"),
// needs to be before `es6.blockScoping` as default parameters have a TDZ
"es6.parameters.default": require("./es6/parameters.default"),
"es6.parameters.rest": require("./es6/parameters.rest"),
// needs to be before `es6.blockScoping` as let variables may be produced
"es6.destructuring": require("./es6/destructuring"),
@@ -62,6 +65,8 @@ module.exports = {
// needs to be after `es6.blockScoping` due to needing `letReferences` set on blocks
"es6.blockScopingTDZ": require("./es6/block-scoping-tdz"),
// needs to be after `es6.parameters.*` and `es6.blockScoping` due to needing pure
// identifiers in parameters and variable declarators
"es6.tailCall": require("./es6/tail-call"),
regenerator: require("./other/regenerator"),

View File

@@ -3,7 +3,8 @@ var t = require("../../../types");
exports.optional = true;
exports.ExpressionStatement = function (node) {
// remove consequenceless expressions such as local variables and literals
// remove consequence-less expressions such as local variables and literals
// note: will remove directives
//
// var foo = true; foo; -> var foo = true;
// "foo"; ->
@@ -33,7 +34,7 @@ exports.IfStatement = {
//
if (t.isLiteral(test) && test.value) {
return alternate;
return consequent;
}
// we can check if a test will be falsy 100% and if so we can inline the
@@ -66,8 +67,7 @@ exports.IfStatement = {
// if (foo) {} else { bar; } -> if (!foo) { bar; }
//
if (t.blockStatement(consequent) && !consequent.body.length &&
t.isBlockStatement(alternate) && alternate.body.length) {
if (t.blockStatement(consequent) && !consequent.body.length && t.isBlockStatement(alternate) && alternate.body.length) {
node.consequent = node.alternate;
node.alternate = null;
node.test = t.unaryExpression("!", test, true);

View File

@@ -6,8 +6,12 @@ var isConsole = t.buildMatchMemberExpression("console", true);
exports.optional = true;
exports.CallExpression = function (node) {
exports.CallExpression = function (node, parent) {
if (isConsole(node.callee)) {
this.remove();
if (t.isExpressionStatement(parent)) {
this.parentPath.remove();
} else {
this.remove();
}
}
};

View File

@@ -2,10 +2,8 @@
exports.optional = true;
exports.Scope = function () {
// todo: get all binding identifiers, generate compact names
// that wont collide and then call the remap identifier helper
// this transformer **has** to be ran last as it will absolutley
// destroy the scope tree
exports.Scopable = function () {
//for (var name in scope.bindings) {
// scope.rename(name, scope.generateUidIdentifier("a").name);
//}
};

View File

@@ -4,7 +4,7 @@ var util = require("../../../util");
var core = require("core-js/library");
var t = require("../../../types");
var has = require("lodash/object/has");
var contains = require("lodash/collection/contains");
var includes = require("lodash/collection/includes");
var coreHas = function (node) {
return node.name !== "_" && has(core, node.name);
@@ -30,11 +30,11 @@ var astVisitor = {
if (!t.isReferenced(obj, node)) return;
if (!node.computed && coreHas(obj) && has(core[obj.name], prop.name) && !scope.getBinding(obj.name)) {
if (!node.computed && coreHas(obj) && has(core[obj.name], prop.name) && !scope.getBindingIdentifier(obj.name)) {
this.skip();
return t.prependToMemberExpression(node, file.get("coreIdentifier"));
}
} else if (t.isReferencedIdentifier(node, parent) && !t.isMemberExpression(parent) && contains(ALIASABLE_CONSTRUCTORS, node.name) && !scope.getBinding(node.name)) {
} else if (t.isReferencedIdentifier(node, parent) && !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)) {

View File

@@ -1,7 +1,8 @@
"use strict";
var build = require("../../helpers/build-conditional-assignment-operator-transformer");
var t = require("../../../types");
var messages = require("../../../messages");
var build = require("../../helpers/build-conditional-assignment-operator-transformer");
var t = require("../../../types");
exports.playground = true;
@@ -11,7 +12,7 @@ build(exports, {
if (is) {
var left = node.left;
if (!t.isMemberExpression(left) && !t.isIdentifier(left)) {
throw file.errorWithNode(left, "Expected type MemeberExpression or Identifier");
throw file.errorWithNode(left, messages.get("expectedMemberExpressionOrIdentifier"));
}
return true;
}

View File

@@ -26,7 +26,7 @@ exports.BindMemberExpression = function (node, parent, scope) {
}
};
exports.BindFunctionExpression = function (node, parent, scope, file) {
exports.BindFunctionExpression = function (node, parent, scope) {
var buildCall = function (args) {
var param = scope.generateUidIdentifier("val");
return t.functionExpression(null, [param], t.blockStatement([
@@ -34,7 +34,7 @@ exports.BindFunctionExpression = function (node, parent, scope, file) {
]));
};
var temp = scope.generateTemp(file, "args");
var temp = scope.generateTemp("args");
return t.sequenceExpression([
t.assignmentExpression("=", temp, t.arrayExpression(node.arguments)),

View File

@@ -1,6 +1,7 @@
"use strict";
var t = require("../../../types");
var messages = require("../../../messages");
var t = require("../../../types");
exports.check = t.isFor;
@@ -9,6 +10,6 @@ exports.ForOfStatement = function (node, parent, scope, file) {
var left = node.left;
if (t.isVariableDeclaration(left)) {
var declar = left.declarations[0];
if (declar.init) throw file.errorWithNode(declar, "No assignments allowed in for-in/of head");
if (declar.init) throw file.errorWithNode(declar, messages.get("noAssignmentsInForHead"));
}
};

View File

@@ -1,5 +1,7 @@
"use strict";
var messages = require("../../../messages");
exports.check = function (node) {
return node.kind === "set";
};
@@ -7,6 +9,6 @@ exports.check = function (node) {
exports.MethodDefinition =
exports.Property = function (node, parent, scope, file) {
if (node.kind === "set" && node.value.params.length !== 1) {
throw file.errorWithNode(node.value, "Setters must have only one parameter");
throw file.errorWithNode(node.value, messages.get("settersInvalidParamLength"));
}
};

View File

@@ -1,6 +1,7 @@
"use strict";
var levenshtein = require("../../../helpers/levenshtein");
var messages = require("../../../messages");
var t = require("../../../types");
exports.optional = true;
@@ -9,8 +10,6 @@ exports.Identifier = function (node, parent, scope, file) {
if (!t.isReferenced(node, parent)) return;
if (scope.hasBinding(node.name)) return;
var msg = "Reference to undeclared variable";
// get the closest declaration to offer as a suggestion
// the variable name may have just been mistyped
@@ -28,8 +27,11 @@ exports.Identifier = function (node, parent, scope, file) {
shortest = distance;
}
var msg;
if (closest) {
msg += " - Did you mean " + closest + "?";
msg = messages.get("undeclaredVariableSuggestion", node.name, closest);
} else {
msg = messages.get("undeclaredVariable", node.name);
}
//

View File

@@ -1,7 +1,5 @@
"use strict";
/* jshint maxparams:7 */
module.exports = TraversalContext;
var TraversalPath = require("./path");

View File

@@ -3,7 +3,7 @@
module.exports = traverse;
var TraversalContext = require("./context");
var contains = require("lodash/collection/contains");
var includes = require("lodash/collection/includes");
var t = require("../types");
function traverse(parent, opts, scope, state) {
@@ -102,7 +102,7 @@ function hasBlacklistedType(node, parent, scope, state) {
traverse.hasType = function (tree, scope, type, blacklistTypes) {
// the node we're searching in is blacklisted
if (contains(blacklistTypes, tree.type)) return false;
if (includes(blacklistTypes, tree.type)) return false;
// the type we're looking for is the same as the passed node
if (tree.type === type) return true;

View File

@@ -5,7 +5,7 @@ module.exports = TraversalPath;
/* jshint maxparams:7 */
var traverse = require("./index");
var contains = require("lodash/collection/contains");
var includes = require("lodash/collection/includes");
var Scope = require("./scope");
var t = require("../types");
@@ -49,7 +49,7 @@ TraversalPath.getScope = function (node, parent, scope) {
var ourScope = scope;
// we're entering a new scope so let's construct it!
if (t.isScope(node)) {
if (t.isScope(node, parent)) {
ourScope = new Scope(node, parent, scope);
}
@@ -96,7 +96,7 @@ TraversalPath.prototype.replaceNode = function (replacement) {
// we're replacing a statement or block node with an array of statements so we better
// ensure that it's a block
if (isArray) {
if (contains(t.STATEMENT_OR_BLOCK_KEYS, this.key) && !t.isBlockStatement(this.obj)) {
if (includes(t.STATEMENT_OR_BLOCK_KEYS, this.key) && !t.isBlockStatement(this.obj)) {
t.ensureBlock(this.obj, this.key);
}

View File

@@ -2,15 +2,15 @@
module.exports = Scope;
var contains = require("lodash/collection/contains");
var includes = require("lodash/collection/includes");
var traverse = require("./index");
var defaults = require("lodash/object/defaults");
var messages = require("../messages");
var globals = require("globals");
var flatten = require("lodash/array/flatten");
var extend = require("lodash/object/extend");
var object = require("../helpers/object");
var each = require("lodash/collection/each");
var has = require("lodash/object/has");
var t = require("../types");
/**
@@ -50,12 +50,11 @@ Scope.prototype.traverse = function (node, opts, state) {
/**
* Description
*
* @param {File} file
* @param {String} [name="temp"]
*/
Scope.prototype.generateTemp = function (file, name) {
var id = file.generateUidIdentifier(name || "temp", this);
Scope.prototype.generateTemp = function (name) {
var id = this.generateUidIdentifier(name || "temp");
this.push({
key: id.name,
id: id
@@ -70,7 +69,33 @@ Scope.prototype.generateTemp = function (file, name) {
*/
Scope.prototype.generateUidIdentifier = function (name) {
return this.file.generateUidIdentifier(name, this);
var id = t.identifier(this.generateUid(name));
this.getFunctionParent().registerBinding("uid", id);
return id;
};
/**
* Description
*
* @param {String} name
*/
Scope.prototype.generateUid = function (name) {
name = t.toIdentifier(name).replace(/^_+/, "");
var uid;
var i = 0;
do {
uid = this._generateUid(name, i);
i++;
} while (this.hasBinding(uid) || this.hasGlobal(uid));
return uid;
};
Scope.prototype._generateUid = function (name, i) {
var id = name;
if (i > 1) id += i;
return "_" + id;
};
/*
@@ -111,7 +136,7 @@ Scope.prototype.generateUidBasedOnNode = function (parent) {
var id = parts.join("$");
id = id.replace(/^_/, "") || "ref";
return this.file.generateUidIdentifier(id, this);
return this.generateUidIdentifier(id);
};
/**
@@ -134,12 +159,50 @@ Scope.prototype.generateTempBasedOnNode = function (node) {
return id;
};
Scope.prototype.checkBlockScopedCollisions = function (key, id) {
if (this.declarationKinds["let"][key] || this.declarationKinds["const"][key]) {
throw this.file.errorWithNode(id, "Duplicate declaration " + key, TypeError);
Scope.prototype.checkBlockScopedCollisions = function (kind, name, id) {
var local = this.getOwnBindingInfo(name);
if (!local) return;
if (kind === "param") return;
if (kind === "hoisted" && local.kind === "let") return;
if (local.kind === "let" || local.kind === "const" || local.kind === "module") {
throw this.file.errorWithNode(id, messages.get("scopeDuplicateDeclaration", name), TypeError);
}
};
Scope.prototype.rename = function (oldName, newName) {
newName = newName || this.generateUidIdentifier(oldName).name;
var info = this.getBindingInfo(oldName);
if (!info) return;
var binding = info.identifier;
var scope = info.scope;
scope.traverse(scope.block, {
enter: function (node, parent, scope) {
if (t.isReferencedIdentifier(node, parent) && node.name === oldName) {
node.name = newName;
} else if (t.isDeclaration(node)) {
var ids = t.getBindingIdentifiers(node);
for (var name in ids) {
if (name === oldName) ids[name].name = newName;
}
} else if (t.isScope(node, parent)) {
if (!scope.bindingIdentifierEquals(oldName, binding)) {
this.skip();
}
}
}
});
this.clearOwnBinding(oldName);
scope.bindings[newName] = info;
binding.name = newName;
};
Scope.prototype.inferType = function (node) {
var target;
@@ -147,24 +210,56 @@ Scope.prototype.inferType = function (node) {
target = node.init;
}
if (t.isLiteral(target) || t.isArrayExpression(target) || t.isObjectExpression(target)) {
// todo: possibly call some helper that will resolve these to a flow type annotation
if (t.isArrayExpression(target)) {
return t.genericTypeAnnotation(t.identifier("Array"));
}
if (t.isCallExpression(target)) {
// todo: resolve this to a return type
if (t.isObjectExpression(target)) {
return;
}
if (t.isMemberExpression(target)) {
// todo: crawl this and find the correct type, bail on anything that we cannot possibly be 100% confident on
if (t.isLiteral(target)) {
return;
}
if (t.isCallExpression(target) && t.isIdentifier(target.callee)) {
var funcInfo = this.getBindingInfo(target.callee.name);
if (funcInfo) {
var funcNode = funcInfo.node;
return !funcInfo.reassigned && t.isFunction(funcNode) && node.returnType;
}
}
if (t.isIdentifier(target)) {
return this.getType(target.name);
return;
}
};
Scope.prototype.registerType = function (key, id, node) {
Scope.prototype.isTypeGeneric = function (name, genericName) {
var info = this.getBindingInfo(name);
if (!info) return false;
var type = info.typeAnnotation;
return t.isGenericTypeAnnotation(type) && t.isIdentifier(type.id, { name: genericName });
};
Scope.prototype.assignTypeGeneric = function (name, type) {
this.assignType(name, t.genericTypeAnnotation(t.identifier(type)));
};
Scope.prototype.assignType = function (name, type) {
var info = this.getBindingInfo(name);
if (!info) return;
info.identifier.typeAnnotation = info.typeAnnotation = type;
};
Scope.prototype.getTypeAnnotation = function (name, id, node) {
var info = {
annotation: null,
inferred: false
};
var type;
if (id.typeAnnotation) {
@@ -172,43 +267,107 @@ Scope.prototype.registerType = function (key, id, node) {
}
if (!type) {
info.inferred = true;
type = this.inferType(node);
}
if (type) {
if (t.isTypeAnnotation(type)) type = type.typeAnnotation;
this.types[key] = type;
info.annotation = type;
}
return info;
};
Scope.prototype.toArray = function (node, i) {
var file = this.file;
if (t.isIdentifier(node) && this.isTypeGeneric(node.name, "Array")) {
return node;
}
if (t.isArrayExpression(node)) {
return node;
}
if (t.isIdentifier(node, { name: "arguments" })) {
return t.callExpression(t.memberExpression(file.addHelper("slice"), t.identifier("call")), [node]);
}
var helperName = "to-array";
var args = [node];
if (i === true) {
helperName = "to-consumable-array";
} else if (i) {
args.push(t.literal(i));
helperName = "sliced-to-array";
}
return t.callExpression(file.addHelper(helperName), args);
};
Scope.prototype.clearOwnBinding = function (name) {
delete this.bindings[name];
};
Scope.prototype.registerDeclaration = function (node) {
if (t.isFunctionDeclaration(node)) {
this.registerBinding("hoisted", node);
} else if (t.isVariableDeclaration(node)) {
for (var i = 0; i < node.declarations.length; i++) {
this.registerBinding(node.kind, node.declarations[i]);
}
} else if (t.isClassDeclaration(node)) {
this.registerBinding("let", node);
} else if (t.isImportDeclaration(node) || t.isExportDeclaration(node)) {
this.registerBinding("module", node);
} else {
this.registerBinding("unknown", node);
}
};
Scope.prototype.register = function (node, reference, kind) {
if (t.isVariableDeclaration(node)) {
return this.registerVariableDeclaration(node);
Scope.prototype.registerBindingReassignment = function (node) {
var ids = t.getBindingIdentifiers(node);
for (var name in ids) {
var info = this.getBindingInfo(name);
if (info) {
info.reassigned = true;
if (info.typeAnnotationInferred) {
// destroy the inferred typeAnnotation
info.typeAnnotation = null;
}
}
}
};
Scope.prototype.registerBinding = function (kind, node) {
if (!kind) throw new ReferenceError("no `kind`");
var ids = t.getBindingIdentifiers(node);
extend(this.references, ids);
for (var name in ids) {
var id = ids[name];
if (reference) return;
this.checkBlockScopedCollisions(kind, name, id);
for (var key in ids) {
var id = ids[key];
var typeInfo = this.getTypeAnnotation(name, id, node);
this.checkBlockScopedCollisions(key, id);
this.registerType(key, id, node);
this.bindings[key] = id;
this.bindings[name] = {
typeAnnotationInferred: typeInfo.inferred,
typeAnnotation: typeInfo.annotation,
reassigned: false,
identifier: id,
scope: this,
node: node,
kind: kind
};
}
var kinds = this.declarationKinds[kind];
if (kinds) extend(kinds, ids);
};
Scope.prototype.registerVariableDeclaration = function (declar) {
var declars = declar.declarations;
for (var i = 0; i < declars.length; i++) {
this.register(declars[i], false, declar.kind);
this.registerBinding(declars[i], declar.kind);
}
};
@@ -217,7 +376,7 @@ var functionVariableVisitor = {
if (t.isFor(node)) {
each(t.FOR_INIT_KEYS, function (key) {
var declar = node[key];
if (t.isVar(declar)) state.scope.register(declar);
if (t.isVar(declar)) state.scope.registerBinding("var", declar);
});
}
@@ -235,30 +394,47 @@ var functionVariableVisitor = {
if (t.isExportDeclaration(node) && t.isDeclaration(node.declaration)) return;
// we've ran into a declaration!
if (t.isDeclaration(node)) state.scope.register(node);
if (t.isDeclaration(node)) state.scope.registerDeclaration(node);
}
};
Scope.prototype.addGlobal = function (node) {
this.globals[node.name] = node;
};
Scope.prototype.hasGlobal = function (name) {
var scope = this;
do {
if (scope.globals[name]) return true;
} while (scope = scope.parent);
return false;
};
var programReferenceVisitor = {
enter: function (node, parent, scope, state) {
if (t.isReferencedIdentifier(node, parent) && !scope.hasReference(node.name)) {
state.register(node, true);
if (t.isReferencedIdentifier(node, parent) && !scope.hasBinding(node.name)) {
state.addGlobal(node);
} else if (t.isLabeledStatement(node)) {
state.addGlobal(node);
} else if (t.isAssignmentExpression(node) || t.isUpdateExpression(node)) {
scope.registerBindingReassignment(node);
}
}
};
var blockVariableVisitor = {
enter: function (node, parent, scope, state) {
if (t.isBlockScoped(node)) {
state.register(node);
} else if (t.isScope(node)) {
if (t.isFunctionDeclaration(node) || t.isBlockScoped(node)) {
state.registerDeclaration(node);
} else if (t.isScope(node, parent)) {
this.skip();
}
}
};
Scope.prototype.crawl = function () {
var parent = this.parent;
var block = this.block;
var i;
@@ -271,34 +447,18 @@ Scope.prototype.crawl = function () {
}
info = block._scopeInfo = {
declarationKinds: {
"const": object(),
"var": object(),
"let": object()
},
references: object(),
bindings: object(),
types: object(),
bindings: object(),
globals: object()
};
extend(this, info);
//
if (parent && t.isBlockStatement(block)) {
if (t.isLoop(parent.block, { body: block }) ||
t.isFunction(parent.block, { body: block })) {
return;
}
}
// ForStatement - left, init
if (t.isLoop(block)) {
for (i = 0; i < t.FOR_INIT_KEYS.length; i++) {
var node = block[t.FOR_INIT_KEYS[i]];
if (t.isBlockScoped(node)) this.register(node, false, true);
if (t.isBlockScoped(node)) this.registerBinding("let", node);
}
if (t.isBlockStatement(block.body)) {
@@ -310,7 +470,7 @@ Scope.prototype.crawl = function () {
if (t.isFunctionExpression(block) && block.id) {
if (!t.isProperty(this.parentBlock, { method: true })) {
this.register(block.id);
this.registerBinding("var", block.id);
}
}
@@ -318,7 +478,7 @@ Scope.prototype.crawl = function () {
if (t.isFunction(block)) {
for (i = 0; i < block.params.length; i++) {
this.register(block.params[i]);
this.registerBinding("param", block.params[i]);
}
this.traverse(block.body, blockVariableVisitor, this);
}
@@ -332,13 +492,13 @@ Scope.prototype.crawl = function () {
// CatchClause - param
if (t.isCatchClause(block)) {
this.register(block.param);
this.registerBinding("let", block.param);
}
// ComprehensionExpression - blocks
if (t.isComprehensionExpression(block)) {
this.register(block);
this.registerBinding("let", block);
}
// Program, Function - var variables
@@ -383,26 +543,6 @@ Scope.prototype.push = function (opts) {
}
};
/**
* Walk up the scope tree until we hit a `Function` and then
* push our `node` to it's references.
*
* @param {String} kind
* @param {Object} node
*/
Scope.prototype.addDeclarationToFunctionScope = function (kind, node) {
var scope = this.getFunctionParent();
var ids = t.getBindingIdentifiers(node);
extend(scope.bindings, ids);
extend(scope.references, ids);
// this ignores the duplicate declaration logic specified in `getInfo`
// but it doesn't really matter
extend(scope.declarationKinds[kind], ids);
};
/**
* Walk up the scope tree until we hit either a Function or reach the
* very top and hit Program.
@@ -441,72 +581,66 @@ Scope.prototype.getAllBindings = function () {
* @returns {Object}
*/
Scope.prototype.getAllDeclarationsOfKind = function (kind) {
Scope.prototype.getAllBindingsOfKind = function (kind) {
var ids = object();
var scope = this;
do {
defaults(ids, scope.declarationKinds[kind]);
for (var name in scope.bindings) {
var binding = scope.bindings[name];
if (binding.kind === kind) ids[name] = binding;
}
scope = scope.parent;
} while (scope);
return ids;
};
//
// misc
Scope.prototype.get = function (id, type) {
return id && (this.getOwn(id, type) || this.parentGet(id, type));
Scope.prototype.bindingIdentifierEquals = function (name, node) {
return this.getBindingIdentifier(name) === node;
};
Scope.prototype.getOwn = function (id, type) {
var refs = {
reference: this.references,
binding: this.bindings,
type: this.types
}[type];
return refs && has(refs, id) && refs[id];
// get
Scope.prototype.getBindingInfo = function (name) {
var scope = this;
do {
var binding = scope.getOwnBindingInfo(name);
if (binding) return binding;
} while (scope = scope.parent);
};
Scope.prototype.parentGet = function (id, type) {
return this.parent && this.parent.get(id, type);
Scope.prototype.getOwnBindingInfo = function (name) {
return this.bindings[name];
};
Scope.prototype.has = function (id, type) {
if (!id) return false;
if (this.hasOwn(id, type)) return true;
if (this.parentHas(id, type)) return true;
if (contains(Scope.defaultDeclarations, id)) return true;
Scope.prototype.getBindingIdentifier = function (name) {
var info = this.getBindingInfo(name);
return info && info.identifier;
};
Scope.prototype.getOwnBindingIdentifier = function (name) {
var binding = this.bindings[name];
return binding && binding.identifier;
};
// has
Scope.prototype.hasOwnBinding = function (name) {
return !!this.getOwnBindingInfo(name);
};
Scope.prototype.hasBinding = function (name) {
if (!name) return false;
if (this.hasOwnBinding(name)) return true;
if (this.parentHasBinding(name)) return true;
if (includes(Scope.defaultDeclarations, name)) return true;
return false;
};
Scope.prototype.hasOwn = function (id, type) {
return !!this.getOwn(id, type);
Scope.prototype.parentHasBinding = function (name) {
return this.parent && this.parent.hasBinding(name);
};
Scope.prototype.parentHas = function (id, type) {
return this.parent && this.parent.has(id, type);
};
each({
reference: "Reference",
binding: "Binding",
type: "Type"
}, function (title, type) {
Scope.prototype[type + "Equals"] = function (id, node) {
return this["get" + title](id) === node;
};
each([
"get",
"has",
"getOwn",
"hasOwn",
"parentGet",
"parentHas",
], function (methodName) {
Scope.prototype[methodName + title] = function (id) {
return this[methodName](id, type);
};
});
});

View File

@@ -3,13 +3,13 @@
"BreakStatement": ["Statement"],
"ContinueStatement": ["Statement"],
"DebuggerStatement": ["Statement"],
"DoWhileStatement": ["Statement", "Loop", "While", "Scope"],
"DoWhileStatement": ["Statement", "Loop", "While", "Scopable"],
"IfStatement": ["Statement"],
"ReturnStatement": ["Statement"],
"SwitchStatement": ["Statement"],
"ThrowStatement": ["Statement"],
"TryStatement": ["Statement"],
"WhileStatement": ["Statement", "Loop", "While", "Scope"],
"WhileStatement": ["Statement", "Loop", "While", "Scopable"],
"WithStatement": ["Statement"],
"EmptyStatement": ["Statement"],
"LabeledStatement": ["Statement"],
@@ -18,13 +18,16 @@
"ImportDeclaration": ["Statement", "Declaration"],
"PrivateDeclaration": ["Statement", "Declaration"],
"ArrowFunctionExpression": ["Scope", "Function", "Expression"],
"FunctionDeclaration": ["Statement", "Declaration", "Scope", "Function"],
"FunctionExpression": ["Scope", "Function", "Expression"],
"ArrowFunctionExpression": ["Scopable", "Function", "Expression"],
"FunctionDeclaration": ["Statement", "Declaration", "Scopable", "Function"],
"FunctionExpression": ["Scopable", "Function", "Expression"],
"BlockStatement": ["Statement", "Scope"],
"Program": ["Scope"],
"CatchClause": ["Scope"],
"ImportSpecifier": ["ModuleSpecifier"],
"ExportSpecifier": ["ModuleSpecifier"],
"BlockStatement": ["Statement", "Scopable"],
"Program": ["Scopable"],
"CatchClause": ["Scopable"],
"LogicalExpression": ["Binary", "Expression"],
"BinaryExpression": ["Binary", "Expression"],
@@ -36,9 +39,9 @@
"ClassDeclaration": ["Statement", "Declaration", "Class"],
"ClassExpression": ["Class", "Expression"],
"ForOfStatement": ["Statement", "For", "Scope", "Loop"],
"ForInStatement": ["Statement", "For", "Scope", "Loop"],
"ForStatement": ["Statement", "For", "Scope", "Loop"],
"ForOfStatement": ["Statement", "For", "Scopable", "Loop"],
"ForInStatement": ["Statement", "For", "Scopable", "Loop"],
"ForStatement": ["Statement", "For", "Scopable", "Loop"],
"ObjectPattern": ["Pattern"],
"ArrayPattern": ["Pattern"],
@@ -53,7 +56,7 @@
"BindFunctionExpression": ["Expression"],
"BindMemberExpression": ["Expression"],
"CallExpression": ["Expression"],
"ComprehensionExpression": ["Expression", "Scope"],
"ComprehensionExpression": ["Expression", "Scopable"],
"ConditionalExpression": ["Expression"],
"Identifier": ["Expression"],
"Literal": ["Expression"],

View File

@@ -1,33 +1,168 @@
{
"ArrayExpression": ["elements"],
"ArrowFunctionExpression": ["params", "body"],
"AssignmentExpression": ["operator", "left", "right"],
"BinaryExpression": ["operator", "left", "right"],
"BlockStatement": ["body"],
"CallExpression": ["callee", "arguments"],
"ConditionalExpression": ["test", "consequent", "alternate"],
"ExpressionStatement": ["expression"],
"File": ["program", "comments", "tokens"],
"FunctionExpression": ["id", "params", "body", "generator"],
"FunctionDeclaration": ["id", "params", "body", "generator"],
"Identifier": ["name"],
"IfStatement": ["test", "consequent", "alternate"],
"ImportDeclaration": ["specifiers", "source"],
"ImportSpecifier": ["id", "name"],
"Literal": ["value"],
"LogicalExpression": ["operator", "left", "right"],
"MemberExpression": ["object", "property", "computed"],
"MethodDefinition": ["key", "value", "computed", "kind"],
"NewExpression": ["callee", "arguments"],
"ObjectExpression": ["properties"],
"Program": ["body"],
"Property": ["kind", "key", "value", "computed"],
"ReturnStatement": ["argument"],
"SequenceExpression": ["expressions"],
"ThrowExpression": ["argument"],
"UnaryExpression": ["operator", "argument", "prefix"],
"VariableDeclaration": ["kind", "declarations"],
"VariableDeclarator": ["id", "init"],
"WithStatement": ["object", "body"],
"YieldExpression": ["argument", "delegate"]
"ArrayExpression": {
"elements": null
},
"ArrowFunctionExpression": {
"params": null,
"body": null
},
"AssignmentExpression": {
"operator": null,
"left": null,
"right": null
},
"BinaryExpression": {
"operator": null,
"left": null,
"right": null
},
"BlockStatement": {
"body": null
},
"CallExpression": {
"callee": null,
"arguments": null
},
"ConditionalExpression": {
"test": null,
"consequent": null,
"alternate": null
},
"ExpressionStatement": {
"expression": null
},
"File": {
"program": null,
"comments": null,
"tokens": null
},
"FunctionExpression": {
"id": null,
"params": null,
"body": null,
"generator": false
},
"FunctionDeclaration": {
"id": null,
"params": null,
"body": null,
"generator": false
},
"GenericTypeAnnotation": {
"id": null,
"typeParameters": null
},
"Identifier": {
"name": null
},
"IfStatement": {
"test": null,
"consequent": null,
"alternate": null
},
"ImportDeclaration": {
"specifiers": null,
"source": null
},
"ImportSpecifier": {
"id": null,
"name": null
},
"Literal": {
"value": null
},
"LogicalExpression": {
"operator": null,
"left": null,
"right": null
},
"MemberExpression": {
"object": null,
"property": null,
"computed": false
},
"MethodDefinition": {
"key": null,
"value": null,
"computed": false,
"static": false,
"kind": null
},
"NewExpression": {
"callee": null,
"arguments": null
},
"ObjectExpression": {
"properties": null
},
"Program": {
"body": null
},
"Property": {
"kind": null,
"key": null,
"value": null,
"computed": false
},
"ReturnStatement": {
"argument": null
},
"SequenceExpression": {
"expressions": null
},
"ThrowExpression": {
"argument": null
},
"UnaryExpression": {
"operator": null,
"argument": null,
"prefix": null
},
"VariableDeclaration": {
"kind": null,
"declarations": null
},
"VariableDeclarator": {
"id": null,
"init": null
},
"WithStatement": {
"object": null,
"body": null
},
"YieldExpression": {
"argument": null,
"delegate": null
}
}

View File

@@ -1,12 +1,10 @@
"use strict";
var toFastProperties = require("../helpers/to-fast-properties");
var defaults = require("lodash/object/defaults");
var isString = require("lodash/lang/isString");
var compact = require("lodash/array/compact");
var esutils = require("esutils");
var object = require("../helpers/object");
var Node = require("./node");
var each = require("lodash/collection/each");
var uniq = require("lodash/array/uniq");
@@ -72,9 +70,9 @@ each(t.FLIPPED_ALIAS_KEYS, function (types, type) {
*/
t.is = function (type, node, opts, skipAliasCheck) {
if (!node) return;
if (!node) return false;
var typeMatches = (type === node.type);
var typeMatches = type === node.type;
if (!typeMatches && !skipAliasCheck) {
var aliases = t.FLIPPED_ALIAS_KEYS[type];
@@ -97,17 +95,32 @@ t.is = function (type, node, opts, skipAliasCheck) {
//
t.BUILDER_KEYS = defaults(require("./builder-keys"), t.VISITOR_KEYS);
t.BUILDER_KEYS = require("./builder-keys");
each(t.VISITOR_KEYS, function (keys, type) {
if (t.BUILDER_KEYS[type]) return;
var defs = {};
each(keys, function (key) {
defs[key] = null;
});
t.BUILDER_KEYS[type] = defs;
});
each(t.BUILDER_KEYS, function (keys, type) {
t[type[0].toLowerCase() + type.slice(1)] = function () {
var args = arguments;
var node = new Node;
var node = {};
node.start = null;
node.type = type;
each(keys, function (key, i) {
node[key] = args[i];
});
var i = 0;
for (var key in keys) {
var arg = arguments[i++];
if (arg === undefined) arg = keys[key];
node[key] = arg;
}
return node;
};
});
@@ -305,7 +318,7 @@ t.isReferenced = function (node, parent) {
// no: [NODE = foo] = [];
// yes: [foo = NODE] = [];
if (t.isAssignmentPattern(parent)) {
return parent.right !== node;
return parent.right === node;
}
// no: [NODE] = [];
@@ -335,8 +348,8 @@ t.isReferenced = function (node, parent) {
/**
* Check if the input `node` is an `Identifier` and `isReferenced`.
*
* @param {Object} node
* @param {Object} parent
* @param {Node} node
* @parma {Node} parent
* @returns {Boolean}
*/
@@ -390,7 +403,7 @@ t.toIdentifier = function (name) {
* Description
*
* @param {Object} node
* @param {String} key
* @param {String=} key
*/
t.ensureBlock = function (node, key) {
@@ -405,7 +418,7 @@ t.ensureBlock = function (node, key) {
* For example, given the match `React.createClass` it would match the
* parsed nodes of `React.createClass` and `React["createClass"]`.
*
* @param {String} match Dot delimetered string
* @param {String} match Dot-delimited string
* @param {Boolean} [allowPartial] Allow a partial match
* @returns {Function}
*/
@@ -423,6 +436,10 @@ t.buildMatchMemberExpression = function (match, allowPartial) {
while (search.length) {
var node = search.shift();
if (allowPartial && i === parts.length) {
return true;
}
if (t.isIdentifier(node)) {
// this part doesn't match
if (parts[i] !== node.name) return false;
@@ -445,11 +462,7 @@ t.buildMatchMemberExpression = function (match, allowPartial) {
// too many parts
if (++i > parts.length) {
if (allowPartial) {
return true;
} else {
return false;
}
return false;
}
}
@@ -577,6 +590,8 @@ t.getBindingIdentifiers = function (node) {
if (t.isIdentifier(id)) {
ids[id.name] = id;
} else if (t.isImportSpecifier(id)) {
search.push(id.name || id.id);
} else if (t.isExportDeclaration(id)) {
if (t.isDeclaration(node.declaration)) {
search.push(node.declaration);
@@ -595,15 +610,14 @@ t.getBindingIdentifiers = function (node) {
t.getBindingIdentifiers.keys = {
AssignmentExpression: ["left"],
ImportBatchSpecifier: ["name"],
ImportSpecifier: ["name", "id"],
ExportSpecifier: ["name", "id"],
VariableDeclarator: ["id"],
FunctionDeclaration: ["id"],
ClassDeclaration: ["id"],
MemeberExpression: ["object"],
MemberExpression: ["object"],
SpreadElement: ["argument"],
RestElement: ["argument"],
UpdateExpression: ["argument"],
SpreadProperty: ["argument"],
Property: ["value"],
ComprehensionBlock: ["left"],
AssignmentPattern: ["left"],
@@ -765,5 +779,27 @@ t.isSpecifierDefault = function (specifier) {
return specifier.default || t.isIdentifier(specifier.id) && specifier.id.name === "default";
};
/**
* Description
*
* @param {Node} node
* @param {Node} parent
* @returns {Boolean}
*/
t.isScope = function (node, parent) {
if (t.isBlockStatement(node)) {
if (t.isLoop(parent.block, { body: node })) {
return false;
}
if (t.isFunction(parent.block, { body: node })) {
return false;
}
}
return t.isScopable(node);
};
toFastProperties(t);
toFastProperties(t.VISITOR_KEYS);

View File

@@ -1,12 +0,0 @@
"use strict";
module.exports = Node;
var acorn = require("acorn-6to5");
var oldNode = acorn.Node;
acorn.Node = Node;
function Node() {
oldNode.apply(this);
}

View File

@@ -73,7 +73,7 @@
"AnyTypeAnnotation": [],
"ArrayTypeAnnotation": [],
"BooleanTypeAnnotation": [],
"ClassProperty": ["key"],
"ClassProperty": ["key", "value"],
"DeclareClass": [],
"DeclareFunction": [],
"DeclareModule": [],

View File

@@ -30,6 +30,10 @@ exports.canCompile = function (filename, altExts) {
exports.canCompile.EXTENSIONS = [".js", ".jsx", ".es6", ".es"];
exports.normalisePathSeparator = function (filename) {
return filename.replace(/\\/g, "/");
};
exports.isInteger = function (i) {
return isNumber(i) && i % 1 === 0;
};
@@ -80,7 +84,11 @@ exports.sourceMapToComment = function (map) {
var templateVisitor = {
enter: function (node, parent, scope, nodes) {
if (t.isExpressionStatement(node)) {
node = node.expression;
}
if (t.isIdentifier(node) && has(nodes, node.name)) {
this.skip();
return nodes[node.name];
}
}

View File

@@ -1,7 +1,7 @@
{
"name": "6to5",
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
"version": "3.5.2",
"version": "3.6.1",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://6to5.org/",
"repository": "6to5/6to5",
@@ -33,12 +33,12 @@
"test": "make test"
},
"dependencies": {
"acorn-6to5": "0.11.1-28",
"acorn-6to5": "0.11.1-30",
"ast-types": "~0.6.1",
"chalk": "^0.5.1",
"chokidar": "0.12.6",
"commander": "2.6.0",
"core-js": "^0.4.9",
"core-js": "^0.5.2",
"debug": "^2.1.1",
"detect-indent": "3.0.0",
"estraverse": "1.9.1",
@@ -49,7 +49,7 @@
"lodash": "3.0.0",
"output-file-sync": "1.1.0",
"private": "0.1.6",
"regenerator-6to5": "0.8.9-8",
"regenerator-6to5": "0.8.10-1",
"regexpu": "1.1.0",
"roadrunner": "1.0.4",
"source-map": "0.1.43",
@@ -58,6 +58,7 @@
"useragent": "^2.1.5"
},
"devDependencies": {
"6to5": "3.6.0",
"browserify": "8.1.1",
"chai": "1.10.0",
"esvalid": "1.1.0",
@@ -69,8 +70,5 @@
"mocha": "2.1.0",
"rimraf": "2.2.8",
"uglify-js": "2.4.16"
},
"optionalDependencies": {
"kexec": "1.0.0"
}
}

View File

@@ -1,7 +1,7 @@
{
"name": "6to5-runtime",
"description": "6to5 selfContained runtime",
"version": "3.5.1",
"version": "3.6.0",
"repository": "6to5/6to5",
"author": "Sebastian McKenzie <sebmck@gmail.com>"
}

View File

@@ -1,3 +1,3 @@
{
"args": ["foo"]
"args": ["bar"]
}

View File

@@ -1,4 +1,4 @@
var foo = () => console.log("foo");
foo();
import "./bar";
import "./bar2";

View File

@@ -1,3 +1,3 @@
{
"args": ["foo"]
"args": ["foo2"]
}

View File

@@ -1,9 +0,0 @@
"use strict";
(function f(n) {
if (n <= 0) {
console.log(this, arguments);
return "foo";
}
return Math.random() > 0.5 ? to5Runtime.tailCall(f.call, [this, n - 1], f) : to5Runtime.tailCall(f.apply, [this, [n - 1]], f);
})(1000000) === "foo";

View File

@@ -1,7 +0,0 @@
function f(n) {
return n <= 0 ? "foo" : g(n - 1);
}
function g(n) {
return n <= 0 ? "goo" : f(n - 1);
}

View File

@@ -1,9 +0,0 @@
"use strict";
function f(n) {
return n <= 0 ? "foo" : to5Runtime.tailCall(g, [n - 1]);
}
function g(n) {
return n <= 0 ? "goo" : to5Runtime.tailCall(f, [n - 1]);
}

View File

@@ -1,5 +0,0 @@
"use strict";
(function f(n) {
return n <= 0 ? "foo" : (doSmth(), getTrueValue() && (getFalseValue() || to5Runtime.tailCall(f, [n - 1])));
})(1000000, true) === "foo";

View File

@@ -1,4 +0,0 @@
{
"runtime": true,
"blacklist": []
}

View File

@@ -1,8 +0,0 @@
(function f(n = getDefaultValue(), /* should be undefined after first pass */ m) {
if (n <= 0) {
return "foo";
}
// Should be clean (undefined) on each pass
var local;
return f(n - 1);
})(1e6, true) === "foo";

View File

@@ -1,11 +0,0 @@
"use strict";
(function f(_x, /* should be undefined after first pass */m) {
var n = arguments[0] === undefined ? getDefaultValue() : arguments[0];
if (n <= 0) {
return "foo";
}
// Should be clean (undefined) on each pass
var local;
return to5Runtime.tailCall(f, [n - 1]);
})(1000000, true) === "foo";

View File

@@ -1,7 +0,0 @@
function f() {
return getObj().method();
}
function g() {
return getFalseValue() || getValue();
}

View File

@@ -1,10 +0,0 @@
"use strict";
function f() {
var _temp;
return to5Runtime.tailCall((_temp = getObj()).method, [], _temp);
}
function g() {
return getFalseValue() || to5Runtime.tailCall(getValue);
}

View File

@@ -1,41 +0,0 @@
"use strict";
(function f(n) {
if (n <= 0) {
return "foo";
}
try {
return f(n - 1);
} catch (e) {}
})(1000000) === "foo";
(function f(n) {
if (n <= 0) {
return "foo";
}
try {
throw new Error();
} catch (e) {
return to5Runtime.tailCall(f, [n - 1]);
}
})(1000000) === "foo";
(function f(n) {
if (n <= 0) {
return "foo";
}
try {
throw new Error();
} catch (e) {
return f(n - 1);
} finally {}
})(1000000) === "foo";
(function f(n) {
if (n <= 0) {
return "foo";
}
try {} finally {
return to5Runtime.tailCall(f, [n - 1]);
}
})(1000000) === "foo";

View File

@@ -1,3 +1,3 @@
{
"throws": "Line 2: MULTIPLIER is read-only"
"throws": "Line 2: \"MULTIPLIER\" is read-only"
}

View File

@@ -0,0 +1,7 @@
class MyClass {
myProp = { someValue: 42 };
}
var myClass = new MyClass;
assert.ok(myClass.myProp !== MyClass.prototype.myProp);
assert.equal(myClass.myProp.someValue, 42);

View File

@@ -0,0 +1,3 @@
{
"playground": true
}

View File

@@ -0,0 +1,5 @@
class MyClass {
static myProp = { someValue: 42 };
}
assert.equal(MyClass.myProp.someValue, 42);

View File

@@ -1,3 +1,3 @@
{
"throws": "illegal kind for constructor method"
"throws": "Illegal kind for constructor method"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "a is read-only"
"throws": "\"a\" is read-only"
}

View File

@@ -0,0 +1,2 @@
const x = {};
x.key = "value";

View File

@@ -0,0 +1,4 @@
"use strict";
var x = {};
x.key = "value";

View File

@@ -1,3 +1,3 @@
{
"throws": "MULTIPLIER is read-only"
"throws": "\"MULTIPLIER\" is read-only"
}

View File

@@ -1,3 +1,3 @@
{
"throws": "Duplicate declaration MULTIPLIER"
"throws": "Duplicate declaration \"MULTIPLIER\""
}

View File

@@ -1,3 +1,3 @@
{
"throws": "Duplicate declaration MULTIPLIER"
"throws": "Duplicate declaration \"MULTIPLIER\""
}

View File

@@ -1,3 +1,3 @@
{
"throws": "Duplicate declaration MULTIPLIER"
"throws": "Duplicate declaration \"MULTIPLIER\""
}

View File

@@ -1,3 +1,3 @@
{
"throws": "foo is read-only"
"throws": "\"foo\" is read-only"
}

View File

@@ -1,6 +1,6 @@
"use strict";
var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
var _ref = ["hello", [", ", "junk"], ["world"]];
@@ -11,4 +11,4 @@ var b = _ref$1[0];
var _ref$2 = _slicedToArray(_ref[2], 1);
var c = _ref$2[0];
var d = _ref[3];
var d = _ref[3];

View File

@@ -1,6 +1,6 @@
"use strict";
var _temp, _temp2;
var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
console.log((_temp = [123], _temp2 = _slicedToArray(_temp, 1), x = _temp2[0], _temp));
console.log((_temp = [123], _temp2 = _slicedToArray(_temp, 1), x = _temp2[0], _temp));

View File

@@ -1,6 +1,6 @@
"use strict";
var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
var _ref = f();
@@ -8,4 +8,4 @@ var _ref2 = _slicedToArray(_ref, 2);
a = _ref2[0];
b = _ref2[1];
;
;

View File

@@ -1,6 +1,6 @@
"use strict";
var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
var _ref = ["foo", "hello", [", ", "junk"], ["world"]];
@@ -11,4 +11,4 @@ var b = _ref$2[0];
var _ref$3 = _slicedToArray(_ref[3], 1);
var c = _ref$3[0];
var d = _ref[4];
var d = _ref[4];

View File

@@ -1,6 +1,6 @@
"use strict";
var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
for (var _ref in obj) {
var _ref2 = _slicedToArray(_ref, 2);
@@ -8,4 +8,4 @@ for (var _ref in obj) {
var name = _ref2[0];
var value = _ref2[1];
print("Name: " + name + ", Value: " + value);
}
}

View File

@@ -1,6 +1,6 @@
"use strict";
var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
for (var _iterator = test.expectation.registers[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) {
var _step$value = _slicedToArray(_step.value, 3);
@@ -8,4 +8,4 @@ for (var _iterator = test.expectation.registers[Symbol.iterator](), _step; !(_st
var name = _step$value[0];
var before = _step$value[1];
var after = _step$value[2];
}
}

View File

@@ -0,0 +1 @@
let [x, ...y] = z;

View File

@@ -0,0 +1,8 @@
"use strict";
var _toArray = function (arr) { return Array.isArray(arr) ? arr : Array.from(arr); };
var _z = _toArray(z);
var x = _z[0];
var y = _z.slice(1);

View File

@@ -1,6 +1,6 @@
"use strict";
var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
var _ref = [1, 2];

View File

@@ -1,6 +1,6 @@
"use strict";
var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
var _rect$topLeft = _slicedToArray(rect.topLeft, 2);
@@ -9,4 +9,4 @@ var y1 = _rect$topLeft[1];
var _rect$bottomRight = _slicedToArray(rect.bottomRight, 2);
var x2 = _rect$bottomRight[0];
var y2 = _rect$bottomRight[1];
var y2 = _rect$bottomRight[1];

View File

@@ -1,6 +1,6 @@
"use strict";
var _slicedToArray = function (arr, i) { if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
var _slicedToArray = function (arr, i) { if (!arr || !arr[Symbol.iterator]) { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } else if (Array.isArray(arr)) { return arr; } else { var _arr = []; for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) { _arr.push(_step.value); if (i && _arr.length === i) break; } return _arr; } };
function somethingAdvanced(_ref) {
var _ref$topLeft = _ref.topLeft;
@@ -33,4 +33,4 @@ var unpackArray = function (_ref, _ref3) {
return a + b + c;
};
console.log(unpackArray(["hello", ", ", "world"], [1, 2, 3]));
console.log(unpackArray(["hello", ", ", "world"], [1, 2, 3]));

Some files were not shown because too many files have changed in this diff Show More