diff --git a/.mention-bot b/.mention-bot index 32b2d0479e72..671103a31cd8 100644 --- a/.mention-bot +++ b/.mention-bot @@ -1,5 +1,11 @@ { - "userBlacklist": [ "amasad", "thejameskyle", "jmm", "kittens" ], + "userBlacklist": [ + "amasad", + "greenkeeperio-bot", + "jmm", + "kittens", + "thejameskyle" + ], "fileBlacklist": ["*.md"], "skipAlreadyAssignedPR": true, "createReviewRequest": true diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ff3de0e5146..96d28278e150 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,96 @@ _Note: Gaps between patch versions are faulty, broken or test releases._ See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog. +## 6.23.0 (2017-02-13) + +#### :rocket: New Feature +* `babel-plugin-transform-react-constant-elements` + * [#4812](https://github.com/babel/babel/pull/4812) feature: Support pure expressions in transform-react-constant-elements. ([@STRML](https://github.com/STRML)) +* `babel-preset-flow`, `babel-preset-react` + * [#5288](https://github.com/babel/babel/pull/5288) Add new flow preset. ([@thejameskyle](https://github.com/thejameskyle)) +* `babel-traverse` + * [#5230](https://github.com/babel/babel/pull/5230) Add path/family sibling traversal methods. ([@chitchu](https://github.com/chitchu)) +* `babel-plugin-transform-es2015-block-scoping` + * [#5236](https://github.com/babel/babel/pull/5236) Add option to block-scoping to throw on slow code. ([@spicyj](https://github.com/spicyj)) + +#### :bug: Bug Fix +* `babel-core`, `babel-traverse` + * [#5050](https://github.com/babel/babel/pull/5050) Rewrite Hub as interface #5047. ([@yongxu](https://github.com/yongxu)) +* `babel-plugin-transform-es2015-for-of` + * [#5298](https://github.com/babel/babel/pull/5298) Fix loose for-of with label. ([@jridgewell](https://github.com/jridgewell)) +* `babel-plugin-transform-react-constant-elements`, `babel-traverse` + * [#5153](https://github.com/babel/babel/pull/5153) Fix react constant elements bindings. ([@STRML](https://github.com/STRML)) + * [#5143](https://github.com/babel/babel/pull/5143) Fix PathHoister hoisting JSX member expressions on "this".. ([@STRML](https://github.com/STRML)) +* `babel-plugin-transform-do-expressions`, `babel-traverse` + * [#5030](https://github.com/babel/babel/pull/5030) Prevent multiple return statements in a loop when replacing expressions. ([@existentialism](https://github.com/existentialism)) +* `babel-register` + * [#5260](https://github.com/babel/babel/pull/5260) Fix TypeError with babel-register's cache. ([@xtuc](https://github.com/xtuc)) +* `babel-traverse` + * [#5206](https://github.com/babel/babel/pull/5206) Deopt evaluation of undefined with a local binding. Closes [#5204](https://github.com/babel/babel/issues/5204). ([@boopathi](https://github.com/boopathi)) +* `babel-plugin-transform-runtime` + * [#5195](https://github.com/babel/babel/pull/5195) Don't transpile ES7 symbol properties. ([@taion](https://github.com/taion)) +* `babel` + * [#5258](https://github.com/babel/babel/pull/5258) checks if babel is installed globally and displays correct cli message. ([@xtina-starr](https://github.com/xtina-starr)) +* `babel-generator` + * [#5270](https://github.com/babel/babel/pull/5270) Emit parens for await of ternary expressions. ([@erikdesjardins](https://github.com/erikdesjardins)) + * [#5193](https://github.com/babel/babel/pull/5193) Fix missing parens when function expressions is tag. ([@existentialism](https://github.com/existentialism)) +* `babel-plugin-transform-es2015-modules-commonjs` + * [#5235](https://github.com/babel/babel/pull/5235) Limit export node default assignment stack size #4323. ([@mattste](https://github.com/mattste)) + +#### :memo: Documentation +* `babel-*` + * [#5244](https://github.com/babel/babel/pull/5244) Normalize options sections in docs [skip ci]. ([@existentialism](https://github.com/existentialism)) + * [#5216](https://github.com/babel/babel/pull/5216) Remove link to REPL. ([@xtuc](https://github.com/xtuc)) +* Other + * [#5242](https://github.com/babel/babel/pull/5242) Add our business model [skip ci]. ([@hzoo](https://github.com/hzoo)) +* `babel-plugin-transform-es2015-spread` + * [#5227](https://github.com/babel/babel/pull/5227) Add example to spread README [skip ci]. ([@finkef](https://github.com/finkef)) +* `babel-plugin-transform-flow-strip-types` + * [#5212](https://github.com/babel/babel/pull/5212) Remove REPL link transform-flow-strip-types doc. ([@xtuc](https://github.com/xtuc)) +* `babel-plugin-transform-regenerator` + * [#5202](https://github.com/babel/babel/pull/5202) Fix transform-regenerator README. ([@xtuc](https://github.com/xtuc)) +* `babel-plugin-transform-es2015-arrow-functions` + * [#5200](https://github.com/babel/babel/pull/5200) Fix transform-es2015-arrow-functions code blocks on the website. ([@xtuc](https://github.com/xtuc)) + * [#5194](https://github.com/babel/babel/pull/5194) Fix transform-es2015-arrow-functions README. ([@xtuc](https://github.com/xtuc)) + +#### :house: Internal +* `babel-core` + * [#5302](https://github.com/babel/babel/pull/5302) Add charset so tests work with convert-source-map@>1.4. ([@loganfsmyth](https://github.com/loganfsmyth)) +* `babel-core`, `babel-traverse` + * [#5050](https://github.com/babel/babel/pull/5050) Rewrite Hub as interface #5047. ([@yongxu](https://github.com/yongxu)) +* `babel-generator` + * [#5255](https://github.com/babel/babel/pull/5255) codegen performance: use trim instead of lodash/trimEnd. ([@jwbay](https://github.com/jwbay)) +* `babel-types` + * [#5181](https://github.com/babel/babel/pull/5181) Remove uses of lodash/compact. ([@zertosh](https://github.com/zertosh)) +* `babel-*` + * [#5265](https://github.com/babel/babel/pull/5265) Re-enable the max-len ESLint rule.. ([@loganfsmyth](https://github.com/loganfsmyth)) +* Other + * [#5264](https://github.com/babel/babel/pull/5264) Add a sublime project file. ([@loganfsmyth](https://github.com/loganfsmyth)) + * [#5182](https://github.com/babel/babel/pull/5182) Run coverage only once. ([@existentialism](https://github.com/existentialism)) + * [#5165](https://github.com/babel/babel/pull/5165) Add Node 7 to CI. ([@chicoxyzzy](https://github.com/chicoxyzzy)) + +#### Committers: 20 +- Andres Suarez ([zertosh](https://github.com/zertosh)) +- Ben Alpert ([spicyj](https://github.com/spicyj)) +- Boopathi Rajaa ([boopathi](https://github.com/boopathi)) +- Brian Ng ([existentialism](https://github.com/existentialism)) +- Christina ([xtina-starr](https://github.com/xtina-starr)) +- Erik Desjardins ([erikdesjardins](https://github.com/erikdesjardins)) +- Fabian Finke ([finkef](https://github.com/finkef)) +- Henry Zhu ([hzoo](https://github.com/hzoo)) +- Jimmy Jia ([taion](https://github.com/taion)) +- Justin Ridgewell ([jridgewell](https://github.com/jridgewell)) +- Logan Smyth ([loganfsmyth](https://github.com/loganfsmyth)) +- Matt Stewart ([mattste](https://github.com/mattste)) +- Samuel Reed ([STRML](https://github.com/STRML)) +- Sergey Rubanov ([chicoxyzzy](https://github.com/chicoxyzzy)) +- Sven SAULEAU ([xtuc](https://github.com/xtuc)) +- Vicente Jr Yuchitcho ([chitchu](https://github.com/chitchu)) +- Yongxu Ren ([yongxu](https://github.com/yongxu)) +- [jwbay](https://github.com/jwbay) +- james kyle ([thejameskyle](https://github.com/thejameskyle)) +- Łukasz Lityński ([hex13](https://github.com/hex13)) + ## 6.22.2 (2017-01-19) #### :bug: Bug Fix diff --git a/packages/babel-cli/package.json b/packages/babel-cli/package.json index dba5eea05a4d..f836c0d113d5 100644 --- a/packages/babel-cli/package.json +++ b/packages/babel-cli/package.json @@ -1,6 +1,6 @@ { "name": "babel-cli", - "version": "6.22.2", + "version": "6.23.0", "description": "Babel command line.", "author": "Sebastian McKenzie ", "homepage": "https://babeljs.io/", @@ -16,9 +16,9 @@ "compiler" ], "dependencies": { - "babel-core": "^6.22.1", - "babel-register": "^6.22.0", - "babel-polyfill": "^6.22.0", + "babel-core": "^6.23.0", + "babel-register": "^6.23.0", + "babel-polyfill": "^6.23.0", "commander": "^2.8.1", "convert-source-map": "^1.1.0", "fs-readdir-recursive": "^1.0.0", diff --git a/packages/babel-core/package.json b/packages/babel-core/package.json index e28bf0b3c70f..4e44376e714f 100644 --- a/packages/babel-core/package.json +++ b/packages/babel-core/package.json @@ -1,6 +1,6 @@ { "name": "babel-core", - "version": "6.22.1", + "version": "6.23.1", "description": "Babel compiler core.", "author": "Sebastian McKenzie ", "homepage": "https://babeljs.io/", @@ -27,13 +27,13 @@ }, "dependencies": { "babel-code-frame": "^6.22.0", - "babel-generator": "^6.22.0", - "babel-helpers": "^6.22.0", - "babel-messages": "^6.22.0", - "babel-template": "^6.22.0", - "babel-register": "^6.22.0", - "babel-traverse": "^6.22.1", - "babel-types": "^6.22.0", + "babel-generator": "^6.23.0", + "babel-helpers": "^6.23.0", + "babel-messages": "^6.23.0", + "babel-template": "^6.23.0", + "babel-register": "^6.23.0", + "babel-traverse": "^6.23.1", + "babel-types": "^6.23.0", "babylon": "^6.11.0", "convert-source-map": "^1.1.0", "debug": "^2.1.1", @@ -46,7 +46,7 @@ }, "devDependencies": { "babel-helper-fixtures": "^6.22.0", - "babel-helper-transform-fixture-test-runner": "^6.22.0", - "babel-polyfill": "^6.22.0" + "babel-helper-transform-fixture-test-runner": "^6.23.0", + "babel-polyfill": "^6.23.0" } } diff --git a/packages/babel-core/test/fixtures/transformation/misc/regression-2364/actual.js b/packages/babel-core/test/fixtures/transformation/misc/regression-2364/actual.js index e995e0d23496..c2ae386b34dd 100644 --- a/packages/babel-core/test/fixtures/transformation/misc/regression-2364/actual.js +++ b/packages/babel-core/test/fixtures/transformation/misc/regression-2364/actual.js @@ -1,6 +1,6 @@ function wrapper(fn) { return (...args) => { - if (someCondition) { + while (someCondition) { const val = fn(...args); return val.test(() => { console.log(val); diff --git a/packages/babel-core/test/fixtures/transformation/misc/regression-2364/expected.js b/packages/babel-core/test/fixtures/transformation/misc/regression-2364/expected.js index ae32dbb4d39a..c1079c01cbbf 100644 --- a/packages/babel-core/test/fixtures/transformation/misc/regression-2364/expected.js +++ b/packages/babel-core/test/fixtures/transformation/misc/regression-2364/expected.js @@ -2,17 +2,19 @@ function wrapper(fn) { return function () { var _arguments = arguments; - if (someCondition) { - var _ret = function () { - var val = fn(..._arguments); - return { - v: val.test(function () { - console.log(val); - }) - }; - }(); + var _loop = function () { + var val = fn(..._arguments); + return { + v: val.test(function () { + console.log(val); + }) + }; + }; + + while (someCondition) { + var _ret = _loop(); if (typeof _ret === "object") return _ret.v; } }; -} \ No newline at end of file +} diff --git a/packages/babel-core/test/fixtures/transformation/source-maps/inline/expected.js b/packages/babel-core/test/fixtures/transformation/source-maps/inline/expected.js index 00ae47b8755d..991056b8bf3a 100644 --- a/packages/babel-core/test/fixtures/transformation/source-maps/inline/expected.js +++ b/packages/babel-core/test/fixtures/transformation/source-maps/inline/expected.js @@ -1,4 +1,4 @@ arr.map(function (x) { return x * x; }); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNvdXJjZS1tYXBzL2lubGluZS9hY3R1YWwuanMiXSwibmFtZXMiOlsiYXJyIiwibWFwIiwieCJdLCJtYXBwaW5ncyI6IkFBQUFBLElBQUlDLEdBQUosQ0FBUTtBQUFBLFNBQUtDLElBQUlBLENBQVQ7QUFBQSxDQUFSIiwiZmlsZSI6InNvdXJjZS1tYXBzL2lubGluZS9leHBlY3RlZC5qcyIsInNvdXJjZXNDb250ZW50IjpbImFyci5tYXAoeCA9PiB4ICogeCk7Il19 +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNvdXJjZS1tYXBzL2lubGluZS9hY3R1YWwuanMiXSwibmFtZXMiOlsiYXJyIiwibWFwIiwieCJdLCJtYXBwaW5ncyI6IkFBQUFBLElBQUlDLEdBQUosQ0FBUTtBQUFBLFNBQUtDLElBQUlBLENBQVQ7QUFBQSxDQUFSIiwiZmlsZSI6InNvdXJjZS1tYXBzL2lubGluZS9leHBlY3RlZC5qcyIsInNvdXJjZXNDb250ZW50IjpbImFyci5tYXAoeCA9PiB4ICogeCk7Il19 diff --git a/packages/babel-generator/package.json b/packages/babel-generator/package.json index 7e5511e36725..e45347d97446 100644 --- a/packages/babel-generator/package.json +++ b/packages/babel-generator/package.json @@ -1,6 +1,6 @@ { "name": "babel-generator", - "version": "6.22.0", + "version": "6.23.0", "description": "Turns an AST into code.", "author": "Sebastian McKenzie ", "homepage": "https://babeljs.io/", @@ -11,9 +11,9 @@ "lib" ], "dependencies": { - "babel-messages": "^6.22.0", - "babel-types": "^6.22.0", - "detect-indent": "^5.0.0", + "babel-messages": "^6.23.0", + "babel-types": "^6.23.0", + "detect-indent": "^4.0.0", "jsesc": "^1.3.0", "lodash": "^4.2.0", "source-map": "^0.5.0", diff --git a/packages/babel-helper-builder-react-jsx/package.json b/packages/babel-helper-builder-react-jsx/package.json index b42a80759e2f..cbeceb179c0f 100644 --- a/packages/babel-helper-builder-react-jsx/package.json +++ b/packages/babel-helper-builder-react-jsx/package.json @@ -1,12 +1,12 @@ { "name": "babel-helper-builder-react-jsx", - "version": "6.22.0", + "version": "6.23.0", "description": "Helper function to build react jsx", "repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-builder-react-jsx", "license": "MIT", "main": "lib/index.js", "dependencies": { - "babel-types": "^6.22.0", + "babel-types": "^6.23.0", "esutils": "^2.0.0", "lodash": "^4.2.0" } diff --git a/packages/babel-helper-define-map/package.json b/packages/babel-helper-define-map/package.json index 6b3757805046..c16bb59384e0 100644 --- a/packages/babel-helper-define-map/package.json +++ b/packages/babel-helper-define-map/package.json @@ -1,13 +1,13 @@ { "name": "babel-helper-define-map", - "version": "6.22.0", + "version": "6.23.0", "description": "Helper function to define a map", "repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-define-map", "license": "MIT", "main": "lib/index.js", "dependencies": { "lodash": "^4.2.0", - "babel-types": "^6.22.0", - "babel-helper-function-name": "^6.22.0" + "babel-types": "^6.23.0", + "babel-helper-function-name": "^6.23.0" } } diff --git a/packages/babel-helper-function-name/package.json b/packages/babel-helper-function-name/package.json index e73131de5d40..62c9f9373f57 100644 --- a/packages/babel-helper-function-name/package.json +++ b/packages/babel-helper-function-name/package.json @@ -1,14 +1,14 @@ { "name": "babel-helper-function-name", - "version": "6.22.0", + "version": "6.23.0", "description": "Helper function to change the property 'name' of every function", "repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-function-name", "license": "MIT", "main": "lib/index.js", "dependencies": { - "babel-types": "^6.22.0", - "babel-traverse": "^6.22.0", + "babel-types": "^6.23.0", + "babel-traverse": "^6.23.0", "babel-helper-get-function-arity": "^6.22.0", - "babel-template": "^6.22.0" + "babel-template": "^6.23.0" } } diff --git a/packages/babel-helper-optimise-call-expression/package.json b/packages/babel-helper-optimise-call-expression/package.json index b3b8cbdcb467..80e1f3424228 100644 --- a/packages/babel-helper-optimise-call-expression/package.json +++ b/packages/babel-helper-optimise-call-expression/package.json @@ -1,11 +1,11 @@ { "name": "babel-helper-optimise-call-expression", - "version": "6.22.0", + "version": "6.23.0", "description": "Helper function to optimise call expression", "repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-optimise-call-expression", "license": "MIT", "main": "lib/index.js", "dependencies": { - "babel-types": "^6.22.0" + "babel-types": "^6.23.0" } } diff --git a/packages/babel-helper-replace-supers/package.json b/packages/babel-helper-replace-supers/package.json index d1bb2832095b..24edb8200270 100644 --- a/packages/babel-helper-replace-supers/package.json +++ b/packages/babel-helper-replace-supers/package.json @@ -1,15 +1,15 @@ { "name": "babel-helper-replace-supers", - "version": "6.22.0", + "version": "6.23.0", "description": "Helper function to replace supers", "repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-replace-supers", "license": "MIT", "main": "lib/index.js", "dependencies": { - "babel-helper-optimise-call-expression": "^6.22.0", - "babel-traverse": "^6.22.0", - "babel-messages": "^6.22.0", - "babel-template": "^6.22.0", - "babel-types": "^6.22.0" + "babel-helper-optimise-call-expression": "^6.23.0", + "babel-traverse": "^6.23.0", + "babel-messages": "^6.23.0", + "babel-template": "^6.23.0", + "babel-types": "^6.23.0" } } diff --git a/packages/babel-helper-transform-fixture-test-runner/package.json b/packages/babel-helper-transform-fixture-test-runner/package.json index 2d9f78097a93..f5c03762893e 100644 --- a/packages/babel-helper-transform-fixture-test-runner/package.json +++ b/packages/babel-helper-transform-fixture-test-runner/package.json @@ -1,6 +1,6 @@ { "name": "babel-helper-transform-fixture-test-runner", - "version": "6.22.0", + "version": "6.23.0", "description": "Transform test runner for babel-helper-fixtures module", "author": "Sebastian McKenzie ", "homepage": "https://babeljs.io/", @@ -8,8 +8,8 @@ "repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-transform-fixture-test-runner", "main": "lib/index.js", "dependencies": { - "babel-core": "^6.22.0", - "babel-polyfill": "^6.22.0", + "babel-core": "^6.23.0", + "babel-polyfill": "^6.23.0", "babel-helper-fixtures": "^6.22.0", "source-map": "^0.5.0", "babel-code-frame": "^6.22.0", diff --git a/packages/babel-helpers/package.json b/packages/babel-helpers/package.json index 19e03ccd865d..bc88144c05e4 100644 --- a/packages/babel-helpers/package.json +++ b/packages/babel-helpers/package.json @@ -1,6 +1,6 @@ { "name": "babel-helpers", - "version": "6.22.0", + "version": "6.23.0", "description": "Collection of helper functions used by Babel transforms.", "author": "Sebastian McKenzie ", "homepage": "https://babeljs.io/", @@ -8,6 +8,6 @@ "repository": "https://github.com/babel/babel/tree/master/packages/babel-helpers", "main": "lib/index.js", "dependencies": { - "babel-template": "^6.22.0" + "babel-template": "^6.23.0" } } diff --git a/packages/babel-messages/package.json b/packages/babel-messages/package.json index 022d7508ac37..177efb0499df 100644 --- a/packages/babel-messages/package.json +++ b/packages/babel-messages/package.json @@ -1,6 +1,6 @@ { "name": "babel-messages", - "version": "6.22.0", + "version": "6.23.0", "description": "Collection of debug messages used by Babel.", "author": "Sebastian McKenzie ", "homepage": "https://babeljs.io/", diff --git a/packages/babel-plugin-transform-class-properties/package.json b/packages/babel-plugin-transform-class-properties/package.json index 7122b69b1065..8f0b3d74cd28 100644 --- a/packages/babel-plugin-transform-class-properties/package.json +++ b/packages/babel-plugin-transform-class-properties/package.json @@ -1,6 +1,6 @@ { "name": "babel-plugin-transform-class-properties", - "version": "6.22.0", + "version": "6.23.0", "description": "This plugin transforms static class properties as well as properties declared with the property initializer syntax", "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-class-properties", "license": "MIT", @@ -9,9 +9,9 @@ "babel-plugin" ], "dependencies": { - "babel-helper-function-name": "^6.22.0", + "babel-helper-function-name": "^6.23.0", "babel-plugin-syntax-class-properties": "^6.8.0", - "babel-template": "^6.22.0" + "babel-template": "^6.23.0" }, "devDependencies": { "babel-helper-plugin-test-runner": "^6.22.0" diff --git a/packages/babel-plugin-transform-es2015-block-scoping/package.json b/packages/babel-plugin-transform-es2015-block-scoping/package.json index ef72fdfecf2b..569706fca18c 100644 --- a/packages/babel-plugin-transform-es2015-block-scoping/package.json +++ b/packages/babel-plugin-transform-es2015-block-scoping/package.json @@ -1,14 +1,14 @@ { "name": "babel-plugin-transform-es2015-block-scoping", - "version": "6.22.0", + "version": "6.23.0", "description": "Compile ES2015 block scoping (const and let) to ES5", "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-block-scoping", "license": "MIT", "main": "lib/index.js", "dependencies": { - "babel-traverse": "^6.22.0", - "babel-types": "^6.22.0", - "babel-template": "^6.22.0", + "babel-traverse": "^6.23.0", + "babel-types": "^6.23.0", + "babel-template": "^6.23.0", "lodash": "^4.2.0" }, "keywords": [ diff --git a/packages/babel-plugin-transform-es2015-block-scoping/src/index.js b/packages/babel-plugin-transform-es2015-block-scoping/src/index.js index b1227d3a52c0..f63305462297 100644 --- a/packages/babel-plugin-transform-es2015-block-scoping/src/index.js +++ b/packages/babel-plugin-transform-es2015-block-scoping/src/index.js @@ -112,8 +112,21 @@ function isVar(node) { } const letReferenceBlockVisitor = traverse.visitors.merge([{ + Loop: { + enter(path, state) { + state.loopDepth++; + }, + exit(path, state) { + state.loopDepth--; + }, + }, Function(path, state) { - path.traverse(letReferenceFunctionVisitor, state); + // References to block-scoped variables only require added closures if it's + // possible for the code to run more than once -- otherwise it is safe to + // simply rename the variables. + if (state.loopDepth > 0) { + path.traverse(letReferenceFunctionVisitor, state); + } return path.skip(); } }, tdzVisitor]); @@ -549,9 +562,19 @@ class BlockScoping { const state = { letReferences: this.letReferences, closurify: false, - file: this.file + file: this.file, + loopDepth: 0, }; + const loopOrFunctionParent = this.blockPath.find( + (path) => path.isLoop() || path.isFunction() + ); + if (loopOrFunctionParent && loopOrFunctionParent.isLoop()) { + // There is a loop ancestor closer than the closest function, so we + // consider ourselves to be in a loop. + state.loopDepth++; + } + // traverse through this block, stopping on functions and checking if they // contain any local let references this.blockPath.traverse(letReferenceBlockVisitor, state); diff --git a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/issue-2174/expected.js b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/issue-2174/expected.js index 1dce9c4c174c..9efbc1091f2b 100644 --- a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/issue-2174/expected.js +++ b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/issue-2174/expected.js @@ -1,11 +1,9 @@ if (true) { - var x; + var foo = function () {}; - (function () { - function foo() {} - function bar() { - return foo; - } - for (x in {}) {} - })(); + var bar = function () { + return foo; + }; + + for (var x in {}) {} } diff --git a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/loops-and-no-loops/actual.js b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/loops-and-no-loops/actual.js new file mode 100644 index 000000000000..f030ac811de4 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/loops-and-no-loops/actual.js @@ -0,0 +1,34 @@ +function foo() { + const x = 5; + console.log(x); + + { + const x = 7; + setTimeout(() => x, 0); + } +} + +function bar() { + const x = 5; + console.log(x); + + for (let i = 0; i < 7; i++) { + { + const x = i; + setTimeout(() => x, 0); + } + } +} + +function baz() { + const x = 5; + console.log(x); + + for (let i = 0; i < 7; i++) { + var qux = function qux(y) { + const x = y; + setTimeout(() => x, 0); + }; + qux(i); + } +} diff --git a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/loops-and-no-loops/expected.js b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/loops-and-no-loops/expected.js new file mode 100644 index 000000000000..a86a2e481147 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/loops-and-no-loops/expected.js @@ -0,0 +1,42 @@ +function foo() { + var x = 5; + console.log(x); + + { + var _x = 7; + setTimeout(function () { + return _x; + }, 0); + } +} + +function bar() { + var x = 5; + console.log(x); + + for (var i = 0; i < 7; i++) { + { + (function () { + var x = i; + setTimeout(function () { + return x; + }, 0); + })(); + } + } +} + +function baz() { + var x = 5; + console.log(x); + + for (var i = 0; i < 7; i++) { + var qux = function qux(y) { + var x = y; + setTimeout(function () { + return x; + }, 0); + }; + qux(i); + } +} diff --git a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/sibling-scopes/actual.js b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/sibling-scopes/actual.js new file mode 100644 index 000000000000..e3020dada7f6 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/sibling-scopes/actual.js @@ -0,0 +1,11 @@ +var f1, f2; +{ + let z = 'z1 value'; + f1 = function() { return z; }; +} +{ + let z = 'z2 value'; + f2 = function() { return z; }; +} +f1(); +f2(); diff --git a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/sibling-scopes/expected.js b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/sibling-scopes/expected.js new file mode 100644 index 000000000000..8bbdfc7ddff4 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/sibling-scopes/expected.js @@ -0,0 +1,15 @@ +var f1, f2; +{ + var z = 'z1 value'; + f1 = function () { + return z; + }; +} +{ + var _z = 'z2 value'; + f2 = function () { + return _z; + }; +} +f1(); +f2(); \ No newline at end of file diff --git a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/superswitch/actual.js b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/superswitch/actual.js index 857b8641f415..5dedf9a59244 100644 --- a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/superswitch/actual.js +++ b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/superswitch/actual.js @@ -1,16 +1,18 @@ function foo() { - switch (2) { - case 0: { - if (true) { - return; - } + while (true) { + switch (2) { + case 0: { + if (true) { + return; + } - const stuff = new Map(); - const data = 0; - stuff.forEach(() => { - const d = data; - }); - break; + const stuff = new Map(); + const data = 0; + stuff.forEach(() => { + const d = data; + }); + break; + } } } } diff --git a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/superswitch/expected.js b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/superswitch/expected.js index 05d7afe3d96c..80b21eba9cdc 100644 --- a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/superswitch/expected.js +++ b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/superswitch/expected.js @@ -1,29 +1,31 @@ function foo() { - switch (2) { - case 0: - { - var _ret = function () { - if (true) { - return { - v: void 0 - }; - } + while (true) { + switch (2) { + case 0: + { + var _ret = function () { + if (true) { + return { + v: void 0 + }; + } - var stuff = new Map(); - var data = 0; - stuff.forEach(function () { - var d = data; - }); - return "break"; - }(); + var stuff = new Map(); + var data = 0; + stuff.forEach(function () { + var d = data; + }); + return "break"; + }(); - switch (_ret) { - case "break": - break; + switch (_ret) { + case "break": + break; - default: - if (typeof _ret === "object") return _ret.v; + default: + if (typeof _ret === "object") return _ret.v; + } } - } + } } } diff --git a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/switch-callbacks/actual.js b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/switch-callbacks/actual.js index c57bdc6e5150..99f8726f058a 100644 --- a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/switch-callbacks/actual.js +++ b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/switch-callbacks/actual.js @@ -1,10 +1,12 @@ function fn() { - switch (true) { - default: - let foo = 4; - if (true) { - let bar = () => foo; - console.log(bar()); + while (true) { + switch (true) { + default: + let foo = 4; + if (true) { + let bar = () => foo; + console.log(bar()); + } } } } diff --git a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/switch-callbacks/expected.js b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/switch-callbacks/expected.js index 2efd145af333..40f23daea608 100644 --- a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/switch-callbacks/expected.js +++ b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/general/switch-callbacks/expected.js @@ -1,14 +1,16 @@ function fn() { - (function () { - switch (true) { - default: - var foo = 4; - if (true) { - var bar = function () { - return foo; - }; - console.log(bar()); - } - } - })(); + while (true) { + (function () { + switch (true) { + default: + var foo = 4; + if (true) { + var bar = function () { + return foo; + }; + console.log(bar()); + } + } + })(); + } } diff --git a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/for-const-closure/expected.js b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/for-const-closure/expected.js new file mode 100644 index 000000000000..c28cb3bf748e --- /dev/null +++ b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/for-const-closure/expected.js @@ -0,0 +1,6 @@ +for (var i = 0; i < 5; i++) { + var l = i; + setTimeout(function () { + console.log(l); + }, 1); +} \ No newline at end of file diff --git a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/superswitch/actual.js b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/superswitch/actual.js deleted file mode 100644 index 857b8641f415..000000000000 --- a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/superswitch/actual.js +++ /dev/null @@ -1,16 +0,0 @@ -function foo() { - switch (2) { - case 0: { - if (true) { - return; - } - - const stuff = new Map(); - const data = 0; - stuff.forEach(() => { - const d = data; - }); - break; - } - } -} diff --git a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/superswitch/options.json b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/superswitch/options.json deleted file mode 100644 index d210fdebfc97..000000000000 --- a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/superswitch/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "Compiling let/const in this block would add a closure (throwIfClosureRequired)." -} diff --git a/packages/babel-plugin-transform-es2015-classes/package.json b/packages/babel-plugin-transform-es2015-classes/package.json index 1d17d0b74835..cd552e395d28 100644 --- a/packages/babel-plugin-transform-es2015-classes/package.json +++ b/packages/babel-plugin-transform-es2015-classes/package.json @@ -1,19 +1,19 @@ { "name": "babel-plugin-transform-es2015-classes", - "version": "6.22.0", + "version": "6.23.0", "description": "Compile ES2015 classes to ES5", "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-classes", "license": "MIT", "main": "lib/index.js", "dependencies": { - "babel-helper-optimise-call-expression": "^6.22.0", - "babel-helper-function-name": "^6.22.0", - "babel-helper-replace-supers": "^6.22.0", - "babel-template": "^6.22.0", - "babel-traverse": "^6.22.0", - "babel-helper-define-map": "^6.22.0", - "babel-messages": "^6.22.0", - "babel-types": "^6.22.0" + "babel-helper-optimise-call-expression": "^6.23.0", + "babel-helper-function-name": "^6.23.0", + "babel-helper-replace-supers": "^6.23.0", + "babel-template": "^6.23.0", + "babel-traverse": "^6.23.0", + "babel-helper-define-map": "^6.23.0", + "babel-messages": "^6.23.0", + "babel-types": "^6.23.0" }, "keywords": [ "babel-plugin" diff --git a/packages/babel-plugin-transform-es2015-destructuring/package.json b/packages/babel-plugin-transform-es2015-destructuring/package.json index 4eb5eb75aee5..53b5174965fd 100644 --- a/packages/babel-plugin-transform-es2015-destructuring/package.json +++ b/packages/babel-plugin-transform-es2015-destructuring/package.json @@ -1,6 +1,6 @@ { "name": "babel-plugin-transform-es2015-destructuring", - "version": "6.22.0", + "version": "6.23.0", "description": "Compile ES2015 destructuring to ES5", "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-destructuring", "license": "MIT", diff --git a/packages/babel-plugin-transform-es2015-for-of/package.json b/packages/babel-plugin-transform-es2015-for-of/package.json index 53b2959969f4..99c92140bf8f 100644 --- a/packages/babel-plugin-transform-es2015-for-of/package.json +++ b/packages/babel-plugin-transform-es2015-for-of/package.json @@ -1,6 +1,6 @@ { "name": "babel-plugin-transform-es2015-for-of", - "version": "6.22.0", + "version": "6.23.0", "description": "Compile ES2015 for...of to ES5", "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-for-of", "license": "MIT", diff --git a/packages/babel-plugin-transform-es2015-for-of/src/index.js b/packages/babel-plugin-transform-es2015-for-of/src/index.js index 958eae6bce1b..b0b3a6bcbffc 100644 --- a/packages/babel-plugin-transform-es2015-for-of/src/index.js +++ b/packages/babel-plugin-transform-es2015-for-of/src/index.js @@ -135,9 +135,8 @@ export default function ({ messages, template, types: t }) { }; function loose(path, file) { - const { node, scope } = path; - - const left = node.left; + const { node, scope, parent } = path; + const { left } = node; let declar, id; if (t.isIdentifier(left) || t.isPattern(left) || t.isMemberExpression(left)) { @@ -171,11 +170,18 @@ export default function ({ messages, template, types: t }) { } // + const isLabeledParent = t.isLabeledStatement(parent); + let labeled; + + if (isLabeledParent) { + labeled = t.labeledStatement(parent.label, loop); + } return { - declar: declar, - node: loop, - loop: loop + replaceParent: isLabeledParent, + declar: declar, + node: labeled || loop, + loop: loop }; } diff --git a/packages/babel-plugin-transform-es2015-for-of/test/fixtures/loose/nested-label-for-of/actual.js b/packages/babel-plugin-transform-es2015-for-of/test/fixtures/loose/nested-label-for-of/actual.js new file mode 100644 index 000000000000..73c8203449d4 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-for-of/test/fixtures/loose/nested-label-for-of/actual.js @@ -0,0 +1,5 @@ +b: for (let c of d()) { + for (let e of f()) { + continue b; + } +} diff --git a/packages/babel-plugin-transform-es2015-for-of/test/fixtures/loose/nested-label-for-of/expected.js b/packages/babel-plugin-transform-es2015-for-of/test/fixtures/loose/nested-label-for-of/expected.js new file mode 100644 index 000000000000..e3e9396649ef --- /dev/null +++ b/packages/babel-plugin-transform-es2015-for-of/test/fixtures/loose/nested-label-for-of/expected.js @@ -0,0 +1,31 @@ +b: for (var _iterator = d(), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + var _ref; + + if (_isArray) { + if (_i >= _iterator.length) break; + _ref = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + _ref = _i.value; + } + + let c = _ref; + + for (var _iterator2 = f(), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { + var _ref2; + + if (_isArray2) { + if (_i2 >= _iterator2.length) break; + _ref2 = _iterator2[_i2++]; + } else { + _i2 = _iterator2.next(); + if (_i2.done) break; + _ref2 = _i2.value; + } + + let e = _ref2; + + continue b; + } +} diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/package.json b/packages/babel-plugin-transform-es2015-modules-commonjs/package.json index 923bf06419bf..47cca38a41d6 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/package.json +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/package.json @@ -1,13 +1,13 @@ { "name": "babel-plugin-transform-es2015-modules-commonjs", - "version": "6.22.0", + "version": "6.23.0", "description": "This plugin transforms ES2015 modules to CommonJS", "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-modules-commonjs", "license": "MIT", "main": "lib/index.js", "dependencies": { - "babel-types": "^6.22.0", - "babel-template": "^6.22.0", + "babel-types": "^6.23.0", + "babel-template": "^6.23.0", "babel-plugin-transform-strict-mode": "^6.22.0" }, "keywords": [ diff --git a/packages/babel-plugin-transform-es2015-modules-systemjs/package.json b/packages/babel-plugin-transform-es2015-modules-systemjs/package.json index 73cdf2d9c589..4d6e0841fbe0 100644 --- a/packages/babel-plugin-transform-es2015-modules-systemjs/package.json +++ b/packages/babel-plugin-transform-es2015-modules-systemjs/package.json @@ -1,12 +1,12 @@ { "name": "babel-plugin-transform-es2015-modules-systemjs", - "version": "6.22.0", + "version": "6.23.0", "description": "This plugin transforms ES2015 modules to SystemJS", "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-modules-systemjs", "license": "MIT", "main": "lib/index.js", "dependencies": { - "babel-template": "^6.22.0", + "babel-template": "^6.23.0", "babel-helper-hoist-variables": "^6.22.0" }, "keywords": [ diff --git a/packages/babel-plugin-transform-es2015-modules-umd/package.json b/packages/babel-plugin-transform-es2015-modules-umd/package.json index 95944f163b55..d4a5a0e71d8b 100644 --- a/packages/babel-plugin-transform-es2015-modules-umd/package.json +++ b/packages/babel-plugin-transform-es2015-modules-umd/package.json @@ -1,13 +1,13 @@ { "name": "babel-plugin-transform-es2015-modules-umd", - "version": "6.22.0", + "version": "6.23.0", "description": "This plugin transforms ES2015 modules to UMD", "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-modules-umd", "license": "MIT", "main": "lib/index.js", "dependencies": { "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-template": "^6.22.0" + "babel-template": "^6.23.0" }, "keywords": [ "babel-plugin" diff --git a/packages/babel-plugin-transform-es2015-parameters/package.json b/packages/babel-plugin-transform-es2015-parameters/package.json index 72fdeee2a421..1dec6ec1515d 100644 --- a/packages/babel-plugin-transform-es2015-parameters/package.json +++ b/packages/babel-plugin-transform-es2015-parameters/package.json @@ -1,16 +1,16 @@ { "name": "babel-plugin-transform-es2015-parameters", - "version": "6.22.0", + "version": "6.23.0", "description": "Compile ES2015 default and rest parameters to ES5", "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-parameters", "license": "MIT", "main": "lib/index.js", "dependencies": { - "babel-traverse": "^6.22.0", + "babel-traverse": "^6.23.0", "babel-helper-call-delegate": "^6.22.0", "babel-helper-get-function-arity": "^6.22.0", - "babel-template": "^6.22.0", - "babel-types": "^6.22.0" + "babel-template": "^6.23.0", + "babel-types": "^6.23.0" }, "keywords": [ "babel-plugin" diff --git a/packages/babel-plugin-transform-es2015-typeof-symbol/package.json b/packages/babel-plugin-transform-es2015-typeof-symbol/package.json index 323c189e9345..75fb73930ea1 100644 --- a/packages/babel-plugin-transform-es2015-typeof-symbol/package.json +++ b/packages/babel-plugin-transform-es2015-typeof-symbol/package.json @@ -1,6 +1,6 @@ { "name": "babel-plugin-transform-es2015-typeof-symbol", - "version": "6.22.0", + "version": "6.23.0", "description": "This transformer wraps all typeof expressions with a method that replicates native behaviour. (ie. returning “symbol” for symbols)", "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-es2015-typeof-symbol", "license": "MIT", diff --git a/packages/babel-plugin-transform-object-rest-spread/package.json b/packages/babel-plugin-transform-object-rest-spread/package.json index b3686266c18a..d4bdce78b56a 100644 --- a/packages/babel-plugin-transform-object-rest-spread/package.json +++ b/packages/babel-plugin-transform-object-rest-spread/package.json @@ -1,6 +1,6 @@ { "name": "babel-plugin-transform-object-rest-spread", - "version": "6.22.0", + "version": "6.23.0", "description": "Compile object rest and spread to ES5", "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-object-rest-spread", "license": "MIT", diff --git a/packages/babel-plugin-transform-proto-to-assign/package.json b/packages/babel-plugin-transform-proto-to-assign/package.json index b0eb2e46e11c..8817ae36f6e4 100644 --- a/packages/babel-plugin-transform-proto-to-assign/package.json +++ b/packages/babel-plugin-transform-proto-to-assign/package.json @@ -1,6 +1,6 @@ { "name": "babel-plugin-transform-proto-to-assign", - "version": "6.22.0", + "version": "6.23.0", "description": "Babel plugin for turning __proto__ into a shallow property clone", "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-proto-to-assign", "license": "MIT", diff --git a/packages/babel-plugin-transform-react-constant-elements/package.json b/packages/babel-plugin-transform-react-constant-elements/package.json index 79d30ac76273..77c911d9a775 100644 --- a/packages/babel-plugin-transform-react-constant-elements/package.json +++ b/packages/babel-plugin-transform-react-constant-elements/package.json @@ -1,6 +1,6 @@ { "name": "babel-plugin-transform-react-constant-elements", - "version": "6.22.0", + "version": "6.23.0", "description": "Treat React JSX elements as value types and hoist them to the highest scope", "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-constant-elements", "license": "MIT", diff --git a/packages/babel-plugin-transform-react-constant-elements/src/index.js b/packages/babel-plugin-transform-react-constant-elements/src/index.js index a25fb67e6c6d..b38f2008d154 100644 --- a/packages/babel-plugin-transform-react-constant-elements/src/index.js +++ b/packages/babel-plugin-transform-react-constant-elements/src/index.js @@ -1,4 +1,4 @@ -export default function () { +export default function ({ types: t }) { const immutabilityVisitor = { enter(path, state) { const stop = () => { @@ -11,15 +11,39 @@ export default function () { return; } + // Elements with refs are not safe to hoist. if (path.isJSXIdentifier({ name: "ref" }) && path.parentPath.isJSXAttribute({ name: path.node })) { return stop(); } + // Ignore identifiers & JSX expressions. if (path.isJSXIdentifier() || path.isIdentifier() || path.isJSXMemberExpression()) { return; } - if (!path.isImmutable()) stop(); + if (!path.isImmutable()) { + // If it's not immutable, it may still be a pure expression, such as string concatenation. + // It is still safe to hoist that, so long as its result is immutable. + // If not, it is not safe to replace as mutable values (like objects) could be mutated after render. + // https://github.com/facebook/react/issues/3226 + if (path.isPure()) { + const expressionResult = path.evaluate(); + if (expressionResult.confident) { + // We know the result; check its mutability. + const { value } = expressionResult; + const isMutable = (value && typeof value === "object") || (typeof value === "function"); + if (!isMutable) { + // It evaluated to an immutable value, so we can hoist it. + return; + } + } else if (t.isIdentifier(expressionResult.deopt)) { + // It's safe to hoist here if the deopt reason is an identifier (e.g. func param). + // The hoister will take care of how high up it can be hoisted. + return; + } + } + stop(); + } } }; diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/append-to-end-when-declared-in-scope-3/expected.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/append-to-end-when-declared-in-scope-3/expected.js index cceca3a5e883..46849febf69f 100644 --- a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/append-to-end-when-declared-in-scope-3/expected.js +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/append-to-end-when-declared-in-scope-3/expected.js @@ -1,18 +1,19 @@ -var _ref =

Parent

; - var _ref2 =
child
; +var _ref3 =

Parent

; + (function () { class App extends React.Component { render() { - return
- {_ref} - -
; + return _ref; } } const AppItem = () => { return _ref2; - }; -}); + }, + _ref =
+ {_ref3} + +
; +}); \ No newline at end of file diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/append-to-end-when-declared-in-scope/expected.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/append-to-end-when-declared-in-scope/expected.js index 5fc826084567..fe04d4853fea 100644 --- a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/append-to-end-when-declared-in-scope/expected.js +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/append-to-end-when-declared-in-scope/expected.js @@ -1,16 +1,14 @@ -var _ref =

