diff --git a/.eslintrc b/.eslintrc index 00dd6a98ad..02f7711758 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,7 +1,6 @@ { "extends": "babel", "rules": { - "max-len": 0 }, "env": { "node": true, diff --git a/.gitignore b/.gitignore index 7e25e4ad05..702ae50d45 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ node_modules test/tmp *.log *.cache +/.eslintcache /templates.json /tests.json /browser.js @@ -17,3 +18,4 @@ dist _babel.github.io /tests/.browser-build.js .nyc_output +/babel.sublime-workspace diff --git a/README.md b/README.md index dca5d6b564..7987b5b840 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@

+ Business Strategy Status Travis Status CircleCI Status Coverage Status diff --git a/babel.sublime-project b/babel.sublime-project new file mode 100644 index 0000000000..1f18a8cc50 --- /dev/null +++ b/babel.sublime-project @@ -0,0 +1,25 @@ +{ + "settings": { + "rulers": [ + 110 + ], + + // Set to false to disable detection of tabs vs. spaces on load + "detect_indentation": false, + + "translate_tabs_to_spaces": true, + + "tab_size": 2 + }, + + "folders": [{ + "path": ".", + "folder_exclude_patterns": [ + "packages/*/lib", + "node_modules" + ], + "file_exclude_patterns": [ + + ] + }] +} diff --git a/packages/babel-cli/src/babel-node.js b/packages/babel-cli/src/babel-node.js index e3d0c2e901..ee25b5f48a 100755 --- a/packages/babel-cli/src/babel-node.js +++ b/packages/babel-cli/src/babel-node.js @@ -1,5 +1,3 @@ -/* eslint indent: 0 */ - /** * This tiny wrapper file checks for known node flags and appends them * when found, before invoking the "real" _babel-node(1) executable. diff --git a/packages/babel-cli/src/babel/index.js b/packages/babel-cli/src/babel/index.js index 3f7f143987..194254bf61 100755 --- a/packages/babel-cli/src/babel/index.js +++ b/packages/babel-cli/src/babel/index.js @@ -1,7 +1,4 @@ #!/usr/bin/env node -/* eslint max-len: 0 */ - -require("babel-core"); const fs = require("fs"); const commander = require("commander"); @@ -38,6 +35,7 @@ Object.keys(options).forEach(function (key) { commander.option(arg, desc.join(" ")); }); +/* eslint-disable max-len */ commander.option("-x, --extensions [extensions]", "List of extensions to compile when a directory has been input [.es6,.js,.es,.jsx]"); commander.option("-w, --watch", "Recompile files on changes"); commander.option("--skip-initial-build", "Do not compile files before watching"); @@ -45,6 +43,7 @@ commander.option("-o, --out-file [out]", "Compile all input files into a single commander.option("-d, --out-dir [out]", "Compile an input directory of modules into an output directory"); commander.option("-D, --copy-files", "When compiling a directory copy over non-compilable files"); commander.option("-q, --quiet", "Don't log anything"); +/* eslint-enable max-len */ const pkg = require("../../package.json"); commander.version(pkg.version + " (babel-core " + require("babel-core").version + ")"); diff --git a/packages/babel-cli/test/index.js b/packages/babel-cli/test/index.js index 1655a4e79b..9da8405733 100644 --- a/packages/babel-cli/test/index.js +++ b/packages/babel-cli/test/index.js @@ -46,7 +46,8 @@ const assertTest = function (stdout, stderr, opts) { if (opts.stderr) { if (opts.stderrContains) { - assert.ok(includes(stderr, expectStderr), "stderr " + JSON.stringify(stderr) + " didn't contain " + JSON.stringify(expectStderr)); + assert.ok(includes(stderr, expectStderr), "stderr " + JSON.stringify(stderr) + + " didn't contain " + JSON.stringify(expectStderr)); } else { chai.expect(stderr).to.equal(expectStderr, "stderr didn't match"); } @@ -60,7 +61,8 @@ const assertTest = function (stdout, stderr, opts) { if (opts.stdout) { if (opts.stdoutContains) { - assert.ok(includes(stdout, expectStdout), "stdout " + JSON.stringify(stdout) + " didn't contain " + JSON.stringify(expectStdout)); + assert.ok(includes(stdout, expectStdout), "stdout " + JSON.stringify(stdout) + + " didn't contain " + JSON.stringify(expectStdout)); } else { chai.expect(stdout).to.equal(expectStdout, "stdout didn't match"); } diff --git a/packages/babel-code-frame/README.md b/packages/babel-code-frame/README.md index 0257a2da1f..7ef5368d31 100644 --- a/packages/babel-code-frame/README.md +++ b/packages/babel-code-frame/README.md @@ -35,9 +35,26 @@ If the column number is not known, you may pass `null` instead. ## Options -name | type | default | description ------------------------|----------|-----------------|------------------------------------------------------ -highlightCode | boolean | `false` | Syntax highlight the code as JavaScript for terminals -linesAbove | number | 2 | The number of lines to show above the error -linesBelow | number | 3 | The number of lines to show below the error -forceColor | boolean | `false` | Forcibly syntax highlight the code as JavaScript (for non-terminals); overrides highlightCode +### `highlightCode` + +`boolean`, defaults to `false`. + +Toggles syntax highlighting the code as JavaScript for terminals. + +### `linesAbove` + +`number`, defaults to `2`. + +Adjust the number of lines to show above the error. + +### `linesBelow` + +`number`, defaults to `3`. + +Adjust the number of lines to show below the error. + +### `forceColor` + +`boolean`, defaults to `false`. + +Enable this to forcibly syntax highlight the code as JavaScript (for non-terminals); overrides `highlightCode`. diff --git a/packages/babel-code-frame/test/index.js b/packages/babel-code-frame/test/index.js index b6906100ee..f91727cb24 100644 --- a/packages/babel-code-frame/test/index.js +++ b/packages/babel-code-frame/test/index.js @@ -197,10 +197,12 @@ describe("babel-code-frame", function () { "", "" ].join("\n"); - assert.equal(codeFrame(rawLines, 3, null, { linesAbove: 1, linesBelow: 1, forceColor: true }), chalk.reset([ - " " + gutter(" 2 | "), - marker(">") + gutter(" 3 | "), - " " + gutter(" 4 | ") - ].join("\n"))); + assert.equal(codeFrame(rawLines, 3, null, { linesAbove: 1, linesBelow: 1, forceColor: true }), + chalk.reset([ + " " + gutter(" 2 | "), + marker(">") + gutter(" 3 | "), + " " + gutter(" 4 | ") + ].join("\n")) + ); }); }); diff --git a/packages/babel-core/README.md b/packages/babel-core/README.md index c4b0f93016..5b2f4d53d1 100644 --- a/packages/babel-core/README.md +++ b/packages/babel-core/README.md @@ -117,4 +117,5 @@ Following is a table of the options you can use: | `sourceMaps` | `false` | If truthy, adds a `map` property to returned output. If set to `"inline"`, a comment with a sourceMappingURL directive is added to the bottom of the returned code. If set to `"both"` then a `map` property is returned as well as a source map comment appended. **This does not emit sourcemap files by itself!** To have sourcemaps emitted using the CLI, you must pass it the `--source-maps` option. | | `sourceMapTarget` | `(filenameRelative)` | Set `file` on returned source map. | | `sourceRoot` | `(moduleRoot)` | The root from which all sources are relative. | +| `sourceType` | `"module"` | Indicate the mode the code should be parsed in. Can be either "script" or "module". | | `wrapPluginVisitorMethod`| `null` | An optional callback that can be used to wrap visitor methods. **NOTE:** This is useful for things like introspection, and not really needed for implementing anything. Called as `wrapPluginVisitorMethod(pluginAlias, visitorType, callback)`. diff --git a/packages/babel-core/src/tools/build-external-helpers.js b/packages/babel-core/src/tools/build-external-helpers.js index b97d25c2d1..8eb206f5ff 100644 --- a/packages/babel-core/src/tools/build-external-helpers.js +++ b/packages/babel-core/src/tools/build-external-helpers.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import * as helpers from "babel-helpers"; import generator from "babel-generator"; import * as messages from "babel-messages"; @@ -23,12 +21,14 @@ const buildUmdWrapper = template(` function buildGlobal(namespace, builder) { const body = []; const container = t.functionExpression(null, [t.identifier("global")], t.blockStatement(body)); - const tree = t.program([t.expressionStatement(t.callExpression(container, [helpers.get("selfGlobal")]))]); + const tree = t.program([ + t.expressionStatement(t.callExpression(container, [helpers.get("selfGlobal")]))]); body.push(t.variableDeclaration("var", [ t.variableDeclarator( namespace, - t.assignmentExpression("=", t.memberExpression(t.identifier("global"), namespace), t.objectExpression([])) + t.assignmentExpression("=", t.memberExpression(t.identifier("global"), namespace), + t.objectExpression([])) ) ])); diff --git a/packages/babel-core/src/transformation/file/index.js b/packages/babel-core/src/transformation/file/index.js index a013eb5d6a..50b641c194 100644 --- a/packages/babel-core/src/transformation/file/index.js +++ b/packages/babel-core/src/transformation/file/index.js @@ -1,5 +1,4 @@ /* global BabelFileResult, BabelParserOptions, BabelFileMetadata */ -/* eslint max-len: 0 */ import getHelper from "babel-helpers"; import * as metadataVisitor from "./metadata"; @@ -339,7 +338,7 @@ export default class File extends Store { this.scope.push({ id: uid, init: init, - _blockHoist: 1.9 // This ensures that we don't fail if not using function expression helpers + _blockHoist: 1.9 // This ensures that we don't fail if not using function expression helpers }); return uid; } @@ -378,8 +377,8 @@ export default class File extends Store { sourceRoot: inputMapConsumer.sourceRoot }); - // This assumes the output map always has a single source, since Babel always compiles a single source file to a - // single output file. + // This assumes the output map always has a single source, since Babel always compiles a + // single source file to a single output file. const source = outputMapConsumer.sources[0]; inputMapConsumer.eachMapping(function (mapping) { @@ -424,7 +423,8 @@ export default class File extends Store { if (parser) { parseCode = require(parser).parse; } else { - throw new Error(`Couldn't find parser ${parserOpts.parser} with "parse" method relative to directory ${dirname}`); + throw new Error(`Couldn't find parser ${parserOpts.parser} with "parse" method ` + + `relative to directory ${dirname}`); } } else { parseCode = parserOpts.parser; @@ -472,7 +472,8 @@ export default class File extends Store { this.log.debug("Start transform traverse"); // merge all plugin visitors into a single visitor - const visitor = traverse.visitors.merge(this.pluginVisitors[i], pluginPasses, this.opts.wrapPluginVisitorMethod); + const visitor = traverse.visitors.merge(this.pluginVisitors[i], pluginPasses, + this.opts.wrapPluginVisitorMethod); traverse(this.ast, visitor, this.scope); this.log.debug("End transform traverse"); @@ -610,14 +611,16 @@ export default class File extends Store { if (generator) { gen = require(generator).print; } else { - throw new Error(`Couldn't find generator ${gen} with "print" method relative to directory ${dirname}`); + throw new Error(`Couldn't find generator ${gen} with "print" method relative ` + + `to directory ${dirname}`); } } } this.log.debug("Generation start"); - const _result = gen(ast, opts.generatorOpts ? Object.assign(opts, opts.generatorOpts) : opts, this.code); + const _result = gen(ast, opts.generatorOpts ? Object.assign(opts, opts.generatorOpts) : opts, + this.code); result.code = _result.code; result.map = _result.map; diff --git a/packages/babel-core/src/transformation/file/options/config.js b/packages/babel-core/src/transformation/file/options/config.js index 7b11963f38..dbc60c6043 100644 --- a/packages/babel-core/src/transformation/file/options/config.js +++ b/packages/babel-core/src/transformation/file/options/config.js @@ -1,4 +1,4 @@ -/* eslint max-len: 0 */ +/* eslint max-len: "off" */ module.exports = { filename: { diff --git a/packages/babel-core/src/transformation/file/options/option-manager.js b/packages/babel-core/src/transformation/file/options/option-manager.js index 8221e3fe19..3e6209abfc 100644 --- a/packages/babel-core/src/transformation/file/options/option-manager.js +++ b/packages/babel-core/src/transformation/file/options/option-manager.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import * as context from "../../../index"; import type Logger from "../logger"; import Plugin from "../../plugin"; @@ -180,10 +178,13 @@ export default class OptionManager { // check for an unknown option if (!option && this.log) { if (removed[key]) { - this.log.error(`Using removed Babel 5 option: ${alias}.${key} - ${removed[key].message}`, ReferenceError); + this.log.error(`Using removed Babel 5 option: ${alias}.${key} - ${removed[key].message}`, + ReferenceError); } else { + /* eslint-disable max-len */ const unknownOptErr = `Unknown option: ${alias}.${key}. Check out http://babeljs.io/docs/usage/options/ for more information about options.`; const presetConfigErr = "A common cause of this error is the presence of a configuration options object without the corresponding preset name. Example:\n\nInvalid:\n `{ presets: [{option: value}] }`\nValid:\n `{ presets: [['presetName', {option: value}]] }`\n\nFor more detailed information on preset configuration, please see http://babeljs.io/docs/plugins/#pluginpresets-options."; + /* eslint-enable max-len */ this.log.error(`${unknownOptErr}\n\n${presetConfigErr}`, ReferenceError); } diff --git a/packages/babel-core/src/transformation/file/options/removed.js b/packages/babel-core/src/transformation/file/options/removed.js index 00a24ea61e..cb0077cb92 100644 --- a/packages/babel-core/src/transformation/file/options/removed.js +++ b/packages/babel-core/src/transformation/file/options/removed.js @@ -1,4 +1,4 @@ -/* eslint max-len: 0 */ +/* eslint max-len: "off" */ module.exports = { "auxiliaryComment": { diff --git a/packages/babel-core/src/transformation/plugin.js b/packages/babel-core/src/transformation/plugin.js index f3461ae9bf..d6c5406574 100644 --- a/packages/babel-core/src/transformation/plugin.js +++ b/packages/babel-core/src/transformation/plugin.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import OptionManager from "./file/options/option-manager"; import * as messages from "babel-messages"; import Store from "../store"; @@ -85,7 +83,8 @@ export default class Plugin extends Store { normaliseVisitor(visitor: Object): Object { for (const key of GLOBAL_VISITOR_PROPS) { if (visitor[key]) { - throw new Error("Plugins aren't allowed to specify catch-all enter/exit handlers. Please target individual nodes."); + throw new Error("Plugins aren't allowed to specify catch-all enter/exit handlers. " + + "Please target individual nodes."); } } diff --git a/packages/babel-core/test/api.js b/packages/babel-core/test/api.js index 910418321b..7cd5157afe 100644 --- a/packages/babel-core/test/api.js +++ b/packages/babel-core/test/api.js @@ -265,6 +265,7 @@ describe("api", function () { it("source map merging", function () { const result = babel.transform([ + /* eslint-disable max-len */ "function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }", "", "let Foo = function Foo() {", @@ -272,6 +273,7 @@ describe("api", function () { "};", "", "//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZG91dCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztJQUFNLEdBQUcsWUFBSCxHQUFHO3dCQUFILEdBQUciLCJmaWxlIjoidW5kZWZpbmVkIiwic291cmNlc0NvbnRlbnQiOlsiY2xhc3MgRm9vIHt9XG4iXX0=" + /* eslint-enable max-len */ ].join("\n"), { sourceMap: true }); @@ -329,12 +331,14 @@ describe("api", function () { }; }] }).then(function (result) { - assert.equal(result.code, "/*before*/start;\n/*after*/class Foo {}\n/*before*/end;\n/*after*/"); + assert.equal(result.code, + "/*before*/start;\n/*after*/class Foo {}\n/*before*/end;\n/*after*/"); }); }); it("modules metadata", function () { return Promise.all([ + // eslint-disable-next-line max-len transformAsync("import { externalName as localName } from \"external\";").then(function (result) { assert.deepEqual(result.metadata.modules.imports[0], { source: "external", @@ -586,8 +590,10 @@ describe("api", function () { }); it("resolveModuleSource option", function () { + /* eslint-disable max-len */ const actual = "import foo from \"foo-import-default\";\nimport \"foo-import-bare\";\nexport { foo } from \"foo-export-named\";"; const expected = "import foo from \"resolved/foo-import-default\";\nimport \"resolved/foo-import-bare\";\nexport { foo } from \"resolved/foo-export-named\";"; + /* eslint-enable max-len */ return transformAsync(actual, { resolveModuleSource: function (originalSource) { diff --git a/packages/babel-core/test/option-manager.js b/packages/babel-core/test/option-manager.js index 2606a4bca0..2ca432dd20 100644 --- a/packages/babel-core/test/option-manager.js +++ b/packages/babel-core/test/option-manager.js @@ -35,6 +35,7 @@ describe("option-manager", () => { "blacklist": true }); }, + // eslint-disable-next-line max-len /Using removed Babel 5 option: base.auxiliaryComment - Use `auxiliaryCommentBefore` or `auxiliaryCommentAfter`/ ); }); @@ -59,6 +60,7 @@ describe("option-manager", () => { "presets": [{ option: "value" }] }); }, + // eslint-disable-next-line max-len /Unknown option: foreign.option\.(?:.|\n)+A common cause of this error is the presence of a configuration options object without the corresponding preset name/ ); }); diff --git a/packages/babel-generator/package.json b/packages/babel-generator/package.json index 9a6b38db42..7e5511e367 100644 --- a/packages/babel-generator/package.json +++ b/packages/babel-generator/package.json @@ -16,7 +16,8 @@ "detect-indent": "^5.0.0", "jsesc": "^1.3.0", "lodash": "^4.2.0", - "source-map": "^0.5.0" + "source-map": "^0.5.0", + "trim-right": "^1.0.1" }, "devDependencies": { "babel-helper-fixtures": "^6.22.0", diff --git a/packages/babel-generator/src/buffer.js b/packages/babel-generator/src/buffer.js index d1187be275..3c53ef666d 100644 --- a/packages/babel-generator/src/buffer.js +++ b/packages/babel-generator/src/buffer.js @@ -1,5 +1,5 @@ import type SourceMap from "./source-map"; -import trimEnd from "lodash/trimEnd"; +import trimRight from "trim-right"; const SPACES_RE = /^[ \t]+$/; @@ -40,7 +40,9 @@ export default class Buffer { const map = this._map; const result = { - code: trimEnd(this._buf.join("")), + // Whatever trim is used here should not execute a regex against the + // source string since it may be arbitrarily large after all transformations + code: trimRight(this._buf.join("")), map: null, rawMappings: map && map.getRawMappings(), }; diff --git a/packages/babel-generator/src/generators/expressions.js b/packages/babel-generator/src/generators/expressions.js index 0cf5f2093e..8ba9491071 100644 --- a/packages/babel-generator/src/generators/expressions.js +++ b/packages/babel-generator/src/generators/expressions.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import * as t from "babel-types"; import * as n from "../node"; diff --git a/packages/babel-generator/src/generators/flow.js b/packages/babel-generator/src/generators/flow.js index 2e96843eaf..d8de870dee 100644 --- a/packages/babel-generator/src/generators/flow.js +++ b/packages/babel-generator/src/generators/flow.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - export function AnyTypeAnnotation() { this.word("any"); } diff --git a/packages/babel-generator/src/generators/methods.js b/packages/babel-generator/src/generators/methods.js index 97bbcd3129..2ad6d41ffb 100644 --- a/packages/babel-generator/src/generators/methods.js +++ b/packages/babel-generator/src/generators/methods.js @@ -93,5 +93,6 @@ export function ArrowFunctionExpression(node: Object) { } function hasTypes(node, param) { - return node.typeParameters || node.returnType || param.typeAnnotation || param.optional || param.trailingComments; + return node.typeParameters || node.returnType || param.typeAnnotation || param.optional || + param.trailingComments; } diff --git a/packages/babel-generator/src/generators/types.js b/packages/babel-generator/src/generators/types.js index fa8498aff7..5fada08e79 100644 --- a/packages/babel-generator/src/generators/types.js +++ b/packages/babel-generator/src/generators/types.js @@ -1,6 +1,3 @@ -/* eslint max-len: 0 */ -/* eslint quotes: 0 */ - import * as t from "babel-types"; import jsesc from "jsesc"; @@ -62,7 +59,8 @@ export function ObjectProperty(node: Object) { this.token("]"); } else { // print `({ foo: foo = 5 } = {})` as `({ foo = 5 } = {});` - if (t.isAssignmentPattern(node.value) && t.isIdentifier(node.key) && node.key.name === node.value.left.name) { + if (t.isAssignmentPattern(node.value) && t.isIdentifier(node.key) && + node.key.name === node.value.left.name) { this.print(node.value, node); return; } diff --git a/packages/babel-generator/src/node/parentheses.js b/packages/babel-generator/src/node/parentheses.js index e6424aced6..558bceb14c 100644 --- a/packages/babel-generator/src/node/parentheses.js +++ b/packages/babel-generator/src/node/parentheses.js @@ -170,16 +170,14 @@ export function FunctionExpression(node: Object, parent: Object, printStack: Arr } export function ArrowFunctionExpression(node: Object, parent: Object): boolean { - // export default (function () {}); - if (t.isExportDeclaration(parent)) { - return true; - } - - if (t.isBinaryExpression(parent) || t.isLogicalExpression(parent)) { - return true; - } - - if (t.isUnaryExpression(parent)) { + if ( + // export default (function () {}); + t.isExportDeclaration(parent) || + t.isBinaryExpression(parent) || + t.isLogicalExpression(parent) || + t.isUnaryExpression(parent) || + t.isTaggedTemplateExpression(parent) + ) { return true; } @@ -199,6 +197,10 @@ export function ConditionalExpression(node: Object, parent: Object): boolean { return true; } + if (t.isAwaitExpression(parent)) { + return true; + } + return UnaryLike(node, parent); } @@ -225,6 +227,10 @@ function isFirstInStatement(printStack: Array, { return true; } + if (t.isTaggedTemplateExpression(parent)) { + return true; + } + if (considerDefaultExports && t.isExportDefaultDeclaration(parent, { declaration: node })) { return true; } diff --git a/packages/babel-generator/src/printer.js b/packages/babel-generator/src/printer.js index e03298d1f9..6d164fc2fe 100644 --- a/packages/babel-generator/src/printer.js +++ b/packages/babel-generator/src/printer.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import find from "lodash/find"; import findLast from "lodash/findLast"; import isInteger from "lodash/isInteger"; @@ -321,6 +319,7 @@ export default class Printer { const printMethod = this[node.type]; if (!printMethod) { + // eslint-disable-next-line max-len throw new ReferenceError(`unknown node of type ${JSON.stringify(node.type)} with constructor ${JSON.stringify(node && node.constructor.name)}`); } diff --git a/packages/babel-generator/test/fixtures/parentheses/await-expression/actual.js b/packages/babel-generator/test/fixtures/parentheses/await-expression/actual.js index 6ac1480c55..d4bdc6b74a 100644 --- a/packages/babel-generator/test/fixtures/parentheses/await-expression/actual.js +++ b/packages/babel-generator/test/fixtures/parentheses/await-expression/actual.js @@ -3,6 +3,7 @@ async function asdf() { (await b)(); new (await b)(); true ? (await 1) : (await 2); + await (1 ? 2 : 3); await (await 1); } diff --git a/packages/babel-generator/test/fixtures/parentheses/await-expression/expected.js b/packages/babel-generator/test/fixtures/parentheses/await-expression/expected.js index a5ec177acd..dc2cb361e0 100644 --- a/packages/babel-generator/test/fixtures/parentheses/await-expression/expected.js +++ b/packages/babel-generator/test/fixtures/parentheses/await-expression/expected.js @@ -3,6 +3,7 @@ async function asdf() { (await b)(); new (await b)(); true ? await 1 : await 2; + await (1 ? 2 : 3); await await 1; } diff --git a/packages/babel-generator/test/fixtures/parentheses/tagged-template-expression/actual.js b/packages/babel-generator/test/fixtures/parentheses/tagged-template-expression/actual.js new file mode 100644 index 0000000000..8a19f04a89 --- /dev/null +++ b/packages/babel-generator/test/fixtures/parentheses/tagged-template-expression/actual.js @@ -0,0 +1,2 @@ +(() => {})``; +(function(){}``); diff --git a/packages/babel-generator/test/fixtures/parentheses/tagged-template-expression/expected.js b/packages/babel-generator/test/fixtures/parentheses/tagged-template-expression/expected.js new file mode 100644 index 0000000000..f47cd2e9af --- /dev/null +++ b/packages/babel-generator/test/fixtures/parentheses/tagged-template-expression/expected.js @@ -0,0 +1,2 @@ +(() => {})``; +(function () {})``; \ No newline at end of file diff --git a/packages/babel-generator/test/fixtures/parentheses/yield-expression/actual.js b/packages/babel-generator/test/fixtures/parentheses/yield-expression/actual.js index 97ef823d3c..b000b972b5 100644 --- a/packages/babel-generator/test/fixtures/parentheses/yield-expression/actual.js +++ b/packages/babel-generator/test/fixtures/parentheses/yield-expression/actual.js @@ -3,6 +3,7 @@ function* asdf() { (yield b)(); new (yield b)(); (yield 1) ? (yield 2) : (yield 3); + yield (1 ? 2 : 3); yield (yield 1); } diff --git a/packages/babel-generator/test/fixtures/parentheses/yield-expression/expected.js b/packages/babel-generator/test/fixtures/parentheses/yield-expression/expected.js index cbc86c5c5c..68c2e6b123 100644 --- a/packages/babel-generator/test/fixtures/parentheses/yield-expression/expected.js +++ b/packages/babel-generator/test/fixtures/parentheses/yield-expression/expected.js @@ -3,6 +3,7 @@ function* asdf() { (yield b)(); new (yield b)(); (yield 1) ? yield 2 : yield 3; + yield 1 ? 2 : 3; yield yield 1; } diff --git a/packages/babel-generator/test/index.js b/packages/babel-generator/test/index.js index d15e53807a..4a9d52aa36 100644 --- a/packages/babel-generator/test/index.js +++ b/packages/babel-generator/test/index.js @@ -324,7 +324,10 @@ suites.forEach(function (testSuite) { }); const result = generate(actualAst, task.options, actualCode); - if (!expect.code && result.code && fs.statSync(path.dirname(expect.loc)).isDirectory() && !process.env.CI) { + if ( + !expect.code && result.code && fs.statSync(path.dirname(expect.loc)).isDirectory() && + !process.env.CI + ) { console.log(`New test file created: ${expect.loc}`); fs.writeFileSync(expect.loc, result.code); } else { diff --git a/packages/babel-helper-builder-react-jsx/src/index.js b/packages/babel-helper-builder-react-jsx/src/index.js index 1a0a1ca626..86d66d2b4d 100644 --- a/packages/babel-helper-builder-react-jsx/src/index.js +++ b/packages/babel-helper-builder-react-jsx/src/index.js @@ -128,7 +128,8 @@ export default function (opts) { const useBuiltIns = file.opts.useBuiltIns || false; if (typeof useBuiltIns !== "boolean") { - throw new Error("transform-react-jsx currently only accepts a boolean option for useBuiltIns (defaults to false)"); + throw new Error("transform-react-jsx currently only accepts a boolean option for " + + "useBuiltIns (defaults to false)"); } function pushProps() { diff --git a/packages/babel-helper-define-map/src/index.js b/packages/babel-helper-define-map/src/index.js index 05fa5ee886..b0c45ab7e1 100644 --- a/packages/babel-helper-define-map/src/index.js +++ b/packages/babel-helper-define-map/src/index.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import nameFunction from "babel-helper-function-name"; import has from "lodash/has"; import * as t from "babel-types"; @@ -36,7 +34,8 @@ export function push(mutatorMap: Object, node: Object, kind: string, file, scope if (node.decorators) { const decorators = map.decorators = map.decorators || t.arrayExpression([]); - decorators.elements = decorators.elements.concat(node.decorators.map((dec) => dec.expression).reverse()); + decorators.elements = decorators.elements.concat( + node.decorators.map((dec) => dec.expression).reverse()); } if (map.value || map.initializer) { @@ -63,7 +62,8 @@ export function push(mutatorMap: Object, node: Object, kind: string, file, scope } // infer function name - if (scope && t.isStringLiteral(key) && (kind === "value" || kind === "initializer") && t.isFunctionExpression(value)) { + if (scope && t.isStringLiteral(key) && (kind === "value" || kind === "initializer") && + t.isFunctionExpression(value)) { value = nameFunction({ id: key, node: value, scope }); } diff --git a/packages/babel-helper-function-name/src/index.js b/packages/babel-helper-function-name/src/index.js index 7623bf0a10..1c38e531ab 100644 --- a/packages/babel-helper-function-name/src/index.js +++ b/packages/babel-helper-function-name/src/index.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import getFunctionArity from "babel-helper-get-function-arity"; import template from "babel-template"; import * as t from "babel-types"; @@ -131,7 +129,8 @@ export default function ({ node, parent, scope, id }) { // has an `id` so we don't need to infer one if (node.id) return; - if ((t.isObjectProperty(parent) || t.isObjectMethod(parent, { kind: "method" })) && (!parent.computed || t.isLiteral(parent.key))) { + if ((t.isObjectProperty(parent) || t.isObjectMethod(parent, { kind: "method" })) && + (!parent.computed || t.isLiteral(parent.key))) { // { foo() {} }; id = parent.key; } else if (t.isVariableDeclarator(parent)) { diff --git a/packages/babel-helper-optimise-call-expression/src/index.js b/packages/babel-helper-optimise-call-expression/src/index.js index d96f2e64c6..485f986321 100644 --- a/packages/babel-helper-optimise-call-expression/src/index.js +++ b/packages/babel-helper-optimise-call-expression/src/index.js @@ -1,9 +1,8 @@ -/* eslint max-len: 0 */ - import * as t from "babel-types"; export default function (callee, thisNode, args) { - if (args.length === 1 && t.isSpreadElement(args[0]) && t.isIdentifier(args[0].argument, { name: "arguments" })) { + if (args.length === 1 && t.isSpreadElement(args[0]) && + t.isIdentifier(args[0].argument, { name: "arguments" })) { // eg. super(...arguments); return t.callExpression( t.memberExpression(callee, t.identifier("apply")), diff --git a/packages/babel-helper-replace-supers/src/index.js b/packages/babel-helper-replace-supers/src/index.js index 8214753552..7fa593bb36 100644 --- a/packages/babel-helper-replace-supers/src/index.js +++ b/packages/babel-helper-replace-supers/src/index.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import type { NodePath, Scope } from "babel-traverse"; import optimiseCall from "babel-helper-optimise-call-expression"; import * as messages from "babel-messages"; @@ -144,7 +142,8 @@ export default class ReplaceSupers { * * @example * - * _set(CLASS.prototype.__proto__ || Object.getPrototypeOf(CLASS.prototype), "METHOD", "VALUE", this) + * _set(CLASS.prototype.__proto__ || Object.getPrototypeOf(CLASS.prototype), "METHOD", "VALUE", + * this) * */ @@ -227,9 +226,8 @@ export default class ReplaceSupers { t.variableDeclaration("var", [ t.variableDeclarator(ref, node.left) ]), - t.expressionStatement( - t.assignmentExpression("=", node.left, t.binaryExpression(node.operator[0], ref, node.right)) - ) + t.expressionStatement(t.assignmentExpression("=", node.left, + t.binaryExpression(node.operator[0], ref, node.right))) ]; } } @@ -251,22 +249,30 @@ export default class ReplaceSupers { if (t.isSuper(callee)) { return; } else if (isMemberExpressionSuper(callee)) { - // super.test(); -> _get(Object.getPrototypeOf(objectRef.prototype), "test", this).call(this); + // super.test(); + // to + // _get(Object.getPrototypeOf(objectRef.prototype), "test", this).call(this); property = callee.property; computed = callee.computed; args = node.arguments; } } else if (t.isMemberExpression(node) && t.isSuper(node.object)) { - // super.name; -> _get(Object.getPrototypeOf(objectRef.prototype), "name", this); + // super.name; + // to + // _get(Object.getPrototypeOf(objectRef.prototype), "name", this); property = node.property; computed = node.computed; } else if (t.isUpdateExpression(node) && isMemberExpressionSuper(node.argument)) { const binary = t.binaryExpression(node.operator[0], node.argument, t.numericLiteral(1)); if (node.prefix) { - // ++super.foo; -> super.foo += 1; + // ++super.foo; + // to + // super.foo += 1; return this.specHandleAssignmentExpression(null, path, binary); } else { - // super.foo++; -> let _ref = super.foo; super.foo = _ref + 1; + // super.foo++; + // to + // let _ref = super.foo; super.foo = _ref + 1; const ref = path.scope.generateUidIdentifier("ref"); return this.specHandleAssignmentExpression(ref, path, binary).concat(t.expressionStatement(ref)); } diff --git a/packages/babel-helper-transform-fixture-test-runner/src/index.js b/packages/babel-helper-transform-fixture-test-runner/src/index.js index d8035b3fa6..6c559e7f8f 100644 --- a/packages/babel-helper-transform-fixture-test-runner/src/index.js +++ b/packages/babel-helper-transform-fixture-test-runner/src/index.js @@ -100,7 +100,8 @@ function wrapPackagesArray(type, names, optionsDir) { if (val[0][0] === ".") { if (!optionsDir) { - throw new Error("Please provide an options.json in test dir when using a relative plugin path."); + throw new Error("Please provide an options.json in test dir when using a " + + "relative plugin path."); } val[0] = path.resolve(optionsDir, val[0]); @@ -129,7 +130,8 @@ function run(task) { newOpts.plugins = wrapPackagesArray("plugin", newOpts.plugins, optionsDir); newOpts.presets = wrapPackagesArray("preset", newOpts.presets, optionsDir).map(function (val) { if (val.length > 2) { - throw new Error(`Unexpected extra options ${JSON.stringify(val.slice(2))} passed to preset.`); + throw new Error("Unexpected extra options " + JSON.stringify(val.slice(2)) + + " passed to preset."); } return val; @@ -160,7 +162,10 @@ function run(task) { const expectCode = expect.code; if (!execCode || actualCode) { result = babel.transform(actualCode, getOpts(actual)); - if (!expect.code && result.code && !opts.throws && fs.statSync(path.dirname(expect.loc)).isDirectory() && !process.env.CI) { + if ( + !expect.code && result.code && !opts.throws && fs.statSync(path.dirname(expect.loc)).isDirectory() && + !process.env.CI + ) { console.log(`New test file created: ${expect.loc}`); fs.writeFileSync(expect.loc, result.code); } else { diff --git a/packages/babel-helpers/src/helpers.js b/packages/babel-helpers/src/helpers.js index cdd63768da..d7d20aedfd 100644 --- a/packages/babel-helpers/src/helpers.js +++ b/packages/babel-helpers/src/helpers.js @@ -1,4 +1,4 @@ -/* eslint max-len: 0 */ +/* eslint max-len: "off" */ import template from "babel-template"; diff --git a/packages/babel-helpers/src/index.js b/packages/babel-helpers/src/index.js index 207318cf27..c25dce9c14 100644 --- a/packages/babel-helpers/src/index.js +++ b/packages/babel-helpers/src/index.js @@ -1,5 +1,3 @@ -/* eslint no-confusing-arrow: 0 */ - import helpers from "./helpers"; export function get(name) { @@ -10,7 +8,7 @@ export function get(name) { } export const list = Object.keys(helpers) - .map((name) => name[0] === "_" ? name.slice(1) : name) + .map((name) => name.replace(/^_/, "")) .filter((name) => name !== "__esModule"); export default get; diff --git a/packages/babel-messages/src/index.js b/packages/babel-messages/src/index.js index 7064bd69b9..e6f94cab3a 100644 --- a/packages/babel-messages/src/index.js +++ b/packages/babel-messages/src/index.js @@ -1,4 +1,4 @@ -/* eslint max-len: 0 */ +/* eslint max-len: "off" */ import * as util from "util"; diff --git a/packages/babel-plugin-check-es2015-constants/README.md b/packages/babel-plugin-check-es2015-constants/README.md index 608891b3d2..1ee65e3f07 100644 --- a/packages/babel-plugin-check-es2015-constants/README.md +++ b/packages/babel-plugin-check-es2015-constants/README.md @@ -20,7 +20,6 @@ repl: "a" is read-only | ^ ``` -[Try in REPL](http://babeljs.io/repl/#?babili=false&evaluate=true&lineWrap=false&presets=es2015&experimental=false&loose=false&spec=false&code=const%20a%20%3D%201%3B%0Aa%20%3D%202%3B&playground=true) ## Installation diff --git a/packages/babel-plugin-syntax-trailing-function-commas/README.md b/packages/babel-plugin-syntax-trailing-function-commas/README.md index fd7022b23f..61622bfe69 100644 --- a/packages/babel-plugin-syntax-trailing-function-commas/README.md +++ b/packages/babel-plugin-syntax-trailing-function-commas/README.md @@ -14,7 +14,6 @@ clownPuppiesEverywhere( 'bar', ); ``` -[Try in REPL](http://babeljs.io/repl/#?evaluate=true&presets=es2015%2Cstage-0&code=function%20clownPuppiesEverywhere(%0A%20%20param1%2C%0A%20%20param2%2C%0A)%20%7B%20%2F*%20...%20*%2F%20%7D%0A%0AclownPuppiesEverywhere(%0A%20%20'foo'%2C%0A%20%20'bar'%2C%0A)%3B) ## Example diff --git a/packages/babel-plugin-transform-class-constructor-call/README.md b/packages/babel-plugin-transform-class-constructor-call/README.md new file mode 100644 index 0000000000..519c27cc71 --- /dev/null +++ b/packages/babel-plugin-transform-class-constructor-call/README.md @@ -0,0 +1,99 @@ +# babel-plugin-transform-class-constructor-call (deprecated) + +> Proposal Withdrawn: can be solved with decorators. + +This plugin allows Babel to transform class constructors. + +It basically allows to use the [new.target](http://mdn.io/new.target) feature on ES2015 classes: + +```js +class Point { + + constructor(x, y) { + this.x = x; + this.y = y; + } + + call constructor(x, y) { + return new Point(x, y); + } + +} + +let p1 = new Point(1, 2); // OK +let p2 = Point(3, 4); // OK +``` + +## Example + +### Date example +The javascript [Date](http://mdn.io/date) works this way: + +```js +// You can get a Date instance using the new keyword +let now = new Date(); +console.log(now.getMonth()); // Prints '3' +console.log(now.toString()); // Prints 'Mon Apr 11 2016 13:26:07 GMT+0100 (BST)' + +// You can get a string of the current date using Date as a function: +let nowStr = Date(); +console.log(nowStr); // Prints 'Mon Apr 11 2016 13:26:07 GMT+0100 (BST)' +``` + +It is currently possible to implement something like that using [new.target](http://mdn.io/new.target) (see [example in proposal](https://github.com/tc39/ecma262/blob/master/workingdocs/callconstructor.md#motivating-example)) and this new feature makes it available for ES2015 classes. + +A date implementation could be: + +```js +class Date { + constructor() { + // ... + } + + call constructor() { + let date = new Date(); + return date.toString(); + } +} + +let now = new Date(); // Get a Date instance +let nowStr = Date(); // Use the 'call constructor()' part to get a string value of the current date +``` + +## Installation + +```sh +npm install --save-dev babel-plugin-transform-class-constructor-call +``` + +## Usage + +### Via `.babelrc` (Recommended) + +**.babelrc** + +```json +{ + "plugins": ["transform-class-constructor-call"] +} +``` + +### Via CLI + +```sh +babel --plugins transform-class-constructor-call script.js +``` + +### Via Node API + +```javascript +require("babel-core").transform("code", { + plugins: ["transform-class-constructor-call"] +}); +``` + +## References + +* [Inactive Proposals](https://github.com/tc39/proposals/blob/master/inactive-proposals.md) +* [Proposal: Call Constructor](https://github.com/tc39/ecma262/blob/master/workingdocs/callconstructor.md) +* [Blog post: ECMAScript proposal: function-callable classes](http://www.2ality.com/2015/10/call-constructor-esprop.html) diff --git a/packages/babel-plugin-transform-class-properties/README.md b/packages/babel-plugin-transform-class-properties/README.md index 9dbe559082..49f48223e4 100644 --- a/packages/babel-plugin-transform-class-properties/README.md +++ b/packages/babel-plugin-transform-class-properties/README.md @@ -33,7 +33,6 @@ Below is a class with four class properties which will be transformed. console.log(Bork.staticFunction()); // > "babelIsCool" ``` -[Try in REPL](http://babeljs.io/repl/#?babili=false&evaluate=false&lineWrap=false&presets=es2016%2Clatest%2Cstage-2&code=%20%20class%20Bork%20%7B%0A%20%20%20%20%2F%2FProperty%20initilizer%20syntax%0A%20%20%20%20instanceProperty%20%3D%20%22bork%22%3B%0A%20%20%20%20boundFunction%20%3D%20()%20%3D%3E%20%7B%0A%20%20%20%20%20%20return%20this.instanceProperty%3B%0A%20%20%20%20%7D%0A%20%20%20%20%0A%20%20%20%20%2F%2FStatic%20class%20properties%0A%20%20%20%20static%20staticProperty%20%3D%20%22babeliscool%22%3B%0A%20%20%20%20static%20staticFunction%20%3D%20function()%20%7B%0A%20%20%20%20%20%20return%20Bork.staticProperty%3B%0A%20%20%20%20%7D%0A%20%20%7D%0A%0A%20%20let%20myBork%20%3D%20new%20Bork%3B%0A%0A%20%20%2F%2FProperty%20initializers%20are%20not%20on%20the%20prototype.%0A%20%20console.log(Bork.prototype.boundFunction)%3B%20%2F%2F%20%3E%20undefined%0A%0A%20%20%2F%2FBound%20functions%20are%20bound%20to%20the%20class%20instance.%0A%20%20console.log(myBork.boundFunction.call(undefined))%3B%20%2F%2F%20%3E%20%22bork%22%0A%0A%20%20%2F%2FStatic%20function%20exists%20on%20the%20class.%0A%20%20console.log(Bork.staticFunction())%3B%20%2F%2F%20%3E%20%22babelIsCool%22) ## Installation @@ -77,7 +76,11 @@ require("babel-core").transform("code", { ## Options -* `spec` - Class properties are compiled to use `Object.defineProperty. Static fields are now defined even if they are not initialized +### `spec` + +`boolean`, defaults to `false`. + +Class properties are compiled to use `Object.defineProperty`. Static fields are now defined even if they are not initialized. ## References diff --git a/packages/babel-plugin-transform-class-properties/src/index.js b/packages/babel-plugin-transform-class-properties/src/index.js index 9c5e7d24a2..1873757ee9 100644 --- a/packages/babel-plugin-transform-class-properties/src/index.js +++ b/packages/babel-plugin-transform-class-properties/src/index.js @@ -1,4 +1,3 @@ -/* eslint max-len: 0 */ import nameFunction from "babel-helper-function-name"; import template from "babel-template"; @@ -44,7 +43,8 @@ export default function ({ types: t }) { visitor: { Class(path, state) { - const buildClassProperty = state.opts.spec ? buildClassPropertySpec : buildClassPropertyNonSpec; + const buildClassProperty = state.opts.spec ? buildClassPropertySpec : + buildClassPropertyNonSpec; const isDerived = !!path.node.superClass; let constructor; const props = []; @@ -92,7 +92,8 @@ export default function ({ types: t }) { if (instanceBody.length) { if (!constructor) { - const newConstructor = t.classMethod("constructor", t.identifier("constructor"), [], t.blockStatement([])); + const newConstructor = t.classMethod("constructor", t.identifier("constructor"), [], + t.blockStatement([])); if (isDerived) { newConstructor.params = [t.restElement(t.identifier("args"))]; newConstructor.body.body.push( @@ -129,7 +130,8 @@ export default function ({ types: t }) { instanceBody = [ t.expressionStatement( - t.callExpression(t.memberExpression(initialisePropsRef, t.identifier("call")), [t.thisExpression()]) + t.callExpression(t.memberExpression(initialisePropsRef, t.identifier("call")), [ + t.thisExpression()]) ) ]; } diff --git a/packages/babel-plugin-transform-do-expressions/README.md b/packages/babel-plugin-transform-do-expressions/README.md index 44e252e17d..3408d8d894 100644 --- a/packages/babel-plugin-transform-do-expressions/README.md +++ b/packages/babel-plugin-transform-do-expressions/README.md @@ -22,7 +22,6 @@ let a = do { let a = x > 10 ? 'big' : 'small'; ``` -[Try in REPL](http://babeljs.io/repl/#?evaluate=true&presets=es2015%2Cstage-0&code=%0Alet%20x%20%3D%20100%3B%0A%0Alet%20a%20%3D%20do%20%7B%0A%20%20if(x%20%3E%2010)%20%7B%0A%20%20%20%20'big'%3B%0A%20%20%7D%20else%20%7B%0A%20%20%20%20'small'%3B%0A%20%20%7D%0A%7D%3B%0A%0Aconsole.log(a)%3B) This example is not the best usage because it is too simple and using a ternary operator is a better option but you can have a much more complex condition in the `do { ... }` expression with several `if ... else` chains: @@ -47,8 +46,6 @@ let a = do { }; ``` -[Try in REPL](http://babeljs.io/repl/#?evaluate=true&presets=es2015%2Cstage-0&code=let%20x%20%3D%20100%3B%0Alet%20y%20%3D%2020%3B%0A%0Alet%20a%20%3D%20do%20%7B%0A%20%20if(x%20%3E%2010)%20%7B%0A%20%20%20%20if(y%20%3E%2020)%20%7B%0A%20%20%20%20%20%20'big%20x%2C%20big%20y'%3B%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20'big%20x%2C%20small%20y'%3B%0A%20%20%20%20%7D%0A%20%20%7D%20else%20%7B%0A%20%20%20%20if(y%20%3E%2010)%20%7B%0A%20%20%20%20%20%20'small%20x%2C%20big%20y'%3B%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20'small%20x%2C%20small%20y'%3B%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D%3B%0A%0Aconsole.log(a)%3B) - ## Example ### In JSX @@ -75,14 +72,13 @@ const Component = props =>
{do { if(color === 'blue') { ; } - if(color === 'red') { ; } - if(color === 'green') { ; } + else if(color === 'red') { ; } + else if(color === 'green') { ; } }}
; ``` -[Try in REPL](http://babeljs.io/repl/#?evaluate=true&presets=es2015%2Creact%2Cstage-0&code=const%20Component%20%3D%20props%20%3D%3E%0A%20%20%3Cdiv%20className%3D'myComponent'%3E%0A%20%20%20%20%7Bdo%20%7B%0A%20%20%20%20%20%20if(color%20%3D%3D%3D%20'blue')%20%7B%20%3CBlueComponent%2F%3E%3B%20%7D%0A%20%20%20%20%20%20if(color%20%3D%3D%3D%20'red')%20%7B%20%3CRedComponent%2F%3E%3B%20%7D%0A%20%20%20%20%20%20if(color%20%3D%3D%3D%20'green')%20%7B%20%3CGreenComponent%2F%3E%3B%20%7D%0A%20%20%20%20%7D%7D%0A%20%20%3C%2Fdiv%3E%0A%3B) ## Installation diff --git a/packages/babel-plugin-transform-do-expressions/test/fixtures/do-expressions/while-if/actual.js b/packages/babel-plugin-transform-do-expressions/test/fixtures/do-expressions/while-if/actual.js new file mode 100644 index 0000000000..d3706c14b3 --- /dev/null +++ b/packages/babel-plugin-transform-do-expressions/test/fixtures/do-expressions/while-if/actual.js @@ -0,0 +1,10 @@ +let p +let a = do { + while (p = p.parentPath) { + if (a) { + 'a' + } else { + 'b' + } + } +}; diff --git a/packages/babel-plugin-transform-do-expressions/test/fixtures/do-expressions/while-if/expected.js b/packages/babel-plugin-transform-do-expressions/test/fixtures/do-expressions/while-if/expected.js new file mode 100644 index 0000000000..5c0298f045 --- /dev/null +++ b/packages/babel-plugin-transform-do-expressions/test/fixtures/do-expressions/while-if/expected.js @@ -0,0 +1,13 @@ +let p; +let a = function () { + var _ret; + + while (p = p.parentPath) { + if (a) { + _ret = 'a'; + } else { + _ret = 'b'; + } + } + return _ret; +}(); diff --git a/packages/babel-plugin-transform-es2015-arrow-functions/README.md b/packages/babel-plugin-transform-es2015-arrow-functions/README.md index 6e1b8f353e..658f413f6c 100644 --- a/packages/babel-plugin-transform-es2015-arrow-functions/README.md +++ b/packages/babel-plugin-transform-es2015-arrow-functions/README.md @@ -51,8 +51,6 @@ var bob = { console.log(bob.printFriends()); ``` -[Try in REPL](http://babeljs.io/repl/#?evaluate=true&lineWrap=true&presets=es2015%2Ces2015-loose&experimental=false&loose=false&spec=false&code=var%20a%20%3D%20()%20%3D%3E%20%7B%7D%3B%0Avar%20a%20%3D%20(b)%20%3D%3E%20b%3B%0A%0Aconst%20double%20%3D%20%5B1%2C2%2C3%5D.map((num)%20%3D%3E%20num%20*%202)%3B%0Aconsole.log(double)%3B%20%2F%2F%20%5B2%2C4%2C6%5D%0A%0Avar%20bob%20%3D%20%7B%0A%20%20_name%3A%20%22Bob%22%2C%0A%20%20_friends%3A%20%5B%22Sally%22%2C%20%22Tom%22%5D%2C%0A%20%20printFriends()%20%7B%0A%20%20%20%20this._friends.forEach(f%20%3D%3E%0A%20%20%20%20%20%20console.log(this._name%20%2B%20%22%20knows%20%22%20%2B%20f))%3B%0A%20%20%7D%0A%7D%3B%0Aconsole.log(bob.printFriends())%3B&playground=true) - ## Installation ```sh @@ -65,13 +63,17 @@ npm install --save-dev babel-plugin-transform-es2015-arrow-functions **.babelrc** -```js -// without options +Without options: + +```json { "plugins": ["transform-es2015-arrow-functions"] } +``` -// with options +With options: + +```json { "plugins": [ ["transform-es2015-arrow-functions", { "spec": true }] @@ -95,4 +97,8 @@ require("babel-core").transform("code", { ## Options -* `spec` - This option wraps the generated function in `.bind(this)` and keeps uses of `this` inside the function as-is, instead of using a renamed `this`. It also adds a runtime check to ensure the functions are not instantiated. +### `spec` + +`boolean`, defaults to `false`. + +This option wraps the generated function in `.bind(this)` and keeps uses of `this` inside the function as-is, instead of using a renamed `this`. It also adds a runtime check to ensure the functions are not instantiated. diff --git a/packages/babel-plugin-transform-es2015-block-scoping/README.md b/packages/babel-plugin-transform-es2015-block-scoping/README.md index ee1d426600..2890f38d09 100644 --- a/packages/babel-plugin-transform-es2015-block-scoping/README.md +++ b/packages/babel-plugin-transform-es2015-block-scoping/README.md @@ -14,12 +14,26 @@ npm install --save-dev babel-plugin-transform-es2015-block-scoping **.babelrc** +Without options: + ```json { "plugins": ["transform-es2015-block-scoping"] } ``` +With options: + +```json +{ + "plugins": [ + ["transform-es2015-block-scoping", { + "throwIfClosureRequired": true + }] + ] +} +``` + ### Via CLI ```sh @@ -33,3 +47,15 @@ require("babel-core").transform("code", { plugins: ["transform-es2015-block-scoping"] }); ``` + +## Options `throwIfClosureRequired` + +In cases such as the following it's impossible to rewrite let/const without adding an additional function and closure while transforming: + +```javascript +for (let i = 0; i < 5; i++) { + setTimeout(() => console.log(i), 1); +} +``` + +In extremely performance-sensitive code, this can be undesirable. If `"throwIfClosureRequired": true` is set, Babel throws when transforming these patterns instead of automatically adding an additional function. 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 19a36f558c..b1227d3a52 100644 --- a/packages/babel-plugin-transform-es2015-block-scoping/src/index.js +++ b/packages/babel-plugin-transform-es2015-block-scoping/src/index.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import type NodePath from "babel-traverse"; import type Scope from "babel-traverse"; import type File from "../../../file"; @@ -362,6 +360,12 @@ class BlockScoping { } wrapClosure() { + if (this.file.opts.throwIfClosureRequired) { + throw this.blockPath.buildCodeFrameError( + "Compiling let/const in this block would add a closure " + + "(throwIfClosureRequired)." + ); + } const block = this.block; const outsideRefs = this.outsideLetReferences; @@ -397,7 +401,8 @@ class BlockScoping { const isSwitch = this.blockPath.isSwitchStatement(); // build the closure that we're going to wrap the block with, possible wrapping switch(){} - const fn = t.functionExpression(null, params, t.blockStatement(isSwitch ? [block] : block.body)); + const fn = t.functionExpression(null, params, + t.blockStatement(isSwitch ? [block] : block.body)); fn.shadow = true; // continuation @@ -654,7 +659,8 @@ class BlockScoping { for (let i = 0; i < cases.length; i++) { const caseConsequent = cases[i].consequent[0]; if (t.isBreakStatement(caseConsequent) && !caseConsequent.label) { - caseConsequent.label = this.loopLabel = this.loopLabel || this.scope.generateUidIdentifier("loop"); + caseConsequent.label = this.loopLabel = this.loopLabel || + this.scope.generateUidIdentifier("loop"); } } } diff --git a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/for-const-closure/actual.js b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/for-const-closure/actual.js new file mode 100644 index 0000000000..55dbb21d37 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/for-const-closure/actual.js @@ -0,0 +1,6 @@ +for (let i = 0; i < 5; i++) { + const l = i; + setTimeout(function() { + console.log(l); + }, 1); +} diff --git a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/for-const-closure/options.json b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/for-const-closure/options.json new file mode 100644 index 0000000000..d210fdebfc --- /dev/null +++ b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/for-const-closure/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Compiling let/const in this block would add a closure (throwIfClosureRequired)." +} diff --git a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/function/actual.js b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/function/actual.js new file mode 100644 index 0000000000..2b9635ec33 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/function/actual.js @@ -0,0 +1,3 @@ +function test() { + let foo = "bar"; +} diff --git a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/function/expected.js b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/function/expected.js new file mode 100644 index 0000000000..bb4b09c9c5 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/function/expected.js @@ -0,0 +1,3 @@ +function test() { + var foo = "bar"; +} diff --git a/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/options.json b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/options.json new file mode 100644 index 0000000000..3228559d0b --- /dev/null +++ b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["transform-es2015-block-scoping", { "throwIfClosureRequired": true }], "syntax-jsx", "transform-react-jsx", "transform-es2015-block-scoped-functions", "transform-es2015-arrow-functions"] +} 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 new file mode 100644 index 0000000000..857b8641f4 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/superswitch/actual.js @@ -0,0 +1,16 @@ +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 new file mode 100644 index 0000000000..d210fdebfc --- /dev/null +++ b/packages/babel-plugin-transform-es2015-block-scoping/test/fixtures/throwIfClosureRequired/superswitch/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Compiling let/const in this block would add a closure (throwIfClosureRequired)." +} diff --git a/packages/babel-plugin-transform-es2015-classes/README.md b/packages/babel-plugin-transform-es2015-classes/README.md index e115f62cfa..c189adf3f5 100644 --- a/packages/babel-plugin-transform-es2015-classes/README.md +++ b/packages/babel-plugin-transform-es2015-classes/README.md @@ -50,7 +50,11 @@ require("babel-core").transform("code", { }); ``` -## Options `loose` +## Options + +### `loose` + +`boolean`, defaults to `false`. #### Method enumerability diff --git a/packages/babel-plugin-transform-es2015-classes/src/vanilla.js b/packages/babel-plugin-transform-es2015-classes/src/vanilla.js index b38a00fa02..a9a36d4680 100644 --- a/packages/babel-plugin-transform-es2015-classes/src/vanilla.js +++ b/packages/babel-plugin-transform-es2015-classes/src/vanilla.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import type { NodePath } from "babel-traverse"; import { visitors } from "babel-traverse"; import ReplaceSupers from "babel-helper-replace-supers"; @@ -28,7 +26,10 @@ const noMethodVisitor = { const verifyConstructorVisitor = visitors.merge([noMethodVisitor, { Super(path) { - if (this.isDerived && !this.hasBareSuper && !path.parentPath.isCallExpression({ callee: path.node })) { + if ( + this.isDerived && !this.hasBareSuper && + !path.parentPath.isCallExpression({ callee: path.node }) + ) { throw path.buildCodeFrameError("'super.*' is not allowed before super()"); } }, @@ -88,7 +89,8 @@ export default class ClassTransformer { this.classId = this.node.id; // this is the name of the binding that will **always** reference the class we've constructed - this.classRef = this.node.id ? t.identifier(this.node.id.name) : this.scope.generateUidIdentifier("class"); + this.classRef = this.node.id ? t.identifier(this.node.id.name) : + this.scope.generateUidIdentifier("class"); this.superName = this.node.superClass || t.identifier("Function"); this.isDerived = !!this.node.superClass; @@ -123,10 +125,12 @@ export default class ClassTransformer { this.buildBody(); // make sure this class isn't directly called - constructorBody.body.unshift(t.expressionStatement(t.callExpression(file.addHelper("classCallCheck"), [ - t.thisExpression(), - this.classRef - ]))); + constructorBody.body.unshift(t.expressionStatement(t.callExpression( + file.addHelper("classCallCheck"), [ + t.thisExpression(), + this.classRef + ] + ))); body = body.concat(this.staticPropBody.map((fn) => fn(this.classRef))); @@ -227,7 +231,8 @@ export default class ClassTransformer { } if (node.decorators) { - throw path.buildCodeFrameError("Method has decorators, put the decorator plugin before the classes one."); + throw path.buildCodeFrameError( + "Method has decorators, put the decorator plugin before the classes one."); } if (t.isClassMethod(node)) { @@ -294,8 +299,13 @@ export default class ClassTransformer { const nullNode = t.nullLiteral(); - // (Constructor, instanceDescriptors, staticDescriptors, instanceInitializers, staticInitializers) - let args = [this.classRef, nullNode, nullNode, nullNode, nullNode]; + let args = [ + this.classRef, // Constructor + nullNode, // instanceDescriptors + nullNode, // staticDescriptors + nullNode, // instanceInitializers + nullNode, // staticInitializers + ]; if (instanceProps) args[1] = instanceProps; if (staticProps) args[2] = staticProps; @@ -336,7 +346,11 @@ export default class ClassTransformer { if (this.isLoose) { bareSuperNode.arguments.unshift(t.thisExpression()); - if (bareSuperNode.arguments.length === 2 && t.isSpreadElement(bareSuperNode.arguments[1]) && t.isIdentifier(bareSuperNode.arguments[1].argument, { name: "arguments" })) { + if ( + bareSuperNode.arguments.length === 2 && + t.isSpreadElement(bareSuperNode.arguments[1]) && + t.isIdentifier(bareSuperNode.arguments[1].argument, { name: "arguments" }) + ) { // special case single arguments spread bareSuperNode.arguments[1] = bareSuperNode.arguments[1].argument; bareSuperNode.callee = t.memberExpression(superRef, t.identifier("apply")); @@ -365,7 +379,11 @@ export default class ClassTransformer { const bareSuperAfter = this.bareSuperAfter.map((fn) => fn(thisRef)); - if (bareSuper.parentPath.isExpressionStatement() && bareSuper.parentPath.container === body.node.body && body.node.body.length - 1 === bareSuper.parentPath.key) { + if ( + bareSuper.parentPath.isExpressionStatement() && + bareSuper.parentPath.container === body.node.body && + body.node.body.length - 1 === bareSuper.parentPath.key + ) { // this super call is the last statement in the body so we can just straight up // turn it into a return @@ -435,7 +453,8 @@ export default class ClassTransformer { // return const bodyPaths = body.get("body"); if (bodyPaths.length && !bodyPaths.pop().isReturnStatement()) { - body.pushContainer("body", t.returnStatement(guaranteedSuperBeforeFinish ? thisRef : wrapReturn())); + body.pushContainer("body", t.returnStatement( + guaranteedSuperBeforeFinish ? thisRef : wrapReturn())); } for (const returnPath of this.superReturns) { diff --git a/packages/babel-plugin-transform-es2015-destructuring/src/index.js b/packages/babel-plugin-transform-es2015-destructuring/src/index.js index 0bdfb8b695..2609076a80 100644 --- a/packages/babel-plugin-transform-es2015-destructuring/src/index.js +++ b/packages/babel-plugin-transform-es2015-destructuring/src/index.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - export default function ({ types: t }) { /** @@ -153,7 +151,8 @@ export default function ({ types: t }) { // - const value = t.callExpression(this.file.addHelper("objectWithoutProperties"), [objRef, keys]); + const value = t.callExpression( + this.file.addHelper("objectWithoutProperties"), [objRef, keys]); this.nodes.push(this.buildVariableAssignment(spreadProp.argument, value)); } @@ -294,7 +293,8 @@ export default function ({ types: t }) { if (t.isRestElement(elem)) { elemRef = this.toArray(arrayRef); - elemRef = t.callExpression(t.memberExpression(elemRef, t.identifier("slice")), [t.numericLiteral(i)]); + elemRef = t.callExpression(t.memberExpression(elemRef, t.identifier("slice")), + [t.numericLiteral(i)]); // set the element to the rest element argument since we've dealt with it // being a rest already @@ -485,14 +485,18 @@ export default function ({ types: t }) { t.inherits(nodes[nodes.length - 1], declar); } } else { - nodes.push(t.inherits(destructuring.buildVariableAssignment(declar.id, declar.init), declar)); + nodes.push(t.inherits( + destructuring.buildVariableAssignment(declar.id, declar.init), declar)); } } const nodesOut = []; for (const node of nodes) { const tail = nodesOut[nodesOut.length - 1]; - if (tail && t.isVariableDeclaration(tail) && t.isVariableDeclaration(node) && tail.kind === node.kind) { + if ( + tail && t.isVariableDeclaration(tail) && t.isVariableDeclaration(node) && + tail.kind === node.kind + ) { // Create a single compound let/var rather than many. tail.declarations.push(...node.declarations); } else { 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 760e0e69b0..958eae6bce 100644 --- a/packages/babel-plugin-transform-es2015-for-of/src/index.js +++ b/packages/babel-plugin-transform-es2015-for-of/src/index.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - export default function ({ messages, template, types: t }) { const buildForOfArray = template(` for (var KEY = 0; KEY < ARR.length; KEY++) BODY; @@ -22,6 +20,7 @@ export default function ({ messages, template, types: t }) { } `); + /* eslint-disable max-len */ const buildForOf = template(` var ITERATOR_COMPLETION = true; var ITERATOR_HAD_ERROR_KEY = false; @@ -44,6 +43,7 @@ export default function ({ messages, template, types: t }) { } } `); + /* eslint-enable max-len */ function _ForOfStatementArray(path) { const { node, scope } = path; @@ -76,7 +76,8 @@ export default function ({ messages, template, types: t }) { left.declarations[0].init = iterationValue; loop.body.body.unshift(left); } else { - loop.body.body.unshift(t.expressionStatement(t.assignmentExpression("=", left, iterationValue))); + loop.body.body.unshift(t.expressionStatement( + t.assignmentExpression("=", left, iterationValue))); } if (path.parentPath.isLabeledStatement()) { diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/README.md b/packages/babel-plugin-transform-es2015-modules-commonjs/README.md index 0693b91f07..3a802ab571 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/README.md +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/README.md @@ -62,7 +62,11 @@ require("babel-core").transform("code", { }); ``` -## Options `loose` +## Options + +### `loose` + +`boolean`, defaults to `false`. As per the spec, `import` and `export` are only allowed to be used at the top level. When in loose mode these are allowed to be used anywhere. diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js index 1b491ea723..74af212c55 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import { basename, extname } from "path"; import template from "babel-template"; import * as t from "babel-types"; @@ -43,7 +41,8 @@ const buildExportAll = template(` }); `); -const THIS_BREAK_KEYS = ["FunctionExpression", "FunctionDeclaration", "ClassProperty", "ClassMethod", "ObjectMethod"]; +const THIS_BREAK_KEYS = ["FunctionExpression", "FunctionDeclaration", "ClassProperty", + "ClassMethod", "ObjectMethod"]; export default function () { const REASSIGN_REMAP_SKIP = Symbol(); @@ -61,7 +60,8 @@ export default function () { path.replaceWith(t.sequenceExpression([t.numericLiteral(0), remap])); } else if (path.isJSXIdentifier() && t.isMemberExpression(remap)) { const { object, property } = remap; - path.replaceWith(t.JSXMemberExpression(t.JSXIdentifier(object.name), t.JSXIdentifier(property.name))); + path.replaceWith(t.JSXMemberExpression(t.JSXIdentifier(object.name), + t.JSXIdentifier(property.name))); } else { path.replaceWith(remap); } @@ -327,9 +327,15 @@ export default function () { // todo } else if (specifier.isExportSpecifier()) { if (specifier.node.local.name === "default") { - topNodes.push(buildExportsFrom(t.stringLiteral(specifier.node.exported.name), t.memberExpression(t.callExpression(this.addHelper("interopRequireDefault"), [ref]), specifier.node.local))); + topNodes.push(buildExportsFrom(t.stringLiteral(specifier.node.exported.name), + t.memberExpression( + t.callExpression(this.addHelper("interopRequireDefault"), [ref]), + specifier.node.local + ) + )); } else { - topNodes.push(buildExportsFrom(t.stringLiteral(specifier.node.exported.name), t.memberExpression(ref, specifier.node.local))); + topNodes.push(buildExportsFrom(t.stringLiteral(specifier.node.exported.name), + t.memberExpression(ref, specifier.node.local))); } nonHoistedExportNames[specifier.node.exported.name] = true; } @@ -414,7 +420,8 @@ export default function () { topNodes.push(varDecl); } } - remaps[specifier.local.name] = t.memberExpression(target, t.cloneWithoutLoc(specifier.imported)); + remaps[specifier.local.name] = t.memberExpression(target, + t.cloneWithoutLoc(specifier.imported)); } } } else { @@ -426,16 +433,32 @@ export default function () { } if (hasImports && Object.keys(nonHoistedExportNames).length) { - let hoistedExportsNode = t.identifier("undefined"); - for (const name in nonHoistedExportNames) { - hoistedExportsNode = buildExportsAssignment(t.identifier(name), hoistedExportsNode).expression; + // avoid creating too long of export assignment to prevent stack overflow + const maxHoistedExportsNodeAssignmentLength = 100; + const nonHoistedExportNamesArr = Object.keys(nonHoistedExportNames); + + for ( + let currentExportsNodeAssignmentLength = 0; + currentExportsNodeAssignmentLength < nonHoistedExportNamesArr.length; + currentExportsNodeAssignmentLength += maxHoistedExportsNodeAssignmentLength + ) { + const nonHoistedExportNamesChunk = nonHoistedExportNamesArr.slice( + currentExportsNodeAssignmentLength, + currentExportsNodeAssignmentLength + maxHoistedExportsNodeAssignmentLength); + + let hoistedExportsNode = t.identifier("undefined"); + + nonHoistedExportNamesChunk.forEach(function (name) { + hoistedExportsNode = buildExportsAssignment(t.identifier(name), hoistedExportsNode) + .expression; + }); + + const node = t.expressionStatement(hoistedExportsNode); + node._blockHoist = 3; + + topNodes.unshift(node); } - - const node = t.expressionStatement(hoistedExportsNode); - node._blockHoist = 3; - - topNodes.unshift(node); } // add __esModule declaration if this file has any exports diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/export-from-8/actual.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/export-from-8/actual.js new file mode 100644 index 0000000000..b42963fe70 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/export-from-8/actual.js @@ -0,0 +1,2 @@ +import { foo, foo1, foo2, foo3, foo4, foo5, foo6, foo7, foo8, foo9, foo10, foo11, foo12, foo13, foo14, foo15, foo16, foo17, foo18, foo19, foo20, foo21, foo22, foo23, foo24, foo25, foo26, foo27, foo28, foo29, foo30, foo31, foo32, foo33, foo34, foo35, foo36, foo37, foo38, foo39, foo40, foo41, foo42, foo43, foo44, foo45, foo46, foo47, foo48, foo49, foo50, foo51, foo52, foo53, foo54, foo55, foo56, foo57, foo58, foo59, foo60, foo61, foo62, foo63, foo64, foo65, foo66, foo67, foo68, foo69, foo70, foo71, foo72, foo73, foo74, foo75, foo76, foo77, foo78, foo79, foo80, foo81, foo82, foo83, foo84, foo85, foo86, foo87, foo88, foo89, foo90, foo91, foo92, foo93, foo94, foo95, foo96, foo97, foo98, foo99, foo100 } from "foo"; +export { foo, foo1, foo2, foo3, foo4, foo5, foo6, foo7, foo8, foo9, foo10, foo11, foo12, foo13, foo14, foo15, foo16, foo17, foo18, foo19, foo20, foo21, foo22, foo23, foo24, foo25, foo26, foo27, foo28, foo29, foo30, foo31, foo32, foo33, foo34, foo35, foo36, foo37, foo38, foo39, foo40, foo41, foo42, foo43, foo44, foo45, foo46, foo47, foo48, foo49, foo50, foo51, foo52, foo53, foo54, foo55, foo56, foo57, foo58, foo59, foo60, foo61, foo62, foo63, foo64, foo65, foo66, foo67, foo68, foo69, foo70, foo71, foo72, foo73, foo74, foo75, foo76, foo77, foo78, foo79, foo80, foo81, foo82, foo83, foo84, foo85, foo86, foo87, foo88, foo89, foo90, foo91, foo92, foo93, foo94, foo95, foo96, foo97, foo98, foo99, foo100 } \ No newline at end of file diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/export-from-8/expected.js b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/export-from-8/expected.js new file mode 100644 index 0000000000..5f034e9682 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/test/fixtures/interop/export-from-8/expected.js @@ -0,0 +1,111 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.foo100 = undefined; +exports.foo99 = exports.foo98 = exports.foo97 = exports.foo96 = exports.foo95 = exports.foo94 = exports.foo93 = exports.foo92 = exports.foo91 = exports.foo90 = exports.foo89 = exports.foo88 = exports.foo87 = exports.foo86 = exports.foo85 = exports.foo84 = exports.foo83 = exports.foo82 = exports.foo81 = exports.foo80 = exports.foo79 = exports.foo78 = exports.foo77 = exports.foo76 = exports.foo75 = exports.foo74 = exports.foo73 = exports.foo72 = exports.foo71 = exports.foo70 = exports.foo69 = exports.foo68 = exports.foo67 = exports.foo66 = exports.foo65 = exports.foo64 = exports.foo63 = exports.foo62 = exports.foo61 = exports.foo60 = exports.foo59 = exports.foo58 = exports.foo57 = exports.foo56 = exports.foo55 = exports.foo54 = exports.foo53 = exports.foo52 = exports.foo51 = exports.foo50 = exports.foo49 = exports.foo48 = exports.foo47 = exports.foo46 = exports.foo45 = exports.foo44 = exports.foo43 = exports.foo42 = exports.foo41 = exports.foo40 = exports.foo39 = exports.foo38 = exports.foo37 = exports.foo36 = exports.foo35 = exports.foo34 = exports.foo33 = exports.foo32 = exports.foo31 = exports.foo30 = exports.foo29 = exports.foo28 = exports.foo27 = exports.foo26 = exports.foo25 = exports.foo24 = exports.foo23 = exports.foo22 = exports.foo21 = exports.foo20 = exports.foo19 = exports.foo18 = exports.foo17 = exports.foo16 = exports.foo15 = exports.foo14 = exports.foo13 = exports.foo12 = exports.foo11 = exports.foo10 = exports.foo9 = exports.foo8 = exports.foo7 = exports.foo6 = exports.foo5 = exports.foo4 = exports.foo3 = exports.foo2 = exports.foo1 = exports.foo = undefined; + +var _foo = require("foo"); + +exports.foo = _foo.foo; +exports.foo1 = _foo.foo1; +exports.foo2 = _foo.foo2; +exports.foo3 = _foo.foo3; +exports.foo4 = _foo.foo4; +exports.foo5 = _foo.foo5; +exports.foo6 = _foo.foo6; +exports.foo7 = _foo.foo7; +exports.foo8 = _foo.foo8; +exports.foo9 = _foo.foo9; +exports.foo10 = _foo.foo10; +exports.foo11 = _foo.foo11; +exports.foo12 = _foo.foo12; +exports.foo13 = _foo.foo13; +exports.foo14 = _foo.foo14; +exports.foo15 = _foo.foo15; +exports.foo16 = _foo.foo16; +exports.foo17 = _foo.foo17; +exports.foo18 = _foo.foo18; +exports.foo19 = _foo.foo19; +exports.foo20 = _foo.foo20; +exports.foo21 = _foo.foo21; +exports.foo22 = _foo.foo22; +exports.foo23 = _foo.foo23; +exports.foo24 = _foo.foo24; +exports.foo25 = _foo.foo25; +exports.foo26 = _foo.foo26; +exports.foo27 = _foo.foo27; +exports.foo28 = _foo.foo28; +exports.foo29 = _foo.foo29; +exports.foo30 = _foo.foo30; +exports.foo31 = _foo.foo31; +exports.foo32 = _foo.foo32; +exports.foo33 = _foo.foo33; +exports.foo34 = _foo.foo34; +exports.foo35 = _foo.foo35; +exports.foo36 = _foo.foo36; +exports.foo37 = _foo.foo37; +exports.foo38 = _foo.foo38; +exports.foo39 = _foo.foo39; +exports.foo40 = _foo.foo40; +exports.foo41 = _foo.foo41; +exports.foo42 = _foo.foo42; +exports.foo43 = _foo.foo43; +exports.foo44 = _foo.foo44; +exports.foo45 = _foo.foo45; +exports.foo46 = _foo.foo46; +exports.foo47 = _foo.foo47; +exports.foo48 = _foo.foo48; +exports.foo49 = _foo.foo49; +exports.foo50 = _foo.foo50; +exports.foo51 = _foo.foo51; +exports.foo52 = _foo.foo52; +exports.foo53 = _foo.foo53; +exports.foo54 = _foo.foo54; +exports.foo55 = _foo.foo55; +exports.foo56 = _foo.foo56; +exports.foo57 = _foo.foo57; +exports.foo58 = _foo.foo58; +exports.foo59 = _foo.foo59; +exports.foo60 = _foo.foo60; +exports.foo61 = _foo.foo61; +exports.foo62 = _foo.foo62; +exports.foo63 = _foo.foo63; +exports.foo64 = _foo.foo64; +exports.foo65 = _foo.foo65; +exports.foo66 = _foo.foo66; +exports.foo67 = _foo.foo67; +exports.foo68 = _foo.foo68; +exports.foo69 = _foo.foo69; +exports.foo70 = _foo.foo70; +exports.foo71 = _foo.foo71; +exports.foo72 = _foo.foo72; +exports.foo73 = _foo.foo73; +exports.foo74 = _foo.foo74; +exports.foo75 = _foo.foo75; +exports.foo76 = _foo.foo76; +exports.foo77 = _foo.foo77; +exports.foo78 = _foo.foo78; +exports.foo79 = _foo.foo79; +exports.foo80 = _foo.foo80; +exports.foo81 = _foo.foo81; +exports.foo82 = _foo.foo82; +exports.foo83 = _foo.foo83; +exports.foo84 = _foo.foo84; +exports.foo85 = _foo.foo85; +exports.foo86 = _foo.foo86; +exports.foo87 = _foo.foo87; +exports.foo88 = _foo.foo88; +exports.foo89 = _foo.foo89; +exports.foo90 = _foo.foo90; +exports.foo91 = _foo.foo91; +exports.foo92 = _foo.foo92; +exports.foo93 = _foo.foo93; +exports.foo94 = _foo.foo94; +exports.foo95 = _foo.foo95; +exports.foo96 = _foo.foo96; +exports.foo97 = _foo.foo97; +exports.foo98 = _foo.foo98; +exports.foo99 = _foo.foo99; +exports.foo100 = _foo.foo100; \ No newline at end of file diff --git a/packages/babel-plugin-transform-es2015-modules-systemjs/src/index.js b/packages/babel-plugin-transform-es2015-modules-systemjs/src/index.js index c79baab12b..c995a972b3 100644 --- a/packages/babel-plugin-transform-es2015-modules-systemjs/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-systemjs/src/index.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import hoistVariables from "babel-helper-hoist-variables"; import template from "babel-template"; @@ -76,7 +74,8 @@ export default function ({ types: t }) { CallExpression(path, state) { if (path.node.callee.type === TYPE_IMPORT) { const contextIdent = state.contextIdent; - path.replaceWith(t.callExpression(t.memberExpression(contextIdent, t.identifier("import")), path.node.arguments)); + path.replaceWith(t.callExpression(t.memberExpression(contextIdent, t.identifier("import")), + path.node.arguments)); } }, @@ -236,7 +235,8 @@ export default function ({ types: t }) { } if (t.isImportSpecifier(specifier)) { - setterBody.push(t.expressionStatement(t.assignmentExpression("=", specifier.local, t.memberExpression(target, specifier.imported)))); + setterBody.push(t.expressionStatement(t.assignmentExpression("=", specifier.local, + t.memberExpression(target, specifier.imported)))); } } @@ -256,7 +256,8 @@ export default function ({ types: t }) { })); } else if (t.isExportSpecifier(node)) { setterBody.push(t.expressionStatement( - t.assignmentExpression("=", t.memberExpression(exportObjRef, node.exported), t.memberExpression(target, node.local)) + t.assignmentExpression("=", t.memberExpression(exportObjRef, node.exported), + t.memberExpression(target, node.local)) )); } else { // todo @@ -279,7 +280,8 @@ export default function ({ types: t }) { } if (variableIds.length) { - beforeBody.unshift(t.variableDeclaration("var", variableIds.map((id) => t.variableDeclarator(id)))); + beforeBody.unshift(t.variableDeclaration("var", + variableIds.map((id) => t.variableDeclarator(id)))); } path.traverse(reassignmentVisitor, { @@ -294,7 +296,8 @@ export default function ({ types: t }) { path.node.body = [ buildTemplate({ - SYSTEM_REGISTER: t.memberExpression(t.identifier(state.opts.systemGlobal || "System"), t.identifier("register")), + SYSTEM_REGISTER: t.memberExpression( + t.identifier(state.opts.systemGlobal || "System"), t.identifier("register")), BEFORE_BODY: beforeBody, MODULE_NAME: moduleName, SETTERS: setters, diff --git a/packages/babel-plugin-transform-es2015-modules-umd/src/index.js b/packages/babel-plugin-transform-es2015-modules-umd/src/index.js index b13ab6af37..46405fc0f3 100644 --- a/packages/babel-plugin-transform-es2015-modules-umd/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-umd/src/index.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import { basename, extname } from "path"; import template from "babel-template"; diff --git a/packages/babel-plugin-transform-es2015-parameters/src/default.js b/packages/babel-plugin-transform-es2015-parameters/src/default.js index f123ed195e..8213efff57 100644 --- a/packages/babel-plugin-transform-es2015-parameters/src/default.js +++ b/packages/babel-plugin-transform-es2015-parameters/src/default.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import getFunctionArity from "babel-helper-get-function-arity"; import callDelegate from "babel-helper-call-delegate"; import template from "babel-template"; diff --git a/packages/babel-plugin-transform-es2015-parameters/src/rest.js b/packages/babel-plugin-transform-es2015-parameters/src/rest.js index d0ff2846cb..1297b13f15 100644 --- a/packages/babel-plugin-transform-es2015-parameters/src/rest.js +++ b/packages/babel-plugin-transform-es2015-parameters/src/rest.js @@ -1,5 +1,3 @@ -/* eslint indent: 0 */ - import template from "babel-template"; import * as t from "babel-types"; diff --git a/packages/babel-plugin-transform-es2015-spread/README.md b/packages/babel-plugin-transform-es2015-spread/README.md index 9d0e16629d..0ba50ddc03 100644 --- a/packages/babel-plugin-transform-es2015-spread/README.md +++ b/packages/babel-plugin-transform-es2015-spread/README.md @@ -2,6 +2,40 @@ > Compile ES2015 spread to ES5 +## Example + +**In** + +```js +var a = ['a', 'b', 'c']; +var b = [...a, 'foo']; + +var c = { foo: 'bar', baz: 42 }; +var d = {...o, a: 2}; +``` + +**Out** + +```js +var _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + return target; +} + +var a = [ 'a', 'b', 'c' ]; +var b = [].concat(a, [ 'foo' ]); + +var c = { foo: 'bar', baz: 42 }; +var d = _extends({}, o, { a: 2 }); +``` + ## Installation ```sh @@ -46,4 +80,8 @@ require("babel-core").transform("code", { ## Options -* `loose` - All iterables are assumed to be arrays. +### `loose` + +`boolean`, defaults to `false`. + +In loose mode, **all** iterables are assumed to be arrays. diff --git a/packages/babel-plugin-transform-es2015-template-literals/README.md b/packages/babel-plugin-transform-es2015-template-literals/README.md index 854bc74be6..fd0f57bf18 100644 --- a/packages/babel-plugin-transform-es2015-template-literals/README.md +++ b/packages/babel-plugin-transform-es2015-template-literals/README.md @@ -62,10 +62,15 @@ require("babel-core").transform("code", { ## Options ### `loose` + +`boolean`, defaults to `false`. + In loose mode, tagged template literal objects aren't frozen. - ### `spec` + +`boolean`, defaults to `false`. + This option wraps all template literal expressions with `String`. See [babel/babel#1065](https://github.com/babel/babel/issues/1065) for more info. **In** diff --git a/packages/babel-plugin-transform-es2015-typeof-symbol/src/index.js b/packages/babel-plugin-transform-es2015-typeof-symbol/src/index.js index 4cea5acd1a..754b496f0e 100644 --- a/packages/babel-plugin-transform-es2015-typeof-symbol/src/index.js +++ b/packages/babel-plugin-transform-es2015-typeof-symbol/src/index.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - export default function ({ types: t }) { const IGNORE = Symbol(); @@ -18,10 +16,17 @@ export default function ({ types: t }) { if (node[IGNORE]) return; if (path.find((path) => path.node && !!path.node._generated)) return; - if (path.parentPath.isBinaryExpression() && t.EQUALITY_BINARY_OPERATORS.indexOf(parent.operator) >= 0) { - // optimise `typeof foo === "string"` since we can determine that they'll never need to handle symbols + if ( + path.parentPath.isBinaryExpression() && + t.EQUALITY_BINARY_OPERATORS.indexOf(parent.operator) >= 0 + ) { + // optimise `typeof foo === "string"` since we can determine that they'll never + // need to handle symbols const opposite = path.getOpposite(); - if (opposite.isLiteral() && opposite.node.value !== "symbol" && opposite.node.value !== "object") { + if ( + opposite.isLiteral() && opposite.node.value !== "symbol" && + opposite.node.value !== "object" + ) { return; } } diff --git a/packages/babel-plugin-transform-exponentiation-operator/README.md b/packages/babel-plugin-transform-exponentiation-operator/README.md index 82769d80a3..274dfe8416 100644 --- a/packages/babel-plugin-transform-exponentiation-operator/README.md +++ b/packages/babel-plugin-transform-exponentiation-operator/README.md @@ -24,7 +24,6 @@ let b = 3; b **= 3; // same as: b = b * b * b; ``` -[Try in REPL](http://babeljs.io/repl/#?evaluate=true&presets=es2015%2Cstage-0&code=%2F%2F%20x%20**%20y%0A%0Alet%20squared%20%3D%202%20**%202%3B%0A%2F%2F%20same%20as%3A%202%20*%202%0A%0Alet%20cubed%20%3D%202%20**%203%3B%0A%2F%2F%20same%20as%3A%202%20*%202%20*%202%0A%0A%0A%2F%2F%20x%20**%3D%20y%0A%0Alet%20a%20%3D%202%3B%0Aa%20**%3D%202%3B%0A%2F%2F%20same%20as%3A%20a%20%3D%20a%20*%20a%3B%0A%0Alet%20b%20%3D%203%3B%0Ab%20**%3D%203%3B%0A%2F%2F%20same%20as%3A%20b%20%3D%20b%20*%20b%20*%20b%3B) ## Installation diff --git a/packages/babel-plugin-transform-export-extensions/README.md b/packages/babel-plugin-transform-export-extensions/README.md index 26f7d51278..6014dc4c53 100644 --- a/packages/babel-plugin-transform-export-extensions/README.md +++ b/packages/babel-plugin-transform-export-extensions/README.md @@ -8,7 +8,6 @@ export * as ns from 'mod'; export v from 'mod'; ``` -[Try in REPL](http://babeljs.io/repl/#?evaluate=true&presets=es2015%2Cstage-0&code=export%20*%20as%20ns%20from%20'mod'%3B%0Aexport%20v%20from%20'mod'%3B) ## Installation diff --git a/packages/babel-plugin-transform-flow-strip-types/README.md b/packages/babel-plugin-transform-flow-strip-types/README.md index afde54949b..6e279dbfae 100644 --- a/packages/babel-plugin-transform-flow-strip-types/README.md +++ b/packages/babel-plugin-transform-flow-strip-types/README.md @@ -16,9 +16,6 @@ function foo(one: any, two: number, three?): string {} function foo(one, two, three) {} ``` -[Try in REPL](http://babeljs.io/repl/#?babili=false&evaluate=true&lineWrap=false&presets=react&code=function%20foo(one%3A%20any%2C%20two%3A%20number%2C%20three%3F)%3A%20string%20%7B%7D&experimental=false&loose=false&spec=false&playground=false&stage=0 -) - ## Installation ```sh diff --git a/packages/babel-plugin-transform-function-bind/README.md b/packages/babel-plugin-transform-function-bind/README.md index 0de2810294..76505a17f4 100644 --- a/packages/babel-plugin-transform-function-bind/README.md +++ b/packages/babel-plugin-transform-function-bind/README.md @@ -18,7 +18,6 @@ func.call(obj, val) func.call(obj, val) ``` -[Try in REPL](http://babeljs.io/repl/#?evaluate=true&presets=es2015%2Cstage-0&code=obj%3A%3Afunc%3B%0A%0Aobj%3A%3Afunc(val)%3B%0A%0A%3A%3Aobj.func(val)%3B) ## Example @@ -43,7 +42,6 @@ function add(val) { return this + val; } console.log(bigBox::getWeight()::add(5)); // prints '15' ``` -[Try in REPL](http://babeljs.io/repl/#?evaluate=true&presets=es2015%2Cstage-0&code=const%20box%20%3D%20%7B%0A%20%20weight%3A%202%2C%0A%20%20getWeight()%20%7B%20return%20this.weight%3B%20%7D%2C%0A%7D%3B%0A%0Aconst%20%7B%20getWeight%20%7D%20%3D%20box%3B%0A%0Aconsole.log(box.getWeight())%3B%20%2F%2F%20prints%20'2'%0A%0Aconst%20bigBox%20%3D%20%7B%20weight%3A%2010%20%7D%3B%0Aconsole.log(bigBox%3A%3AgetWeight())%3B%20%2F%2F%20prints%20'10'%0A%2F%2F%20bigBox%3A%3AgetWeight()%20is%20equivalent%20to%20getWeight.call(bigBox)%0A%0A%2F%2F%20Can%20be%20chained%3A%0Afunction%20add(val)%20%7B%20return%20this%20%2B%20val%3B%20%7D%0A%0Aconsole.log(bigBox%3A%3AgetWeight()%3A%3Aadd(5))%3B%20%2F%2F%20prints%20'15') ### Using with `document.querySelectorAll` @@ -59,7 +57,6 @@ let sslUrls = document.querySelectorAll('a') console.log(sslUrls); ``` -[Try in REPL](http://babeljs.io/repl/#?evaluate=true&presets=es2015%2Cstage-0&code=%0Aconst%20%7B%20map%2C%20filter%20%7D%20%3D%20Array.prototype%3B%0A%0Alet%20sslUrls%20%3D%20document.querySelectorAll('a')%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3A%3Amap(node%20%3D%3E%20node.href)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3A%3Afilter(href%20%3D%3E%20href.substring(0%2C%205)%20%3D%3D%3D%20'https')%3B%0A%0Aconsole.log(sslUrls)%3B%0A) `document.querySelectorAll` returns a `NodeList` element which is not a plain array, so you normally can't use the `map` function on it, and have to use it this way: `Array.prototype.map.call(document.querySelectorAll(...), node => { ... })`. The above code using the `::` will work because it is equivalent to: diff --git a/packages/babel-plugin-transform-object-rest-spread/README.md b/packages/babel-plugin-transform-object-rest-spread/README.md index 7fd2afe530..b8f365d7af 100644 --- a/packages/babel-plugin-transform-object-rest-spread/README.md +++ b/packages/babel-plugin-transform-object-rest-spread/README.md @@ -16,7 +16,6 @@ let n = { x, y, ...z }; console.log(n); // { x: 1, y: 2, a: 3, b: 4 } ``` -[Try in REPL](https://babeljs.io/repl/#?evaluate=true&presets=es2015%2Cstage-0&code=%2F%2F%20Rest%20properties%0Alet%20%7B%20x%2C%20y%2C%20...z%20%7D%20%3D%20%7B%20x%3A%201%2C%20y%3A%202%2C%20a%3A%203%2C%20b%3A%204%20%7D%3B%0Aconsole.log(x)%3B%20%2F%2F%201%0Aconsole.log(y)%3B%20%2F%2F%202%0Aconsole.log(z)%3B%20%2F%2F%20%7B%20a%3A%203%2C%20b%3A%204%20%7D%0A%0A%2F%2F%20Spread%20properties%0Alet%20n%20%3D%20%7B%20x%2C%20y%2C%20...z%20%7D%3B%0Aconsole.log(n)%3B%20%2F%2F%20%7B%20x%3A%201%2C%20y%3A%202%2C%20a%3A%203%2C%20b%3A%204%20%7D) ## Installation diff --git a/packages/babel-plugin-transform-object-rest-spread/src/index.js b/packages/babel-plugin-transform-object-rest-spread/src/index.js index 8de5e5eea2..91f7a0c40a 100644 --- a/packages/babel-plugin-transform-object-rest-spread/src/index.js +++ b/packages/babel-plugin-transform-object-rest-spread/src/index.js @@ -94,11 +94,14 @@ export default function ({ types: t }) { // to avoid calling foo() twice, as a first step convert it to: // const _foo = foo(), // { a, ...b } = _foo; - const initRef = path.scope.generateUidIdentifierBasedOnNode(this.originalPath.node.init, "ref"); + const initRef = path.scope.generateUidIdentifierBasedOnNode( + this.originalPath.node.init, "ref"); // insert _foo = foo() - this.originalPath.insertBefore(t.variableDeclarator(initRef, this.originalPath.node.init)); + this.originalPath.insertBefore(t.variableDeclarator(initRef, + this.originalPath.node.init)); // replace foo() with _foo - this.originalPath.replaceWith(t.variableDeclarator(this.originalPath.node.id, initRef)); + this.originalPath.replaceWith(t.variableDeclarator( + this.originalPath.node.id, initRef)); return; } @@ -247,7 +250,8 @@ export default function ({ types: t }) { const useBuiltIns = file.opts.useBuiltIns || false; if (typeof useBuiltIns !== "boolean") { - throw new Error("transform-object-rest-spread currently only accepts a boolean option for useBuiltIns (defaults to false)"); + throw new Error("transform-object-rest-spread currently only accepts a boolean " + + "option for useBuiltIns (defaults to false)"); } const args = []; diff --git a/packages/babel-plugin-transform-proto-to-assign/src/index.js b/packages/babel-plugin-transform-proto-to-assign/src/index.js index 41b0ff442d..c139e20de4 100644 --- a/packages/babel-plugin-transform-proto-to-assign/src/index.js +++ b/packages/babel-plugin-transform-proto-to-assign/src/index.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import pull from "lodash/pull"; export default function ({ types: t }) { @@ -9,7 +7,8 @@ export default function ({ types: t }) { function isProtoAssignmentExpression(node) { const left = node.left; - return t.isMemberExpression(left) && t.isLiteral(t.toComputedKey(left, left.property), { value: "__proto__" }); + return t.isMemberExpression(left) && + t.isLiteral(t.toComputedKey(left, left.property), { value: "__proto__" }); } function buildDefaultsCallExpression(expr, ref, file) { diff --git a/packages/babel-plugin-transform-react-display-name/package.json b/packages/babel-plugin-transform-react-display-name/package.json index 1bb155829a..09a05f65e0 100644 --- a/packages/babel-plugin-transform-react-display-name/package.json +++ b/packages/babel-plugin-transform-react-display-name/package.json @@ -2,7 +2,7 @@ "name": "babel-plugin-transform-react-display-name", "version": "6.22.0", "description": "Add displayName to React.createClass calls", - "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-display-name", + "repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-display-name", "license": "MIT", "main": "lib/index.js", "keywords": [ diff --git a/packages/babel-plugin-transform-react-jsx/README.md b/packages/babel-plugin-transform-react-jsx/README.md index 4a7c3ae0fb..44a20066dd 100644 --- a/packages/babel-plugin-transform-react-jsx/README.md +++ b/packages/babel-plugin-transform-react-jsx/README.md @@ -95,6 +95,16 @@ require("babel-core").transform("code", { ## Options -* `pragma` - Replace the function used when compiling JSX expressions (Defaults to `React.createElement`). - - Note that the `@jsx React.DOM` pragma has been deprecated as of React v0.12 -* `useBuiltIns` - When spreading props, use Object.assign instead of Babel's extend helper (Disabled by default). +### `pragma` + +`string`, defaults to `React.createElement`. + +Replace the function used when compiling JSX expressions. + +Note that the `@jsx React.DOM` pragma has been deprecated as of React v0.12 + +### `useBuiltIns` + +`boolean`, defaults to `false`. + +When spreading props, use `Object.assign` directly instead of Babel's extend helper. diff --git a/packages/babel-plugin-transform-react-jsx/src/index.js b/packages/babel-plugin-transform-react-jsx/src/index.js index 65758283c0..bb57b52d7f 100644 --- a/packages/babel-plugin-transform-react-jsx/src/index.js +++ b/packages/babel-plugin-transform-react-jsx/src/index.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import jsx from "babel-plugin-syntax-jsx"; import helper from "babel-helper-builder-react-jsx"; @@ -31,7 +29,8 @@ export default function ({ types: t }) { if (matches) { id = matches[1]; if (id === "React.DOM") { - throw file.buildCodeFrameError(comment, "The @jsx React.DOM pragma has been deprecated as of React 0.12"); + throw file.buildCodeFrameError(comment, + "The @jsx React.DOM pragma has been deprecated as of React 0.12"); } else { break; } diff --git a/packages/babel-plugin-transform-regenerator/README.md b/packages/babel-plugin-transform-regenerator/README.md index 18adfa4bca..e82f106380 100644 --- a/packages/babel-plugin-transform-regenerator/README.md +++ b/packages/babel-plugin-transform-regenerator/README.md @@ -34,8 +34,6 @@ function a() { } ``` -[Try in REPL](http://babeljs.io/repl/#?evaluate=true&lineWrap=true&presets=es2015%2Ces2015-loose%2Creact&experimental=false&loose=false&spec=false&code=function%20*range(max%2C%20step)%20%7B%0A%20%20var%20count%20%3D%200%3B%0A%20%20step%20%3D%20step%20%7C%7C%201%3B%0A%20%0A%20%20for%20(var%20i%20%3D%200%3B%20i%20%3C%20max%3B%20i%20%2B%3D%20step)%20%7B%0A%20%20%20%20count%2B%2B%3B%0A%20%20%20%20yield%20i%3B%0A%20%20%7D%0A%20%0A%20%20return%20count%3B%0A%7D%0A%20%0Avar%20gen%20%3D%20range(20%2C%203)%2C%20info%3B%0A%20%0Awhile%20(!(info%20%3D%20gen.next()).done)%20%7B%0A%20%20console.log(info.value)%3B%0A%7D%0A%20%0Aconsole.log(%22steps%20taken%3A%20%22%20%2B%20info.value)%3B&playground=true) - ## Installation ```sh @@ -46,20 +44,29 @@ npm install --save-dev babel-plugin-transform-regenerator ### Via `.babelrc` (Recommended) -**.babelrc** +Without options: -```js -// without options +```json { "plugins": ["transform-regenerator"] } -// with options +``` + +With options: + +|name|default value| +|---|---| +|asyncGenerators|true| +|generators|true| +|async|true| + +````json { "plugins": [ ["transform-regenerator", { - asyncGenerators: false, // true by default - generators: false, // true by default - async: false // true by default + asyncGenerators: false, + generators: false, + async: false }] ] } diff --git a/packages/babel-plugin-transform-runtime/src/definitions.js b/packages/babel-plugin-transform-runtime/src/definitions.js index 64a185b695..f6a6e25f44 100644 --- a/packages/babel-plugin-transform-runtime/src/definitions.js +++ b/packages/babel-plugin-transform-runtime/src/definitions.js @@ -93,14 +93,12 @@ module.exports = { }, Symbol: { - asyncIterator: "symbol/async-iterator", for: "symbol/for", hasInstance: "symbol/has-instance", isConcatSpreadable: "symbol/is-concat-spreadable", iterator: "symbol/iterator", keyFor: "symbol/key-for", match: "symbol/match", - observable: "symbol/observable", replace: "symbol/replace", search: "symbol/search", species: "symbol/species", diff --git a/packages/babel-polyfill/src/index.js b/packages/babel-polyfill/src/index.js index cff406dbbf..943e349060 100644 --- a/packages/babel-polyfill/src/index.js +++ b/packages/babel-polyfill/src/index.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - if (global._babelPolyfill) { throw new Error("only one instance of babel-polyfill is allowed"); } diff --git a/packages/babel-preset-es2015/README.md b/packages/babel-preset-es2015/README.md index dacd924c73..77340ab708 100644 --- a/packages/babel-preset-es2015/README.md +++ b/packages/babel-preset-es2015/README.md @@ -36,30 +36,22 @@ require("babel-core").transform("code", { ## Options -* `loose` - Enable "loose" transformations for any plugins in this preset that allow them (Disabled by default). -* `modules` - Enable transformation of ES6 module syntax to another module type (Enabled by default to `"commonjs"`). - * Can be `false` to not transform modules, or one of `["amd", "umd", "systemjs", "commonjs"]` -* `spec` - Enable "spec" transformations for any plugins in this preset that allow them (Disabled by default) +### `loose` -```js -{ - presets: [ - ["es2015", { "loose": true }] - ] -} -{ - presets: [ - ["es2015", { "modules": false }] - ] -} -{ - presets: [ - ["es2015", { "loose": true, "modules": false }] - ] -} -{ - presets: [ - ["es2015", { "spec": true }] - ] -} -``` +`boolean`, defaults to `false`. + +Enable "loose" transformations for any plugins in this preset that allow them. + +### `modules` + +`"amd" | "umd" | "systemjs" | "commonjs" | false`, defaults to `"commonjs"`. + +Enable transformation of ES6 module syntax to another module type. + +Setting this to `false` will not transform modules. + +### `spec` + +`boolean`, defaults to `false`. + +Enable "spec" transformations for any plugins in this preset that allow them. diff --git a/packages/babel-preset-latest/README.md b/packages/babel-preset-latest/README.md index f46761d1aa..056d95645d 100644 --- a/packages/babel-preset-latest/README.md +++ b/packages/babel-preset-latest/README.md @@ -36,15 +36,17 @@ require("babel-core").transform("code", { ### Options -- `es2015`: Optionally not run any plugins from this preset (defaults to true) -- `es2016`: Optionally not run any plugins from this preset (defaults to true) -- `es2017`: Optionally not run any plugins from this preset (defaults to true) +### `es2015` + +`boolean`, defaults to `true`. + +Toggles including plugins from the [es2015 preset](https://babeljs.io/docs/plugins/preset-es2015/). ```js { "presets": [ ["latest", { - "es2015": false // defaults to true + "es2015": false }] ] } @@ -57,9 +59,23 @@ You can also pass options down to the `es2015` preset. "presets": [ ["latest", { "es2015": { - "modules": false + "modules": false } }] ] } ``` + +**Note:** This also works for the other preset-year options below. + +### `es2016` + +`boolean`, defaults to `true`. + +Toggles including plugins from the [es2016 preset](https://babeljs.io/docs/plugins/preset-es2016/). + +### `es2017` + +`boolean`, defaults to `true`. + +Toggles including plugins from the [es2017 preset](https://babeljs.io/docs/plugins/preset-es2017/). diff --git a/packages/babel-preset-stage-1/README.md b/packages/babel-preset-stage-1/README.md index d0af0ffd58..19692c62a5 100644 --- a/packages/babel-preset-stage-1/README.md +++ b/packages/babel-preset-stage-1/README.md @@ -2,6 +2,16 @@ > Babel preset for stage 1 plugins. +The gist of Stage 1 is: + +> **Stage 1**: proposal +> +> **What is it?** A formal proposal for the feature. +> +> **What’s required?** A so-called champion must be identified who is responsible for the proposal. Either the champion or a co-champion must be a member of TC39 (source). The problem solved by the proposal must be described in prose. The solution must be described via examples, an API and a discussion of semantics and algorithms. Lastly, potential obstacles for the proposal must be identified, such as interactions with other features and implementation challenges. Implementation-wise, polyfills and demos are needed. +> +> **What’s next?** By accepting a proposal for stage 1, TC39 declares its willingness to examine, discuss and contribute to the proposal. Going forward, major changes to the proposal are expected + ## Install ```sh @@ -33,3 +43,7 @@ require("babel-core").transform("code", { presets: ["stage-1"] }); ``` + +## References + +- Chapter "[The TC39 process for ECMAScript features](http://exploringjs.com/es2016-es2017/ch_tc39-process.html)" in "Exploring ES2016 and ES2017" by Axel Rauschmayer diff --git a/packages/babel-preset-stage-2/README.md b/packages/babel-preset-stage-2/README.md index 1c6a5f900e..0007aa1a67 100644 --- a/packages/babel-preset-stage-2/README.md +++ b/packages/babel-preset-stage-2/README.md @@ -2,6 +2,18 @@ > Babel preset for stage 2 plugins. +The gist of Stage 2 is: + +> **Stage 2:** draft +> +> **What is it?** A first version of what will be in the specification. At this point, an eventual inclusion of the feature in the standard is likely. +> +> **What’s required?** The proposal must now additionally have a formal description of the syntax and semantics of the feature (using the formal language of the ECMAScript specification). The description should be as complete as possible, but can contain todos and placeholders. Two experimental implementations of the feature are needed, but one of them can be in a transpiler such as Babel. +> +> **What’s next?** Only incremental changes are expected from now on. + + + ## Install ```sh @@ -33,3 +45,6 @@ require("babel-core").transform("code", { presets: ["stage-2"] }); ``` +## References + +- Chapter "[The TC39 process for ECMAScript features](http://exploringjs.com/es2016-es2017/ch_tc39-process.html)" in "Exploring ES2016 and ES2017" by Axel Rauschmayer diff --git a/packages/babel-preset-stage-3/README.md b/packages/babel-preset-stage-3/README.md index fd29e4670e..656cd0d72c 100644 --- a/packages/babel-preset-stage-3/README.md +++ b/packages/babel-preset-stage-3/README.md @@ -2,6 +2,18 @@ > Babel preset for stage 3 plugins. +The gist of Stage 3 is: + +> **Stage 3**: candidate +> +> **What is it?** The proposal is mostly finished and now needs feedback from implementations and users to progress further. + +> **What’s required?** The spec text must be complete. Designated reviewers (appointed by TC39, not by the champion) and the ECMAScript spec editor must sign off on the spec text. There must be at least two spec-compliant implementations (which don’t have to be enabled by default). +> +> **What’s next?** Henceforth, changes should only be made in response to critical issues raised by the implementations and their use. + + + ## Install ```sh @@ -33,3 +45,7 @@ require("babel-core").transform("code", { presets: ["stage-3"] }); ``` + +## References + +- Chapter "[The TC39 process for ECMAScript features](http://exploringjs.com/es2016-es2017/ch_tc39-process.html)" in "Exploring ES2016 and ES2017" by Axel Rauschmayer diff --git a/packages/babel-register/package.json b/packages/babel-register/package.json index 600bd1f920..0ace0ca3b8 100644 --- a/packages/babel-register/package.json +++ b/packages/babel-register/package.json @@ -14,5 +14,8 @@ "lodash": "^4.2.0", "mkdirp": "^0.5.1", "source-map-support": "^0.4.2" + }, + "devDependencies": { + "decache": "^4.1.0" } } diff --git a/packages/babel-register/src/cache.js b/packages/babel-register/src/cache.js index 4b08e63ac7..204ac04019 100644 --- a/packages/babel-register/src/cache.js +++ b/packages/babel-register/src/cache.js @@ -3,18 +3,20 @@ import fs from "fs"; import { sync as mkdirpSync } from "mkdirp"; import homeOrTmp from "home-or-tmp"; -const FILENAME = process.env.BABEL_CACHE_PATH || path.join(homeOrTmp, ".babel.json"); -let data = {}; +const FILENAME: string = process.env.BABEL_CACHE_PATH || path.join(homeOrTmp, ".babel.json"); +let data: Object = {}; /** * Write stringified cache to disk. */ export function save() { - let serialised = {}; + let serialised: string = "{}"; + try { serialised = JSON.stringify(data, null, " "); } catch (err) { + if (err.message === "Invalid string length") { err.message = "Cache too large so it's been cleared."; console.error(err.stack); @@ -22,6 +24,7 @@ export function save() { throw err; } } + mkdirpSync(path.dirname(FILENAME)); fs.writeFileSync(FILENAME, serialised); } @@ -49,6 +52,6 @@ export function load() { * Retrieve data from cache. */ -export function get() { +export function get(): Object { return data; } diff --git a/packages/babel-register/test/index.js b/packages/babel-register/test/index.js new file mode 100644 index 0000000000..e736f3e484 --- /dev/null +++ b/packages/babel-register/test/index.js @@ -0,0 +1,84 @@ +import { expect } from "chai"; +import fs from "fs"; +import path from "path"; +import decache from "decache"; + +const testCacheFilename = path.join(__dirname, ".babel"); +const oldBabelDisableCacheValue = process.env.BABEL_DISABLE_CACHE; + +process.env.BABEL_CACHE_PATH = testCacheFilename; +delete process.env.BABEL_DISABLE_CACHE; + +function writeCache(data) { + if (typeof data === "object") { + data = JSON.stringify(data); + } + + fs.writeFileSync(testCacheFilename, data); +} + +function cleanCache() { + + try { + fs.unlinkSync(testCacheFilename); + } catch (e) { + // It is convenient to always try to clear + } +} + +function resetCache() { + process.env.BABEL_CACHE_PATH = null; + process.env.BABEL_DISABLE_CACHE = oldBabelDisableCacheValue; +} + +describe("babel register", () => { + + describe("cache", () => { + let load, get, save; + + beforeEach(() => { + // Since lib/cache is a singleton we need to fully reload it + decache("../lib/cache"); + const cache = require("../lib/cache"); + + load = cache.load; + get = cache.get; + save = cache.save; + }); + + afterEach(cleanCache); + after(resetCache); + + it("should load and get cached data", () => { + writeCache({ foo: "bar" }); + + load(); + + expect(get()).to.be.an("object"); + expect(get()).to.deep.equal({ foo: "bar" }); + }); + + it("should load and get an object with no cached data", () => { + load(); + + expect(get()).to.be.an("object"); + expect(get()).to.deep.equal({}); + }); + + it("should load and get an object with invalid cached data", () => { + writeCache("foobar"); + + load(); + + expect(get()).to.be.an("object"); + expect(get()).to.deep.equal({}); + }); + + it("should create the cache on save", () => { + save(); + + expect(fs.existsSync(testCacheFilename)).to.be.true; + expect(get()).to.deep.equal({}); + }); + }); +}); diff --git a/packages/babel-template/src/index.js b/packages/babel-template/src/index.js index 164652c143..0384dfec16 100644 --- a/packages/babel-template/src/index.js +++ b/packages/babel-template/src/index.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import cloneDeep from "lodash/cloneDeep"; import assign from "lodash/assign"; import has from "lodash/has"; @@ -15,7 +13,8 @@ export default function (code: string, opts?: Object): Function { // original stack to append if it errors when parsing let stack; try { - // error stack gets populated in IE only on throw (https://msdn.microsoft.com/en-us/library/hh699850(v=vs.94).aspx) + // error stack gets populated in IE only on throw + // (https://msdn.microsoft.com/en-us/library/hh699850(v=vs.94).aspx) throw new Error(); } catch (error) { if (error.stack) { diff --git a/packages/babel-traverse/src/index.js b/packages/babel-traverse/src/index.js index 464a5a150f..1c5c96b58c 100644 --- a/packages/babel-traverse/src/index.js +++ b/packages/babel-traverse/src/index.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import TraversalContext from "./context"; import * as visitors from "./visitors"; import * as messages from "babel-messages"; @@ -45,7 +43,14 @@ traverse.cheap = function (node, enter) { return t.traverseFast(node, enter); }; -traverse.node = function (node: Object, opts: Object, scope: Object, state: Object, parentPath: Object, skipKeys?) { +traverse.node = function ( + node: Object, + opts: Object, + scope: Object, + state: Object, + parentPath: Object, + skipKeys? +) { const keys: Array = t.VISITOR_KEYS[node.type]; if (!keys) return; @@ -74,7 +79,12 @@ function hasBlacklistedType(path, state) { } } -traverse.hasType = function (tree: Object, scope: Object, type: Object, blacklistTypes: Array): boolean { +traverse.hasType = function ( + tree: Object, + scope: Object, + type: Object, + blacklistTypes: Array +): boolean { // the node we're searching in is blacklisted if (includes(blacklistTypes, tree.type)) return false; diff --git a/packages/babel-traverse/src/path/evaluation.js b/packages/babel-traverse/src/path/evaluation.js index 82c15a743e..971a66a409 100644 --- a/packages/babel-traverse/src/path/evaluation.js +++ b/packages/babel-traverse/src/path/evaluation.js @@ -1,12 +1,7 @@ -/* eslint indent: 0 */ -/* eslint max-len: 0 */ - import type NodePath from "./index"; // This file contains Babels metainterpreter that can evaluate static code. -/* eslint eqeqeq: 0 */ - const VALID_CALLEES = ["String", "Number", "Math"]; const INVALID_METHODS = ["random"]; @@ -181,11 +176,11 @@ export function evaluate(): { confident: boolean; value: any } { return binding.value; } else { if (node.name === "undefined") { - return undefined; + return binding ? deopt(binding.path) : undefined; } else if (node.name === "Infinity") { - return Infinity; + return binding ? deopt(binding.path) : Infinity; } else if (node.name === "NaN") { - return NaN; + return binding ? deopt(binding.path) : NaN; } const resolved = path.resolve(); @@ -316,7 +311,7 @@ export function evaluate(): { confident: boolean; value: any } { case ">": return left > right; case "<=": return left <= right; case ">=": return left >= right; - case "==": return left == right; + case "==": return left == right; // eslint-disable-line eqeqeq case "!=": return left != right; case "===": return left === right; case "!==": return left !== right; @@ -335,7 +330,10 @@ export function evaluate(): { confident: boolean; value: any } { let func; // Number(1); - if (callee.isIdentifier() && !path.scope.getBinding(callee.node.name, true) && VALID_CALLEES.indexOf(callee.node.name) >= 0) { + if ( + callee.isIdentifier() && !path.scope.getBinding(callee.node.name, true) && + VALID_CALLEES.indexOf(callee.node.name) >= 0 + ) { func = global[node.callee.name]; } @@ -344,7 +342,11 @@ export function evaluate(): { confident: boolean; value: any } { const property = callee.get("property"); // Math.min(1, 2) - if (object.isIdentifier() && property.isIdentifier() && VALID_CALLEES.indexOf(object.node.name) >= 0 && INVALID_METHODS.indexOf(property.node.name) < 0) { + if ( + object.isIdentifier() && property.isIdentifier() && + VALID_CALLEES.indexOf(object.node.name) >= 0 && + INVALID_METHODS.indexOf(property.node.name) < 0 + ) { context = global[object.node.name]; func = context[property.node.name]; } diff --git a/packages/babel-traverse/src/path/family.js b/packages/babel-traverse/src/path/family.js index d17ae8aed7..3af5c1e022 100644 --- a/packages/babel-traverse/src/path/family.js +++ b/packages/babel-traverse/src/path/family.js @@ -57,7 +57,7 @@ export function getCompletionRecords(): Array { return paths; } -export function getSibling(key) { +export function getSibling(key): NodePath { return NodePath.get({ parentPath: this.parentPath, parent: this.parent, @@ -67,6 +67,36 @@ export function getSibling(key) { }); } +export function getPrevSibling(): NodePath { + return this.getSibling(this.key - 1); +} + +export function getNextSibling(): NodePath { + return this.getSibling(this.key + 1); +} + +export function getAllNextSiblings(): Array { + let _key = this.key; + let sibling:NodePath = this.getSibling(++_key); + const siblings:Array = []; + while (sibling.node) { + siblings.push(sibling); + sibling = this.getSibling(++_key); + } + return siblings; +} + +export function getAllPrevSiblings(): Array { + let _key = this.key; + let sibling:NodePath = this.getSibling(--_key); + const siblings:Array = []; + while (sibling.node) { + siblings.push(sibling); + sibling = this.getSibling(--_key); + } + return siblings; +} + export function get(key: string, context?: boolean | TraversalContext): NodePath { if (context === true) context = this.context; const parts = key.split("."); diff --git a/packages/babel-traverse/src/path/index.js b/packages/babel-traverse/src/path/index.js index 853a735bb8..c66d0e8482 100644 --- a/packages/babel-traverse/src/path/index.js +++ b/packages/babel-traverse/src/path/index.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import type Hub from "../hub"; import type TraversalContext from "../context"; import * as virtualTypes from "./lib/virtual-types"; diff --git a/packages/babel-traverse/src/path/lib/hoister.js b/packages/babel-traverse/src/path/lib/hoister.js index 243e9c18ac..93b9323bd3 100644 --- a/packages/babel-traverse/src/path/lib/hoister.js +++ b/packages/babel-traverse/src/path/lib/hoister.js @@ -153,7 +153,8 @@ export default class PathHoister { const attachTo = this.getAttachmentPath(); if (!attachTo) return; - // don't bother hoisting to the same function as this will cause multiple branches to be evaluated more than once leading to a bad optimisation + // don't bother hoisting to the same function as this will cause multiple branches to be + // evaluated more than once leading to a bad optimisation if (attachTo.getFunctionParent() === this.path.getFunctionParent()) return; // generate declaration and insert it to our point diff --git a/packages/babel-traverse/src/path/lib/removal-hooks.js b/packages/babel-traverse/src/path/lib/removal-hooks.js index 0678d1da28..73341ae651 100644 --- a/packages/babel-traverse/src/path/lib/removal-hooks.js +++ b/packages/babel-traverse/src/path/lib/removal-hooks.js @@ -6,28 +6,29 @@ export const hooks = [ function (self, parent) { - let removeParent = false; + const removeParent = + // while (NODE); + // removing the test of a while/switch, we can either just remove it entirely *or* turn the + // `test` into `true` unlikely that the latter will ever be what's wanted so we just remove + // the loop to avoid infinite recursion + (self.key === "test" && (parent.isWhile() || parent.isSwitchCase())) || - // while (NODE); - // removing the test of a while/switch, we can either just remove it entirely *or* turn the `test` into `true` - // unlikely that the latter will ever be what's wanted so we just remove the loop to avoid infinite recursion - removeParent = removeParent || (self.key === "test" && (parent.isWhile() || parent.isSwitchCase())); + // export NODE; + // just remove a declaration for an export as this is no longer valid + (self.key === "declaration" && parent.isExportDeclaration()) || - // export NODE; - // just remove a declaration for an export as this is no longer valid - removeParent = removeParent || (self.key === "declaration" && parent.isExportDeclaration()); + // label: NODE + // stray labeled statement with no body + (self.key === "body" && parent.isLabeledStatement()) || - // label: NODE - // stray labeled statement with no body - removeParent = removeParent || (self.key === "body" && parent.isLabeledStatement()); + // let NODE; + // remove an entire declaration if there are no declarators left + (self.listKey === "declarations" && parent.isVariableDeclaration() && + parent.node.declarations.length === 1) || - // let NODE; - // remove an entire declaration if there are no declarators left - removeParent = removeParent || (self.listKey === "declarations" && parent.isVariableDeclaration() && parent.node.declarations.length === 1); - - // NODE; - // remove the entire expression statement if there's no expression - removeParent = removeParent || (self.key === "expression" && parent.isExpressionStatement()); + // NODE; + // remove the entire expression statement if there's no expression + (self.key === "expression" && parent.isExpressionStatement()); if (removeParent) { parent.remove(); diff --git a/packages/babel-traverse/src/path/modification.js b/packages/babel-traverse/src/path/modification.js index 704014c16e..9df7ecc873 100644 --- a/packages/babel-traverse/src/path/modification.js +++ b/packages/babel-traverse/src/path/modification.js @@ -1,4 +1,3 @@ -/* eslint max-len: 0 */ // This file contains methods that modify the path/node in some ways. import { path as pathCache } from "../cache"; @@ -17,7 +16,10 @@ export function insertBefore(nodes) { if (this.parentPath.isExpressionStatement() || this.parentPath.isLabeledStatement()) { return this.parentPath.insertBefore(nodes); - } else if (this.isNodeType("Expression") || (this.parentPath.isForStatement() && this.key === "init")) { + } else if ( + this.isNodeType("Expression") || + (this.parentPath.isForStatement() && this.key === "init") + ) { if (this.node) nodes.push(this.node); this.replaceExpressionWithStatements(nodes); } else { @@ -28,7 +30,8 @@ export function insertBefore(nodes) { if (this.node) nodes.push(this.node); this._replaceWith(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?"); + 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?"); } } @@ -88,7 +91,8 @@ export function _containerInsertAfter(nodes) { export function _maybePopFromStatements(nodes) { const last = nodes[nodes.length - 1]; - const isIdentifier = t.isIdentifier(last) || (t.isExpressionStatement(last) && t.isIdentifier(last.expression)); + const isIdentifier = t.isIdentifier(last) || + (t.isExpressionStatement(last) && t.isIdentifier(last.expression)); if (isIdentifier && !this.isCompletionRecord()) { nodes.pop(); @@ -107,7 +111,10 @@ export function insertAfter(nodes) { if (this.parentPath.isExpressionStatement() || this.parentPath.isLabeledStatement()) { return this.parentPath.insertAfter(nodes); - } else if (this.isNodeType("Expression") || (this.parentPath.isForStatement() && this.key === "init")) { + } else if ( + this.isNodeType("Expression") || + (this.parentPath.isForStatement() && this.key === "init") + ) { if (this.node) { const temp = this.scope.generateDeclaredUidIdentifier(); nodes.unshift(t.expressionStatement(t.assignmentExpression("=", temp, this.node))); @@ -122,7 +129,8 @@ export function insertAfter(nodes) { if (this.node) nodes.unshift(this.node); this._replaceWith(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?"); + 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?"); } } diff --git a/packages/babel-traverse/src/path/replacement.js b/packages/babel-traverse/src/path/replacement.js index 08df6ce16c..47e706d0d2 100644 --- a/packages/babel-traverse/src/path/replacement.js +++ b/packages/babel-traverse/src/path/replacement.js @@ -1,4 +1,3 @@ -/* eslint max-len: 0 */ // This file contains methods responsible for replacing a node with another. import codeFrame from "babel-code-frame"; @@ -114,22 +113,30 @@ export function replaceWith(replacement) { } if (Array.isArray(replacement)) { - throw new Error("Don't use `path.replaceWith()` with an array of nodes, use `path.replaceWithMultiple()`"); + throw new Error( + "Don't use `path.replaceWith()` with an array of nodes, use `path.replaceWithMultiple()`"); } if (typeof replacement === "string") { - throw new Error("Don't use `path.replaceWith()` with a source string, use `path.replaceWithSourceString()`"); + throw new Error( + "Don't use `path.replaceWith()` with a source string, use `path.replaceWithSourceString()`"); } if (this.isNodeType("Statement") && t.isExpression(replacement)) { - if (!this.canHaveVariableDeclarationOrExpression() && !this.canSwapBetweenExpressionAndStatement(replacement)) { + if ( + !this.canHaveVariableDeclarationOrExpression() && + !this.canSwapBetweenExpressionAndStatement(replacement) + ) { // replacing a statement with an expression so wrap it in an expression statement replacement = t.expressionStatement(replacement); } } if (this.isNodeType("Expression") && t.isStatement(replacement)) { - if (!this.canHaveVariableDeclarationOrExpression() && !this.canSwapBetweenExpressionAndStatement(replacement)) { + if ( + !this.canHaveVariableDeclarationOrExpression() && + !this.canSwapBetweenExpressionAndStatement(replacement) + ) { // replacing an expression with a statement so let's explode it return this.replaceExpressionWithStatements([replacement]); } @@ -212,10 +219,16 @@ export function replaceExpressionWithStatements(nodes: Array) { const loop = path.findParent((path) => path.isLoop()); if (loop) { - const callee = this.get("callee"); + let uid = loop.getData("expressionReplacementReturnUid"); - const uid = callee.scope.generateDeclaredUidIdentifier("ret"); - callee.get("body").pushContainer("body", t.returnStatement(uid)); + if (!uid) { + const callee = this.get("callee"); + uid = callee.scope.generateDeclaredUidIdentifier("ret"); + callee.get("body").pushContainer("body", t.returnStatement(uid)); + loop.setData("expressionReplacementReturnUid", uid); + } else { + uid = t.identifier(uid.name); + } path.get("expression").replaceWith( t.assignmentExpression("=", uid, path.node.expression) diff --git a/packages/babel-traverse/src/scope/index.js b/packages/babel-traverse/src/scope/index.js index b7b3388b8d..a0b26bc573 100644 --- a/packages/babel-traverse/src/scope/index.js +++ b/packages/babel-traverse/src/scope/index.js @@ -1,5 +1,3 @@ -/* eslint max-len: 0 */ - import includes from "lodash/includes"; import repeat from "lodash/repeat"; import Renamer from "./lib/renamer"; @@ -78,7 +76,7 @@ const collectorVisitor = { }, Declaration(path) { - // delegate block scope handling to the `blockVariableVisitor` + // delegate block scope handling to the `BlockScoped` method if (path.isBlockScoped()) return; // this will be hit again once we traverse into it after this iteration @@ -341,13 +339,11 @@ export default class Scope { // ignore hoisted functions if there's also a local let if (kind === "hoisted" && local.kind === "let") return; - let duplicate = false; - - // don't allow duplicate bindings to exist alongside - if (!duplicate) duplicate = kind === "let" || local.kind === "let" || local.kind === "const" || local.kind === "module"; - - // don't allow a local of param with a kind of let - if (!duplicate) duplicate = local.kind === "param" && (kind === "let" || kind === "const"); + const duplicate = + // don't allow duplicate bindings to exist alongside + kind === "let" || local.kind === "let" || local.kind === "const" || local.kind === "module" || + // don't allow a local of param with a kind of let + local.kind === "param" && (kind === "let" || kind === "const"); if (duplicate) { throw this.hub.file.buildCodeFrameError(id, messages.get("scopeDuplicateDeclaration", name), TypeError); diff --git a/packages/babel-traverse/test/evaluation.js b/packages/babel-traverse/test/evaluation.js index 3c53fbf615..148173fa7d 100644 --- a/packages/babel-traverse/test/evaluation.js +++ b/packages/babel-traverse/test/evaluation.js @@ -33,7 +33,8 @@ describe("evaluation", function () { it("should bail out on recursive evaluation", function () { assert.strictEqual( - getPath("function fn(a) { var g = a ? 1 : 2, a = g * this.foo; }").get("body.0.body.body.0.declarations.1.init").evaluate().confident, + getPath("function fn(a) { var g = a ? 1 : 2, a = g * this.foo; }") + .get("body.0.body.body.0.declarations.1.init").evaluate().confident, false ); }); @@ -54,7 +55,8 @@ describe("evaluation", function () { it("should deopt when var is redeclared in the same scope", function () { assert.strictEqual( - getPath("var x = 2; var y = x + 2; { var x = 3 }").get("body.1.declarations.0.init").evaluate().confident, + getPath("var x = 2; var y = x + 2; { var x = 3 }") + .get("body.1.declarations.0.init").evaluate().confident, false ); }); @@ -73,7 +75,8 @@ describe("evaluation", function () { it("it should not deopt let/const inside blocks", function () { assert.strictEqual( - getPath("let x = 5; { let x = 1; } let y = x + 5").get("body.2.declarations.0.init").evaluate().value, + getPath("let x = 5; { let x = 1; } let y = x + 5") + .get("body.2.declarations.0.init").evaluate().value, 10 ); const constExample = "const d = true; if (d && true || false) { const d = false; d && 5; }"; @@ -98,4 +101,22 @@ describe("evaluation", function () { false ); }); + + it("should evaluate undefined, NaN and Infinity", () => { + assert.strictEqual(getPath("undefined").get("body.0.expression").evaluate().confident, true); + assert.strictEqual(getPath("NaN").get("body.0.expression").evaluate().confident, true); + assert.strictEqual(getPath("Infinity").get("body.0.expression").evaluate().confident, true); + }); + + it("should deopt redefined primitives - undefined, NaN and Infinity", () => { + const eval_undef = getPath("let undefined; undefined;").get("body.1.expression").evaluate(); + const eval_nan = getPath("let NaN; NaN;").get("body.1.expression").evaluate(); + const eval_inf = getPath("let Infinity; Infinity;").get("body.1.expression").evaluate(); + assert.strictEqual(eval_undef.confident, false); + assert.strictEqual(eval_nan.confident, false); + assert.strictEqual(eval_inf.confident, false); + + assert.strictEqual(eval_undef.deopt.type, "VariableDeclarator"); + assert.strictEqual(eval_undef.deopt.parentPath.node.kind, "let"); + }); }); diff --git a/packages/babel-traverse/test/family.js b/packages/babel-traverse/test/family.js index 6e9a497df7..6c34906c44 100644 --- a/packages/babel-traverse/test/family.js +++ b/packages/babel-traverse/test/family.js @@ -52,6 +52,31 @@ describe("path/family", function () { assert.strictEqual(outerNodes[id], outerPaths[id].node, "nodes match"); }); }); + + }); + describe("getSibling", function () { + const ast = parse("var a = 1, {b} = c, [d] = e; function f() {} function g() {}"); + let sibling = {}, lastSibling = {}; + traverse(ast, { + VariableDeclaration(path) { + sibling = path.getSibling(path.key); + lastSibling = sibling.getNextSibling().getNextSibling(); + } + }); + + it("should return traverse sibling nodes", function () { + assert.ok(sibling.getNextSibling().node, "has property node"); + assert.ok(lastSibling.getPrevSibling().node, "has property node"); + assert.equal(!!sibling.getPrevSibling().node, false, "out of scope"); + assert.equal(!!lastSibling.getNextSibling().node, false, "out of scope"); + }); + + it("should return all preceding and succeeding sibling nodes", function () { + assert.ok(sibling.getAllNextSiblings().length, "Has next sibling"); + assert.ok(lastSibling.getAllPrevSiblings().length, "Has prev sibling"); + assert.equal(sibling.getAllNextSiblings().length, 2, "Has 2 succeeding sibling"); + assert.equal(lastSibling.getAllPrevSiblings().length, 2, "Has 2 preceeding sibling"); + }); }); }); diff --git a/packages/babel-traverse/test/inference.js b/packages/babel-traverse/test/inference.js index 225f2c7430..03ff842ecf 100644 --- a/packages/babel-traverse/test/inference.js +++ b/packages/babel-traverse/test/inference.js @@ -36,7 +36,8 @@ describe("inference", function () { }); it("it should bail when type changes", function () { - const path = getPath("var x = 1; if (foo) x = null;else x = 3; x === 2").get("body")[2].get("expression"); + const path = getPath("var x = 1; if (foo) x = null;else x = 3; x === 2") + .get("body")[2].get("expression"); const left = path.get("left"); const right = path.get("right"); @@ -144,7 +145,8 @@ describe("inference", function () { it("should infer call return type using async generator function", function () { const path = getPath("(async function * (): string {})()").get("body")[0].get("expression"); const type = path.getTypeAnnotation(); - assert.ok(t.isGenericTypeAnnotation(type) && type.id.name === "AsyncIterator", "should be AsyncIterator"); + assert.ok(t.isGenericTypeAnnotation(type) && type.id.name === "AsyncIterator", + "should be AsyncIterator"); }); it("should infer number from x/y", function () { const path = getPath("x/y").get("body")[0].get("expression"); diff --git a/packages/babel-traverse/test/scope.js b/packages/babel-traverse/test/scope.js index db51118fcf..7f823ecfd6 100644 --- a/packages/babel-traverse/test/scope.js +++ b/packages/babel-traverse/test/scope.js @@ -17,22 +17,29 @@ function getPath(code) { describe("scope", function () { describe("binding paths", function () { it("function declaration id", function () { - assert.ok(getPath("function foo() {}").scope.getBinding("foo").path.type === "FunctionDeclaration"); + assert.ok(getPath("function foo() {}") + .scope.getBinding("foo").path.type === "FunctionDeclaration"); }); it("function expression id", function () { - assert.ok(getPath("(function foo() {})").get("body")[0].get("expression").scope.getBinding("foo").path.type === "FunctionExpression"); + assert.ok(getPath("(function foo() {})").get("body")[0].get("expression") + .scope.getBinding("foo").path.type === "FunctionExpression"); }); it("function param", function () { - assert.ok(getPath("(function (foo) {})").get("body")[0].get("expression").scope.getBinding("foo").path.type === "Identifier"); + assert.ok(getPath("(function (foo) {})").get("body")[0].get("expression") + .scope.getBinding("foo").path.type === "Identifier"); }); it("variable declaration", function () { - assert.ok(getPath("var foo = null;").scope.getBinding("foo").path.type === "VariableDeclarator"); - assert.ok(getPath("var { foo } = null;").scope.getBinding("foo").path.type === "VariableDeclarator"); - assert.ok(getPath("var [ foo ] = null;").scope.getBinding("foo").path.type === "VariableDeclarator"); - assert.ok(getPath("var { bar: [ foo ] } = null;").scope.getBinding("foo").path.type === "VariableDeclarator"); + assert.ok(getPath("var foo = null;") + .scope.getBinding("foo").path.type === "VariableDeclarator"); + assert.ok(getPath("var { foo } = null;") + .scope.getBinding("foo").path.type === "VariableDeclarator"); + assert.ok(getPath("var [ foo ] = null;") + .scope.getBinding("foo").path.type === "VariableDeclarator"); + assert.ok(getPath("var { bar: [ foo ] } = null;") + .scope.getBinding("foo").path.type === "VariableDeclarator"); }); it("purity", function () { diff --git a/packages/babel-traverse/test/traverse.js b/packages/babel-traverse/test/traverse.js index 3f62821ce5..5434620947 100644 --- a/packages/babel-traverse/test/traverse.js +++ b/packages/babel-traverse/test/traverse.js @@ -31,7 +31,8 @@ describe("traverse", function () { it("traverse", function () { const expect = [ body[0], body[0].declarations[0], body[0].declarations[0].id, body[0].declarations[0].init, - body[1], body[1].expression, body[1].expression.left, body[1].expression.left.object, body[1].expression.left.property, body[1].expression.right + body[1], body[1].expression, body[1].expression.left, body[1].expression.left.object, + body[1].expression.left.property, body[1].expression.right ]; const actual = []; diff --git a/packages/babel-types/src/constants.js b/packages/babel-types/src/constants.js index 72f0a16387..1ed965382e 100644 --- a/packages/babel-types/src/constants.js +++ b/packages/babel-types/src/constants.js @@ -1,4 +1,4 @@ -/* eslint max-len: 0 */ +/* eslint max-len: "off" */ export const STATEMENT_OR_BLOCK_KEYS = ["consequent", "body", "alternate"]; export const FLATTENABLE_KEYS = ["body", "expressions"]; diff --git a/packages/babel-types/src/definitions/core.js b/packages/babel-types/src/definitions/core.js index 276db2048a..e7b7a272e0 100644 --- a/packages/babel-types/src/definitions/core.js +++ b/packages/babel-types/src/definitions/core.js @@ -1,4 +1,4 @@ -/* eslint max-len: 0 */ +/* eslint max-len: "off" */ import * as t from "../index"; diff --git a/packages/babel-types/src/definitions/es2015.js b/packages/babel-types/src/definitions/es2015.js index 843a831fa6..f0231478d3 100644 --- a/packages/babel-types/src/definitions/es2015.js +++ b/packages/babel-types/src/definitions/es2015.js @@ -1,4 +1,4 @@ -/* eslint max-len: 0 */ +/* eslint max-len: "off" */ import defineType, { assertNodeType, diff --git a/packages/babel-types/src/index.js b/packages/babel-types/src/index.js index 54edc7d981..fc633e1474 100644 --- a/packages/babel-types/src/index.js +++ b/packages/babel-types/src/index.js @@ -1,5 +1,4 @@ import toFastProperties from "to-fast-properties"; -import compact from "lodash/compact"; import loClone from "lodash/clone"; import uniq from "lodash/uniq"; @@ -398,7 +397,10 @@ export function inheritInnerComments(child: Object, parent: Object) { function _inheritComments(key, child, parent) { if (child && parent) { - child[key] = uniq(compact([].concat(child[key], parent[key]))); + child[key] = uniq( + [].concat(child[key], parent[key]) + .filter(Boolean) + ); } } diff --git a/packages/babel-types/src/validators.js b/packages/babel-types/src/validators.js index 183a304a9b..c5f25327bd 100644 --- a/packages/babel-types/src/validators.js +++ b/packages/babel-types/src/validators.js @@ -1,5 +1,3 @@ -/* eslint indent: 0 */ - import { getBindingIdentifiers } from "./retrievers"; import esutils from "esutils"; import * as t from "./index"; @@ -276,7 +274,7 @@ export function isNodesEquivalent(a, b) { } if (!isNodesEquivalent(a[field], b[field])) { - return false; + return false; } } diff --git a/packages/babel-types/test/converters.js b/packages/babel-types/test/converters.js index 56dabf6586..b89e6dbe3f 100644 --- a/packages/babel-types/test/converters.js +++ b/packages/babel-types/test/converters.js @@ -25,7 +25,8 @@ describe("converters", function () { assert.deepEqual(t.valueToNode(/abc.+/gm), t.regExpLiteral("abc.+", "gm")); }); it("array", function () { - assert.deepEqual(t.valueToNode([1, "a"]), t.arrayExpression([t.numericLiteral(1), t.stringLiteral("a")])); + assert.deepEqual(t.valueToNode([1, "a"]), + t.arrayExpression([t.numericLiteral(1), t.stringLiteral("a")])); }); it("object", function () { assert.deepEqual(t.valueToNode({ diff --git a/packages/babel/package.json b/packages/babel/package.json index a4440b5718..4c03e3eb51 100644 --- a/packages/babel/package.json +++ b/packages/babel/package.json @@ -7,8 +7,8 @@ "license": "MIT", "repository": "https://github.com/babel/babel/tree/master/packages/babel", "bin": { - "babel": "./cli.js", - "babel-node": "./cli.js", - "babel-external-helpers": "./cli.js" + "babel": "./lib/cli.js", + "babel-node": "./lib/cli.js", + "babel-external-helpers": "./lib/cli.js" } } diff --git a/packages/babel/cli.js b/packages/babel/src/cli.js similarity index 58% rename from packages/babel/cli.js rename to packages/babel/src/cli.js index 92c1235cd0..0a6c889d7d 100755 --- a/packages/babel/cli.js +++ b/packages/babel/src/cli.js @@ -1,10 +1,13 @@ #!/usr/bin/env node +import path from "path"; + +const globalMessage = path.dirname(process.execPath) === path.dirname(process.env._ || "") ? " -g" : ""; console.error("You have mistakenly installed the `babel` package, which is a no-op in Babel 6.\n" + "Babel's CLI commands have been moved from the `babel` package to the `babel-cli` package.\n" + "\n" + - " npm uninstall babel\n" + - " npm install babel-cli\n" + + " npm uninstall" + globalMessage + " babel\n" + + " npm install --save-dev babel-cli\n" + "\n" + "See http://babeljs.io/docs/usage/cli/ for setup instructions."); process.exit(1);