Compare commits

...

92 Commits

Author SHA1 Message Date
Sebastian McKenzie
a0befe349d v5.4.3 2015-05-16 01:58:52 +01:00
Sebastian McKenzie
04992effb3 improve lost node path tracking message 2015-05-16 01:54:35 +01:00
Sebastian McKenzie
9ae54d2a50 add 5.4.3 changelog 2015-05-16 01:54:25 +01:00
Sebastian McKenzie
fe72a40159 Revert "add back descriptor.initializer existence check"
This reverts commit 02dfd18023.
2015-05-16 01:50:31 +01:00
Sebastian McKenzie
ea510d09d0 fix module shadowing when using CommonJS-like module formatters - fixes #1544 2015-05-16 01:47:48 +01:00
Sebastian McKenzie
375689a1ff handle path contexts MUCH better, they're now only held during the traversal iteration and the previous context is released upon completion, also verify path keys and try and obtain a new one if invalid - fixes #1545 2015-05-16 01:37:55 +01:00
Sebastian McKenzie
9908e331b7 Merge pull request #1549 from Naddiseo/master
Added DCE tests for all the bugs I've reported so far.
2015-05-15 23:08:32 +01:00
Richard Eames
cd8655708d Added DCE tests for all the bugs I've reported so far. 2015-05-15 15:55:58 -06:00
Sebastian McKenzie
62b94f297a don't create a new binding for local class ids, just copy the parents - fixes #1547 2015-05-15 19:11:24 +01:00
Sebastian McKenzie
01d399ee3c check for existence of variable when checking if node is pure 2015-05-15 18:48:17 +01:00
Sebastian McKenzie
30e3908484 don't perform DCE on single references nested inside the binding initializer - fixes #1546 2015-05-15 18:48:05 +01:00
Sebastian McKenzie
ff12046009 move traverse replace test up 2015-05-15 18:35:15 +01:00
Sebastian McKenzie
1a058b4a6e Merge branch 'master' of github.com:babel/babel 2015-05-15 17:42:40 +01:00
Sebastian McKenzie
02dfd18023 add back descriptor.initializer existence check 2015-05-15 17:42:28 +01:00
Sebastian McKenzie
9ab7df5f47 remove wildcards from start of patterns 2015-05-15 17:42:10 +01:00
Sebastian McKenzie
7a5b140f92 minor generation style nits 2015-05-15 17:41:56 +01:00
Sebastian McKenzie
6f83111c55 Merge pull request #1542 from amasad/already-printed
Fix bug with paren printing in compact + line retained mode
2015-05-15 17:38:40 +01:00
Sebastian McKenzie
f3f60368da remove TraversalPath node getter/setter 2015-05-15 17:34:31 +01:00
Sebastian McKenzie
7a09640b20 add environment to register cache key 2015-05-15 17:34:06 +01:00
Amjad Masad
2916d1262b Don't print leftParen if already printed before the catchup 2015-05-14 23:57:35 -07:00
Amjad Masad
741abb73d2 Add failing test for printing with compact & retainLines 2015-05-14 23:57:05 -07:00
Sebastian McKenzie
2e46755260 5.4.2 2015-05-15 02:36:22 +01:00
Sebastian McKenzie
2cff9519e1 v5.4.2 2015-05-15 02:35:07 +01:00
Sebastian McKenzie
f9c2c6e988 Merge branch 'master' of github.com:babel/babel
# Conflicts:
#	CHANGELOG.md
2015-05-15 02:34:11 +01:00
Sebastian McKenzie
5ae3dc01f1 make path patterns used by only and ignore **very** liberal, this will ease a lot of pain in dealing with them 2015-05-15 02:33:40 +01:00
Sebastian McKenzie
af4fd69dd0 make path patterns used by only and ignore **very** liberal, this will ease a lot of pain in dealing with them 2015-05-15 02:33:22 +01:00
Sebastian McKenzie
4d4493f325 elaborate on shouldIgnore changes in 5.4.1 2015-05-15 02:03:02 +01:00
Sebastian McKenzie
e70d474b39 5.4.1 2015-05-15 02:01:42 +01:00
Sebastian McKenzie
1b45f64858 v5.4.1 2015-05-15 02:00:18 +01:00
Sebastian McKenzie
b89cf6768f fix shouldIgnore only matches switch 2015-05-15 01:57:10 +01:00
Sebastian McKenzie
36ad1108b4 fix loose mode loop being weirdly inserted 2015-05-15 01:56:34 +01:00
Sebastian McKenzie
4c04371ea4 remove loop label due to babel bug 2015-05-15 01:48:47 +01:00
Sebastian McKenzie
d3e385c554 one last try fixing the shouldIgnore only filter... 2015-05-15 01:46:36 +01:00
Sebastian McKenzie
6afcef9805 actually fix shouldIgnore algorithm this time, ugh 2015-05-15 01:44:57 +01:00
Sebastian McKenzie
ed861e230b fix shouldIgnore method for only 2015-05-15 01:41:49 +01:00
Sebastian McKenzie
e15ced2922 add 5.4.1 changelog 2015-05-15 01:37:48 +01:00
Sebastian McKenzie
93052e532f Merge branch 'master' of github.com:babel/babel 2015-05-15 01:35:43 +01:00
Sebastian McKenzie
198d51ddaa heavily improve shouldIgnore algorithm - fixes #1539 2015-05-15 01:34:58 +01:00
Sebastian McKenzie
8730b24def Merge pull request #1540 from browncolyn/master
Added slash as needed dependency
2015-05-15 01:30:50 +01:00
Colyn Brown
f09c0d5998 Added slash as needed dependency 2015-05-14 17:28:20 -07:00
Sebastian McKenzie
21e4481ab7 5.4.0 2015-05-15 00:32:36 +01:00
Sebastian McKenzie
2f61754a24 v5.4.0 2015-05-15 00:29:42 +01:00
Sebastian McKenzie
3910d18bc9 add 5.4.0 changelog 2015-05-15 00:28:47 +01:00
Sebastian McKenzie
583111ebfb expose file metadata object to transformers 2015-05-15 00:24:14 +01:00
Sebastian McKenzie
1b15481460 ignore "ignored files" when babel.transform has determined that it should be ignored, this is likely the result of an rc file resolution - fixes #1362 2015-05-15 00:24:03 +01:00
Sebastian McKenzie
fd9c98ff86 move strict transformer to builtin-setup group - fixes #1538 2015-05-15 00:18:42 +01:00
Sebastian McKenzie
41b5607ef3 fix env option tests 2015-05-15 00:11:28 +01:00
Sebastian McKenzie
ae77ea807f normalise source map file paths when using the CLI - fixes #1496 2015-05-15 00:05:11 +01:00
Sebastian McKenzie
ad44190c6b properly register for head variable declaration paths when performing scope tracking - fixes #1524 2015-05-14 23:53:04 +01:00
Sebastian McKenzie
024e4454a1 add env option - closes #1531 2015-05-14 23:47:56 +01:00
Sebastian McKenzie
14dddcda36 make PathHoister much more flexible, now ignores global references and will not deopt on reassignments and will instead hoist as high as it can, this also fixes #1529 since the order of operations has changed 2015-05-14 23:29:02 +01:00
Sebastian McKenzie
d4fb924b6a add tion comment to all function visitors 2015-05-14 22:37:15 +01:00
Sebastian McKenzie
b02c97af60 Merge pull request #1536 from benjamn/master
Invoke Regenerator on async/generator Function nodes, not whole AST.
2015-05-14 22:27:42 +01:00
Ben Newman
cc611cb71c Invoke Regenerator on async/generator Function nodes, not whole AST.
This should help (dramatically?) with
https://github.com/babel/babel/issues/1486#issuecomment-101491605,
although I'm not sure how to run the benchmarks myself.
2015-05-14 15:42:58 -05:00
Sebastian McKenzie
b8a01a9919 move traversal scope logic and binding into it's own folder, rename Scope#generateTemp to generateDeclaredUidIdentifier, rename Scope#generateUidBasedOnNode to Scope#generateUidIdentifierBasedOnNode 2015-05-14 19:12:26 +01:00
Sebastian McKenzie
55c99661be NFO 2015-05-14 18:07:36 +01:00
Sebastian McKenzie
1563b216df Merge branch 'master' of github.com:babel/babel 2015-05-14 17:56:33 +01:00
Sebastian McKenzie
a9d4b485d9 simplify getStaticContext in es7.functionBind transformer - thanks @RReverser! 2015-05-14 17:48:51 +01:00
Sebastian McKenzie
360daa6267 Merge pull request #1532 from dchambers/prefix-private-methods-with-underscore
Prefix private methods names with underscore.
2015-05-14 16:52:16 +01:00
Sebastian McKenzie
724bf52929 handle "static" contexts in es7.functionBind - #1518 2015-05-14 16:37:44 +01:00
Sebastian McKenzie
7407b37bd9 Merge pull request #1518 from babel/es7.functionBind
Add experimental support for ES7 function bind.
2015-05-14 16:22:21 +01:00
Ingvar Stepanyan
da765cc4c1 Flip the negation in if-else. 2015-05-14 18:05:55 +03:00
dchambers
4f862eee6e Prefix private methods names with underscore. 2015-05-14 13:19:41 +01:00
Ingvar Stepanyan
e05d7cf49a Fix some parsing edge cases for :: operator. 2015-05-14 12:47:51 +03:00
Ingvar Stepanyan
fd8e94a90f Preserve original execution order in :: operator. 2015-05-14 12:39:05 +03:00
Sebastian McKenzie
a6cf28c5b5 Merge pull request #1525 from nkt/exponentiation-operator-inline
Added missing exponential operator inlining
2015-05-13 23:09:57 +01:00
Nikita Gusakov
6b07b13a8e Added missing exponential operator inlining 2015-05-14 01:08:02 +03:00
Sebastian McKenzie
561c4dcc25 5.3.3 2015-05-13 22:09:37 +01:00
Sebastian McKenzie
b516ea596a v5.3.3 2015-05-13 22:08:32 +01:00
Sebastian McKenzie
248758eee3 fix version number 2015-05-13 22:07:33 +01:00
Sebastian McKenzie
a808602ae0 v3.5.3 2015-05-13 22:07:00 +01:00
Sebastian McKenzie
40e3436e95 add 3.5.3 changelog 2015-05-13 22:05:07 +01:00
Sebastian McKenzie
f704770b26 uncomment out return traversal path skipping - fixes #1523 2015-05-13 22:03:50 +01:00
Sebastian McKenzie
330665f150 ignore modules alongside param bindings in minification.deadCodeElimination transformer - fixes #1523 2015-05-13 21:49:28 +01:00
Sebastian McKenzie
af41899d74 5.3.2 2015-05-13 19:58:21 +01:00
Sebastian McKenzie
d12f4d0bc8 v5.3.2 2015-05-13 19:57:20 +01:00
Sebastian McKenzie
97680e9dfd properly hoist all var patterns when wrapping bodies in the es6.blockScoping transformer - fixes #1521 2015-05-13 19:55:40 +01:00
Sebastian McKenzie
51341ca6c3 fix and add missing module specifier reference detection - fixes #1520 2015-05-13 19:23:47 +01:00
Sebastian McKenzie
ab54bfa50e Merge pull request #1519 from zpao/package-licenses
Add license fields to packages
2015-05-13 18:36:25 +01:00
Paul O’Shannessy
60aa933fb6 Add license fields to packages 2015-05-13 10:21:42 -07:00
Ingvar Stepanyan
1a299b2bcc Small fixes to es7.functionBind and generation tests added. 2015-05-13 18:20:33 +03:00
Ingvar Stepanyan
37f662d790 Add experimental support for ES7 function bind. (issue #1287) 2015-05-13 17:58:21 +03:00
Sebastian McKenzie
b0317f9bab don't consider "globals" to cause incompatible scope hoist 2015-05-13 12:33:08 +01:00
Sebastian McKenzie
be2dfaf081 register variable declarator in scope when pushing 2015-05-13 09:11:09 +01:00
Sebastian McKenzie
2c8437ae92 ignore initializerless variable declaration when trying to inline single use variables - fixes #1516 2015-05-13 08:46:41 +01:00
Sebastian McKenzie
2a0bcfd086 add support for evaluating unary ~ 2015-05-13 08:45:16 +01:00
Sebastian McKenzie
2cf41afac3 move expression inlining to exit rather than enter in minification.inlineExpressions transformer 2015-05-13 08:45:06 +01:00
Sebastian McKenzie
e318f5f3be use ReferencedIdentifier virtual type in minification.deadCodeElimination transformer 2015-05-13 08:44:33 +01:00
Sebastian McKenzie
939decb86c stop entire unnecessary traversal for regenerator 2015-05-13 08:44:18 +01:00
Sebastian McKenzie
1baa0df948 clean up array inferrence for #1515 2015-05-13 08:44:03 +01:00
Sebastian McKenzie
e8956a8c44 upgrade dev dependency babel to 5.3.1 2015-05-13 08:43:25 +01:00
Sebastian McKenzie
2f0fdbbc26 5.3.1 2015-05-13 03:21:54 +01:00
117 changed files with 1197 additions and 269 deletions

View File

@@ -13,6 +13,53 @@ _Note: Gaps between patch versions are faulty/broken releases._
See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
## 5.4.3
* **Bug Fix**
* Fix `module` being incorrectly rewritten when used as in an export declaration.
* When performing single-reference inlining, ensure that the single reference isn't a child of the binding itself.
* Fix a bug in `minification.deadCodeElimination` where a new binding instance was being created for local class bindings instead of just inheriting the parent one.
* Fix bug with paren printing in `compact` and `retainLines` mode where a left paren was already printed before catching up.
* **Internal**
* Handle contexts for paths much better. This will ensure that the path node location info is in sync.
## 5.4.2
* **Polish**
* `ignore` and `only` patterns are now **very** liberal. The pattern can now exist anywhere in the path.
## 5.4.1
* **Bug Fix**
* Add missing `slash` dependency. Thanks [@browncolyn](https://github.com/browncolyn)!
* **Polish**
* Clean up `shouldIgnore` algorithm to work how you'd expect rather than being a hacky piece of shit. It now crawls the entire path, checking each section of it against the input ignore/only patterns. This means that the pattern `foo` will ignore the paths `foo/bar.js`, `bar/foo` etc.
## 5.4.0
* **New Feature**
* Added [function bind syntax](https://github.com/zenparsing/es-function-bind) behind stage 0. Thanks [@RReverser](https://github.com/rreverser)!
* Added `env` option. Especially handy when using the `.babelrc`.
* **Bug Fix**
* Fix files not properly being ignored when `babel.transform` ignores them when using `$ babel`.
* Fix scope tracking registering loop head bindings to their `VariableDeclaration` instead of `VariableDeclarator`.
* **Polish**
* Normalise path separators for souce map paths when using `$ babel`.
* Rework `PathHoister` to ignore global references and to not deopt on reassignments to referenced bindings, instead it tries to hoist to the highest scope.
* Added missing exponential operator inlining. Thanks [@nkt](https://github.com/nkt)!
* Optimise `regenerator` transformer. Thanks [@benjamn](https://github.com/benjamn)!
## 5.3.3
* **Bug Fix**
* Fix `minification.deadCodeElimination` transformer incorrectly trying to inline import declarations.
* Fix `minification.inlineExpression` transformer getting into an infinite loop.
## 5.3.2
* **Bug Fix**
* Fix patterns not being considered when hoisting variables in the `es6.blockScoping` transformer.
## 5.3.1
* **Bug Fix**
@@ -37,6 +84,7 @@ See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
* Properly hoist temp param declarations when doing TCO.
* **Internal**
* Add `--harmony_generators` flag to `$ babel-node`.
* Internal AST traversals have been minimised **drastically**. Transformers have been grouped together which means entire tree traversals are much fewer. Visiting nodes is now also skipped if the traversal context can detect that the handler is a noop. This sames precious cycles as it avoids constructing traversal paths and creating a new traversal context. See issues [#1472](https://github.com/babel/babel/issues/1472) and [#1486](https://github.com/babel/babel/issues/1486) for related discussion.
* **Polish**
* Move many `utility` transformers to `minification`.

View File

@@ -1,7 +1,7 @@
{
"name": "babel-core",
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
"version": "5.3.1",
"version": "5.4.3",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
"license": "MIT",
@@ -64,7 +64,7 @@
"user-home": "^1.1.1"
},
"devDependencies": {
"babel": "5.3.0",
"babel": "5.3.1",
"browserify": "^9.0.8",
"chai": "^2.2.0",
"eslint": "^0.18.0",

View File

@@ -1,5 +1,6 @@
var outputFileSync = require("output-file-sync");
var chokidar = require("chokidar");
var slash = require("slash");
var path = require("path");
var util = require("./util");
var fs = require("fs");
@@ -13,8 +14,9 @@ module.exports = function (commander, filenames, opts) {
var dest = path.join(commander.outDir, relative);
var data = util.compile(src, {
sourceFileName: path.relative(dest + "/..", src)
sourceFileName: slash(path.relative(dest + "/..", src))
});
if (data.ignored) return;
if (commander.sourceMaps && commander.sourceMaps !== "inline") {
var mapLoc = dest + ".map";

View File

@@ -1,6 +1,7 @@
var convertSourceMap = require("convert-source-map");
var sourceMap = require("source-map");
var chokidar = require("chokidar");
var slash = require("slash");
var path = require("path");
var util = require("./util");
var fs = require("fs");
@@ -15,7 +16,7 @@ module.exports = function (commander, filenames, opts) {
var buildResult = function () {
var map = new sourceMap.SourceMapGenerator({
file: commander.outFile || "stdout"
file: slash(commander.outFile || "stdout")
});
var code = "";
@@ -27,11 +28,12 @@ module.exports = function (commander, filenames, opts) {
if (result.map) {
var consumer = new sourceMap.SourceMapConsumer(result.map);
var sourceFilename = filename;
var sourceFilename = filename;
if (commander.outFile) {
sourceFilename = path.relative(path.dirname(commander.outFile), sourceFilename);
}
sourceFilename = slash(sourceFilename);
map._sources.add(sourceFilename);
map.setSourceContent(sourceFilename, result.actual);
@@ -114,7 +116,9 @@ module.exports = function (commander, filenames, opts) {
_.each(_filenames, function (filename) {
if (util.shouldIgnore(filename)) return;
results.push(util.compile(filename));
var data = util.compile(filename);
if (data.ignored) return;
results.push(data);
});
output();

View File

@@ -1,13 +1,14 @@
{
"name": "babel",
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
"version": "5.3.0",
"version": "5.4.2",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
"license": "MIT",
"repository": "babel/babel",
"preferGlobal": true,
"dependencies": {
"babel-core": "^5.3.0",
"babel-core": "^5.4.2",
"chokidar": "^1.0.0",
"commander": "^2.6.0",
"convert-source-map": "^1.1.0",
@@ -16,7 +17,8 @@
"lodash": "^3.2.0",
"output-file-sync": "^1.1.0",
"path-is-absolute": "^1.0.0",
"source-map": "^0.4.0"
"source-map": "^0.4.0",
"slash": "^1.0.0"
},
"bin": {
"babel": "./bin/babel/index.js",

View File

@@ -1,7 +1,8 @@
{
"name": "babel-runtime",
"description": "babel selfContained runtime",
"version": "5.3.0",
"version": "5.4.2",
"license": "MIT",
"repository": "babel/babel",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"dependencies": {

48
sebmck-bjs.nfo Normal file
View File

@@ -0,0 +1,48 @@
====== ==========M=
============= == ======O= ======= MM ==
M==+=== ==M === ==== == === ==
=D === === ====MM ==M ==M ==M ===
===M ====M ==== =D ===M === === ==
==7 ====M ==M == ======== =========M ==M
=========== ======M ===MMM === ==M ==
=======MM==========MM== ==M ==M=== ==
==M === M== ==M == === === =D =
==M ===+ == == == ==$M =========== ============M
=== ====M == ==M ===M== ====?MMMM M M
== ===== ==M == ==MM M
==M===M=M =M =MM M M
==MM=M ==
MMM =M
M
> ú B ú A ú B ú E ú L ú <
ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸
³ SOFTWARE .. : JavaScript Compiler ³ COMPANY ... : N/A ³
³ SUPPLIER .. : N/A ³ CRACKER ... : Sebastian McKenzie ³
³ RATING .... : depends.. ³ PACKAGER .. : Sebastian McKenzie ³
³ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ³
³ GRAFIX .... : - ³ SOUND ..... : - ³
ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
Babel is a JavaScript compiler and transformation platform for writing NeXt
GeNeRaTiOn JavaScript.
ÆÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍ͵
³ :: Greets :: ³
³ ³
³ sebmck, thejameskyle, RReverser, zloirock, monsanto, gaearon, zertosh, ³
³ stefanpenner, eventualbuddha, AluisioASG, Apoxx, Couto, dominicbarnes, ³
³ es128, gordonkristan, hkjels, jmeas, josh, loganfsmyth, nightire, ³
³ Rich-Harris, shinnn, shuhei, sindresorhus, tricknotes ³
³ ³
ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
-*- JavaScripts for all , All for JavaScripts ! -*-
ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸
³ If you want to Contact us, call 555-720-4228, Use the Handle "BABEL" w/ ³
³ password : VISITOR and leave a mail to Sebastian or James. ³
ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
-=- We LoVe fun Too! -=-

View File

@@ -214,7 +214,12 @@ pp.parseExprSubscripts = function(refShorthandDefaultPos) {
}
pp.parseSubscripts = function(base, start, noCalls) {
if (this.eat(tt.dot)) {
if (!noCalls && this.eat(tt.doubleColon)) {
let node = this.startNodeAt(start)
node.object = base
node.callee = this.parseNoCallExpr()
return this.parseSubscripts(this.finishNode(node, "BindExpression"), start, noCalls)
} else if (this.eat(tt.dot)) {
let node = this.startNodeAt(start)
node.object = base
node.property = this.parseIdent(true)
@@ -240,6 +245,13 @@ pp.parseSubscripts = function(base, start, noCalls) {
} return base
}
// Parse a no-call expression (like argument of `new` or `::` operators).
pp.parseNoCallExpr = function() {
let start = this.markPosition()
return this.parseSubscripts(this.parseExprAtom(), start, true)
}
// Parse an atomic expression — either a single token that is an
// expression, an expression started by a keyword like `function` or
// `new`, or an expression wrapped in punctuation like `()`, `[]`,
@@ -363,6 +375,15 @@ pp.parseExprAtom = function(refShorthandDefaultPos) {
case tt.backQuote:
return this.parseTemplate()
case tt.doubleColon:
node = this.startNode()
this.next()
node.object = null
let callee = node.callee = this.parseNoCallExpr()
if (callee.type !== "MemberExpression")
this.raise(callee.start, "Binding should be performed on object property.")
return this.finishNode(node, "BindExpression")
default:
this.unexpected()
}
@@ -472,8 +493,7 @@ pp.parseNew = function() {
this.raise(node.property.start, "The only valid meta property for new is new.target")
return this.finishNode(node, "MetaProperty")
}
let start = this.markPosition()
node.callee = this.parseSubscripts(this.parseExprAtom(), start, true)
node.callee = this.parseNoCallExpr()
if (this.eat(tt.parenL)) node.arguments = this.parseExprList(
tt.parenR,
this.options.features["es7.trailingFunctionCommas"]

View File

@@ -320,7 +320,13 @@ pp.getTokenFromCode = function(code) {
case 93: ++this.pos; return this.finishToken(tt.bracketR)
case 123: ++this.pos; return this.finishToken(tt.braceL)
case 125: ++this.pos; return this.finishToken(tt.braceR)
case 58: ++this.pos; return this.finishToken(tt.colon)
case 58:
if (this.options.features["es7.functionBind"] && this.input.charCodeAt(this.pos + 1) === 58)
return this.finishOp(tt.doubleColon, 2)
++this.pos
return this.finishToken(tt.colon)
case 63: ++this.pos; return this.finishToken(tt.question)
case 64: ++this.pos; return this.finishToken(tt.at)

View File

@@ -54,6 +54,7 @@ export const types = {
comma: new TokenType(",", beforeExpr),
semi: new TokenType(";", beforeExpr),
colon: new TokenType(":", beforeExpr),
doubleColon: new TokenType("::", beforeExpr),
dot: new TokenType("."),
question: new TokenType("?", beforeExpr),
arrow: new TokenType("=>", beforeExpr),

View File

@@ -53,6 +53,9 @@ var compile = function (filename) {
var cacheKey = `${filename}:${JSON.stringify(opts)}:${babel.version}`;
var env = process.env.BABEL_ENV || process.env.NODE_ENV;
if (env) cacheKey += `:${env}`;
if (cache) {
var cached = cache[cacheKey];
if (cached && cached.mtime === mtime(filename)) {

View File

@@ -117,8 +117,9 @@ export default class Buffer {
_removeSpacesAfterLastNewline() {
var lastNewlineIndex = this.buf.lastIndexOf("\n");
if (lastNewlineIndex === -1)
if (lastNewlineIndex === -1) {
return;
}
var index = this.buf.length - 1;
while (index > lastNewlineIndex) {

View File

@@ -133,6 +133,12 @@ export function AssignmentExpression(node, print) {
print(node.right);
}
export function BindExpression(node, print) {
print(node.object);
this.push("::");
print(node.callee);
}
export {
AssignmentExpression as BinaryExpression,
AssignmentExpression as LogicalExpression,

View File

@@ -149,11 +149,12 @@ class CodeGenerator {
return print;
}
catchUp(node, parent) {
catchUp(node, parent, leftParenPrinted) {
// catch up to this nodes newline if we're behind
if (node.loc && this.format.retainLines && this.buffer.buf) {
var needsParens = false;
if (parent && this.position.line < node.loc.start.line && t.isTerminatorless(parent)) {
if (!leftParenPrinted && parent &&
this.position.line < node.loc.start.line && t.isTerminatorless(parent)) {
needsParens = true;
this._push("(");
}
@@ -216,7 +217,7 @@ class CodeGenerator {
this.printLeadingComments(node, parent);
var needsParensFromCatchup = this.catchUp(node, parent);
var needsParensFromCatchup = this.catchUp(node, parent, needsParens);
newline(true);
@@ -330,7 +331,6 @@ class CodeGenerator {
_printComments(comments) {
if (this.format.compact) return;
if (!this.format.comments) return;
if (!comments || !comments.length) return;

View File

@@ -0,0 +1,17 @@
import merge from "lodash/object/merge";
export default function (dest, src) {
if (!dest || !src) return;
return merge(dest, src, function(a, b) {
if (Array.isArray(a)) {
var c = a.slice(0);
for (var v of b) {
if (a.indexOf(v) < 0) {
c.push(v);
}
}
return c;
}
});
}

View File

@@ -22,6 +22,7 @@ export const MESSAGES = {
missingTemplatesDirectory: "no templates directory - this is most likely the result of a broken `npm publish`. Please report to https://github.com/babel/babel/issues",
unsupportedOutputType: "Unsupported output type $1",
illegalMethodName: "Illegal method name $1",
lostTrackNodePath: "We lost track of this nodes position, likely because the AST was directly manipulated",
traverseNeedsParent: "Must pass a scope and parentPath unless traversing a Program/File got a $1 node",
traverseVerifyRootFunction: "You passed `traverse()` a function when it expected a visitor object, are you sure you didn't mean `{ enter: Function }`?",

View File

@@ -72,4 +72,10 @@ def("ExportAllDeclaration")
.field("exported", def("Identifier"))
.field("source", def("Literal"));
def("BindExpression")
.bases("Expression")
.build("object", "callee")
.field("object", or(def("Expression"), null))
.field("callee", def("Expression"));
types.finalize();

View File

@@ -1,5 +1,5 @@
import stripJsonComments from "strip-json-comments";
import merge from "lodash/object/merge";
import merge from "../helpers/merge";
import path from "path";
import fs from "fs";
@@ -42,17 +42,7 @@ export default function (loc, opts = {}) {
opts.babelrc.push(file);
if (json.breakConfig) return;
merge(opts, json, function(a, b) {
if (Array.isArray(a)) {
var c = a.slice(0);
for (var v of b) {
if (a.indexOf(v) < 0) {
c.push(v);
}
}
return c;
}
});
merge(opts, json);
}
var up = path.dirname(start);

View File

@@ -19,6 +19,7 @@ import assign from "lodash/object/assign";
import Logger from "./logger";
import parse from "../../helpers/parse";
import Scope from "../../traversal/scope";
import merge from "../../helpers/merge";
import slash from "slash";
import clone from "lodash/lang/clone";
import * as util from "../../util";
@@ -37,6 +38,7 @@ export default class File {
this.declarations = {};
this.usedHelpers = {};
this.dynamicData = {};
this.metadata = {};
this.data = {};
this.pipeline = pipeline;
@@ -106,6 +108,9 @@ export default class File {
if (!option) this.log.error(`Unknown option: ${key}`, ReferenceError);
}
var envKey = process.env.BABEL_ENV || process.env.NODE_ENV || "development";
if (opts.env) merge(opts, opts.env[envKey]);
for (let key in File.options) {
let option = File.options[key];
@@ -458,19 +463,9 @@ export default class File {
}
_addAst(ast) {
this.path = TraversalPath.get(null, null, ast, ast, "program", this);
this.path = TraversalPath.get(null, ast, ast, "program", this).setContext(null, this);
this.scope = this.path.scope;
this.ast = ast;
this.path.traverse({
enter(node, parent, scope) {
if (this.isScope()) {
for (var key in scope.bindings) {
scope.bindings[key].setTypeAnnotation();
}
}
}
});
}
addAst(ast) {
@@ -498,7 +493,8 @@ export default class File {
try {
if (this.shouldIgnore()) {
return {
metadata: {},
metadata: this.metadata,
ignored: true,
code: code,
map: null,
ast: null
@@ -591,7 +587,7 @@ export default class File {
var ast = this.ast;
var result = {
metadata: {},
metadata: this.metadata,
code: "",
map: null,
ast: null

View File

@@ -20,6 +20,11 @@
"default": {}
},
"env": {
"hidden": true,
"default": {}
},
"moduleId": {
"description": "specify a custom name for module ids",
"type": "string"

View File

@@ -26,7 +26,7 @@ var getObjRef = function (node, nodes, file, scope) {
throw new Error(`We can't explode this node type ${node.type}`);
}
var temp = scope.generateUidBasedOnNode(ref);
var temp = scope.generateUidIdentifierBasedOnNode(ref);
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(temp, ref)
]));
@@ -38,7 +38,7 @@ var getPropRef = function (node, nodes, file, scope) {
var key = t.toComputedKey(node, prop);
if (t.isLiteral(key)) return key;
var temp = scope.generateUidBasedOnNode(prop);
var temp = scope.generateUidIdentifierBasedOnNode(prop);
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(temp, prop)
]));

View File

@@ -6,7 +6,7 @@ export default function (decorators, scope) {
var expression = decorator.expression;
if (!t.isMemberExpression(expression)) continue;
var temp = scope.generateMemoisedReference(expression.object);
var temp = scope.maybeGenerateMemoised(expression.object);
var ref;
var nodes = [];

View File

@@ -6,8 +6,8 @@ import * as util from "../../util";
import * as t from "../../types";
export default class AMDFormatter extends DefaultFormatter {
init() {
CommonFormatter.prototype._init.call(this, this.hasNonDefaultExports);
setup() {
CommonFormatter.prototype._setup.call(this, this.hasNonDefaultExports);
}
buildDependencyLiterals() {

View File

@@ -4,11 +4,11 @@ import * as util from "../../util";
import * as t from "../../types";
export default class CommonJSFormatter extends DefaultFormatter {
init() {
this._init(this.hasLocalExports);
setup() {
this._setup(this.hasLocalExports);
}
_init(conditional) {
_setup(conditional) {
var file = this.file;
var scope = file.scope;
@@ -52,7 +52,7 @@ export default class CommonJSFormatter extends DefaultFormatter {
} else if (this.noInteropRequireImport) {
this.internalRemap[variableName.name] = t.memberExpression(ref, t.identifier("default"));
} else {
var uid = this.scope.generateUidBasedOnNode(node, "import");
var uid = this.scope.generateUidIdentifierBasedOnNode(node, "import");
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(uid, t.callExpression(this.file.addHelper("interop-require-default"), [ref]))
@@ -111,7 +111,7 @@ export default class CommonJSFormatter extends DefaultFormatter {
} else if (this.isModuleType(node, "absoluteDefault")) {
call = t.memberExpression(call, t.identifier("default"));
} else {
uid = this.scope.generateUidBasedOnNode(node, "import");
uid = this.scope.generateUidIdentifierBasedOnNode(node, "import");
}
uid = uid || node.specifiers[0].local;

View File

@@ -21,7 +21,7 @@ var hoistVariablesVisitor = {
}
// ignore block hoisted nodes as these can be left in
if (state.formatter.canHoist(node)) return;
if (state.formatter._canHoist(node)) return;
var nodes = [];
@@ -50,7 +50,7 @@ var hoistFunctionsVisitor = {
enter(node, parent, scope, state) {
if (t.isFunction(node)) this.skip();
if (t.isFunctionDeclaration(node) || state.formatter.canHoist(node)) {
if (t.isFunctionDeclaration(node) || state.formatter._canHoist(node)) {
state.handlerBody.push(node);
this.remove();
}
@@ -101,14 +101,14 @@ export default class SystemFormatter extends AMDFormatter {
var right = objectIdentifier;
var block = t.blockStatement([
t.expressionStatement(this.buildExportCall(leftIdentifier, valIdentifier))
t.expressionStatement(this._buildExportCall(leftIdentifier, valIdentifier))
]);
return this._addImportSource(t.forInStatement(left, right, block), node);
}
buildExportsAssignment(id, init, node) {
var call = this.buildExportCall(t.literal(id.name), init, true);
var call = this._buildExportCall(t.literal(id.name), init, true);
return this._addImportSource(call, node);
}
@@ -120,13 +120,13 @@ export default class SystemFormatter extends AMDFormatter {
var assign = node;
for (var i = 0; i < exported.length; i++) {
assign = this.buildExportCall(t.literal(exported[i].name), assign);
assign = this._buildExportCall(t.literal(exported[i].name), assign);
}
return assign;
}
buildExportCall(id, init, isStatement) {
_buildExportCall(id, init, isStatement) {
var call = t.callExpression(this.exportIdentifier, [id, init]);
if (isStatement) {
return t.expressionStatement(call);
@@ -149,7 +149,7 @@ export default class SystemFormatter extends AMDFormatter {
this._addImportSource(last(nodes), node);
}
buildRunnerSetters(block, hoistDeclarators) {
_buildRunnerSetters(block, hoistDeclarators) {
var scope = this.file.scope;
return t.arrayExpression(map(this.ids, function (uid, source) {
@@ -165,7 +165,7 @@ export default class SystemFormatter extends AMDFormatter {
}));
}
canHoist(node) {
_canHoist(node) {
return node._blockHoist && !this.file.dynamicImports.length;
}
@@ -182,7 +182,7 @@ export default class SystemFormatter extends AMDFormatter {
MODULE_DEPENDENCIES: t.arrayExpression(this.buildDependencyLiterals()),
EXPORT_IDENTIFIER: this.exportIdentifier,
MODULE_NAME: moduleNameLiteral,
SETTERS: this.buildRunnerSetters(block, hoistDeclarators),
SETTERS: this._buildRunnerSetters(block, hoistDeclarators),
EXECUTE: t.functionExpression(null, [], block)
}, true);

View File

@@ -1,3 +1,3 @@
for (var LEN = ARGUMENTS.length, ARRAY = Array(ARRAY_LEN), KEY = START; KEY < LEN; KEY++) {
for (var LEN = ARGUMENTS.length, ARRAY: ARRAY_TYPE = Array(ARRAY_LEN), KEY = START; KEY < LEN; KEY++) {
ARRAY[ARRAY_KEY] = ARGUMENTS[KEY];
}

View File

@@ -557,9 +557,13 @@ class BlockScoping {
*/
pushDeclar(node: { type: "VariableDeclaration" }): Array<Object> {
this.body.push(t.variableDeclaration(node.kind, node.declarations.map(function (declar) {
return t.variableDeclarator(declar.id);
})));
var declars = [];
var names = t.getBindingIdentifiers(node);
for (var name in names) {
declars.push(t.variableDeclarator(names[name]));
}
this.body.push(t.variableDeclaration(node.kind, declars));
var replace = [];

View File

@@ -173,7 +173,7 @@ class ClassTransformer {
if (this.hasSuper) {
closureArgs.push(superName);
superName = this.scope.generateUidBasedOnNode(superName);
superName = this.scope.generateUidIdentifierBasedOnNode(superName);
closureParams.push(superName);
this.superName = superName;

View File

@@ -55,7 +55,7 @@ export function ForOfStatement(node, parent, scope, file) {
export { ForOfStatement as ForInStatement };
export function Func(node, parent, scope, file) {
export function Func/*tion*/(node, parent, scope, file) {
var nodes = [];
var hasDestructuring = false;
@@ -179,7 +179,7 @@ export function VariableDeclaration(node, parent, scope, file) {
file: file
});
if (t.isPattern(pattern) && patternId) {
if (t.isPattern(pattern)) {
destructuring.init(pattern, patternId);
if (+i !== node.declarations.length - 1) {
@@ -295,7 +295,7 @@ class DestructuringTransformer {
// we need to assign the current value of the assignment to avoid evaluating
// it more than once
var tempValueRef = this.scope.generateUidBasedOnNode(valueRef);
var tempValueRef = this.scope.generateUidIdentifierBasedOnNode(valueRef);
var declar = t.variableDeclaration("var", [
t.variableDeclarator(tempValueRef, valueRef)
@@ -377,7 +377,7 @@ class DestructuringTransformer {
// only evaluated once
if (pattern.properties.length > 1 && t.isMemberExpression(objRef)) {
var temp = this.scope.generateUidBasedOnNode(objRef, this.file);
var temp = this.scope.generateUidIdentifierBasedOnNode(objRef, this.file);
this.nodes.push(this.buildVariableDeclaration(temp, objRef));
objRef = temp;
}
@@ -461,7 +461,7 @@ class DestructuringTransformer {
// array
arrayRef = toArray;
} else {
arrayRef = this.scope.generateUidBasedOnNode(arrayRef);
arrayRef = this.scope.generateUidIdentifierBasedOnNode(arrayRef);
this.arrays[arrayRef.name] = true;
this.nodes.push(this.buildVariableDeclaration(arrayRef, toArray));
}
@@ -500,7 +500,7 @@ class DestructuringTransformer {
var shouldMemoise = true;
if (!t.isArrayExpression(ref) && !t.isMemberExpression(ref)) {
var memo = this.scope.generateMemoisedReference(ref, true);
var memo = this.scope.maybeGenerateMemoised(ref, true);
if (memo) {
this.nodes.push(this.buildVariableDeclaration(memo, ref));
ref = memo;

View File

@@ -33,7 +33,7 @@ export function ForOfStatement(node, parent, scope, file) {
this.parentPath.replaceWithMultiple(build.node);
this.remove();
} else {
this.replaceWithMultiple(build.node);
return build.node;
}
}

View File

@@ -22,7 +22,7 @@ var iifeVisitor = {
}
};
export function Func(node, parent, scope, file) {
export function Func/*tion*/(node, parent, scope, file) {
if (!hasDefaults(node)) return;
t.ensureBlock(node);

View File

@@ -53,10 +53,11 @@ var hasRest = function (node) {
return t.isRestElement(node.params[node.params.length - 1]);
};
export function Func(node, parent, scope, file) {
export function Func/*tion*/(node, parent, scope, file) {
if (!hasRest(node)) return;
var rest = node.params.pop().argument;
var restParam = node.params.pop();
var rest = restParam.argument;
var argsId = t.identifier("arguments");
@@ -125,13 +126,14 @@ export function Func(node, parent, scope, file) {
}
var loop = util.template("rest", {
ARGUMENTS: argsId,
ARRAY_KEY: arrKey,
ARRAY_LEN: arrLen,
START: start,
ARRAY: rest,
KEY: key,
LEN: len
ARRAY_TYPE: restParam.typeAnnotation,
ARGUMENTS: argsId,
ARRAY_KEY: arrKey,
ARRAY_LEN: arrLen,
START: start,
ARRAY: rest,
KEY: key,
LEN: len
});
loop._blockHoist = node.params.length + 1;
node.body.body.unshift(loop);

View File

@@ -75,7 +75,7 @@ export var ObjectExpression = {
if (!hasComputed) return;
var initProps = [];
var objId = scope.generateUidBasedOnNode(parent);
var objId = scope.generateUidIdentifierBasedOnNode(parent);
//

View File

@@ -84,7 +84,7 @@ export function CallExpression(node, parent, scope) {
var callee = node.callee;
if (this.get("callee").isMemberExpression()) {
var temp = scope.generateMemoisedReference(callee.object);
var temp = scope.maybeGenerateMemoised(callee.object);
if (temp) {
callee.object = t.assignmentExpression("=", temp, callee.object);
contextLiteral = temp;

View File

@@ -10,7 +10,7 @@ export var metadata = {
group: "builtin-trailing"
};
export function Func(node, parent, scope, file) {
export function Func/*tion*/(node, parent, scope, file) {
if (node.generator || node.async) return;
var tailCall = new TailCallTransformer(this, scope, file);
tailCall.run();

View File

@@ -26,7 +26,7 @@ function generator(node) {
}
function array(node, parent, scope, file) {
var uid = scope.generateUidBasedOnNode(parent);
var uid = scope.generateUidIdentifierBasedOnNode(parent);
var container = util.template("array-comprehension-container", {
KEY: uid

View File

@@ -0,0 +1,51 @@
// https://github.com/zenparsing/es-function-bind
import * as t from "../../../types";
export var metadata = {
optional: true,
stage: 0
};
function getTempId(scope) {
var id = scope.path.getData("functionBind");
if (id) return id;
id = scope.generateDeclaredUidIdentifier("context");
return scope.path.setData("functionBind", id);
}
function getStaticContext(bind, scope) {
var object = bind.object || bind.callee.object;
return scope.isStatic(object) && object;
}
function inferBindContext(bind, scope) {
var staticContext = getStaticContext(bind, scope);
if (staticContext) return staticContext;
var tempId = getTempId(scope);
if (bind.object) {
bind.callee = t.sequenceExpression([
t.assignmentExpression("=", tempId, bind.object),
bind.callee
]);
} else {
bind.callee.object = t.assignmentExpression("=", tempId, bind.callee.object);
}
return tempId;
}
export function CallExpression(node, parent, scope, file) {
var bind = node.callee;
if (!t.isBindExpression(bind)) return;
var context = inferBindContext(bind, scope);
node.callee = t.memberExpression(bind.callee, t.identifier("call"));
node.arguments.unshift(context);
}
export function BindExpression(node, parent, scope, file) {
var context = inferBindContext(node, scope);
return t.callExpression(t.memberExpression(node.callee, t.identifier("bind")), [context]);
}

View File

@@ -1,5 +1,6 @@
export default {
//- builtin-setup
strict: require("./other/strict"),
_explode: require("./internal/explode"),
_validation: require("./internal/validation"),
_hoistDirectives: require("./internal/hoist-directives"),
@@ -18,15 +19,12 @@ export default {
"es7.trailingFunctionCommas": require("./es7/trailing-function-commas"),
"es7.asyncFunctions": require("./es7/async-functions"),
"es7.decorators": require("./es7/decorators"),
strict: require("./other/strict"),
"validation.undeclaredVariableCheck": require("./validation/undeclared-variable-check"),
"validation.react": require("./validation/react"),
"es6.arrowFunctions": require("./es6/arrow-functions"),
"spec.blockScopedFunctions": require("./spec/block-scoped-functions"),
"optimisation.react.constantElements": require("./optimisation/react.constant-elements"),
"optimisation.react.inlineElements": require("./optimisation/react.inline-elements"),
reactCompat: require("./other/react-compat"),
react: require("./other/react"),
"es7.comprehensions": require("./es7/comprehensions"),
"es6.classes": require("./es6/classes"),
asyncToGenerator: require("./other/async-to-generator"),
@@ -51,6 +49,7 @@ export default {
"spec.protoToAssign": require("./spec/proto-to-assign"),
"es7.doExpressions": require("./es7/do-expressions"),
"es6.spec.symbols": require("./es6/spec.symbols"),
"es7.functionBind": require("./es7/function-bind"),
"spec.undefinedToVoid": require("./spec/undefined-to-void"),
jscript: require("./other/jscript"),
flow: require("./other/flow"),
@@ -59,6 +58,8 @@ export default {
"es6.destructuring": require("./es6/destructuring"),
"es6.blockScoping": require("./es6/block-scoping"),
"es6.spec.blockScoping": require("./es6/spec.block-scoping"),
reactCompat: require("./other/react-compat"),
react: require("./other/react"),
// es6 syntax transformation is **forbidden** past this point since regenerator will chuck a massive
// hissy fit

View File

@@ -85,18 +85,28 @@ export function ExportNamedDeclaration(node, parent, scope) {
}
}
export function Program(node) {
var imports = [];
var rest = [];
export var Program = {
enter(node) {
var imports = [];
var rest = [];
for (var i = 0; i < node.body.length; i++) {
var bodyNode = node.body[i];
if (t.isImportDeclaration(bodyNode)) {
imports.push(bodyNode);
} else {
rest.push(bodyNode);
for (var i = 0; i < node.body.length; i++) {
var bodyNode = node.body[i];
if (t.isImportDeclaration(bodyNode)) {
imports.push(bodyNode);
} else {
rest.push(bodyNode);
}
}
node.body = imports.concat(rest);
},
exit(node, parent, scope, file) {
if (!file.transformers["es6.modules"].canTransform()) return;
if (file.moduleFormatter.setup) {
file.moduleFormatter.setup();
}
}
node.body = imports.concat(rest);
}
};

View File

@@ -22,21 +22,23 @@ export var metadata = {
group: "builtin-setup"
};
export function Identifier(node, parent, scope) {
if (!this.isReferenced()) return;
export function ReferencedIdentifier(node, parent, scope) {
var binding = scope.getBinding(node.name);
if (!binding || binding.references > 1 || !binding.constant) return;
if (binding.kind === "param") return;
if (binding.kind === "param" || binding.kind === "module") return;
var replacement = binding.path.node;
if (t.isVariableDeclarator(replacement)) {
replacement = replacement.init;
}
if (!replacement) return;
if (this.findParent((node) => replacement)) {
return;
}
t.toExpression(replacement);
scope.removeBinding(node.name);
binding.path.remove();
return replacement;
}

View File

@@ -5,10 +5,12 @@ export var metadata = {
group: "builtin-setup"
};
export function Expression(node, parent, scope) {
var res = this.evaluate();
if (res.confident) return t.valueToNode(res.value);
}
export var Expression = {
exit(node, parent, scope) {
var res = this.evaluate();
if (res.confident) return t.valueToNode(res.value);
}
};
export function Identifier() {
// override Expression

View File

@@ -36,8 +36,7 @@ export function JSXElement(node, parent, scope, file) {
if (state.isImmutable) {
this.hoist();
this.skip();
} else {
node._hoisted = true;
}
node._hoisted = true;
}

View File

@@ -7,7 +7,7 @@ export var metadata = {
dependencies: ["es7.asyncFunctions", "es6.classes"]
};
export function Func(node, parent, scope, file) {
export function Func/*tion*/(node, parent, scope, file) {
if (!node.async || node.generator) return;
return remapAsyncToGenerator(node, file.addHelper("async-to-generator"), scope);

View File

@@ -10,7 +10,7 @@ export var metadata = {
dependencies: ["es7.asyncFunctions", "es6.classes"]
};
export function Func(node, parent, scope, file) {
export function Func/*tion*/(node, parent, scope, file) {
if (!node.async || node.generator) return;
return remapAsyncToGenerator(

View File

@@ -12,7 +12,7 @@ export function Class(node) {
node.implements = null;
}
export function Func(node) {
export function Func/*tion*/(node) {
for (var i = 0; i < node.params.length; i++) {
var param = node.params[i];
param.optional = false;

View File

@@ -6,7 +6,8 @@ export function manipulateOptions(opts) {
}
export var metadata = {
optional: true
optional: true,
group: "builtin-advanced"
};
require("../../helpers/build-react-transformer")(exports, {

View File

@@ -3,6 +3,10 @@ import * as t from "../../../types";
var JSX_ANNOTATION_REGEX = /^\*\s*@jsx\s+([^\s]+)/;
export var metadata = {
group: "builtin-advanced"
};
export function Program(node, parent, scope, file) {
var id = file.opts.jsxPragma;

View File

@@ -1,10 +1,69 @@
import regenerator from "regenerator";
import * as t from "../../../types";
import { NodePath } from "ast-types";
export var metadata = {
group: "regenerator"
};
export function Program(ast) {
regenerator.transform(ast);
export function Func/*tion*/(node) {
if (node.async || node.generator) {
// Although this code transforms only the subtree rooted at the given
// Function node, that node might contain other generator functions
// that will also be transformed. It might help performance to ignore
// nested functions, and rely on the traversal to visit them later,
// but that's a small optimization. Starting here instead of at the
// root of the AST is the key optimization, since huge async/generator
// functions are relatively rare.
regenerator.transform(convertTraversalPathToNodePath(this));
}
}
// Given a TraversalPath, return a NodePath that includes full ancestry
// information (up to and including the Program node). This is complicated
// by having to include intermediate objects like blockStatement.body
// arrays, in addition to Node objects.
function convertTraversalPathToNodePath(path) {
var programNode;
var keysAlongPath = [];
while (path) {
var pp = path.parentPath;
var parentNode = pp && pp.node;
if (parentNode) {
keysAlongPath.push(path.key);
if (parentNode !== path.container) {
var found = Object.keys(parentNode).some(containerKey => {
if (parentNode[containerKey] === path.container) {
keysAlongPath.push(containerKey);
return true;
}
});
if (!found) {
throw new Error("Failed to find container object in parent node");
}
}
if (t.isProgram(parentNode)) {
programNode = parentNode;
break;
}
}
path = pp;
}
if (!programNode) {
throw new Error("Failed to find root Program node");
}
var nodePath = new NodePath(programNode);
while (keysAlongPath.length > 0) {
nodePath = nodePath.get(keysAlongPath.pop());
}
return nodePath;
}

View File

@@ -1,6 +1,10 @@
import * as messages from "../../../messages";
import * as t from "../../../types";
export var metadata = {
group: "builtin-setup"
};
const THIS_BREAK_KEYS = ["FunctionExpression", "FunctionDeclaration", "ClassExpression", "ClassDeclaration"];
export var Program = {

View File

@@ -24,7 +24,7 @@ export function AssignmentExpression(node, parent, scope, file) {
var nodes = [];
var left = node.left.object;
var temp = scope.generateMemoisedReference(left);
var temp = scope.maybeGenerateMemoised(left);
nodes.push(t.expressionStatement(t.assignmentExpression("=", temp, left)));
nodes.push(buildDefaultsCallExpression(node, temp, file));

View File

@@ -16,7 +16,9 @@ export default class TraversalContext {
}
create(node, obj, key) {
return TraversalPath.get(this.parentPath, this, node, obj, key);
var path = TraversalPath.get(this.parentPath, node, obj, key);
path.unshiftContext(this);
return path;
}
visitMultiple(nodes, node, key) {
@@ -37,25 +39,32 @@ export default class TraversalContext {
}
// visit the queue
for (let i = 0; i < queue.length; i++) {
var path = queue[i];
for (let path of (queue: Array)) {
path.update();
if (visited.indexOf(path.node) >= 0) continue;
visited.push(path.node);
path.setContext(this.parentPath, this, path.key);
if (path.visit()) {
stop = true;
break;
}
}
for (let path of (queue: Array)) {
path.shiftContext();
}
this.queue = null;
return stop;
}
visitSingle(node, key) {
if (this.shouldVisit(node[key])) {
return this.create(node, node, key).visit();
var path = this.create(node, node, key);
path.visit();
path.shiftContext();
}
}

View File

@@ -92,6 +92,7 @@ export function evaluate(): { confident: boolean; value: any } {
case "!": return !arg;
case "+": return +arg;
case "-": return -arg;
case "~": return ~arg;
}
}
@@ -119,6 +120,7 @@ export function evaluate(): { confident: boolean; value: any } {
case "/": return left / right;
case "*": return left * right;
case "%": return left % right;
case "**": return Math.pow(left, right);
case "<": return left < right;
case ">": return left > right;
case "<=": return left <= right;

View File

@@ -2,26 +2,24 @@ import * as react from "../../transformation/helpers/react";
import * as t from "../../types";
var referenceVisitor = {
enter(node, parent, scope, state) {
ReferencedIdentifier(node, parent, scope, state) {
if (this.isJSXIdentifier() && react.isCompatTag(node.name)) {
return;
}
if (this.isJSXIdentifier() || this.isIdentifier()) {
// direct references that we need to track to hoist this to the highest scope we can
if (this.isReferenced()) {
var bindingInfo = scope.getBinding(node.name);
// direct references that we need to track to hoist this to the highest scope we can
var bindingInfo = scope.getBinding(node.name);
if (!bindingInfo) return;
// this binding isn't accessible from the parent scope so we can safely ignore it
// eg. it's in a closure etc
if (bindingInfo !== state.scope.getBinding(node.name)) return;
// this binding isn't accessible from the parent scope so we can safely ignore it
// eg. it's in a closure etc
if (bindingInfo !== state.scope.getBinding(node.name)) return;
if (bindingInfo && bindingInfo.constant) {
state.bindings[node.name] = bindingInfo;
} else {
state.foundIncompatible = true;
this.stop();
}
if (bindingInfo.constant) {
state.bindings[node.name] = bindingInfo;
} else {
for (var violationPath of (bindingInfo.constantViolations: Array)) {
state.breakOnScopePaths.push(violationPath.scope.path);
}
}
}
@@ -29,10 +27,10 @@ var referenceVisitor = {
export default class PathHoister {
constructor(path, scope) {
this.foundIncompatible = false;
this.breakOnScopePaths = [];
this.bindings = {};
this.scope = scope;
this.scopes = [];
this.scope = scope;
this.path = path;
}
@@ -43,32 +41,41 @@ export default class PathHoister {
return false;
}
}
return true;
}
getCompatibleScopes() {
var checkScope = this.path.scope;
var scope = this.path.scope;
do {
if (this.isCompatibleScope(checkScope)) {
this.scopes.push(checkScope);
if (this.isCompatibleScope(scope)) {
this.scopes.push(scope);
} else {
break;
}
} while(checkScope = checkScope.parent);
if (this.breakOnScopePaths.indexOf(scope.path) >= 0) {
break;
}
} while(scope = scope.parent);
}
getAttachmentPath() {
var scopes = this.scopes;
var scope = scopes.pop();
if (!scope) return;
if (scope.path.isFunction()) {
if (this.hasNonParamBindings()) {
// can't be attached to this scope
return this.getNextScopeStatementParent();
} else {
if (this.hasOwnParamBindings(scope)) {
// should ignore this scope since it's ourselves
if (this.scope.is(scope)) return;
// needs to be attached to the body
return scope.path.get("body").get("body")[0];
} else {
// doesn't need to be be attached to this scope
return this.getNextScopeStatementParent();
}
} else if (scope.path.isProgram()) {
return this.getNextScopeStatementParent();
@@ -80,10 +87,12 @@ export default class PathHoister {
if (scope) return scope.path.getStatementParent();
}
hasNonParamBindings() {
hasOwnParamBindings(scope) {
for (var name in this.bindings) {
if (!scope.hasOwnBinding(name)) continue
var binding = this.bindings[name];
if (binding.kind !== "param") return true;
if (binding.kind === "param") return true;
}
return false;
}
@@ -94,7 +103,6 @@ export default class PathHoister {
node._hoisted = true;
this.path.traverse(referenceVisitor, this);
if (this.foundIncompatible) return;
this.getCompatibleScopes();

View File

@@ -1,5 +1,6 @@
import PathHoister from "./hoister";
import * as virtualTypes from "./virtual-types";
import * as messages from "../../messages";
import isBoolean from "lodash/lang/isBoolean";
import isNumber from "lodash/lang/isNumber";
import isRegExp from "lodash/lang/isRegExp";
@@ -45,6 +46,7 @@ var hoistVariablesVisitor = explode({
export default class TraversalPath {
constructor(parent, container) {
this.container = container;
this.contexts = [];
this.parent = parent;
this.data = {};
}
@@ -53,7 +55,7 @@ export default class TraversalPath {
* Description
*/
static get(parentPath: TraversalPath, context?: TraversalContext, parent, container, key, file?: File) {
static get(parentPath: TraversalPath, parent, container, key) {
var targetNode = container[key];
var paths = container._paths = container._paths || [];
var path;
@@ -71,7 +73,7 @@ export default class TraversalPath {
paths.push(path);
}
path.setContext(parentPath, context, key, file);
path.setup(parentPath, key);
return path;
}
@@ -178,8 +180,10 @@ export default class TraversalPath {
*/
queueNode(path) {
if (this.context && this.context.queue) {
this.context.queue.push(path);
for (var context of (this.contexts: Array)) {
if (context.queue) {
context.queue.push(path);
}
}
}
@@ -201,7 +205,7 @@ export default class TraversalPath {
this._containerInsertBefore(nodes);
} else if (this.isStatementOrBlock()) {
if (this.node) nodes.push(this.node);
this.container[this.key] = t.blockStatement(nodes);
this.node = this.container[this.key] = t.blockStatement(nodes);
} else {
throw new Error("We don't know what to do with this node type. We were previously a Statement but we can't fit in here?");
}
@@ -225,17 +229,19 @@ export default class TraversalPath {
paths.push(path);
this.queueNode(path);
} else {
paths.push(TraversalPath.get(this, null, node, this.container, to));
paths.push(TraversalPath.get(this, node, this.container, to));
}
}
return paths;
}
_containerInsertBefore(nodes) {
this._containerInsert(this.key, nodes);
return this._containerInsert(this.key, nodes);
}
_containerInsertAfter(nodes) {
this._containerInsert(this.key + 1, nodes);
return this._containerInsert(this.key + 1, nodes);
}
_maybePopFromStatements(nodes) {
@@ -285,7 +291,7 @@ export default class TraversalPath {
return this.parentPath.insertAfter(nodes);
} else if (this.isPreviousType("Expression") || (this.parentPath.isForStatement() && this.key === "init")) {
if (this.node) {
var temp = this.scope.generateTemp();
var temp = this.scope.generateDeclaredUidIdentifier();
nodes.unshift(t.expressionStatement(t.assignmentExpression("=", temp, this.node)));
nodes.push(t.expressionStatement(temp));
}
@@ -296,7 +302,7 @@ export default class TraversalPath {
this._containerInsertAfter(nodes);
} else if (this.isStatementOrBlock()) {
if (this.node) nodes.unshift(this.node);
this.container[this.key] = t.blockStatement(nodes);
this.node = this.container[this.key] = t.blockStatement(nodes);
} else {
throw new Error("We don't know what to do with this node type. We were previously a Statement but we can't fit in here?");
}
@@ -342,6 +348,8 @@ export default class TraversalPath {
*/
setScope(file?) {
if (this.opts && this.opts.noScope) return;
var target = this.context || this.parentPath;
this.scope = TraversalPath.getScope(this, target && target.scope, file);
}
@@ -350,34 +358,87 @@ export default class TraversalPath {
* Description
*/
clearContext() {
this.context = null;
}
/**
* Description
*/
setContext(parentPath, context, key, file?) {
setContext(context, file) {
this.shouldSkip = false;
this.shouldStop = false;
this.removed = false;
this.parentPath = parentPath || this.parentPath;
this.key = key;
if (context) {
this.context = context;
this.state = context.state;
this.opts = context.opts;
}
this.type = this.node && this.node.type;
var log = file && this.type === "Program";
if (log) file.log.debug("Start scope building");
this.setScope(file);
if (log) file.log.debug("End scope building");
return this;
}
/**
* Description
*/
update() {
if (this.node === this.container[this.key]) return;
// grrr, path key is out of sync. this is likely due to a modification to the AST
// not through our path APIs
if (Array.isArray(this.container)) {
for (var i = 0; i < this.container.length; i++) {
if (this.container[i] === this.node) {
return this.setKey(i);
}
}
} else {
for (var key in this.container) {
if (this.container[key] === this.node) {
return this.setKey(key);
}
}
}
throw new Error(messages.get("lostTrackNodePath"));
}
/**
* Description
*/
shiftContext() {
this.contexts.shift();
this.setContext(this.contexts[0]);
}
/**
* Description
*/
unshiftContext(context) {
this.contexts.unshift(context);
this.setContext(context);
}
/**
* Description
*/
setup(parentPath, key) {
this.parentPath = parentPath || this.parentPath;
this.setKey(key);
}
/**
* Description
*/
setKey(key) {
this.key = key;
this.node = this.container[this.key];
this.type = this.node && this.node.type;
}
/**
@@ -468,6 +529,7 @@ export default class TraversalPath {
} else {
this.container[this.key] = null;
}
this.node = null;
}
/**
@@ -498,18 +560,6 @@ export default class TraversalPath {
return err;
}
get node() {
if (this.removed) {
return null;
} else {
return this.container[this.key];
}
}
set node(replacement) {
throw new Error("Don't use `path.node = newNode;`, use `path.replaceWith(newNode)` or `path.replaceWithMultiple([newNode])`");
}
/**
* Description
*/
@@ -562,7 +612,7 @@ export default class TraversalPath {
// doesn't matter, our nodes will be inserted anyway
var container = this.node[containerKey];
var path = TraversalPath.get(this, null, this.node, container, 0);
var path = TraversalPath.get(this, this.node, container, 0);
return path.insertBefore(nodes);
}
@@ -579,7 +629,7 @@ export default class TraversalPath {
var container = this.node[containerKey];
var i = container.length;
var path = TraversalPath.get(this, null, this.node, container, i);
var path = TraversalPath.get(this, this.node, container, i);
return path.replaceWith(nodes, true);
}
@@ -591,7 +641,7 @@ export default class TraversalPath {
replaceWithMultiple(nodes: Array<Object>) {
nodes = this._verifyNodeList(nodes);
t.inheritsComments(nodes[0], this.node);
this.container[this.key] = null;
this.node = this.container[this.key] = null;
this.insertAfter(nodes);
if (!this.node) this.remove();
}
@@ -671,7 +721,7 @@ export default class TraversalPath {
if (oldNode) t.inheritsComments(replacement, oldNode);
// replace the node
this.container[this.key] = replacement;
this.node = this.container[this.key] = replacement;
this.type = replacement.type;
// potentially create new scope
@@ -775,9 +825,10 @@ export default class TraversalPath {
var node = this.node;
if (!node) return;
var previousType = this.type;
// call the function with the params (node, parent, scope, state)
var replacement = fn.call(this, node, this.parent, this.scope, this.state);
var previousType = this.type;
if (replacement) {
this.replaceWith(replacement, true);
@@ -785,7 +836,7 @@ export default class TraversalPath {
if (this.shouldStop || this.shouldSkip || this.removed) return;
if (replacement && previousType !== this.type) {
if (previousType !== this.type) {
this.queueNode(this);
return;
}
@@ -839,7 +890,7 @@ export default class TraversalPath {
*/
getSibling(key) {
return TraversalPath.get(this.parentPath, null, this.parent, this.container, key, this.file);
return TraversalPath.get(this.parentPath, this.parent, this.container, key, this.file);
}
/**
@@ -866,10 +917,10 @@ export default class TraversalPath {
if (Array.isArray(container)) {
// requested a container so give them all the paths
return container.map((_, i) => {
return TraversalPath.get(this, null, node, container, i);
return TraversalPath.get(this, node, container, i).setContext();
});
} else {
return TraversalPath.get(this, null, node, node, key);
return TraversalPath.get(this, node, node, key).setContext();
}
}
@@ -947,7 +998,7 @@ export default class TraversalPath {
annotation: null
};
var type = this.node.typeAnnotation;
var type = this.node && this.node.typeAnnotation;
if (!type) {
info.inferred = true;
@@ -1025,36 +1076,36 @@ export default class TraversalPath {
path = path.resolve();
if (!path) return;
if (path.isRestElement() || path.parentPath.isRestElement() || path.isArrayExpression()) {
if (path.isPreviousType("RestElement") || path.parentPath.isPreviousType("RestElement") || path.isPreviousType("ArrayExpression")) {
return t.genericTypeAnnotation(t.identifier("Array"));
}
if (path.parentPath.isTypeCastExpression()) {
if (path.parentPath.isPreviousType("TypeCastExpression")) {
return path.parentPath.node.typeAnnotation;
}
if (path.isTypeCastExpression()) {
if (path.isPreviousType("TypeCastExpression")) {
return path.node.typeAnnotation;
}
if (path.isObjectExpression()) {
if (path.isPreviousType("ObjectExpression")) {
return t.genericTypeAnnotation(t.identifier("Object"));
}
if (path.isFunction()) {
if (path.isPreviousType("Function")) {
return t.identifier("Function");
}
if (path.isLiteral()) {
if (path.isPreviousType("Literal")) {
var value = path.node.value;
if (isString(value)) return t.stringTypeAnnotation();
if (isNumber(value)) return t.numberTypeAnnotation();
if (isBoolean(value)) return t.booleanTypeAnnotation();
}
if (path.isCallExpression()) {
if (path.isPreviousType("CallExpression")) {
var callee = path.get("callee").resolve();
if (callee && callee.isFunction()) return callee.node.returnType;
if (callee && callee.isPreviousType("Function")) return callee.node.returnType;
}
}
@@ -1103,6 +1154,7 @@ export default class TraversalPath {
*/
traverse(visitor, state) {
if (!this.scope) console.log(this.contexts);
traverse(this.node, visitor, this.scope, state, this);
}

View File

@@ -1,11 +1,14 @@
import * as t from "../types";
import * as t from "../../types";
export default class Binding {
constructor({ identifier, scope, path, kind }) {
this.constantViolations = [];
this.constant = true;
this.identifier = identifier;
this.references = 0;
this.referenced = false;
this.constant = true;
this.scope = scope;
this.path = path;
this.kind = kind;
@@ -51,8 +54,9 @@ export default class Binding {
* Description
*/
reassign() {
reassign(path) {
this.constant = false;
this.constantViolations.push(path);
if (this.typeAnnotationInferred) {
// destroy the inferred typeAnnotation
@@ -69,6 +73,15 @@ export default class Binding {
this.references++;
}
/**
* Description
*/
dereference() {
this.references--;
this.referenced = !!this.references;
}
/**
* Description
*/

View File

@@ -1,15 +1,15 @@
import includes from "lodash/collection/includes";
import { explode } from "./visitors";
import traverse from "./index";
import { explode } from "../visitors";
import traverse from "../index";
import defaults from "lodash/object/defaults";
import * as messages from "../messages";
import * as messages from "../../messages";
import Binding from "./binding";
import globals from "globals";
import flatten from "lodash/array/flatten";
import extend from "lodash/object/extend";
import object from "../helpers/object";
import object from "../../helpers/object";
import each from "lodash/collection/each";
import * as t from "../types";
import * as t from "../../types";
var functionVariableVisitor = {
enter(node, parent, scope, state) {
@@ -163,11 +163,22 @@ export default class Scope {
traverse(node, opts, this, state, this.path);
}
/**
* Since `Scope` instances are unique to their traversal we need some other
* way to compare if scopes are the same. Here we just compare `this.bindings`
* as it will be the same across all instances.
*/
is(scope) {
return this.bindings === scope.bindings;
}
/**
* Description
*/
generateTemp(name: string = "temp") {
generateDeclaredUidIdentifier(name: string = "temp") {
var id = this.generateUidIdentifier(name);
this.push({ id });
return id;
@@ -213,7 +224,7 @@ export default class Scope {
* Description
*/
generateUidBasedOnNode(parent: Object, defaultName?: String): Object {
generateUidIdentifierBasedOnNode(parent: Object, defaultName?: String): Object {
var node = parent;
if (t.isAssignmentExpression(parent)) {
@@ -264,21 +275,39 @@ export default class Scope {
}
/**
* Description
* Determine whether evaluating the specific input `node` is a consequenceless reference. ie.
* evaluating it wont result in potentially arbitrary code from being ran. The following are
* whitelisted and determined not cause side effects:
*
* - `this` expressions
* - `super` expressions
* - Bound identifiers
*/
generateMemoisedReference(node: Object, dontPush?: boolean): ?Object {
isStatic(node: Object): boolean {
if (t.isThisExpression(node) || t.isSuper(node)) {
return null;
return true;
}
if (t.isIdentifier(node) && this.hasBinding(node.name)) {
return null;
return true;
}
var id = this.generateUidBasedOnNode(node);
if (!dontPush) this.push({ id });
return id;
return false;
}
/**
* Description
*/
maybeGenerateMemoised(node: Object, dontPush?: boolean): ?Object {
if (this.isStatic(node)) {
return null;
} else {
var id = this.generateUidIdentifierBasedOnNode(node);
if (!dontPush) this.push({ id });
return id;
}
}
/**
@@ -417,11 +446,13 @@ export default class Scope {
for (var name in ids) {
var binding = this.getBinding(name);
if (!binding) continue;
if (right) {
var rightType = right.typeAnnotation;
if (rightType && binding.isCompatibleWithType(rightType)) continue;
}
binding.reassign();
binding.reassign(left, right);
}
}
@@ -432,6 +463,14 @@ export default class Scope {
registerBinding(kind: string, path: TraversalPath) {
if (!kind) throw new ReferenceError("no `kind`");
if (path.isVariableDeclaration()) {
var declarators = path.get("declarations");
for (var declar of (declarators: Array)) {
this.registerBinding(kind, declar);
}
return;
}
var ids = path.getBindingIdentifiers();
for (var name in ids) {
@@ -514,7 +553,7 @@ export default class Scope {
isPure(node) {
if (t.isIdentifier(node)) {
var bindingInfo = this.getBinding(node.name);
return bindingInfo.constant;
return bindingInfo && bindingInfo.constant;
} else {
return t.isPure(node);
}
@@ -560,8 +599,13 @@ export default class Scope {
// Class
if (path.isClass() && path.has("id")) {
this.registerBinding("var", path.get("id"));
if (path.isClassDeclaration()) {
var name = path.node.id.name;
this.bindings[name] = this.parent.bindings[name];
}
if (path.isClassExpression() && path.has("id")) {
this.registerBinding("var", path);
}
// Function - params, rest
@@ -631,13 +675,14 @@ export default class Scope {
var declar = !unique && path.getData(dataKey);
if (!declar) {
declar = t.variableDeclaration(opts.kind || "var", []);
declar = t.variableDeclaration(kind, []);
declar._generated = true;
declar._blockHoist = 2;
this.file.attachAuxiliaryComment(declar);
path.get("body")[0]._containerInsertBefore([declar]);
var [declarPath] = path.get("body")[0]._containerInsertBefore([declar]);
this.registerBinding(kind, declarPath);
if (!unique) path.setData(dataKey, declar);
}

View File

@@ -20,6 +20,11 @@
"right": null
},
"BindExpression": {
"object": null,
"callee": null
},
"BlockStatement": {
"body": null
},

View File

@@ -49,12 +49,27 @@ export function isReferenced(node: Object, parent: Object): boolean {
return parent.id !== node;
// no: export { foo as NODE };
// yes: export { NODE as foo };
// no: export { NODE as foo } from "foo";
case "ExportSpecifier":
return parent.exported !== node;
if (parent.source) {
return false;
} else {
return parent.local === node;
}
// no: import NODE from "foo";
case "ImportDefaultSpecifier":
return false;
// no: import * as NODE from "foo";
case "ImportNamespaceSpecifier":
return false;
// no: import { NODE as foo } from "foo";
// no: import { foo as NODE } from "foo";
case "ImportSpecifier":
return parent.imported !== node;
return false;
// no: class NODE {}
case "ClassDeclaration":

View File

@@ -6,6 +6,7 @@
"AssignmentPattern": ["left", "right"],
"AwaitExpression": ["argument"],
"BinaryExpression": ["left", "right"],
"BindExpression": ["object", "callee"],
"BlockStatement": ["body"],
"BreakStatement": ["label"],
"CallExpression": ["callee", "arguments"],

View File

@@ -1,7 +1,7 @@
import "./patch";
import escapeRegExp from "lodash/string/escapeRegExp";
import startsWith from "lodash/string/startsWith";
import cloneDeep from "lodash/lang/cloneDeep";
import isBoolean from "lodash/lang/isBoolean";
import * as messages from "./messages";
@@ -69,9 +69,23 @@ export function list(val: string): Array<string> {
export function regexify(val: any): RegExp {
if (!val) return new RegExp(/.^/);
if (Array.isArray(val)) val = new RegExp(val.map(escapeRegExp).join("|"), "i");
if (isString(val)) return minimatch.makeRe(val, { nocase: true });
if (isString(val)) {
// normalise path separators
val = slash(val);
// remove starting wildcards or relative separator if present
if (startsWith(val, "./") || startsWith(val, "*/")) val = val.slice(2);
if (startsWith(val, "**/")) val = val.slice(3);
var regex = minimatch.makeRe(val, { nocase: true });
return new RegExp(regex.source.slice(1, -1), "i");
}
if (isRegExp(val)) return val;
throw new TypeError("illegal type for regexify");
}
@@ -96,6 +110,7 @@ export function booleanify(val: any): boolean {
export function shouldIgnore(filename, ignore, only) {
filename = slash(filename);
if (only.length) {
for (var pattern of (only: Array)) {
if (pattern.test(filename)) return false;

View File

@@ -99,6 +99,47 @@ suite("api", function () {
});
});
suite("env option", function () {
var oldBabelEnv = process.env.BABEL_ENV;
var oldNodeEnv = process.env.NODE_ENV;
before(function () {
delete process.env.BABEL_ENV;
delete process.env.NODE_ENV;
});
after(function () {
process.env.BABEL_ENV = oldBabelEnv;
process.env.NODE_ENV = oldNodeEnv;
});
test("default", function () {
assert.equal(transform("foo;", {
env: {
development: { blacklist: "strict" }
}
}).code, "foo;");
});
test("BABEL_ENV", function () {
process.env.BABEL_ENV = "foo";
assert.equal(transform("foo;", {
env: {
foo: { blacklist: "strict" }
}
}).code, "foo;");
});
test("NODE_ENV", function () {
process.env.NODE_ENV = "foo";
assert.equal(transform("foo;", {
env: {
foo: { blacklist: "strict" }
}
}).code, "foo;");
});
});
test("addHelper unknown", function () {
var file = new File({}, transform.pipeline);
assert.throws(function () {

View File

@@ -0,0 +1,6 @@
function foo(l) {
return (
// hi
l
);
}

View File

@@ -0,0 +1,4 @@
function foo(l){
return (
l);}

View File

@@ -0,0 +1,4 @@
{
"retainLines": true,
"compact": true
}

View File

@@ -0,0 +1,5 @@
::foo.bar.foo;
::foo.bar["foo"];
ctx::foo.bar.foo;
ctx::foo.bar["foo"];

View File

@@ -0,0 +1,5 @@
::foo.bar.foo;
::foo.bar["foo"];
ctx::foo.bar.foo;
ctx::foo.bar["foo"];

View File

@@ -1,5 +1,6 @@
for (let i of nums) {
var x = 5;
var { f } = { f: 2 };
fns.push(function () {
return i * x;
});

View File

@@ -8,6 +8,8 @@ try {
var _loop = function () {
var i = _step.value;
x = 5;
var _f = { f: 2 };
f = _f.f;
fns.push(function () {
return i * x;
@@ -16,6 +18,7 @@ try {
for (var _iterator = nums[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var x;
var f;
_loop();
}
@@ -32,4 +35,4 @@ try {
throw _iteratorError;
}
}
}
}

View File

@@ -0,0 +1,3 @@
export function module() {
}

View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.module = _module;
function _module() {}

View File

@@ -0,0 +1,3 @@
var f = ctx::ns.obj.func;
var g = ::ns.obj.func;
var h = new X::y;

View File

@@ -0,0 +1,7 @@
"use strict";
var _context;
var f = (_context = ctx, ns.obj.func).bind(_context);
var g = (_context = ns.obj).func.bind(_context);
var h = (_context = new X(), y).bind(_context);

View File

@@ -0,0 +1,4 @@
ctx::ns.obj.func();
::ns.obj.func();
ns.obj2::ns.obj1.func();

View File

@@ -0,0 +1,8 @@
"use strict";
var _context;
(_context = ctx, ns.obj.func).call(_context);
(_context = ns.obj).func.call(_context);
(_context = ns.obj2, ns.obj1.func).call(_context);

View File

@@ -0,0 +1,6 @@
import { map, takeWhile, forEach } from "iterlib";
getPlayers()
::map(x => x.character())
::takeWhile(x => x.strength > 100)
::forEach(x => console.log(x));

View File

@@ -0,0 +1,27 @@
var operations = [];
var lib = {};
for (let key of ['f', 'g', 'h']) {
let func = () => operations.push(`lib.${key}()`);
Object.defineProperty(lib, key, {
get() {
operations.push(`get lib.${key}`);
return func;
}
});
}
({prop:'value'})
::lib.f()
::lib.g()
::lib.h();
assert.deepEqual(operations, [
'get lib.f',
'lib.f()',
'get lib.g',
'lib.g()',
'get lib.h',
'lib.h()'
]);

View File

@@ -0,0 +1,13 @@
"use strict";
var _context;
var _iterlib = require("iterlib");
(_context = (_context = (_context = getPlayers(), _iterlib.map).call(_context, function (x) {
return x.character();
}), _iterlib.takeWhile).call(_context, function (x) {
return x.strength > 100;
}), _iterlib.forEach).call(_context, function (x) {
return console.log(x);
});

View File

@@ -0,0 +1,3 @@
{
"optional": "es7.functionBind"
}

View File

@@ -0,0 +1,5 @@
var bar = function () {};
foo::bar;
var foo = {};
::foo.bar;

View File

@@ -0,0 +1,7 @@
"use strict";
var bar = function bar() {};
bar.bind(foo);
var foo = {};
foo.bar.bind(foo);

View File

@@ -0,0 +1,4 @@
class A {
constructor() { this.value = 12345; }
}
export default new A();

View File

@@ -0,0 +1,3 @@
import aInstance from './imported';
assert.equal(aInstance.value, 12345);

View File

@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var A = function A() {
babelHelpers.classCallCheck(this, A);
this.value = 12345;
};
exports["default"] = new A();
module.exports = exports["default"];

View File

@@ -0,0 +1,4 @@
class A {
constructor() { this.value = 12345; }
}
export default new A();

View File

@@ -0,0 +1,5 @@
class A {
f() { return 1235; }
}
let a = new A();

View File

@@ -0,0 +1,5 @@
class A {
k() { return 12345; }
}
assert.equal((new A()).k(), 12345);

View File

@@ -0,0 +1,17 @@
"use strict";
var A = (function () {
function A() {
babelHelpers.classCallCheck(this, A);
}
babelHelpers.createClass(A, [{
key: "f",
value: function f() {
return 1235;
}
}]);
return A;
})();
var a = new A();

View File

@@ -0,0 +1 @@
import x from 'y';

View File

@@ -0,0 +1,6 @@
'use strict';
var _y = require('y');
var _y2 = babelHelpers.interopRequireDefault(_y);

View File

@@ -0,0 +1,3 @@
import x from 'y';
x.foo = function (err) {};

View File

@@ -0,0 +1,5 @@
import x from 'y';
x.z = function (a) { return 1 + a; };
assert(x.z(x.value), 43);

View File

@@ -0,0 +1,8 @@
'use strict';
var _y = require('y');
var _y2 = babelHelpers.interopRequireDefault(_y);
_y2['default'].foo = function (err) {};

View File

@@ -0,0 +1,2 @@
let y = { value: 42 };
export default y;

View File

@@ -0,0 +1,5 @@
function f(a) {
return !a;
}
export { f };

View File

@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function f(a) {
return !a;
}
exports.f = f;

View File

@@ -0,0 +1,13 @@
function* x() {
for (let a of []) {
for (let b of a) {
yield 1;
}
}
}
function y() {
return [...x()];
}
export { y };

View File

@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function* x() {
var _arr = [];
for (var _i = 0; _i < _arr.length; _i++) {
var a = _arr[_i];var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = a[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var b = _step.value;
yield 1;
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator["return"]) {
_iterator["return"]();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
}
function y() {
return [].concat(babelHelpers.toConsumableArray(x()));
}
exports.y = y;

View File

@@ -0,0 +1,7 @@
class X {
Y() {
return new X();
}
}
export { X };

View File

@@ -0,0 +1,22 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var X = (function () {
function X() {
babelHelpers.classCallCheck(this, X);
}
babelHelpers.createClass(X, [{
key: "Y",
value: function Y() {
return new X();
}
}]);
return X;
})();
exports.X = X;

View File

@@ -0,0 +1,6 @@
{
"externalHelpers": true,
"noCheckAst": true,
"blacklist": ["regenerator"],
"optional": ["minification.deadCodeElimination"]
}

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