Parent

; - export default class App extends React.Component { render() { - return
- {_ref} - -
; + return _ref; } } -var _ref2 =
child
; - -const AppItem = () => { +const _ref2 =
child
, + AppItem = () => { return _ref2; -}; +}, + _ref =
+

Parent

+ +
; \ No newline at end of file diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-before-class/actual.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-before-class/actual.js new file mode 100644 index 000000000000..0bcdd9ef7c39 --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-before-class/actual.js @@ -0,0 +1,15 @@ +import React from "react"; + +const Parent = ({}) => ( +
+ +
+); + +export default Parent; + +let Child = () => ( +
+ ChildTextContent +
+); diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-before-class/expected.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-before-class/expected.js new file mode 100644 index 000000000000..6bcd6e0ffbd8 --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-before-class/expected.js @@ -0,0 +1,13 @@ +import React from "react"; + +const Parent = ({}) => _ref; + +export default Parent; + +let _ref2 =
+ ChildTextContent +
, + Child = () => _ref2, + _ref =
+ +
; diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-before-declaration/expected.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-before-declaration/expected.js index d85f9f3244c6..45b91bd2961c 100644 --- a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-before-declaration/expected.js +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-before-declaration/expected.js @@ -8,8 +8,9 @@ function render() { function render() { const bar = "bar", - renderFoo = () => , - baz = "baz"; + renderFoo = () => _ref2, + baz = "baz", + _ref2 = ; return renderFoo(); } \ No newline at end of file diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-before-hoc/actual.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-before-hoc/actual.js new file mode 100644 index 000000000000..21f7b2ed905d --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-before-hoc/actual.js @@ -0,0 +1,18 @@ +import React from "react"; + +const HOC = component => component; + +const Parent = ({}) => ( +
+ +
+); + +export default Parent; + +let Child = () => ( +
+ ChildTextContent +
+); +Child = HOC(Child); diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-before-hoc/expected.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-before-hoc/expected.js new file mode 100644 index 000000000000..8da0cc5ad12f --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-before-hoc/expected.js @@ -0,0 +1,18 @@ +import React from "react"; + +const HOC = component => component; + +const Parent = ({}) => _ref; + +export default Parent; + +var _ref2 =
+ ChildTextContent +
; + +let Child = () => _ref2; +Child = HOC(Child); + +var _ref =
+ +
; \ No newline at end of file diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-block-scoped-variables/expected.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-block-scoped-variables/expected.js index 9618e6da028f..ab6ad7d4c478 100644 --- a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-block-scoped-variables/expected.js +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/dont-hoist-block-scoped-variables/expected.js @@ -1,17 +1,11 @@ function render(flag) { if (flag) { - var _ret = function () { - var bar = "bar"; + var bar = "bar"; - [].map(() => bar); + [].map(() => bar); - return { - v: - }; - }(); - - if (typeof _ret === "object") return _ret.v; + return ; } return null; -} \ No newline at end of file +} diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression-constant/actual.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression-constant/actual.js new file mode 100644 index 000000000000..a6c1f9b6ec88 --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression-constant/actual.js @@ -0,0 +1,4 @@ +function render() { + this.component = "div"; + return () => ; +} diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression-constant/expected.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression-constant/expected.js new file mode 100644 index 000000000000..aa7a9994baeb --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression-constant/expected.js @@ -0,0 +1,7 @@ +function render() { + this.component = "div"; + + var _ref = ; + + return () => _ref; +} diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression-this/actual.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression-this/actual.js new file mode 100644 index 000000000000..bdc61d684a69 --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression-this/actual.js @@ -0,0 +1,5 @@ +class Component extends React.Component { + subComponent = () => Sub Component + + render = () => +} diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression-this/expected.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression-this/expected.js new file mode 100644 index 000000000000..9ce3a08e7437 --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression-this/expected.js @@ -0,0 +1,12 @@ +var _ref = Sub Component; + +class Component extends React.Component { + constructor(...args) { + var _temp; + + var _ref2 = ; + + return _temp = super(...args), this.subComponent = () => _ref, this.render = () => _ref2, _temp; + } + +} diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression-this/options.json b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression-this/options.json new file mode 100644 index 000000000000..d4789bbda3fb --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression-this/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["syntax-jsx", "transform-react-constant-elements", "transform-class-properties"] +} diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression/actual.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression/actual.js new file mode 100644 index 000000000000..2ab59df97b89 --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression/actual.js @@ -0,0 +1,6 @@ +const els = { + subComponent: () => Sub Component +}; +class Component extends React.Component { + render = () => +} diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression/expected.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression/expected.js new file mode 100644 index 000000000000..fe12eb988d5d --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression/expected.js @@ -0,0 +1,16 @@ +var _ref = Sub Component; + +const els = { + subComponent: () => _ref +}; + +var _ref2 = ; + +class Component extends React.Component { + constructor(...args) { + var _temp; + + return _temp = super(...args), this.render = () => _ref2, _temp; + } + +} diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression/options.json b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression/options.json new file mode 100644 index 000000000000..d4789bbda3fb --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/member-expression/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["syntax-jsx", "transform-react-constant-elements", "transform-class-properties"] +} diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-deopt/actual.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-deopt/actual.js new file mode 100644 index 000000000000..4df51832c7ce --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-deopt/actual.js @@ -0,0 +1,5 @@ +// https://github.com/facebook/react/issues/3226 +// Not safe to reuse because it is mutable +function render() { + return
; +} diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-deopt/expected.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-deopt/expected.js new file mode 100644 index 000000000000..4df51832c7ce --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-deopt/expected.js @@ -0,0 +1,5 @@ +// https://github.com/facebook/react/issues/3226 +// Not safe to reuse because it is mutable +function render() { + return
; +} diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression-2/actual.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression-2/actual.js new file mode 100644 index 000000000000..0acb75cfaf6a --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression-2/actual.js @@ -0,0 +1,5 @@ +function render(offset) { + return function () { + return
; + }; +} diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression-2/expected.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression-2/expected.js new file mode 100644 index 000000000000..65df627806b2 --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression-2/expected.js @@ -0,0 +1,8 @@ +function render(offset) { + var _ref =
; + + return function () { + return _ref; + }; +} + diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression-3/actual.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression-3/actual.js new file mode 100644 index 000000000000..c6b89c77fd1a --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression-3/actual.js @@ -0,0 +1,10 @@ +const OFFSET = 3; + +var Foo = React.createClass({ + render: function () { + return ( +
+ ); + } +}); + diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression-3/expected.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression-3/expected.js new file mode 100644 index 000000000000..e709176c4870 --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression-3/expected.js @@ -0,0 +1,10 @@ +const OFFSET = 3; + +var _ref =
; + +var Foo = React.createClass({ + render: function () { + return _ref; + } +}); + diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression/actual.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression/actual.js new file mode 100644 index 000000000000..5131c839899b --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression/actual.js @@ -0,0 +1,11 @@ +var Foo = React.createClass({ + render: function () { + return ( +
+ ); + } +}); + diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression/expected.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression/expected.js new file mode 100644 index 000000000000..a7afcb1d6edf --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/pure-expression/expected.js @@ -0,0 +1,8 @@ +var _ref =
; + +var Foo = React.createClass({ + render: function () { + return _ref; + } +}); + diff --git a/packages/babel-plugin-transform-react-display-name/package.json b/packages/babel-plugin-transform-react-display-name/package.json index 09a05f65e01c..4ae2eb1509a1 100644 --- a/packages/babel-plugin-transform-react-display-name/package.json +++ b/packages/babel-plugin-transform-react-display-name/package.json @@ -1,6 +1,6 @@ { "name": "babel-plugin-transform-react-display-name", - "version": "6.22.0", + "version": "6.23.0", "description": "Add displayName to React.createClass calls", "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-display-name", "license": "MIT", diff --git a/packages/babel-plugin-transform-react-jsx/package.json b/packages/babel-plugin-transform-react-jsx/package.json index 1f6033802360..17391a3be506 100644 --- a/packages/babel-plugin-transform-react-jsx/package.json +++ b/packages/babel-plugin-transform-react-jsx/package.json @@ -1,6 +1,6 @@ { "name": "babel-plugin-transform-react-jsx", - "version": "6.22.0", + "version": "6.23.0", "description": "Turn JSX into React function calls", "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx", "license": "MIT", @@ -9,7 +9,7 @@ "babel-plugin" ], "dependencies": { - "babel-helper-builder-react-jsx": "^6.22.0", + "babel-helper-builder-react-jsx": "^6.23.0", "babel-plugin-syntax-jsx": "^6.8.0" }, "devDependencies": { diff --git a/packages/babel-plugin-transform-runtime/package.json b/packages/babel-plugin-transform-runtime/package.json index 4caf8e695188..98e5430b0783 100644 --- a/packages/babel-plugin-transform-runtime/package.json +++ b/packages/babel-plugin-transform-runtime/package.json @@ -1,6 +1,6 @@ { "name": "babel-plugin-transform-runtime", - "version": "6.22.0", + "version": "6.23.0", "description": "Externalise references to helpers and builtins, automatically polyfilling your code without polluting globals", "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-runtime", "license": "MIT", diff --git a/packages/babel-polyfill/package.json b/packages/babel-polyfill/package.json index 77a62a8485d9..673e8166fe07 100644 --- a/packages/babel-polyfill/package.json +++ b/packages/babel-polyfill/package.json @@ -1,6 +1,6 @@ { "name": "babel-polyfill", - "version": "6.22.0", + "version": "6.23.0", "description": "Provides polyfills necessary for a full ES2015+ environment", "author": "Sebastian McKenzie ", "homepage": "https://babeljs.io/", diff --git a/packages/babel-preset-flow/.npmignore b/packages/babel-preset-flow/.npmignore new file mode 100644 index 000000000000..47cdd2c65551 --- /dev/null +++ b/packages/babel-preset-flow/.npmignore @@ -0,0 +1,3 @@ +src +test +node_modules diff --git a/packages/babel-preset-flow/README.md b/packages/babel-preset-flow/README.md new file mode 100644 index 000000000000..26593bd87824 --- /dev/null +++ b/packages/babel-preset-flow/README.md @@ -0,0 +1,53 @@ +# babel-preset-flow + +> Babel preset for all Flow plugins. + +This preset includes the following plugins: + +- [transform-flow-strip-types](https://babeljs.io/docs/plugins/transform-flow-strip-types/) + +## Example + +**In** + +```javascript +function foo(one: any, two: number, three?): string {} +``` + +**Out** + +```javascript +function foo(one, two, three) {} +``` + +## Installation + +```sh +npm install --save-dev babel-preset-flow +``` + +## Usage + +### Via `.babelrc` (Recommended) + +**.babelrc** + +```json +{ + "presets": ["flow"] +} +``` + +### Via CLI + +```sh +babel --presets flow script.js +``` + +### Via Node API + +```javascript +require("babel-core").transform("code", { + presets: ["flow"] +}); +``` diff --git a/packages/babel-preset-flow/package.json b/packages/babel-preset-flow/package.json new file mode 100644 index 000000000000..e9f4cb59797e --- /dev/null +++ b/packages/babel-preset-flow/package.json @@ -0,0 +1,18 @@ +{ + "name": "babel-preset-flow", + "version": "6.23.0", + "description": "Babel preset for all Flow plugins.", + "author": "James Kyle ", + "repository": "https://github.com/babel/babel/tree/master/packages/babel-preset-flow", + "license": "MIT", + "main": "lib/index.js", + "keywords": [ + "babel-preset", + "flowtype", + "flow", + "types" + ], + "dependencies": { + "babel-plugin-transform-flow-strip-types": "^6.22.0" + } +} diff --git a/packages/babel-preset-flow/src/index.js b/packages/babel-preset-flow/src/index.js new file mode 100644 index 000000000000..8251ca827050 --- /dev/null +++ b/packages/babel-preset-flow/src/index.js @@ -0,0 +1,7 @@ +import transformFlowStripTypes from "babel-plugin-transform-flow-strip-types"; + +export default { + plugins: [ + transformFlowStripTypes + ] +}; diff --git a/packages/babel-preset-react/README.md b/packages/babel-preset-react/README.md index aceb108affd3..591a59547b89 100644 --- a/packages/babel-preset-react/README.md +++ b/packages/babel-preset-react/README.md @@ -2,11 +2,10 @@ > Babel preset for all React plugins. -This preset includes the following plugins: +This preset includes the following plugins/presets: -- [syntax-flow](https://babeljs.io/docs/plugins/syntax-flow/) +- [preset-flow](https://babeljs.io/docs/plugins/preset-flow/) - [syntax-jsx](https://babeljs.io/docs/plugins/syntax-jsx/) -- [transform-flow-strip-types](https://babeljs.io/docs/plugins/transform-flow-strip-types/) - [transform-react-jsx](https://babeljs.io/docs/plugins/transform-react-jsx/) - [transform-react-display-name](https://babeljs.io/docs/plugins/transform-react-display-name/) diff --git a/packages/babel-preset-react/package.json b/packages/babel-preset-react/package.json index 378b3a04563d..1a4bf7c55d52 100644 --- a/packages/babel-preset-react/package.json +++ b/packages/babel-preset-react/package.json @@ -1,6 +1,6 @@ { "name": "babel-preset-react", - "version": "6.22.0", + "version": "6.23.0", "description": "Babel preset for all React plugins.", "author": "Sebastian McKenzie ", "homepage": "https://babeljs.io/", @@ -8,11 +8,10 @@ "repository": "https://github.com/babel/babel/tree/master/packages/babel-preset-react", "main": "lib/index.js", "dependencies": { - "babel-plugin-syntax-flow": "^6.3.13", + "babel-preset-flow": "^6.23.0", "babel-plugin-syntax-jsx": "^6.3.13", - "babel-plugin-transform-flow-strip-types": "^6.22.0", - "babel-plugin-transform-react-display-name": "^6.22.0", - "babel-plugin-transform-react-jsx": "^6.22.0", + "babel-plugin-transform-react-display-name": "^6.23.0", + "babel-plugin-transform-react-jsx": "^6.23.0", "babel-plugin-transform-react-jsx-source": "^6.22.0", "babel-plugin-transform-react-jsx-self": "^6.22.0" } diff --git a/packages/babel-preset-react/src/index.js b/packages/babel-preset-react/src/index.js index 55dd6bbd8d54..361238658ef9 100644 --- a/packages/babel-preset-react/src/index.js +++ b/packages/babel-preset-react/src/index.js @@ -1,6 +1,5 @@ +import presetFlow from "babel-preset-flow"; import transformReactJSX from "babel-plugin-transform-react-jsx"; -import transformFlowStripTypes from "babel-plugin-transform-flow-strip-types"; -import transformSyntaxFlow from "babel-plugin-syntax-flow"; import transformSyntaxJSX from "babel-plugin-syntax-jsx"; import transformReactDisplayName from "babel-plugin-transform-react-display-name"; @@ -9,10 +8,11 @@ import transformReactDisplayName from "babel-plugin-transform-react-display-name // import transformReactJSXSelf from "babel-plugin-transform-react-jsx-self"; export default { + presets: [ + presetFlow + ], plugins: [ transformReactJSX, - transformFlowStripTypes, - transformSyntaxFlow, transformSyntaxJSX, transformReactDisplayName ], diff --git a/packages/babel-register/package.json b/packages/babel-register/package.json index 0ace0ca3b829..e6e328efc57d 100644 --- a/packages/babel-register/package.json +++ b/packages/babel-register/package.json @@ -1,6 +1,6 @@ { "name": "babel-register", - "version": "6.22.0", + "version": "6.23.0", "description": "babel require hook", "license": "MIT", "repository": "https://github.com/babel/babel/tree/master/packages/babel-register", @@ -8,7 +8,7 @@ "main": "lib/node.js", "browser": "lib/browser.js", "dependencies": { - "babel-core": "^6.22.0", + "babel-core": "^6.23.0", "core-js": "^2.4.0", "home-or-tmp": "^3.0.0", "lodash": "^4.2.0", diff --git a/packages/babel-template/package.json b/packages/babel-template/package.json index 8c36f1655b22..d75b97caaf86 100644 --- a/packages/babel-template/package.json +++ b/packages/babel-template/package.json @@ -1,6 +1,6 @@ { "name": "babel-template", - "version": "6.22.0", + "version": "6.23.0", "description": "Generate an AST from a string template.", "author": "Sebastian McKenzie ", "homepage": "https://babeljs.io/", @@ -9,8 +9,8 @@ "main": "lib/index.js", "dependencies": { "babylon": "^6.11.0", - "babel-traverse": "^6.22.0", - "babel-types": "^6.22.0", + "babel-traverse": "^6.23.0", + "babel-types": "^6.23.0", "lodash": "^4.2.0" } } diff --git a/packages/babel-traverse/package.json b/packages/babel-traverse/package.json index 51dff4bfd716..40de088ff39c 100644 --- a/packages/babel-traverse/package.json +++ b/packages/babel-traverse/package.json @@ -1,6 +1,6 @@ { "name": "babel-traverse", - "version": "6.22.1", + "version": "6.23.1", "description": "The Babel Traverse module maintains the overall tree state, and is responsible for replacing, removing, and adding nodes", "author": "Sebastian McKenzie ", "homepage": "https://babeljs.io/", @@ -9,8 +9,8 @@ "main": "lib/index.js", "dependencies": { "babel-code-frame": "^6.22.0", - "babel-messages": "^6.22.0", - "babel-types": "^6.22.0", + "babel-messages": "^6.23.0", + "babel-types": "^6.23.0", "babylon": "^6.15.0", "debug": "^2.2.0", "globals": "^9.0.0", @@ -18,6 +18,6 @@ "lodash": "^4.2.0" }, "devDependencies": { - "babel-generator": "^6.22.0" + "babel-generator": "^6.23.0" } } diff --git a/packages/babel-traverse/src/path/lib/hoister.js b/packages/babel-traverse/src/path/lib/hoister.js index 93b9323bd35d..69154bbc2d27 100644 --- a/packages/babel-traverse/src/path/lib/hoister.js +++ b/packages/babel-traverse/src/path/lib/hoister.js @@ -2,11 +2,27 @@ import { react } from "babel-types"; import * as t from "babel-types"; const referenceVisitor = { + // This visitor looks for bindings to establish a topmost scope for hoisting. ReferencedIdentifier(path, state) { - if (path.isJSXIdentifier() && react.isCompatTag(path.node.name)) { + // Don't hoist regular JSX identifiers ('div', 'span', etc). + // We do have to consider member expressions for hoisting (e.g. `this.component`) + if ( + path.isJSXIdentifier() && + react.isCompatTag(path.node.name) && + !path.parentPath.isJSXMemberExpression() + ) { return; } + // If the identifier refers to `this`, we need to break on the closest non-arrow scope. + if (path.node.name === "this") { + let scope = path.scope; + do { + if (scope.path.isFunction() && !scope.path.isArrowFunctionExpression()) break; + } while (scope = scope.parent); + if (scope) state.breakOnScopePaths.push(scope.path); + } + // direct references that we need to track to hoist this to the highest scope we can const binding = path.scope.getBinding(path.node.name); if (!binding) return; @@ -15,25 +31,27 @@ const referenceVisitor = { // eg. it's in a closure etc if (binding !== state.scope.getBinding(path.node.name)) return; - if (binding.constant) { - state.bindings[path.node.name] = binding; - } else { - for (const violationPath of (binding.constantViolations: Array)) { - state.breakOnScopePaths = state.breakOnScopePaths.concat(violationPath.getAncestry()); - } - } + state.bindings[path.node.name] = binding; } }; export default class PathHoister { constructor(path, scope) { + // Storage for scopes we can't hoist above. this.breakOnScopePaths = []; + // Storage for bindings that may affect what path we can hoist to. this.bindings = {}; + // Storage for eligible scopes. this.scopes = []; + // Our original scope and path. this.scope = scope; this.path = path; + // By default, we attach as far up as we can; but if we're trying + // to avoid referencing a binding, we may have to go after. + this.attachAfter = false; } + // A scope is compatible if all required bindings are reachable. isCompatibleScope(scope) { for (const key in this.bindings) { const binding = this.bindings[key]; @@ -45,6 +63,7 @@ export default class PathHoister { return true; } + // Look through all scopes and push compatible ones. getCompatibleScopes() { let scope = this.path.scope; do { @@ -54,6 +73,7 @@ export default class PathHoister { break; } + // deopt: These scopes are set in the visitor on const violations if (this.breakOnScopePaths.indexOf(scope.path) >= 0) { break; } @@ -61,7 +81,7 @@ export default class PathHoister { } getAttachmentPath() { - const path = this._getAttachmentPath(); + let path = this._getAttachmentPath(); if (!path) return; let targetScope = path.scope; @@ -82,8 +102,18 @@ export default class PathHoister { // allow parameter references if (binding.kind === "param") continue; - // if this binding appears after our attachment point then don't hoist it - if (this.getAttachmentParentForPath(binding.path).key > path.key) return; + // if this binding appears after our attachment point, then we move after it. + if (this.getAttachmentParentForPath(binding.path).key > path.key) { + this.attachAfter = true; + path = binding.path; + + // We also move past any constant violations. + for (const violationPath of (binding.constantViolations: Array)) { + if (this.getAttachmentParentForPath(violationPath).key > path.key) { + path = violationPath; + } + } + } } } @@ -94,11 +124,12 @@ export default class PathHoister { const scopes = this.scopes; const scope = scopes.pop(); + // deopt: no compatible scopes if (!scope) return; if (scope.path.isFunction()) { if (this.hasOwnParamBindings(scope)) { - // should ignore this scope since it's ourselves + // deopt: should ignore this scope since it's ourselves if (this.scope === scope) return; // needs to be attached to the body @@ -117,26 +148,30 @@ export default class PathHoister { if (scope) return this.getAttachmentParentForPath(scope.path); } + // Find an attachment for this path. getAttachmentParentForPath(path) { do { - if (!path.parentPath || - (Array.isArray(path.container) && path.isStatement()) || - ( - path.isVariableDeclarator() && - path.parentPath.node !== null && - path.parentPath.node.declarations.length > 1 - ) - ) + if ( + // Beginning of the scope + !path.parentPath || + // Has siblings and is a statement + (Array.isArray(path.container) && path.isStatement()) || + // Is part of multiple var declarations + (path.isVariableDeclarator() && + path.parentPath.node !== null && + path.parentPath.node.declarations.length > 1)) return path; } while ((path = path.parentPath)); } + // Returns true if a scope has param bindings. hasOwnParamBindings(scope) { for (const name in this.bindings) { if (!scope.hasOwnBinding(name)) continue; const binding = this.bindings[name]; - if (binding.kind === "param") return true; + // Ensure constant; without it we could place behind a reassignment + if (binding.kind === "param" && binding.constant) return true; } return false; } @@ -161,7 +196,8 @@ export default class PathHoister { let uid = attachTo.scope.generateUidIdentifier("ref"); const declarator = t.variableDeclarator(uid, this.path.node); - attachTo.insertBefore([ + const insertFn = this.attachAfter ? "insertAfter" : "insertBefore"; + attachTo[insertFn]([ attachTo.isVariableDeclarator() ? declarator : t.variableDeclaration("var", [declarator]) ]); diff --git a/packages/babel-types/README.md b/packages/babel-types/README.md index 13b2ec3a5a64..683388362925 100644 --- a/packages/babel-types/README.md +++ b/packages/babel-types/README.md @@ -930,6 +930,7 @@ Aliases: `ModuleSpecifier` - `local`: `Identifier` (required) - `imported`: `Identifier` (required) + - `importKind`: `null | 'type' | 'typeof'` (default: `null`) --- diff --git a/packages/babel-types/package.json b/packages/babel-types/package.json index 57c4bc762a15..5ed4524a29b6 100644 --- a/packages/babel-types/package.json +++ b/packages/babel-types/package.json @@ -1,6 +1,6 @@ { "name": "babel-types", - "version": "6.22.0", + "version": "6.23.0", "description": "Babel Types is a Lodash-esque utility library for AST nodes", "author": "Sebastian McKenzie ", "homepage": "https://babeljs.io/",