From 6f664ca64e9e76683fa52c97e0148d8e857933ae Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 7 May 2015 15:53:22 +0100 Subject: [PATCH 01/30] merge internal transformers into single traversal pass --- src/babel/transformation/file/index.js | 76 ++++++++++--------- ...-binary-assignment-operator-transformer.js | 4 - .../helpers/build-react-transformer.js | 6 -- src/babel/transformation/index.js | 7 ++ src/babel/transformation/transformer-pass.js | 19 ++--- src/babel/transformation/transformer.js | 13 ---- .../transformers/es5/properties.mutators.js | 42 +++++----- .../transformers/es6/arrow-functions.js | 2 - .../transformers/es6/block-scoping.js | 4 - .../transformers/es6/classes.js | 10 +-- .../transformers/es6/constants.js | 4 - .../transformers/es6/destructuring.js | 5 -- .../transformation/transformers/es6/for-of.js | 2 - .../transformers/es6/modules.js | 2 - .../transformers/es6/object-super.js | 2 - .../transformers/es6/parameters.default.js | 6 -- .../transformers/es6/parameters.rest.js | 4 - .../transformers/es6/properties.computed.js | 70 +++++++++-------- .../transformers/es6/properties.shorthand.js | 4 - .../transformers/es6/regex.sticky.js | 4 - .../transformers/es6/regex.unicode.js | 4 - .../transformation/transformers/es6/spread.js | 2 - .../transformers/es6/template-literals.js | 4 - .../transformers/es7/async-functions.js | 4 - .../transformers/es7/class-properties.js | 4 - .../transformers/es7/decorators.js | 4 - .../transformers/es7/do-expressions.js | 2 - .../transformers/es7/export-extensions.js | 4 - .../es7/trailing-function-commas.js | 4 - .../transformation/transformers/index.js | 66 +--------------- .../transformers/internal/hoist-directives.js | 16 ++++ .../transformers/internal/module-formatter.js | 2 - .../transformers/internal/modules.js | 4 - .../transformers/internal/shadow-functions.js | 29 +++---- .../transformers/internal/strict.js | 19 ----- .../transformers/internal/validation.js | 17 ----- .../transformers/optimisation/flow.for-of.js | 1 - .../transformation/transformers/other/flow.js | 4 - .../transformers/other/regenerator.js | 8 +- .../transformers/other/strict.js | 35 ++++++--- .../spec/block-scoped-functions.js | 15 ---- .../transformers/validation/react.js | 8 -- .../validation/undeclared-variable-check.js | 3 +- src/babel/traversal/index.js | 9 ++- src/babel/traversal/path/index.js | 67 +++++++++------- src/babel/traversal/visitors.js | 23 ++++-- .../es6.arrow-functions/arguments/expected.js | 10 +-- .../assignment-expression/expected.js | 6 +- 48 files changed, 243 insertions(+), 417 deletions(-) create mode 100644 src/babel/transformation/transformers/internal/hoist-directives.js delete mode 100644 src/babel/transformation/transformers/internal/strict.js diff --git a/src/babel/transformation/file/index.js b/src/babel/transformation/file/index.js index bec58c718a..bb2d3697db 100644 --- a/src/babel/transformation/file/index.js +++ b/src/babel/transformation/file/index.js @@ -4,6 +4,7 @@ import moduleFormatters from "../modules"; import PluginManager from "./plugin-manager"; import shebangRegex from "shebang-regex"; import TraversalPath from "../../traversal/path"; +import Transformer from "../transformer"; import isFunction from "lodash/lang/isFunction"; import isAbsolute from "path-is-absolute"; import resolveRc from "../../tools/resolve-rc"; @@ -26,19 +27,6 @@ import path from "path"; import each from "lodash/collection/each"; import * as t from "../../types"; -var checkTransformerVisitor = { - exit(node, parent, scope, state) { - checkPath(state.stack, this); - } -}; - -function checkPath(stack, path) { - each(stack, function (pass) { - if (pass.shouldRun || pass.ran) return; - pass.checkPath(path); - }); -} - export default class File { constructor(opts = {}, pipeline) { this.dynamicImportTypes = {}; @@ -234,7 +222,46 @@ export default class File { stack = beforePlugins.concat(stack, afterPlugins); // register - this.transformerStack = stack.concat(secondaryStack); + this.transformerStack = this.mergeStack(stack.concat(secondaryStack)); + + + } + + mergeStack(_stack) { + var stack = []; + var ignore = []; + + for (let pass of (_stack: Array)) { + // been merged + if (ignore.indexOf(pass) >= 0) continue; + + var category = pass.transformer.metadata.category; + + // can't merge + if (!pass.canTransform() || !category) { + stack.push(pass); + continue; + } + + var mergeStack = []; + for (let pass of (_stack: Array)) { + if (pass.transformer.metadata.category === category) { + mergeStack.push(pass); + ignore.push(pass); + } + } + + var visitors = []; + for (let pass of (mergeStack: Array)) { + visitors.push(pass.handlers); + } + var visitor = traverse.visitors.merge(visitors); + var mergeTransformer = new Transformer(category, visitor); + //console.log(mergeTransformer); + stack.push(mergeTransformer.buildPass(this)); + } + + return stack; } set(key: string, val): any { @@ -357,23 +384,6 @@ export default class File { return err; } - checkPath(path) { - if (Array.isArray(path)) { - for (var i = 0; i < path.length; i++) { - this.checkPath(path[i]); - } - return; - } - - var stack = this.transformerStack; - - checkPath(stack, path); - - path.traverse(checkTransformerVisitor, { - stack: stack - }); - } - mergeSourceMap(map: Object) { var opts = this.opts; @@ -461,10 +471,6 @@ export default class File { this._addAst(ast); this.log.debug("End set AST"); - this.log.debug("Start prepass"); - this.checkPath(this.path); - this.log.debug("End prepass"); - this.log.debug("Start module formatter init"); var modFormatter = this.moduleFormatter = this.getModuleFormatter(this.opts.modules); if (modFormatter.init && this.transformers["es6.modules"].canTransform()) { diff --git a/src/babel/transformation/helpers/build-binary-assignment-operator-transformer.js b/src/babel/transformation/helpers/build-binary-assignment-operator-transformer.js index 45a6d812c5..04ffc4c1b3 100644 --- a/src/babel/transformation/helpers/build-binary-assignment-operator-transformer.js +++ b/src/babel/transformation/helpers/build-binary-assignment-operator-transformer.js @@ -10,10 +10,6 @@ export default function (exports, opts) { return t.assignmentExpression("=", left, right); }; - exports.shouldVisit = function (node) { - return node.operator && (node.operator === opts.operator || node.operator === opts.operator + "="); - }; - exports.ExpressionStatement = function (node, parent, scope, file) { // hit the `AssignmentExpression` one below if (this.isCompletionRecord()) return; diff --git a/src/babel/transformation/helpers/build-react-transformer.js b/src/babel/transformation/helpers/build-react-transformer.js index 46a9bdfef7..c63bd60882 100644 --- a/src/babel/transformation/helpers/build-react-transformer.js +++ b/src/babel/transformation/helpers/build-react-transformer.js @@ -10,12 +10,6 @@ import * as react from "./react"; import * as t from "../../types"; export default function (exports, opts) { - exports.shouldVisit = function (node) { - if (t.isJSX(node)) return true; - if (react.isCreateClass(node)) return true; - return false; - }; - exports.JSXIdentifier = function (node, parent) { if (node.name === "this" && this.isReferenced()) { return t.thisExpression(); diff --git a/src/babel/transformation/index.js b/src/babel/transformation/index.js index 442ed37849..3f71068bc2 100644 --- a/src/babel/transformation/index.js +++ b/src/babel/transformation/index.js @@ -5,6 +5,13 @@ var pipeline = new Pipeline; // import transformers from "./transformers"; + +for (var key in transformers) { + var transformer = transformers[key]; + var metadata = transformer.metadata = transformer.metadata || {}; + metadata.category = metadata.category || "builtin"; +} + pipeline.addTransformers(transformers); // diff --git a/src/babel/transformation/transformer-pass.js b/src/babel/transformation/transformer-pass.js index 38c3e8ef8c..715ba6de2e 100644 --- a/src/babel/transformation/transformer-pass.js +++ b/src/babel/transformation/transformer-pass.js @@ -8,27 +8,18 @@ import traverse from "../traversal"; export default class TransformerPass { constructor(file: File, transformer: Transformer) { - this.shouldTransform = !transformer.shouldVisit; - this.transformer = transformer; - this.handlers = transformer.handlers; - this.skipKey = transformer.skipKey; - this.file = file; - this.ran = false; + this.transformer = transformer; + this.handlers = transformer.handlers; + this.skipKey = transformer.skipKey; + this.file = file; + this.ran = false; } canTransform(): boolean { return this.file.pipeline.canTransform(this.transformer, this.file.opts); } - checkPath(path: TraversalPath): boolean { - if (this.shouldTransform || this.ran) return; - - this.shouldTransform = this.transformer.shouldVisit(path.node); - } - transform() { - if (!this.shouldTransform) return; - var file = this.file; file.log.debug(`Start transformer ${this.transformer.key}`); diff --git a/src/babel/transformation/transformer.js b/src/babel/transformation/transformer.js index 3e12abcf1d..a5fac03bf9 100644 --- a/src/babel/transformation/transformer.js +++ b/src/babel/transformation/transformer.js @@ -25,7 +25,6 @@ export default class Transformer { }; this.manipulateOptions = take("manipulateOptions"); - this.shouldVisit = take("shouldVisit"); this.metadata = take("metadata") || {}; this.parser = take("parser"); this.post = take("post"); @@ -41,18 +40,6 @@ export default class Transformer { this.handlers = this.normalize(transformer); this.key = transformerKey; - - // - - if (!this.shouldVisit && !this.handlers.enter && !this.handlers.exit) { - var types = Object.keys(this.handlers); - this.shouldVisit = function (node) { - for (var i = 0; i < types.length; i++) { - if (node.type === types[i]) return true; - } - return false; - }; - } } normalize(transformer: Object): Object { diff --git a/src/babel/transformation/transformers/es5/properties.mutators.js b/src/babel/transformation/transformers/es5/properties.mutators.js index 9b1deb2870..7fe77c7f41 100644 --- a/src/babel/transformation/transformers/es5/properties.mutators.js +++ b/src/babel/transformation/transformers/es5/properties.mutators.js @@ -1,28 +1,26 @@ import * as defineMap from "../../helpers/define-map"; import * as t from "../../../types"; -export function shouldVisit(node) { - return t.isProperty(node) && (node.kind === "get" || node.kind === "set"); -} +export var ObjectExpression = { + exit(node, parent, scope, file) { + var mutatorMap = {}; + var hasAny = false; -export function ObjectExpression(node, parent, scope, file) { - var mutatorMap = {}; - var hasAny = false; + node.properties = node.properties.filter(function (prop) { + if (prop.kind === "get" || prop.kind === "set") { + hasAny = true; + defineMap.push(mutatorMap, prop, prop.kind, file); + return false; + } else { + return true; + } + }); - node.properties = node.properties.filter(function (prop) { - if (prop.kind === "get" || prop.kind === "set") { - hasAny = true; - defineMap.push(mutatorMap, prop, prop.kind, file); - return false; - } else { - return true; - } - }); + if (!hasAny) return; - if (!hasAny) return; - - return t.callExpression( - t.memberExpression(t.identifier("Object"), t.identifier("defineProperties")), - [node, defineMap.toDefineObject(mutatorMap)] - ); -} + return t.callExpression( + t.memberExpression(t.identifier("Object"), t.identifier("defineProperties")), + [node, defineMap.toDefineObject(mutatorMap)] + ); + } +}; diff --git a/src/babel/transformation/transformers/es6/arrow-functions.js b/src/babel/transformation/transformers/es6/arrow-functions.js index d40d436727..39d93f829a 100644 --- a/src/babel/transformation/transformers/es6/arrow-functions.js +++ b/src/babel/transformation/transformers/es6/arrow-functions.js @@ -1,7 +1,5 @@ import * as t from "../../../types"; -export var shouldVisit = t.isArrowFunctionExpression; - export function ArrowFunctionExpression(node) { t.ensureBlock(node); diff --git a/src/babel/transformation/transformers/es6/block-scoping.js b/src/babel/transformation/transformers/es6/block-scoping.js index 1b81d95232..850dca35f0 100644 --- a/src/babel/transformation/transformers/es6/block-scoping.js +++ b/src/babel/transformation/transformers/es6/block-scoping.js @@ -37,10 +37,6 @@ function standardizeLets(declars) { } } -export function shouldVisit(node) { - return t.isVariableDeclaration(node) && (node.kind === "let" || node.kind === "const"); -} - export function VariableDeclaration(node, parent, scope, file) { if (!isLet(node, parent)) return; diff --git a/src/babel/transformation/transformers/es6/classes.js b/src/babel/transformation/transformers/es6/classes.js index 670a18b5fb..e1bb106659 100644 --- a/src/babel/transformation/transformers/es6/classes.js +++ b/src/babel/transformation/transformers/es6/classes.js @@ -11,17 +11,17 @@ import * as t from "../../../types"; const PROPERTY_COLLISION_METHOD_NAME = "__initializeProperties"; -export var shouldVisit = t.isClass; - export function ClassDeclaration(node, parent, scope, file) { return t.variableDeclaration("let", [ t.variableDeclarator(node.id, t.toExpression(node)) ]); } -export function ClassExpression(node, parent, scope, file) { - return new ClassTransformer(this, file).run(); -} +export var ClassExpression = { + exit(node, parent, scope, file) { + return new ClassTransformer(this, file).run(); + } +}; var collectPropertyReferencesVisitor = { Identifier: { diff --git a/src/babel/transformation/transformers/es6/constants.js b/src/babel/transformation/transformers/es6/constants.js index b8df344bfb..4125b68d10 100644 --- a/src/babel/transformation/transformers/es6/constants.js +++ b/src/babel/transformation/transformers/es6/constants.js @@ -1,10 +1,6 @@ import * as messages from "../../../messages"; import * as t from "../../../types"; -export function shouldVisit(node) { - return t.isVariableDeclaration(node, { kind: "const" }) || t.isImportDeclaration(node); -} - var visitor = { enter(node, parent, scope, state) { if (this.isAssignmentExpression() || this.isUpdateExpression()) { diff --git a/src/babel/transformation/transformers/es6/destructuring.js b/src/babel/transformation/transformers/es6/destructuring.js index 5dd84da762..5fb2df518b 100644 --- a/src/babel/transformation/transformers/es6/destructuring.js +++ b/src/babel/transformation/transformers/es6/destructuring.js @@ -1,8 +1,6 @@ import * as messages from "../../../messages"; import * as t from "../../../types"; -export var shouldVisit = t.isPattern; - export function ForOfStatement(node, parent, scope, file) { var left = node.left; @@ -83,7 +81,6 @@ exports.Function = function (node, parent, scope, file) { var block = node.body; block.body = nodes.concat(block.body); - this.checkSelf(); }; export function CatchClause(node, parent, scope, file) { @@ -104,8 +101,6 @@ export function CatchClause(node, parent, scope, file) { destructuring.init(pattern, ref); node.body.body = nodes.concat(node.body.body); - - this.checkSelf(); } export function ExpressionStatement(node, parent, scope, file) { diff --git a/src/babel/transformation/transformers/es6/for-of.js b/src/babel/transformation/transformers/es6/for-of.js index 7d007d6465..b986492da9 100644 --- a/src/babel/transformation/transformers/es6/for-of.js +++ b/src/babel/transformation/transformers/es6/for-of.js @@ -2,8 +2,6 @@ import * as messages from "../../../messages"; import * as util from "../../../util"; import * as t from "../../../types"; -export var shouldVisit = t.isForOfStatement; - export function ForOfStatement(node, parent, scope, file) { if (this.get("right").isArrayExpression()) { return _ForOfStatementArray.call(this, node, scope, file); diff --git a/src/babel/transformation/transformers/es6/modules.js b/src/babel/transformation/transformers/es6/modules.js index 5abf2b1af4..6141ab9217 100644 --- a/src/babel/transformation/transformers/es6/modules.js +++ b/src/babel/transformation/transformers/es6/modules.js @@ -1,7 +1,5 @@ import * as t from "../../../types"; -export { shouldVisit } from "../internal/modules"; - function keepBlockHoist(node, nodes) { if (node._blockHoist) { for (let i = 0; i < nodes.length; i++) { diff --git a/src/babel/transformation/transformers/es6/object-super.js b/src/babel/transformation/transformers/es6/object-super.js index b261520da2..10d01e09f8 100644 --- a/src/babel/transformation/transformers/es6/object-super.js +++ b/src/babel/transformation/transformers/es6/object-super.js @@ -1,8 +1,6 @@ import ReplaceSupers from "../../helpers/replace-supers"; import * as t from "../../../types"; -export var shouldVisit = t.isSuper; - function Property(path, node, scope, getObjectRef, file) { if (!node.method) return; diff --git a/src/babel/transformation/transformers/es6/parameters.default.js b/src/babel/transformation/transformers/es6/parameters.default.js index 56345ee839..165c177844 100644 --- a/src/babel/transformation/transformers/es6/parameters.default.js +++ b/src/babel/transformation/transformers/es6/parameters.default.js @@ -3,10 +3,6 @@ import * as util from "../../../util"; import traverse from "../../../traversal"; import * as t from "../../../types"; -export function shouldVisit(node) { - return t.isFunction(node) && hasDefaults(node); -} - var hasDefaults = function (node) { for (var i = 0; i < node.params.length; i++) { if (!t.isIdentifier(node.params[i])) return true; @@ -96,6 +92,4 @@ exports.Function = function (node, parent, scope, file) { } else { node.body.body = body.concat(node.body.body); } - - this.checkSelf(); }; diff --git a/src/babel/transformation/transformers/es6/parameters.rest.js b/src/babel/transformation/transformers/es6/parameters.rest.js index 631701a766..6b57c156a3 100644 --- a/src/babel/transformation/transformers/es6/parameters.rest.js +++ b/src/babel/transformation/transformers/es6/parameters.rest.js @@ -2,8 +2,6 @@ import isNumber from "lodash/lang/isNumber"; import * as util from "../../../util"; import * as t from "../../../types"; -export var shouldVisit = t.isRestElement; - var memberExpressionOptimisationVisitor = { enter(node, parent, scope, state) { // check if this scope has a local binding that will shadow the rest parameter @@ -96,7 +94,6 @@ exports.Function = function (node, parent, scope, file) { candidate.replaceWith(argsId); optimizeMemberExpression(candidate.parent, node.params.length); } - this.checkSelf(); return; } @@ -138,5 +135,4 @@ exports.Function = function (node, parent, scope, file) { }); loop._blockHoist = node.params.length + 1; node.body.body.unshift(loop); - this.checkSelf(); }; diff --git a/src/babel/transformation/transformers/es6/properties.computed.js b/src/babel/transformation/transformers/es6/properties.computed.js index e846e4d2a6..d944844ca0 100644 --- a/src/babel/transformation/transformers/es6/properties.computed.js +++ b/src/babel/transformation/transformers/es6/properties.computed.js @@ -63,42 +63,40 @@ function spec(node, body, objId, initProps, file) { } } -export function shouldVisit(node) { - return t.isProperty(node) && node.computed; -} +export var ObjectExpression = { + exit(node, parent, scope, file) { + var hasComputed = false; -export function ObjectExpression(node, parent, scope, file) { - var hasComputed = false; + for (var i = 0; i < node.properties.length; i++) { + hasComputed = t.isProperty(node.properties[i], { computed: true, kind: "init" }); + if (hasComputed) break; + } - for (var i = 0; i < node.properties.length; i++) { - hasComputed = t.isProperty(node.properties[i], { computed: true, kind: "init" }); - if (hasComputed) break; + if (!hasComputed) return; + + var initProps = []; + var objId = scope.generateUidBasedOnNode(parent); + + // + + var body = []; + + // + + var callback = spec; + if (file.isLoose("es6.properties.computed")) callback = loose; + + var result = callback(node, body, objId, initProps, file); + if (result) return result; + + // + + body.unshift(t.variableDeclaration("var", [ + t.variableDeclarator(objId, t.objectExpression(initProps)) + ])); + + body.push(t.expressionStatement(objId)); + + return body; } - - if (!hasComputed) return; - - var initProps = []; - var objId = scope.generateUidBasedOnNode(parent); - - // - - var body = []; - - // - - var callback = spec; - if (file.isLoose("es6.properties.computed")) callback = loose; - - var result = callback(node, body, objId, initProps, file); - if (result) return result; - - // - - body.unshift(t.variableDeclaration("var", [ - t.variableDeclarator(objId, t.objectExpression(initProps)) - ])); - - body.push(t.expressionStatement(objId)); - - return body; -} +}; diff --git a/src/babel/transformation/transformers/es6/properties.shorthand.js b/src/babel/transformation/transformers/es6/properties.shorthand.js index 5f6830cfb7..b5140ac364 100644 --- a/src/babel/transformation/transformers/es6/properties.shorthand.js +++ b/src/babel/transformation/transformers/es6/properties.shorthand.js @@ -1,9 +1,5 @@ import * as t from "../../../types"; -export function shouldVisit(node) { - return t.isProperty(node) && (node.method || node.shorthand); -} - export function Property(node) { if (node.method) { node.method = false; diff --git a/src/babel/transformation/transformers/es6/regex.sticky.js b/src/babel/transformation/transformers/es6/regex.sticky.js index 3227c59635..e298e0501b 100644 --- a/src/babel/transformation/transformers/es6/regex.sticky.js +++ b/src/babel/transformation/transformers/es6/regex.sticky.js @@ -1,10 +1,6 @@ import * as regex from "../../helpers/regex"; import * as t from "../../../types"; -export function shouldVisit(node) { - return regex.is(node, "y"); -} - export function Literal(node) { if (!regex.is(node, "y")) return; return t.newExpression(t.identifier("RegExp"), [ diff --git a/src/babel/transformation/transformers/es6/regex.unicode.js b/src/babel/transformation/transformers/es6/regex.unicode.js index 58471da84a..a914f2b529 100644 --- a/src/babel/transformation/transformers/es6/regex.unicode.js +++ b/src/babel/transformation/transformers/es6/regex.unicode.js @@ -1,10 +1,6 @@ import rewritePattern from "regexpu/rewrite-pattern"; import * as regex from "../../helpers/regex"; -export function shouldVisit(node) { - return regex.is(node, "u"); -} - export function Literal(node) { if (!regex.is(node, "u")) return; node.regex.pattern = rewritePattern(node.regex.pattern, node.regex.flags); diff --git a/src/babel/transformation/transformers/es6/spread.js b/src/babel/transformation/transformers/es6/spread.js index a856453ed0..e7c403588a 100644 --- a/src/babel/transformation/transformers/es6/spread.js +++ b/src/babel/transformation/transformers/es6/spread.js @@ -44,8 +44,6 @@ function build(props, scope) { return nodes; } -export var shouldVisit = t.isSpreadElement; - export function ArrayExpression(node, parent, scope) { var elements = node.elements; if (!hasSpread(elements)) return; diff --git a/src/babel/transformation/transformers/es6/template-literals.js b/src/babel/transformation/transformers/es6/template-literals.js index 10128abaf7..912fcdbbdf 100644 --- a/src/babel/transformation/transformers/es6/template-literals.js +++ b/src/babel/transformation/transformers/es6/template-literals.js @@ -4,10 +4,6 @@ var buildBinaryExpression = function (left, right) { return t.binaryExpression("+", left, right); }; -export function shouldVisit(node) { - return t.isTemplateLiteral(node) || t.isTaggedTemplateExpression(node); -} - export function TaggedTemplateExpression(node, parent, scope, file) { var quasi = node.quasi; var args = []; diff --git a/src/babel/transformation/transformers/es7/async-functions.js b/src/babel/transformation/transformers/es7/async-functions.js index df6bc46bd4..5059fdd666 100644 --- a/src/babel/transformation/transformers/es7/async-functions.js +++ b/src/babel/transformation/transformers/es7/async-functions.js @@ -1,7 +1,3 @@ export var metadata = { stage: 1 }; - -export function shouldVisit() { - return false; -} diff --git a/src/babel/transformation/transformers/es7/class-properties.js b/src/babel/transformation/transformers/es7/class-properties.js index 9c08f42ae1..871398b386 100644 --- a/src/babel/transformation/transformers/es7/class-properties.js +++ b/src/babel/transformation/transformers/es7/class-properties.js @@ -1,7 +1,3 @@ export var metadata = { stage: 0 }; - -export function shouldVisit() { - return false; -} diff --git a/src/babel/transformation/transformers/es7/decorators.js b/src/babel/transformation/transformers/es7/decorators.js index a67843cf3d..af98294cf8 100644 --- a/src/babel/transformation/transformers/es7/decorators.js +++ b/src/babel/transformation/transformers/es7/decorators.js @@ -7,10 +7,6 @@ export var metadata = { stage: 1 }; -export function shouldVisit(node) { - return !!node.decorators; -} - export function ObjectExpression(node, parent, scope, file) { var hasDecorators = false; for (var i = 0; i < node.properties.length; i++) { diff --git a/src/babel/transformation/transformers/es7/do-expressions.js b/src/babel/transformation/transformers/es7/do-expressions.js index 8f1e18875f..efefe06ba2 100644 --- a/src/babel/transformation/transformers/es7/do-expressions.js +++ b/src/babel/transformation/transformers/es7/do-expressions.js @@ -5,8 +5,6 @@ export var metadata = { stage: 0 }; -export var shouldVisit = t.isDoExpression; - export function DoExpression(node) { var body = node.body.body; if (body.length) { diff --git a/src/babel/transformation/transformers/es7/export-extensions.js b/src/babel/transformation/transformers/es7/export-extensions.js index 80a11c34ab..77880f3a10 100644 --- a/src/babel/transformation/transformers/es7/export-extensions.js +++ b/src/babel/transformation/transformers/es7/export-extensions.js @@ -6,10 +6,6 @@ export var metadata = { stage: 1 }; -export function shouldVisit(node) { - return t.isExportDefaultSpecifier(node) || t.isExportNamespaceSpecifier(node); -} - function build(node, nodes, scope) { var first = node.specifiers[0]; if (!t.isExportNamespaceSpecifier(first) && !t.isExportDefaultSpecifier(first)) return; diff --git a/src/babel/transformation/transformers/es7/trailing-function-commas.js b/src/babel/transformation/transformers/es7/trailing-function-commas.js index df6bc46bd4..5059fdd666 100644 --- a/src/babel/transformation/transformers/es7/trailing-function-commas.js +++ b/src/babel/transformation/transformers/es7/trailing-function-commas.js @@ -1,7 +1,3 @@ export var metadata = { stage: 1 }; - -export function shouldVisit() { - return false; -} diff --git a/src/babel/transformation/transformers/index.js b/src/babel/transformation/transformers/index.js index 05f7c47c41..0c3ea89b1d 100644 --- a/src/babel/transformation/transformers/index.js +++ b/src/babel/transformation/transformers/index.js @@ -1,124 +1,66 @@ export default { "utility.removeDebugger": require("./utility/remove-debugger"), "utility.removeConsole": require("./utility/remove-console"), - "utility.inlineEnvironmentVariables": require("./utility/inline-environment-variables"), "utility.inlineExpressions": require("./utility/inline-expressions"), - "minification.deadCodeElimination": require("./minification/dead-code-elimination"), - _modules: require("./internal/modules"), - "es7.classProperties": require("./es7/class-properties"), "es7.trailingFunctionCommas": require("./es7/trailing-function-commas"), "es7.asyncFunctions": require("./es7/async-functions"), "es7.decorators": require("./es7/decorators"), - strict: require("./other/strict"), - _validation: require("./internal/validation"), - "validation.undeclaredVariableCheck": require("./validation/undeclared-variable-check"), "validation.react": require("./validation/react"), - - // this goes at the start so we only transform the original user code "spec.functionName": require("./spec/function-name"), - - // needs to be before `_shadowFunctions` "es6.arrowFunctions": require("./es6/arrow-functions"), - "spec.blockScopedFunctions": require("./spec/block-scoped-functions"), - "optimisation.react.constantElements": require("./optimisation/react.constant-elements"), "optimisation.react.inlineElements": require("./optimisation/react.inline-elements"), reactCompat: require("./other/react-compat"), react: require("./other/react"), - - // needs to be before `regenerator` due to generator comprehensions - // needs to be before `_shadowFunctions` "es7.comprehensions": require("./es7/comprehensions"), - "es6.classes": require("./es6/classes"), - asyncToGenerator: require("./other/async-to-generator"), bluebirdCoroutines: require("./other/bluebird-coroutines"), - "es6.objectSuper": require("./es6/object-super"), "es7.objectRestSpread": require("./es7/object-rest-spread"), "es7.exponentiationOperator": require("./es7/exponentiation-operator"), - "es6.spec.templateLiterals": require("./es6/spec.template-literals"), "es6.templateLiterals": require("./es6/template-literals"), - "es5.properties.mutators": require("./es5/properties.mutators"), "es6.properties.shorthand": require("./es6/properties.shorthand"), - - // needs to be before `_shadowFunctions` due to define property closure "es6.properties.computed": require("./es6/properties.computed"), - "optimisation.flow.forOf": require("./optimisation/flow.for-of"), "es6.forOf": require("./es6/for-of"), - "es6.regex.sticky": require("./es6/regex.sticky"), "es6.regex.unicode": require("./es6/regex.unicode"), - "es6.constants": require("./es6/constants"), - - // needs to be before `es6.parameters.default` as default parameters will destroy the rest param "es6.parameters.rest": require("./es6/parameters.rest"), - - // needs to be after `es6.parameters.rest` as we use `toArray` and avoid turning an already known array into one "es6.spread": require("./es6/spread"), - - // needs to be before `es6.blockScoping` as default parameters have a TDZ "es6.parameters.default": require("./es6/parameters.default"), - - // needs to be before `es6.blockScoping` as let variables may be produced "es6.destructuring": require("./es6/destructuring"), - - // needs to be before `_shadowFunctions` due to block scopes sometimes being wrapped in a - // closure "es6.blockScoping": require("./es6/block-scoping"), - - // needs to be after `es6.blockScoping` due to needing `letReferences` set on blocks "es6.spec.blockScoping": require("./es6/spec.block-scoping"), - - // needs to be after `es6.parameters.*` and `es6.blockScoping` due to needing pure - // identifiers in parameters and variable declarators "es6.tailCall": require("./es6/tail-call"), - regenerator: require("./other/regenerator"), - - // needs to be after `regenerator` due to needing `regeneratorRuntime` references - // needs to be after `es6.forOf` due to needing `Symbol.iterator` references - // needs to be before `es6.modules` due to dynamic imports - runtime: require("./other/runtime"), - - // needs to be before `_blockHoist` due to function hoisting etc + runtime: require("./other/runtime"), "es7.exportExtensions": require("./es7/export-extensions"), "es6.modules": require("./es6/modules"), - - _blockHoist: require("./internal/block-hoist"), - "spec.protoToAssign": require("./spec/proto-to-assign"), - _shadowFunctions: require("./internal/shadow-functions"), - "es7.doExpressions": require("./es7/do-expressions"), - "es6.spec.symbols": require("./es6/spec.symbols"), ludicrous: require("./other/ludicrous"), "spec.undefinedToVoid": require("./spec/undefined-to-void"), - - _strict: require("./internal/strict"), _moduleFormatter: require("./internal/module-formatter"), - "es3.propertyLiterals": require("./es3/property-literals"), "es3.memberExpressionLiterals": require("./es3/member-expression-literals"), - "minification.memberExpressionLiterals": require("./minification/member-expression-literals"), "minification.propertyLiterals": require("./minification/property-literals"), - jscript: require("./other/jscript"), - flow: require("./other/flow") + flow: require("./other/flow"), + _hoistDirectives: require("./internal/hoist-directives"), + _blockHoist: require("./internal/block-hoist") }; diff --git a/src/babel/transformation/transformers/internal/hoist-directives.js b/src/babel/transformation/transformers/internal/hoist-directives.js new file mode 100644 index 0000000000..8c0c1280cf --- /dev/null +++ b/src/babel/transformation/transformers/internal/hoist-directives.js @@ -0,0 +1,16 @@ +import * as t from "../../../types"; + +export var BlockStatement = { + exit(node) { + for (var i = 0; i < node.body.length; i++) { + var bodyNode = node.body[i]; + if (t.isExpressionStatement(bodyNode) && t.isLiteral(bodyNode.expression)) { + bodyNode._blockHoist = Infinity; + } else { + return; + } + } + } +}; + +export { BlockStatement as Program }; diff --git a/src/babel/transformation/transformers/internal/module-formatter.js b/src/babel/transformation/transformers/internal/module-formatter.js index 92ef7baab2..400f27e28a 100644 --- a/src/babel/transformation/transformers/internal/module-formatter.js +++ b/src/babel/transformation/transformers/internal/module-formatter.js @@ -1,8 +1,6 @@ import * as strict from "../../helpers/strict"; export function Program(program, parent, scope, file) { - this.stop(); - strict.wrap(program, function () { program.body = file.dynamicImports.concat(program.body); }); diff --git a/src/babel/transformation/transformers/internal/modules.js b/src/babel/transformation/transformers/internal/modules.js index 5953072c27..6d3dfe83c8 100644 --- a/src/babel/transformation/transformers/internal/modules.js +++ b/src/babel/transformation/transformers/internal/modules.js @@ -6,10 +6,6 @@ import * as t from "../../../types"; -export function shouldVisit(node) { - return t.isImportDeclaration(node) || t.isExportDeclaration(node); -} - export function ImportDeclaration(node, parent, scope, file) { if (node.source) { node.source.value = file.resolveModuleSource(node.source.value); diff --git a/src/babel/transformation/transformers/internal/shadow-functions.js b/src/babel/transformation/transformers/internal/shadow-functions.js index 4eb4e5e375..30925d8a8f 100644 --- a/src/babel/transformation/transformers/internal/shadow-functions.js +++ b/src/babel/transformation/transformers/internal/shadow-functions.js @@ -82,21 +82,24 @@ function aliasFunction(getBody, path, scope) { } }; -export function shouldVisit(node) { - return true; -} +// todo: on all `this` and `arguments`, walk UP the tree instead of +// crawling the entire function tree -export function Program(node, parent, scope) { - aliasFunction(function () { - return node.body; - }, this, scope); +export var Program = { + exit(node, parent, scope) { + aliasFunction(function () { + return node.body; + }, this, scope); + } }; -export function FunctionDeclaration(node, parent, scope) { - aliasFunction(function () { - t.ensureBlock(node); - return node.body.body; - }, this, scope); -} +export var FunctionDeclaration = { + exit(node, parent, scope) { + aliasFunction(function () { + t.ensureBlock(node); + return node.body.body; + }, this, scope); + } +}; export { FunctionDeclaration as FunctionExpression }; diff --git a/src/babel/transformation/transformers/internal/strict.js b/src/babel/transformation/transformers/internal/strict.js deleted file mode 100644 index afc820c665..0000000000 --- a/src/babel/transformation/transformers/internal/strict.js +++ /dev/null @@ -1,19 +0,0 @@ -import * as t from "../../../types"; - -export function Program(program, parent, scope, file) { - if (file.transformers.strict.canTransform()) { - var directive = file.get("existingStrictDirective"); - - if (!directive) { - directive = t.expressionStatement(t.literal("use strict")); - var first = program.body[0]; - if (first) { - directive.leadingComments = first.leadingComments; - first.leadingComments = []; - } - } - - this.unshiftContainer("body", [directive]); - } - this.stop(); -} diff --git a/src/babel/transformation/transformers/internal/validation.js b/src/babel/transformation/transformers/internal/validation.js index 8fab413fdd..da830eabef 100644 --- a/src/babel/transformation/transformers/internal/validation.js +++ b/src/babel/transformation/transformers/internal/validation.js @@ -1,10 +1,6 @@ import * as messages from "../../../messages"; import * as t from "../../../types"; -export var metadata = { - readOnly: true -}; - export function ForOfStatement(node, parent, scope, file) { var left = node.left; if (t.isVariableDeclaration(left)) { @@ -43,16 +39,3 @@ export function Property(node, parent, scope, file) { } } } - -export function BlockStatement(node) { - for (var i = 0; i < node.body.length; i++) { - var bodyNode = node.body[i]; - if (t.isExpressionStatement(bodyNode) && t.isLiteral(bodyNode.expression)) { - bodyNode._blockHoist = Infinity; - } else { - return; - } - } -} - -export { BlockStatement as Program }; diff --git a/src/babel/transformation/transformers/optimisation/flow.for-of.js b/src/babel/transformation/transformers/optimisation/flow.for-of.js index f69525e307..0f031a9b51 100644 --- a/src/babel/transformation/transformers/optimisation/flow.for-of.js +++ b/src/babel/transformation/transformers/optimisation/flow.for-of.js @@ -1,7 +1,6 @@ import { _ForOfStatementArray } from "../es6/for-of"; import * as t from "../../../types"; -export var shouldVisit = t.isForOfStatement; export var metadata = { optional: true }; diff --git a/src/babel/transformation/transformers/other/flow.js b/src/babel/transformation/transformers/other/flow.js index b3a963e3cc..bb6bf4c393 100644 --- a/src/babel/transformation/transformers/other/flow.js +++ b/src/babel/transformation/transformers/other/flow.js @@ -1,9 +1,5 @@ import * as t from "../../../types"; -export function shouldVisit(node) { - return node.isType || node.optional || node.implements || node.typeAnnotation || t.isFlow(node); -} - export function Flow(node) { this.remove(); } diff --git a/src/babel/transformation/transformers/other/regenerator.js b/src/babel/transformation/transformers/other/regenerator.js index 7c109a92a5..2897527cd1 100644 --- a/src/babel/transformation/transformers/other/regenerator.js +++ b/src/babel/transformation/transformers/other/regenerator.js @@ -1,14 +1,8 @@ import regenerator from "regenerator"; import * as t from "../../../types"; -export function shouldVisit(node) { - return t.isFunction(node) && (node.async || node.generator); -} - export var Program = { - enter(ast) { + exit(ast) { regenerator.transform(ast); - this.stop(); - this.checkSelf(); } }; diff --git a/src/babel/transformation/transformers/other/strict.js b/src/babel/transformation/transformers/other/strict.js index 1c8acc2651..1889800b11 100644 --- a/src/babel/transformation/transformers/other/strict.js +++ b/src/babel/transformation/transformers/other/strict.js @@ -1,22 +1,33 @@ import * as messages from "../../../messages"; import * as t from "../../../types"; -export function Program(program, parent, scope, file) { - var first = program.body[0]; - if (t.isExpressionStatement(first) && t.isLiteral(first.expression, { value: "use strict" })) { - file.set("existingStrictDirective", program.body.shift()); +const THIS_BREAK_KEYS = ["FunctionExpression", "FunctionDeclaration", "ClassExpression", "ClassDeclaration"]; + +export var Program = { + enter(program, parent, scope, file) { + var first = program.body[0]; + + var directive; + if (t.isExpressionStatement(first) && t.isLiteral(first.expression, { value: "use strict" })) { + directive = first; + } else { + directive = t.expressionStatement(t.literal("use strict")); + this.unshiftContainer("body", directive); + if (first) { + directive.leadingComments = first.leadingComments; + first.leadingComments = []; + } + } + directive._blockHoist = Infinity; } } -export function FunctionExpression() { - this.skip(); -} - -export { FunctionExpression as FunctionDeclaration }; -export { FunctionExpression as Class }; - export function ThisExpression() { - return t.identifier("undefined"); + if (!this.findParent(function (node) { + return !node.shadow && THIS_BREAK_KEYS.indexOf(node.type) >= 0; + })) { + return t.identifier("undefined"); + } } export function CallExpression(node, parent, scope, file) { diff --git a/src/babel/transformation/transformers/spec/block-scoped-functions.js b/src/babel/transformation/transformers/spec/block-scoped-functions.js index b5327d8c0f..ae16f05fcb 100644 --- a/src/babel/transformation/transformers/spec/block-scoped-functions.js +++ b/src/babel/transformation/transformers/spec/block-scoped-functions.js @@ -23,21 +23,6 @@ function statementList(key, path, file) { } } -export function shouldVisit(node) { - var body; - if (node.type === "SwitchCase") { - body = node.consequent; - } else if (node.type === "BlockStatement") { - body = node.body; - } - if (body) { - for (var i = 0; i < body.length; i++) { - if (body[i].type === "FunctionDeclaration") return true; - } - } - return false; -} - export function BlockStatement(node, parent, scope, file) { if ((t.isFunction(parent) && parent.body === node) || t.isExportDeclaration(parent)) { return; diff --git a/src/babel/transformation/transformers/validation/react.js b/src/babel/transformation/transformers/validation/react.js index 5666f8c299..536aff1768 100644 --- a/src/babel/transformation/transformers/validation/react.js +++ b/src/babel/transformation/transformers/validation/react.js @@ -1,14 +1,6 @@ import * as messages from "../../../messages"; import * as t from "../../../types"; -export var metadata = { - readOnly: true -}; - -export function shouldVisit(node) { - return t.isModuleDeclaration(node) || (t.isCallExpression(node) && t.isIdentifier(node.callee, { name: "require" })); -} - // check if the input Literal `source` is an alternate casing of "react" function check(source, file) { if (t.isLiteral(source)) { diff --git a/src/babel/transformation/transformers/validation/undeclared-variable-check.js b/src/babel/transformation/transformers/validation/undeclared-variable-check.js index 01f1f4a86c..f8d3b25a78 100644 --- a/src/babel/transformation/transformers/validation/undeclared-variable-check.js +++ b/src/babel/transformation/transformers/validation/undeclared-variable-check.js @@ -2,8 +2,7 @@ import levenshtein from "leven"; import * as messages from "../../../messages"; export var metadata = { - optional: true, - readOnly: true + optional: true }; export function Identifier(node, parent, scope, file) { diff --git a/src/babel/traversal/index.js b/src/babel/traversal/index.js index 1f2ccccf12..80cb1f0c93 100644 --- a/src/babel/traversal/index.js +++ b/src/babel/traversal/index.js @@ -1,5 +1,5 @@ import TraversalContext from "./context"; -import { explode, verify } from "./visitors"; +import * as visitors from "./visitors"; import * as messages from "../messages"; import includes from "lodash/collection/includes"; import * as t from "../types"; @@ -14,7 +14,7 @@ export default function traverse(parent, opts, scope, state, parentPath) { } if (!opts) opts = {}; - verify(opts); + visitors.verify(opts); // array of nodes if (Array.isArray(parent)) { @@ -26,8 +26,9 @@ export default function traverse(parent, opts, scope, state, parentPath) { } } -traverse.verify = verify; -traverse.explode = explode; +traverse.visitors = visitors; +traverse.verify = visitors.verify; +traverse.explode = visitors.explode; traverse.node = function (node, opts, scope, state, parentPath) { var keys = t.VISITOR_KEYS[node.type]; diff --git a/src/babel/traversal/path/index.js b/src/babel/traversal/path/index.js index 14b801de53..23b971a900 100644 --- a/src/babel/traversal/path/index.js +++ b/src/babel/traversal/path/index.js @@ -107,12 +107,43 @@ export default class TraversalPath { return ancestry; } + /** + * Description + */ + + inType(types) { + if (!Array.isArray(types)) types = [types]; + + var path = this; + while (path) { + for (var type of (types: Array)) { + if (path.node.type === type) return true; + } + path = path.parentPath; + } + + return false; + } + + /** + * Description + */ + + findParent(callback) { + var path = this; + while (path) { + if (callback(path.node)) return path.node; + path = path.parentPath; + } + return null; + } + /** * Description */ queueNode(path) { - if (this.context) { + if (this.context && this.context.queue) { this.context.queue.push(path); } } @@ -136,7 +167,6 @@ export default class TraversalPath { } else if (this.isStatementOrBlock()) { if (this.node) nodes.push(this.node); this.container[this.key] = t.blockStatement(nodes); - this.checkSelf(); } 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?"); } @@ -163,8 +193,6 @@ export default class TraversalPath { paths.push(TraversalPath.get(this, null, node, this.container, to)); } } - - this.checkPaths(paths); } _containerInsertBefore(nodes) { @@ -234,7 +262,6 @@ export default class TraversalPath { } else if (this.isStatementOrBlock()) { if (this.node) nodes.unshift(this.node); this.container[this.key] = t.blockStatement(nodes); - this.checkSelf(); } 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?"); } @@ -528,7 +555,7 @@ export default class TraversalPath { } if (this.node === replacement) { - return this.checkSelf(); + return; } // normalise inserting an entire AST @@ -572,26 +599,6 @@ export default class TraversalPath { // potentially create new scope this.setScope(); - - this.checkSelf(); - } - - /** - * Description - */ - - checkSelf() { - this.checkPaths(this); - } - - /** - * Description - */ - - checkPaths(paths) { - var scope = this.scope; - var file = scope && scope.file; - if (file) file.checkPath(paths); } /** @@ -691,9 +698,13 @@ export default class TraversalPath { // call the function with the params (node, parent, scope, state) var replacement = fn.call(this, node, this.parent, this.scope, this.state); - if (replacement) this.replaceWith(replacement, true); + if (replacement) { + this.replaceWith(replacement, true); + this.queueNode(this); + break; + } - if (this.shouldStop) break; + if (this.shouldStop || this.removed) break; } } diff --git a/src/babel/traversal/visitors.js b/src/babel/traversal/visitors.js index 8e994c1ccb..f922351d1f 100644 --- a/src/babel/traversal/visitors.js +++ b/src/babel/traversal/visitors.js @@ -36,12 +36,12 @@ export function explode(visitor, mergeConflicts) { if (wrapper.type) { // merge the visitor if necessary or just put it back in if (visitor[wrapper.type]) { - merge(visitor[wrapper.type], fns); + mergePair(visitor[wrapper.type], fns); } else { visitor[wrapper.type] = fns; } } else { - merge(visitor, fns); + mergePair(visitor, fns); } } @@ -61,7 +61,7 @@ export function explode(visitor, mergeConflicts) { var existing = visitor[alias]; if (existing) { if (mergeConflicts) { - merge(existing, fns); + mergePair(existing, fns); } } else { visitor[alias] = fns; @@ -105,6 +105,19 @@ export function verify(visitor) { visitor._verified = true; } +export function merge(visitors) { + var rootVisitor = {}; + + for (var visitor of (visitors: Array)) { + for (var type in visitor) { + var nodeVisitor = rootVisitor[type] = rootVisitor[type] || {}; + mergePair(nodeVisitor, visitor[type]); + } + } + + return rootVisitor; +} + function ensureEntranceObjects(obj) { for (let key in obj) { if (shouldIgnoreKey(key)) continue; @@ -135,7 +148,7 @@ function addSelector(visitor, selector, fns) { }; } - merge(visitor, fns); + mergePair(visitor, fns); } function wrapCheck(wrapper, fn) { @@ -159,7 +172,7 @@ function shouldIgnoreKey(key) { return false; } -function merge(dest, src) { +function mergePair(dest, src) { for (var key in src) { dest[key] = (dest[key] || []).concat(src[key]); } diff --git a/test/core/fixtures/transformation/es6.arrow-functions/arguments/expected.js b/test/core/fixtures/transformation/es6.arrow-functions/arguments/expected.js index b8104fab4d..2972f6b9b1 100644 --- a/test/core/fixtures/transformation/es6.arrow-functions/arguments/expected.js +++ b/test/core/fixtures/transformation/es6.arrow-functions/arguments/expected.js @@ -11,17 +11,17 @@ function one() { one(1, 2); function two() { - var _arguments2 = arguments; + var _arguments3 = arguments; var inner = function inner() { - return _arguments2; + return _arguments3; }; var another = function another() { - var _arguments3 = arguments; + var _arguments2 = arguments; var inner2 = function inner2() { - return _arguments3; + return _arguments2; }; }; @@ -66,4 +66,4 @@ function six(obj) { }; return fn(); } -six(); \ No newline at end of file +six(); diff --git a/test/core/fixtures/transformation/spec.proto-to-assign/assignment-expression/expected.js b/test/core/fixtures/transformation/spec.proto-to-assign/assignment-expression/expected.js index 1a55265b4c..0980420528 100644 --- a/test/core/fixtures/transformation/spec.proto-to-assign/assignment-expression/expected.js +++ b/test/core/fixtures/transformation/spec.proto-to-assign/assignment-expression/expected.js @@ -1,11 +1,11 @@ "use strict"; -function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; } - var _foo, _foo$bar, _foo$bar2; +function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; } + console.log((_foo = foo, _defaults(_foo, bar), _foo)); console.log((_foo$bar = foo[bar], _defaults(_foo$bar, bar), _foo$bar)); -console.log((_foo$bar2 = foo[bar()], _defaults(_foo$bar2, bar), _foo$bar2)); \ No newline at end of file +console.log((_foo$bar2 = foo[bar()], _defaults(_foo$bar2, bar), _foo$bar2)); From 9ffc265beaa1ec17ac6ce972abf73ac50e190747 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 7 May 2015 16:01:00 +0100 Subject: [PATCH 02/30] don't requeue node unless the `type` has changed --- src/babel/traversal/path/index.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/babel/traversal/path/index.js b/src/babel/traversal/path/index.js index 23b971a900..408726f235 100644 --- a/src/babel/traversal/path/index.js +++ b/src/babel/traversal/path/index.js @@ -699,9 +699,12 @@ export default class TraversalPath { // call the function with the params (node, parent, scope, state) var replacement = fn.call(this, node, this.parent, this.scope, this.state); if (replacement) { + var previousType = this.type; this.replaceWith(replacement, true); - this.queueNode(this); - break; + if (this.type !== previousType) { + this.queueNode(this); + break; + } } if (this.shouldStop || this.removed) break; From f17b268a71d20751ee425fd08a0b33f63af67618 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 7 May 2015 16:23:33 +0100 Subject: [PATCH 03/30] do member expression and property literal conversion to computed on exit rather than on entrance --- .../es3/member-expression-literals.js | 16 +++++++++------- .../transformers/es3/property-literals.js | 14 ++++++++------ .../minification/member-expression-literals.js | 16 +++++++++------- .../minification/property-literals.js | 16 +++++++++------- 4 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/babel/transformation/transformers/es3/member-expression-literals.js b/src/babel/transformation/transformers/es3/member-expression-literals.js index 9b6b30bff7..1665d20b25 100644 --- a/src/babel/transformation/transformers/es3/member-expression-literals.js +++ b/src/babel/transformation/transformers/es3/member-expression-literals.js @@ -1,10 +1,12 @@ import * as t from "../../../types"; -export function MemberExpression(node) { - var prop = node.property; - if (!node.computed && t.isIdentifier(prop) && !t.isValidIdentifier(prop.name)) { - // foo.default -> foo["default"] - node.property = t.literal(prop.name); - node.computed = true; +export var MemberExpression = { + exit(node) { + var prop = node.property; + if (!node.computed && t.isIdentifier(prop) && !t.isValidIdentifier(prop.name)) { + // foo.default -> foo["default"] + node.property = t.literal(prop.name); + node.computed = true; + } } -} +}; diff --git a/src/babel/transformation/transformers/es3/property-literals.js b/src/babel/transformation/transformers/es3/property-literals.js index 0c9b26a9cd..f70a81661b 100644 --- a/src/babel/transformation/transformers/es3/property-literals.js +++ b/src/babel/transformation/transformers/es3/property-literals.js @@ -1,9 +1,11 @@ import * as t from "../../../types"; -export function Property(node) { - var key = node.key; - if (!node.computed && t.isIdentifier(key) && !t.isValidIdentifier(key.name)) { - // default: "bar" -> "default": "bar" - node.key = t.literal(key.name); +export var Property = { + exit(node) { + var key = node.key; + if (!node.computed && t.isIdentifier(key) && !t.isValidIdentifier(key.name)) { + // default: "bar" -> "default": "bar" + node.key = t.literal(key.name); + } } -} +}; diff --git a/src/babel/transformation/transformers/minification/member-expression-literals.js b/src/babel/transformation/transformers/minification/member-expression-literals.js index 2038c70d4b..fe8862dc8c 100644 --- a/src/babel/transformation/transformers/minification/member-expression-literals.js +++ b/src/babel/transformation/transformers/minification/member-expression-literals.js @@ -4,11 +4,13 @@ export var metadata = { optional: true }; -export function MemberExpression(node) { - var prop = node.property; - if (node.computed && t.isLiteral(prop) && t.isValidIdentifier(prop.value)) { - // foo["bar"] => foo.bar - node.property = t.identifier(prop.value); - node.computed = false; +export var MemberExpression = { + exit(node) { + var prop = node.property; + if (node.computed && t.isLiteral(prop) && t.isValidIdentifier(prop.value)) { + // foo["bar"] => foo.bar + node.property = t.identifier(prop.value); + node.computed = false; + } } -} +}; diff --git a/src/babel/transformation/transformers/minification/property-literals.js b/src/babel/transformation/transformers/minification/property-literals.js index 84902d2b94..c85769a4e8 100644 --- a/src/babel/transformation/transformers/minification/property-literals.js +++ b/src/babel/transformation/transformers/minification/property-literals.js @@ -4,11 +4,13 @@ export var metadata = { optional: true }; -export function Property(node) { - var key = node.key; - if (t.isLiteral(key) && t.isValidIdentifier(key.value)) { - // "foo": "bar" -> foo: "bar" - node.key = t.identifier(key.value); - node.computed = false; +export var Property = { + exit(node) { + var key = node.key; + if (t.isLiteral(key) && t.isValidIdentifier(key.value)) { + // "foo": "bar" -> foo: "bar" + node.key = t.identifier(key.value); + node.computed = false; + } } -} +}; From 0bbfd427af7037437afa4700b114bbc5c2e0ce4d Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 7 May 2015 16:23:47 +0100 Subject: [PATCH 04/30] do module formatter on program exit rather than entrance --- .../transformers/internal/module-formatter.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/babel/transformation/transformers/internal/module-formatter.js b/src/babel/transformation/transformers/internal/module-formatter.js index 400f27e28a..00cd641998 100644 --- a/src/babel/transformation/transformers/internal/module-formatter.js +++ b/src/babel/transformation/transformers/internal/module-formatter.js @@ -1,13 +1,15 @@ import * as strict from "../../helpers/strict"; -export function Program(program, parent, scope, file) { - strict.wrap(program, function () { - program.body = file.dynamicImports.concat(program.body); - }); +export var Program = { + exit(program, parent, scope, file) { + strict.wrap(program, function () { + program.body = file.dynamicImports.concat(program.body); + }); - if (!file.transformers["es6.modules"].canTransform()) return; + if (!file.transformers["es6.modules"].canTransform()) return; - if (file.moduleFormatter.transform) { - file.moduleFormatter.transform(program); + if (file.moduleFormatter.transform) { + file.moduleFormatter.transform(program); + } } -} +}; From a1bc0704abd2f5e1de89c09879037b5cc297641a Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 7 May 2015 20:11:02 +0100 Subject: [PATCH 05/30] attach auxiliary comment to function declaration helpers - fixes #1476 --- src/babel/transformation/file/index.js | 1 + test/core/api.js | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/src/babel/transformation/file/index.js b/src/babel/transformation/file/index.js index bb2d3697db..c31196bf09 100644 --- a/src/babel/transformation/file/index.js +++ b/src/babel/transformation/file/index.js @@ -364,6 +364,7 @@ export default class File { ref._generated = true; ref.id = uid; ref.type = "FunctionDeclaration"; + this.attachAuxiliaryComment(ref); this.path.unshiftContainer("body", ref); } else { ref._compact = true; diff --git a/test/core/api.js b/test/core/api.js index 2fb0330ff3..4464600e3e 100644 --- a/test/core/api.js +++ b/test/core/api.js @@ -18,6 +18,16 @@ suite("api", function () { assert.ok(!result.ast); }); + test("{ auxiliaryComment }", function () { + assert.ok(transform("class Foo {}", { + auxiliaryComment: "foobar" + }).code.indexOf("foobar") >= 0); + + assert.ok(transform("for (let i in bar) { foo(function () { i; }); break; continue; }", { + auxiliaryComment: "foobar" + }).code.indexOf("foobar") >= 0); + }); + suite("getModuleId() {} option", function () { // As of this commit, `getModuleId` is the only option that isn't JSON // compatible which is why it's not inside /test/core/fixtures/transformation From 23ac2319afabb7bf10a7a043dd339bad4685d02b Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 7 May 2015 20:11:14 +0100 Subject: [PATCH 06/30] add Super node type to ast-types patch --- src/babel/patch.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/babel/patch.js b/src/babel/patch.js index 09afdbd301..f8f5dcf95e 100644 --- a/src/babel/patch.js +++ b/src/babel/patch.js @@ -33,6 +33,9 @@ def("DoExpression") .build("body") .field("body", [def("Statement")]); +def("Super") + .bases("Expression"); + def("ExportDefaultDeclaration") .bases("Declaration") .build("declaration") From 380293d030327d4ad4c7cf18fb3b6d61e25d91d6 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 7 May 2015 21:35:12 +0100 Subject: [PATCH 07/30] add transformer dependencies - fixes #1477 --- src/babel/transformation/file/index.js | 16 +++++++++++++--- src/babel/transformation/transformer-pass.js | 9 +++++---- src/babel/transformation/transformer.js | 1 + .../transformers/es7/class-properties.js | 3 ++- .../transformers/es7/decorators.js | 1 + .../transformers/es7/object-rest-spread.js | 7 ++----- .../transformers/other/async-to-generator.js | 3 ++- .../transformers/other/bluebird-coroutines.js | 4 ++-- 8 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/babel/transformation/file/index.js b/src/babel/transformation/file/index.js index c31196bf09..e3757ac860 100644 --- a/src/babel/transformation/file/index.js +++ b/src/babel/transformation/file/index.js @@ -29,6 +29,8 @@ import * as t from "../../types"; export default class File { constructor(opts = {}, pipeline) { + this.transformerDependencies = {}; + this.dynamicImportTypes = {}; this.dynamicImportIds = {}; this.dynamicImports = []; @@ -221,13 +223,21 @@ export default class File { } stack = beforePlugins.concat(stack, afterPlugins); - // register - this.transformerStack = this.mergeStack(stack.concat(secondaryStack)); + // build transformer stack + stack = stack.concat(secondaryStack); + // build dependency graph + for (var pass of (stack: Array)) { + for (var dep of (pass.transformer.dependencies: Array)) { + this.transformerDependencies[dep] = pass.key; + } + } + // collapse stack categories + this.transformerStack = this.collapseStack(stack); } - mergeStack(_stack) { + collapseStack(_stack) { var stack = []; var ignore = []; diff --git a/src/babel/transformation/transformer-pass.js b/src/babel/transformation/transformer-pass.js index 715ba6de2e..62e91cd7ca 100644 --- a/src/babel/transformation/transformer-pass.js +++ b/src/babel/transformation/transformer-pass.js @@ -10,23 +10,24 @@ export default class TransformerPass { constructor(file: File, transformer: Transformer) { this.transformer = transformer; this.handlers = transformer.handlers; - this.skipKey = transformer.skipKey; this.file = file; this.ran = false; + this.key = transformer.key; } canTransform(): boolean { - return this.file.pipeline.canTransform(this.transformer, this.file.opts); + return this.file.transformerDependencies[this.key] || + this.file.pipeline.canTransform(this.transformer, this.file.opts); } transform() { var file = this.file; - file.log.debug(`Start transformer ${this.transformer.key}`); + file.log.debug(`Start transformer ${this.key}`); traverse(file.ast, this.handlers, file.scope, file); - file.log.debug(`Finish transformer ${this.transformer.key}`); + file.log.debug(`Finish transformer ${this.key}`); this.ran = true; } diff --git a/src/babel/transformation/transformer.js b/src/babel/transformation/transformer.js index a5fac03bf9..3f700974d9 100644 --- a/src/babel/transformation/transformer.js +++ b/src/babel/transformation/transformer.js @@ -26,6 +26,7 @@ export default class Transformer { this.manipulateOptions = take("manipulateOptions"); this.metadata = take("metadata") || {}; + this.dependencies = this.metadata.dependencies || []; this.parser = take("parser"); this.post = take("post"); this.pre = take("pre"); diff --git a/src/babel/transformation/transformers/es7/class-properties.js b/src/babel/transformation/transformers/es7/class-properties.js index 871398b386..ca95104fab 100644 --- a/src/babel/transformation/transformers/es7/class-properties.js +++ b/src/babel/transformation/transformers/es7/class-properties.js @@ -1,3 +1,4 @@ export var metadata = { - stage: 0 + stage: 0, + dependencies: ["es6.classes"] }; diff --git a/src/babel/transformation/transformers/es7/decorators.js b/src/babel/transformation/transformers/es7/decorators.js index af98294cf8..aaa54b0ee2 100644 --- a/src/babel/transformation/transformers/es7/decorators.js +++ b/src/babel/transformation/transformers/es7/decorators.js @@ -3,6 +3,7 @@ import * as defineMap from "../../helpers/define-map"; import * as t from "../../../types"; export var metadata = { + dependencies: ["es6.classes"], optional: true, stage: 1 }; diff --git a/src/babel/transformation/transformers/es7/object-rest-spread.js b/src/babel/transformation/transformers/es7/object-rest-spread.js index e6fe46b993..7b9f448f9c 100644 --- a/src/babel/transformation/transformers/es7/object-rest-spread.js +++ b/src/babel/transformation/transformers/es7/object-rest-spread.js @@ -3,13 +3,10 @@ import * as t from "../../../types"; export var metadata = { - stage: 1 + stage: 1, + dependencies: ["es6.destructuring"] }; -export function manipulateOptions(opts) { - if (opts.whitelist) opts.whitelist.push("es6.destructuring"); -} - var hasSpread = function (node) { for (var i = 0; i < node.properties.length; i++) { if (t.isSpreadProperty(node.properties[i])) { diff --git a/src/babel/transformation/transformers/other/async-to-generator.js b/src/babel/transformation/transformers/other/async-to-generator.js index 7789fd2506..b5a54b478d 100644 --- a/src/babel/transformation/transformers/other/async-to-generator.js +++ b/src/babel/transformation/transformers/other/async-to-generator.js @@ -3,7 +3,8 @@ import remapAsyncToGenerator from "../../helpers/remap-async-to-generator"; export { manipulateOptions } from "./bluebird-coroutines"; export var metadata = { - optional: true + optional: true, + dependencies: ["es7.asyncFunctions", "es6.classes"] }; exports.Function = function (node, parent, scope, file) { diff --git a/src/babel/transformation/transformers/other/bluebird-coroutines.js b/src/babel/transformation/transformers/other/bluebird-coroutines.js index cb4f99e09a..2d1c467edd 100644 --- a/src/babel/transformation/transformers/other/bluebird-coroutines.js +++ b/src/babel/transformation/transformers/other/bluebird-coroutines.js @@ -2,12 +2,12 @@ import remapAsyncToGenerator from "../../helpers/remap-async-to-generator"; import * as t from "../../../types"; export function manipulateOptions(opts) { - opts.optional.push("es7.asyncFunctions"); opts.blacklist.push("regenerator"); } export var metadata = { - optional: true + optional: true, + dependencies: ["es7.asyncFunctions", "es6.classes"] }; exports.Function = function (node, parent, scope, file) { From 13a6c696681de0eac6eb1945f41907aceb94887c Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Thu, 7 May 2015 23:02:40 +0100 Subject: [PATCH 08/30] add node existence check to each visitor call --- src/babel/traversal/path/index.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/babel/traversal/path/index.js b/src/babel/traversal/path/index.js index 408726f235..6ac9cc1819 100644 --- a/src/babel/traversal/path/index.js +++ b/src/babel/traversal/path/index.js @@ -696,6 +696,9 @@ export default class TraversalPath { for (var fn of (fns: Array)) { if (!fn) continue; + var node = this.node; + if (!node) return; + // call the function with the params (node, parent, scope, state) var replacement = fn.call(this, node, this.parent, this.scope, this.state); if (replacement) { @@ -703,11 +706,11 @@ export default class TraversalPath { this.replaceWith(replacement, true); if (this.type !== previousType) { this.queueNode(this); - break; + return; } } - if (this.shouldStop || this.removed) break; + if (this.shouldStop || this.removed) return; } } From 6e8ab16b25e96486b9f41f9e7965ae1927ee1807 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 00:22:23 +0100 Subject: [PATCH 09/30] run es6.spec.blockScoping transformer on exit rather than enter --- .../transformers/es6/spec.block-scoping.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/babel/transformation/transformers/es6/spec.block-scoping.js b/src/babel/transformation/transformers/es6/spec.block-scoping.js index 43699b2b1b..0ca41863a9 100644 --- a/src/babel/transformation/transformers/es6/spec.block-scoping.js +++ b/src/babel/transformation/transformers/es6/spec.block-scoping.js @@ -31,14 +31,16 @@ export var metadata = { optional: true }; -export function BlockStatement(node, parent, scope, file) { - var letRefs = node._letReferences; - if (!letRefs) return; +export var BlockStatement = { + exit(node, parent, scope, file) { + var letRefs = node._letReferences; + if (!letRefs) return; - this.traverse(visitor, { - letRefs: letRefs, - file: file - }); -} + this.traverse(visitor, { + letRefs: letRefs, + file: file + }); + } +}; export { BlockStatement as Program, BlockStatement as Loop }; From 8daf95bf5911f52ddeefeac3176741ab8b4b424c Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 00:22:43 +0100 Subject: [PATCH 10/30] name additional methods that are now covered since the naming is done in tandem --- src/babel/transformation/transformers/spec/function-name.js | 5 ++++- .../es7.decorators/class-getter-and-setter/expected.js | 6 +++--- .../transformation/es7.decorators/class-getter/expected.js | 4 ++-- .../es7.decorators/class-init-instance-props/expected.js | 4 ++-- .../es7.decorators/class-init-static-props/expected.js | 4 ++-- .../transformation/es7.decorators/class-setter/expected.js | 4 ++-- .../transformation/es7.decorators/object/expected.js | 2 +- 7 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/babel/transformation/transformers/spec/function-name.js b/src/babel/transformation/transformers/spec/function-name.js index bf31ee407a..928036e0be 100644 --- a/src/babel/transformation/transformers/spec/function-name.js +++ b/src/babel/transformation/transformers/spec/function-name.js @@ -1 +1,4 @@ -export { bare as FunctionExpression, bare as ArrowFunctionExpression } from "../../helpers/name-method"; +export { + bare as FunctionExpression, + bare as ArrowFunctionExpression +} from "../../helpers/name-method"; diff --git a/test/core/fixtures/transformation/es7.decorators/class-getter-and-setter/expected.js b/test/core/fixtures/transformation/es7.decorators/class-getter-and-setter/expected.js index 73f0d1d146..8e9b70a100 100644 --- a/test/core/fixtures/transformation/es7.decorators/class-getter-and-setter/expected.js +++ b/test/core/fixtures/transformation/es7.decorators/class-getter-and-setter/expected.js @@ -8,8 +8,8 @@ var Foo = (function () { babelHelpers.createDecoratedClass(Foo, [{ key: "foo", decorators: [bar, foo], - get: function () {}, - set: function (bar) {} + get: function get() {}, + set: function set(bar) {} }]); return Foo; -})(); \ No newline at end of file +})(); diff --git a/test/core/fixtures/transformation/es7.decorators/class-getter/expected.js b/test/core/fixtures/transformation/es7.decorators/class-getter/expected.js index 3beba2e582..06b1d2294e 100644 --- a/test/core/fixtures/transformation/es7.decorators/class-getter/expected.js +++ b/test/core/fixtures/transformation/es7.decorators/class-getter/expected.js @@ -8,7 +8,7 @@ var Foo = (function () { babelHelpers.createDecoratedClass(Foo, [{ key: "foo", decorators: [bar], - get: function () {} + get: function get() {} }]); return Foo; -})(); \ No newline at end of file +})(); diff --git a/test/core/fixtures/transformation/es7.decorators/class-init-instance-props/expected.js b/test/core/fixtures/transformation/es7.decorators/class-init-instance-props/expected.js index 6753403675..e564a5f47e 100644 --- a/test/core/fixtures/transformation/es7.decorators/class-init-instance-props/expected.js +++ b/test/core/fixtures/transformation/es7.decorators/class-init-instance-props/expected.js @@ -11,10 +11,10 @@ var Foo = (function () { babelHelpers.createDecoratedClass(Foo, [{ key: "foo", decorators: [bar], - initializer: function () { + initializer: function initializer() { return "Bar"; }, enumerable: true }], null, _instanceInitializers); return Foo; -})(); \ No newline at end of file +})(); diff --git a/test/core/fixtures/transformation/es7.decorators/class-init-static-props/expected.js b/test/core/fixtures/transformation/es7.decorators/class-init-static-props/expected.js index c365832ed7..8bdff77924 100644 --- a/test/core/fixtures/transformation/es7.decorators/class-init-static-props/expected.js +++ b/test/core/fixtures/transformation/es7.decorators/class-init-static-props/expected.js @@ -10,11 +10,11 @@ var Foo = (function () { babelHelpers.createDecoratedClass(Foo, null, [{ key: "foo", decorators: [bar], - initializer: function () { + initializer: function initializer() { return "Bar"; }, enumerable: true }], null, _staticInitializers); babelHelpers.defineDecoratedPropertyDescriptor(Foo, "foo", _staticInitializers); return Foo; -})(); \ No newline at end of file +})(); diff --git a/test/core/fixtures/transformation/es7.decorators/class-setter/expected.js b/test/core/fixtures/transformation/es7.decorators/class-setter/expected.js index ece61ab6e1..57426dd80c 100644 --- a/test/core/fixtures/transformation/es7.decorators/class-setter/expected.js +++ b/test/core/fixtures/transformation/es7.decorators/class-setter/expected.js @@ -8,7 +8,7 @@ var Foo = (function () { babelHelpers.createDecoratedClass(Foo, [{ key: "foo", decorators: [bar], - set: function (arg) {} + set: function set(arg) {} }]); return Foo; -})(); \ No newline at end of file +})(); diff --git a/test/core/fixtures/transformation/es7.decorators/object/expected.js b/test/core/fixtures/transformation/es7.decorators/object/expected.js index b6259d0cdc..efe805cf25 100644 --- a/test/core/fixtures/transformation/es7.decorators/object/expected.js +++ b/test/core/fixtures/transformation/es7.decorators/object/expected.js @@ -17,4 +17,4 @@ var obj = babelHelpers.createDecoratedObject([{ initializer: function initializer() { return "wow"; } -}]); \ No newline at end of file +}]); From 2621081a13ad7720e8c28a9dc8aa3a4b1086748a Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 00:23:00 +0100 Subject: [PATCH 11/30] merge in astVisitor in runtime transformer - unsure why this was separate in the first place --- .../transformers/other/runtime/index.js | 176 +++++++++--------- 1 file changed, 85 insertions(+), 91 deletions(-) diff --git a/src/babel/transformation/transformers/other/runtime/index.js b/src/babel/transformation/transformers/other/runtime/index.js index 972701e099..dbb3632d56 100644 --- a/src/babel/transformation/transformers/other/runtime/index.js +++ b/src/babel/transformation/transformers/other/runtime/index.js @@ -9,98 +9,11 @@ var isSymbolIterator = t.buildMatchMemberExpression("Symbol.iterator"); const RUNTIME_MODULE_NAME = "babel-runtime"; -var astVisitor = traverse.explode({ - Identifier(node, parent, scope, file) { - if (!this.isReferenced()) return; - if (t.isMemberExpression(parent)) return; - if (!has(definitions.builtins, node.name)) return; - if (scope.getBindingIdentifier(node.name)) return; - - // Symbol() -> _core.Symbol(); new Promise -> new _core.Promise - var modulePath = definitions.builtins[node.name]; - return file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, node.name, "absoluteDefault"); - }, - - CallExpression(node, parent, scope, file) { - // arr[Symbol.iterator]() -> _core.$for.getIterator(arr) - - var callee = node.callee; - if (node.arguments.length) return; - - if (!t.isMemberExpression(callee)) return; - if (!callee.computed) return; - - var prop = callee.property; - if (!isSymbolIterator(prop)) return; - - return t.callExpression(file.addImport(`${RUNTIME_MODULE_NAME}/core-js/get-iterator`, "getIterator", "absoluteDefault"), [callee.object]); - }, - - BinaryExpression(node, parent, scope, file) { - // Symbol.iterator in arr -> core.$for.isIterable(arr) - - if (node.operator !== "in") return; - - var left = node.left; - if (!isSymbolIterator(left)) return; - - return t.callExpression( - file.addImport(`${RUNTIME_MODULE_NAME}/core-js/is-iterable`, "isIterable", "absoluteDefault"), - [node.right] - ); - }, - - MemberExpression: { - enter(node, parent, scope, file) { - // Array.from -> _core.Array.from - - if (!this.isReferenced()) return; - - var obj = node.object; - var prop = node.property; - - if (!t.isReferenced(obj, node)) return; - - if (node.computed) return; - - if (!has(definitions.methods, obj.name)) return; - - var methods = definitions.methods[obj.name]; - if (!has(methods, prop.name)) return; - - if (scope.getBindingIdentifier(obj.name)) return; - - var modulePath = methods[prop.name]; - return file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, `${obj.name}$${prop.name}`, "absoluteDefault"); - }, - - exit(node, parent, scope, file) { - if (!this.isReferenced()) return; - - var prop = node.property; - var obj = node.object; - - if (!has(definitions.builtins, obj.name)) return; - if (scope.getBindingIdentifier(obj.name)) return; - - var modulePath = definitions.builtins[obj.name]; - return t.memberExpression( - file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, `${obj.name}`, "absoluteDefault"), - prop - ); - } - } -}); - -exports.metadata = { +export var metadata = { optional: true }; -exports.Program = function (node, parent, scope, file) { - this.traverse(astVisitor, file); -}; - -exports.pre = function (file) { +export function pre(file) { file.set("helperGenerator", function (name) { return file.addImport(`${RUNTIME_MODULE_NAME}/helpers/${name}`, name, "absoluteDefault"); }); @@ -108,10 +21,91 @@ exports.pre = function (file) { file.setDynamic("regeneratorIdentifier", function () { return file.addImport(`${RUNTIME_MODULE_NAME}/regenerator`, "regeneratorRuntime", "absoluteDefault"); }); +} + +export function Identifier(node, parent, scope, file) { + if (!this.isReferenced()) return; + if (t.isMemberExpression(parent)) return; + if (!has(definitions.builtins, node.name)) return; + if (scope.getBindingIdentifier(node.name)) return; + + // Symbol() -> _core.Symbol(); new Promise -> new _core.Promise + var modulePath = definitions.builtins[node.name]; + return file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, node.name, "absoluteDefault"); +} + +export function CallExpression(node, parent, scope, file) { + // arr[Symbol.iterator]() -> _core.$for.getIterator(arr) + + var callee = node.callee; + if (node.arguments.length) return; + + if (!t.isMemberExpression(callee)) return; + if (!callee.computed) return; + + var prop = callee.property; + if (!isSymbolIterator(prop)) return; + + return t.callExpression(file.addImport(`${RUNTIME_MODULE_NAME}/core-js/get-iterator`, "getIterator", "absoluteDefault"), [callee.object]); +} + +export function BinaryExpression(node, parent, scope, file) { + // Symbol.iterator in arr -> core.$for.isIterable(arr) + + if (node.operator !== "in") return; + + var left = node.left; + if (!isSymbolIterator(left)) return; + + return t.callExpression( + file.addImport(`${RUNTIME_MODULE_NAME}/core-js/is-iterable`, "isIterable", "absoluteDefault"), + [node.right] + ); +} + +export var MemberExpression = { + enter(node, parent, scope, file) { + // Array.from -> _core.Array.from + + if (!this.isReferenced()) return; + + var obj = node.object; + var prop = node.property; + + if (!t.isReferenced(obj, node)) return; + + if (node.computed) return; + + if (!has(definitions.methods, obj.name)) return; + + var methods = definitions.methods[obj.name]; + if (!has(methods, prop.name)) return; + + if (scope.getBindingIdentifier(obj.name)) return; + + var modulePath = methods[prop.name]; + return file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, `${obj.name}$${prop.name}`, "absoluteDefault"); + }, + + exit(node, parent, scope, file) { + if (!this.isReferenced()) return; + + var prop = node.property; + var obj = node.object; + + if (!has(definitions.builtins, obj.name)) return; + if (scope.getBindingIdentifier(obj.name)) return; + + var modulePath = definitions.builtins[obj.name]; + return t.memberExpression( + file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, `${obj.name}`, "absoluteDefault"), + prop + ); + } }; -exports.Identifier = function (node, parent, scope, file) { +export function Identifier(node, parent, scope, file) { if (this.isReferencedIdentifier({ name: "regeneratorRuntime" })) { return file.get("regeneratorIdentifier"); } -}; +} From 2fbb3cad9f67a5bb5e9f9f768d69cd10141c0035 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 00:23:28 +0100 Subject: [PATCH 12/30] add isUser and isGenerated path methods --- src/babel/traversal/path/index.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/babel/traversal/path/index.js b/src/babel/traversal/path/index.js index 6ac9cc1819..68735963d8 100644 --- a/src/babel/traversal/path/index.js +++ b/src/babel/traversal/path/index.js @@ -125,6 +125,22 @@ export default class TraversalPath { return false; } + /** + * Check whether this node was a part of the original AST. + */ + + isUser() { + return this.node && !!this.node.loc; + } + + /** + * Check whether this node was generated by us and not a part of the original AST. + */ + + isGenerated() { + return !this.isUser(); + } + /** * Description */ From 78b72512cbbf620f58de318f44c1da853ab3bafa Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 00:24:04 +0100 Subject: [PATCH 13/30] better verify the type of the new node before requeueing it and also stop current node traversal on skip --- src/babel/traversal/path/index.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/babel/traversal/path/index.js b/src/babel/traversal/path/index.js index 68735963d8..1988f661ff 100644 --- a/src/babel/traversal/path/index.js +++ b/src/babel/traversal/path/index.js @@ -717,16 +717,19 @@ export default class TraversalPath { // call the function with the params (node, parent, scope, state) var replacement = fn.call(this, node, this.parent, this.scope, this.state); + if (replacement) { var previousType = this.type; + this.replaceWith(replacement, true); - if (this.type !== previousType) { + + if (previousType !== this.type) { this.queueNode(this); return; } } - if (this.shouldStop || this.removed) return; + if (this.shouldStop || this.shouldSkip || this.removed) return; } } From 5b793f88824f23285f360657836184adb3a52f69 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 15:25:34 +0100 Subject: [PATCH 14/30] fix TraversalPath#_getPattern incorrectly iterating over the parts --- src/babel/traversal/path/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/babel/traversal/path/index.js b/src/babel/traversal/path/index.js index 1988f661ff..1cbe84ce59 100644 --- a/src/babel/traversal/path/index.js +++ b/src/babel/traversal/path/index.js @@ -820,8 +820,7 @@ export default class TraversalPath { _getPattern(parts) { var path = this; - for (var i = 0; i > parts.length; i++) { - var part = parts[i]; + for (var part of (parts: Array)) { if (part === ".") { path = path.parentPath; } else { From 8f52229a868d278c930f5336e6be6373d9f3fa01 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 15:25:50 +0100 Subject: [PATCH 15/30] add get function name to source map classes test --- test/core/fixtures/transformation/source-maps/class/expected.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/fixtures/transformation/source-maps/class/expected.js b/test/core/fixtures/transformation/source-maps/class/expected.js index 25517b3e99..c9b2c12183 100644 --- a/test/core/fixtures/transformation/source-maps/class/expected.js +++ b/test/core/fixtures/transformation/source-maps/class/expected.js @@ -7,7 +7,7 @@ var Test = (function () { babelHelpers.createClass(Test, [{ key: "bar", - get: function () { + get: function get() { throw new Error("wow"); } }]); From ba516901aff678563a0c39a29a944af46956788b Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 15:26:00 +0100 Subject: [PATCH 16/30] restructure transformers into multiple categories --- src/babel/transformation/index.js | 2 +- .../es3/member-expression-literals.js | 4 +++ .../transformers/es3/property-literals.js | 4 +++ .../transformers/es6/block-scoping.js | 4 +++ .../transformers/es6/modules.js | 4 +++ .../transformers/es6/spec.block-scoping.js | 3 +- .../transformation/transformers/index.js | 25 +++++++++++------ .../transformers/internal/block-hoist.js | 4 +++ .../transformers/internal/module-formatter.js | 4 +++ .../member-expression-literals.js | 3 +- .../minification/property-literals.js | 3 +- .../transformation/transformers/other/flow.js | 1 - .../transformers/other/regenerator.js | 4 +++ .../transformers/other/runtime/index.js | 28 ++++++++----------- 14 files changed, 62 insertions(+), 31 deletions(-) diff --git a/src/babel/transformation/index.js b/src/babel/transformation/index.js index 3f71068bc2..5a523a4ea2 100644 --- a/src/babel/transformation/index.js +++ b/src/babel/transformation/index.js @@ -9,7 +9,7 @@ import transformers from "./transformers"; for (var key in transformers) { var transformer = transformers[key]; var metadata = transformer.metadata = transformer.metadata || {}; - metadata.category = metadata.category || "builtin"; + metadata.category = metadata.category || "builtin-basic"; } pipeline.addTransformers(transformers); diff --git a/src/babel/transformation/transformers/es3/member-expression-literals.js b/src/babel/transformation/transformers/es3/member-expression-literals.js index 1665d20b25..d4465fde70 100644 --- a/src/babel/transformation/transformers/es3/member-expression-literals.js +++ b/src/babel/transformation/transformers/es3/member-expression-literals.js @@ -1,5 +1,9 @@ import * as t from "../../../types"; +export var metadata = { + category: "builtin-cleanup" +}; + export var MemberExpression = { exit(node) { var prop = node.property; diff --git a/src/babel/transformation/transformers/es3/property-literals.js b/src/babel/transformation/transformers/es3/property-literals.js index f70a81661b..ecfd63c8dd 100644 --- a/src/babel/transformation/transformers/es3/property-literals.js +++ b/src/babel/transformation/transformers/es3/property-literals.js @@ -1,5 +1,9 @@ import * as t from "../../../types"; +export var metadata = { + category: "builtin-cleanup" +}; + export var Property = { exit(node) { var key = node.key; diff --git a/src/babel/transformation/transformers/es6/block-scoping.js b/src/babel/transformation/transformers/es6/block-scoping.js index 850dca35f0..515c0711e9 100644 --- a/src/babel/transformation/transformers/es6/block-scoping.js +++ b/src/babel/transformation/transformers/es6/block-scoping.js @@ -37,6 +37,10 @@ function standardizeLets(declars) { } } +export var metadata = { + category: "builtin-advanced" +}; + export function VariableDeclaration(node, parent, scope, file) { if (!isLet(node, parent)) return; diff --git a/src/babel/transformation/transformers/es6/modules.js b/src/babel/transformation/transformers/es6/modules.js index 6141ab9217..80772e3163 100644 --- a/src/babel/transformation/transformers/es6/modules.js +++ b/src/babel/transformation/transformers/es6/modules.js @@ -8,6 +8,10 @@ function keepBlockHoist(node, nodes) { } } +export var metadata = { + category: "builtin-modules" +}; + export function ImportDeclaration(node, parent, scope, file) { // flow type if (node.isType) return; diff --git a/src/babel/transformation/transformers/es6/spec.block-scoping.js b/src/babel/transformation/transformers/es6/spec.block-scoping.js index 0ca41863a9..6906b1d7c1 100644 --- a/src/babel/transformation/transformers/es6/spec.block-scoping.js +++ b/src/babel/transformation/transformers/es6/spec.block-scoping.js @@ -28,7 +28,8 @@ var visitor = traverse.explode({ }); export var metadata = { - optional: true + optional: true, + category: "builtin-advanced" }; export var BlockStatement = { diff --git a/src/babel/transformation/transformers/index.js b/src/babel/transformation/transformers/index.js index 0c3ea89b1d..a4e0317b84 100644 --- a/src/babel/transformation/transformers/index.js +++ b/src/babel/transformation/transformers/index.js @@ -1,4 +1,5 @@ export default { + // builtin-basic "utility.removeDebugger": require("./utility/remove-debugger"), "utility.removeConsole": require("./utility/remove-console"), "utility.inlineEnvironmentVariables": require("./utility/inline-environment-variables"), @@ -41,26 +42,32 @@ export default { "es6.spread": require("./es6/spread"), "es6.parameters.default": require("./es6/parameters.default"), "es6.destructuring": require("./es6/destructuring"), - "es6.blockScoping": require("./es6/block-scoping"), - "es6.spec.blockScoping": require("./es6/spec.block-scoping"), "es6.tailCall": require("./es6/tail-call"), - regenerator: require("./other/regenerator"), - runtime: require("./other/runtime"), "es7.exportExtensions": require("./es7/export-extensions"), - "es6.modules": require("./es6/modules"), "spec.protoToAssign": require("./spec/proto-to-assign"), _shadowFunctions: require("./internal/shadow-functions"), "es7.doExpressions": require("./es7/do-expressions"), "es6.spec.symbols": require("./es6/spec.symbols"), ludicrous: require("./other/ludicrous"), "spec.undefinedToVoid": require("./spec/undefined-to-void"), + jscript: require("./other/jscript"), + flow: require("./other/flow"), + _hoistDirectives: require("./internal/hoist-directives"), + + // builtin-modules + "es6.modules": require("./es6/modules"), + regenerator: require("./other/regenerator"), + runtime: require("./other/runtime"), _moduleFormatter: require("./internal/module-formatter"), + + // builtin-advanced + "es6.blockScoping": require("./es6/block-scoping"), + "es6.spec.blockScoping": require("./es6/spec.block-scoping"), + + // builtin-cleanup "es3.propertyLiterals": require("./es3/property-literals"), "es3.memberExpressionLiterals": require("./es3/member-expression-literals"), "minification.memberExpressionLiterals": require("./minification/member-expression-literals"), "minification.propertyLiterals": require("./minification/property-literals"), - jscript: require("./other/jscript"), - flow: require("./other/flow"), - _hoistDirectives: require("./internal/hoist-directives"), - _blockHoist: require("./internal/block-hoist") + _blockHoist: require("./internal/block-hoist"), }; diff --git a/src/babel/transformation/transformers/internal/block-hoist.js b/src/babel/transformation/transformers/internal/block-hoist.js index b732e2b2f3..700d91b2a9 100644 --- a/src/babel/transformation/transformers/internal/block-hoist.js +++ b/src/babel/transformation/transformers/internal/block-hoist.js @@ -1,5 +1,9 @@ import sortBy from "lodash/collection/sortBy"; +export var metadata = { + category: "builtin-cleanup" +}; + // Priority: // // - 0 We want this to be at the **very** bottom diff --git a/src/babel/transformation/transformers/internal/module-formatter.js b/src/babel/transformation/transformers/internal/module-formatter.js index 00cd641998..da48d94c6d 100644 --- a/src/babel/transformation/transformers/internal/module-formatter.js +++ b/src/babel/transformation/transformers/internal/module-formatter.js @@ -1,5 +1,9 @@ import * as strict from "../../helpers/strict"; +export var metadata = { + category: "builtin-modules" +}; + export var Program = { exit(program, parent, scope, file) { strict.wrap(program, function () { diff --git a/src/babel/transformation/transformers/minification/member-expression-literals.js b/src/babel/transformation/transformers/minification/member-expression-literals.js index fe8862dc8c..a7d9823535 100644 --- a/src/babel/transformation/transformers/minification/member-expression-literals.js +++ b/src/babel/transformation/transformers/minification/member-expression-literals.js @@ -1,7 +1,8 @@ import * as t from "../../../types"; export var metadata = { - optional: true + optional: true, + category: "builtin-cleanup" }; export var MemberExpression = { diff --git a/src/babel/transformation/transformers/minification/property-literals.js b/src/babel/transformation/transformers/minification/property-literals.js index c85769a4e8..d1d682fbdb 100644 --- a/src/babel/transformation/transformers/minification/property-literals.js +++ b/src/babel/transformation/transformers/minification/property-literals.js @@ -1,7 +1,8 @@ import * as t from "../../../types"; export var metadata = { - optional: true + optional: true, + category: "builtin-cleanup" }; export var Property = { diff --git a/src/babel/transformation/transformers/other/flow.js b/src/babel/transformation/transformers/other/flow.js index bb6bf4c393..14fc5bcbc4 100644 --- a/src/babel/transformation/transformers/other/flow.js +++ b/src/babel/transformation/transformers/other/flow.js @@ -6,7 +6,6 @@ export function Flow(node) { export function ClassProperty(node) { node.typeAnnotation = null; - if (!node.value) this.remove(); } export function Class(node) { diff --git a/src/babel/transformation/transformers/other/regenerator.js b/src/babel/transformation/transformers/other/regenerator.js index 2897527cd1..9d1b17e675 100644 --- a/src/babel/transformation/transformers/other/regenerator.js +++ b/src/babel/transformation/transformers/other/regenerator.js @@ -1,6 +1,10 @@ import regenerator from "regenerator"; import * as t from "../../../types"; +export var metadata = { + category: "builtin-modules" +}; + export var Program = { exit(ast) { regenerator.transform(ast); diff --git a/src/babel/transformation/transformers/other/runtime/index.js b/src/babel/transformation/transformers/other/runtime/index.js index dbb3632d56..3fa283268d 100644 --- a/src/babel/transformation/transformers/other/runtime/index.js +++ b/src/babel/transformation/transformers/other/runtime/index.js @@ -10,10 +10,11 @@ var isSymbolIterator = t.buildMatchMemberExpression("Symbol.iterator"); const RUNTIME_MODULE_NAME = "babel-runtime"; export var metadata = { - optional: true + optional: true, + category: "builtin-modules" }; -export function pre(file) { +export function Program(node, parent, scope, file) { file.set("helperGenerator", function (name) { return file.addImport(`${RUNTIME_MODULE_NAME}/helpers/${name}`, name, "absoluteDefault"); }); @@ -23,8 +24,11 @@ export function pre(file) { }); } -export function Identifier(node, parent, scope, file) { - if (!this.isReferenced()) return; +export function ReferencedIdentifier(node, parent, scope, file) { + if (node.name === "regeneratorRuntime") { + return file.get("regeneratorIdentifier"); + } + if (t.isMemberExpression(parent)) return; if (!has(definitions.builtins, node.name)) return; if (scope.getBindingIdentifier(node.name)) return; @@ -37,14 +41,12 @@ export function Identifier(node, parent, scope, file) { export function CallExpression(node, parent, scope, file) { // arr[Symbol.iterator]() -> _core.$for.getIterator(arr) - var callee = node.callee; if (node.arguments.length) return; + var callee = node.callee; if (!t.isMemberExpression(callee)) return; if (!callee.computed) return; - - var prop = callee.property; - if (!isSymbolIterator(prop)) return; + if (!this.get("callee.property").matchesPattern("Symbol.iterator")) return; return t.callExpression(file.addImport(`${RUNTIME_MODULE_NAME}/core-js/get-iterator`, "getIterator", "absoluteDefault"), [callee.object]); } @@ -53,9 +55,7 @@ export function BinaryExpression(node, parent, scope, file) { // Symbol.iterator in arr -> core.$for.isIterable(arr) if (node.operator !== "in") return; - - var left = node.left; - if (!isSymbolIterator(left)) return; + if (!this.get("left").matchesPattern("Symbol.iterator")) return; return t.callExpression( file.addImport(`${RUNTIME_MODULE_NAME}/core-js/is-iterable`, "isIterable", "absoluteDefault"), @@ -103,9 +103,3 @@ export var MemberExpression = { ); } }; - -export function Identifier(node, parent, scope, file) { - if (this.isReferencedIdentifier({ name: "regeneratorRuntime" })) { - return file.get("regeneratorIdentifier"); - } -} From c526a3eb0424e9b24479ca2e2d8237d28512a53c Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 15:51:56 +0100 Subject: [PATCH 17/30] move shadow-functions internal transformer to builtin-cleanup category --- .../transformation/transformers/internal/shadow-functions.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/babel/transformation/transformers/internal/shadow-functions.js b/src/babel/transformation/transformers/internal/shadow-functions.js index 30925d8a8f..decec95409 100644 --- a/src/babel/transformation/transformers/internal/shadow-functions.js +++ b/src/babel/transformation/transformers/internal/shadow-functions.js @@ -85,6 +85,10 @@ function aliasFunction(getBody, path, scope) { // todo: on all `this` and `arguments`, walk UP the tree instead of // crawling the entire function tree +export var metadata = { + category: "builtin-cleanup" +}; + export var Program = { exit(node, parent, scope) { aliasFunction(function () { From 4a439d8c8e04cc4d8ef78d568abc754868e7958d Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 15:52:08 +0100 Subject: [PATCH 18/30] update flow strip type annotations test --- .../flow/strip-type-annotations/expected.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/core/fixtures/transformation/flow/strip-type-annotations/expected.js b/test/core/fixtures/transformation/flow/strip-type-annotations/expected.js index 6a52c762fc..277f1ad2f0 100644 --- a/test/core/fixtures/transformation/flow/strip-type-annotations/expected.js +++ b/test/core/fixtures/transformation/flow/strip-type-annotations/expected.js @@ -64,8 +64,14 @@ class Foo8 { "bar"() {} } function foo(requiredParam, optParam) {} -class Foo9 {} -class Foo10 {} +class Foo9 { + prop1; + prop2; +} +class Foo10 { + static prop1; + prop2; +} var x = 4; class Array { concat(items) {} From abf4a5495a08938f5d2feffbcf0f3dd17b4112c0 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 22:51:47 +0100 Subject: [PATCH 19/30] don't pretty print variable declarators in concise mode --- src/babel/generation/generators/statements.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/babel/generation/generators/statements.js b/src/babel/generation/generators/statements.js index 5a9b0067d6..81ba6f2c83 100644 --- a/src/babel/generation/generators/statements.js +++ b/src/babel/generation/generators/statements.js @@ -191,7 +191,7 @@ export function VariableDeclaration(node, print, parent) { } var sep = ","; - if (!this.format.compact && hasInits && !this.format.retainLines) { + if (!this.format.compact && !this.format.concise && hasInits && !this.format.retainLines) { sep += `\n${repeating(" ", node.kind.length + 1)}`; } else { sep += " "; From 2a9a59f7842402e7308d9ba74bdb83eab5e4d476 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 22:52:02 +0100 Subject: [PATCH 20/30] remove incomplete ludicrous transformer --- .../templates/helper-ludicrous-in.js | 1 - .../helper-ludicrous-proxy-create.js | 4 -- .../helper-ludicrous-proxy-directory.js | 1 - .../transformers/other/ludicrous.js | 66 ------------------- 4 files changed, 72 deletions(-) delete mode 100644 src/babel/transformation/templates/helper-ludicrous-in.js delete mode 100644 src/babel/transformation/templates/helper-ludicrous-proxy-create.js delete mode 100644 src/babel/transformation/templates/helper-ludicrous-proxy-directory.js delete mode 100644 src/babel/transformation/transformers/other/ludicrous.js diff --git a/src/babel/transformation/templates/helper-ludicrous-in.js b/src/babel/transformation/templates/helper-ludicrous-in.js deleted file mode 100644 index 80348f0da7..0000000000 --- a/src/babel/transformation/templates/helper-ludicrous-in.js +++ /dev/null @@ -1 +0,0 @@ -Object(RIGHT)[LEFT] !== undefined; diff --git a/src/babel/transformation/templates/helper-ludicrous-proxy-create.js b/src/babel/transformation/templates/helper-ludicrous-proxy-create.js deleted file mode 100644 index 8ecc6af771..0000000000 --- a/src/babel/transformation/templates/helper-ludicrous-proxy-create.js +++ /dev/null @@ -1,4 +0,0 @@ -(function (proxy, directory) { - directory.push(proxy); - return proxy; -}) diff --git a/src/babel/transformation/templates/helper-ludicrous-proxy-directory.js b/src/babel/transformation/templates/helper-ludicrous-proxy-directory.js deleted file mode 100644 index 5e1ab7855e..0000000000 --- a/src/babel/transformation/templates/helper-ludicrous-proxy-directory.js +++ /dev/null @@ -1 +0,0 @@ -[]; diff --git a/src/babel/transformation/transformers/other/ludicrous.js b/src/babel/transformation/transformers/other/ludicrous.js deleted file mode 100644 index d2c56bb118..0000000000 --- a/src/babel/transformation/transformers/other/ludicrous.js +++ /dev/null @@ -1,66 +0,0 @@ -import * as t from "../../../types"; -import * as util from "../../../util"; - -export var metadata = { - optional: true -}; - -// foo in bar -export function BinaryExpression(node) { - if (node.operator === "in") { - return util.template("ludicrous-in", { - LEFT: node.left, - RIGHT: node.right - }); - } -} - -// { 1: "foo" } -export function Property(node) { - var key = node.key; - if (t.isLiteral(key) && typeof key.value === "number") { - key.value = "" + key.value; - } -} - -// /foobar/g -export function Literal(node) { - if (node.regex) { - node.regex.pattern = "foobar"; - node.regex.flags = ""; - } -} - -// foo.bar -export function MemberExpression(node) { - -} - -// Object.setPrototypeOf -// Object.preventExtensions -// Object.keys -// Object.isExtensible -// Object.getOwnPropertyDescriptor -// Object.defineProperty -export function CallExpression(node) { - -} - -// delete foo.bar -export function UnaryExpression(node) { - -} - -// foo.bar = bar; -export function AssignmentExpression(node) { - -} - -// new Proxy -export function NewExpression(node, parent, scope, file) { - if (this.get("callee").isIdentifier({ name: "Proxy" })) { - return t.callExpression(file.addHelper("proxy-create"), [node.arguments[0], file.addHelper("proxy-directory")]); - } else { - // possible proxy constructor - } -} From d6a5c390791a738a57fe973f925ca158c765ab17 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 22:52:19 +0100 Subject: [PATCH 21/30] update classes to reflect new transformer precedence --- .../exports-default/expected.js | 6 ++--- .../exports-from/expected.js | 8 +++---- .../exports-named/expected.js | 6 ++--- .../exports-variable/expected.js | 6 ++--- .../get-module-name-option/expected.js | 8 +++---- .../hoist-function-exports/expected.js | 6 ++--- .../imports-default/expected.js | 8 +++---- .../imports-glob/expected.js | 8 +++---- .../imports-mixing/expected.js | 8 +++---- .../imports-named/expected.js | 8 +++---- .../es6.modules-system/imports/expected.js | 8 +++---- .../es6.modules-system/overview/expected.js | 6 ++--- .../es6.modules-system/remap/expected.js | 6 ++--- .../class-getter-and-setter/expected.js | 4 ++-- .../es7.decorators/class-getter/expected.js | 2 +- .../class-init-instance-props/expected.js | 2 +- .../class-init-static-props/expected.js | 2 +- .../es7.decorators/class-setter/expected.js | 2 +- .../object-getter-and-setter/actual.js | 2 +- .../object-getter-and-setter/expected.js | 4 ++-- .../es7.decorators/object-getter/expected.js | 2 +- .../es7.decorators/object-setter/actual.js | 2 +- .../es7.decorators/object-setter/expected.js | 2 +- .../es7.decorators/object/expected.js | 8 +++---- .../transformation/runtime/full/expected.js | 23 ++++++++++--------- .../source-maps/class/expected.js | 2 +- 26 files changed, 75 insertions(+), 74 deletions(-) diff --git a/test/core/fixtures/transformation/es6.modules-system/exports-default/expected.js b/test/core/fixtures/transformation/es6.modules-system/exports-default/expected.js index 453baf6142..7854fc3ce8 100644 --- a/test/core/fixtures/transformation/es6.modules-system/exports-default/expected.js +++ b/test/core/fixtures/transformation/es6.modules-system/exports-default/expected.js @@ -1,4 +1,6 @@ System.register([], function (_export) { + "use strict"; + var _default, Foo; _export("default", foo); @@ -10,8 +12,6 @@ System.register([], function (_export) { return { setters: [], execute: function () { - "use strict"; - _export("default", 42); _export("default", {}); @@ -39,4 +39,4 @@ System.register([], function (_export) { _export("default", Foo); } }; -}); \ No newline at end of file +}); diff --git a/test/core/fixtures/transformation/es6.modules-system/exports-from/expected.js b/test/core/fixtures/transformation/es6.modules-system/exports-from/expected.js index c1eaca763d..b7b8242360 100644 --- a/test/core/fixtures/transformation/es6.modules-system/exports-from/expected.js +++ b/test/core/fixtures/transformation/es6.modules-system/exports-from/expected.js @@ -1,4 +1,6 @@ System.register(["foo"], function (_export) { + "use strict"; + return { setters: [function (_foo) { for (var _key in _foo) { @@ -19,8 +21,6 @@ System.register(["foo"], function (_export) { _export("bar", _foo.bar); }], - execute: function () { - "use strict"; - } + execute: function () {} }; -}); \ No newline at end of file +}); diff --git a/test/core/fixtures/transformation/es6.modules-system/exports-named/expected.js b/test/core/fixtures/transformation/es6.modules-system/exports-named/expected.js index 410345bcfa..86487ee2f5 100644 --- a/test/core/fixtures/transformation/es6.modules-system/exports-named/expected.js +++ b/test/core/fixtures/transformation/es6.modules-system/exports-named/expected.js @@ -1,9 +1,9 @@ System.register([], function (_export) { + "use strict"; + return { setters: [], execute: function () { - "use strict"; - _export("foo", foo); _export("foo", foo); @@ -19,4 +19,4 @@ System.register([], function (_export) { _export("bar", bar); } }; -}); \ No newline at end of file +}); diff --git a/test/core/fixtures/transformation/es6.modules-system/exports-variable/expected.js b/test/core/fixtures/transformation/es6.modules-system/exports-variable/expected.js index c5ab473b75..bc93dd73b5 100644 --- a/test/core/fixtures/transformation/es6.modules-system/exports-variable/expected.js +++ b/test/core/fixtures/transformation/es6.modules-system/exports-variable/expected.js @@ -1,4 +1,6 @@ System.register([], function (_export) { + "use strict"; + var foo, foo2, foo3, foo4, foo5, foo6, foo8; _export("foo7", foo7); @@ -10,8 +12,6 @@ System.register([], function (_export) { return { setters: [], execute: function () { - "use strict"; - foo = 1; _export("foo", foo); @@ -43,4 +43,4 @@ System.register([], function (_export) { _export("foo3", foo3 = 5); } }; -}); \ No newline at end of file +}); diff --git a/test/core/fixtures/transformation/es6.modules-system/get-module-name-option/expected.js b/test/core/fixtures/transformation/es6.modules-system/get-module-name-option/expected.js index 0f7fc369ae..0def1f9524 100644 --- a/test/core/fixtures/transformation/es6.modules-system/get-module-name-option/expected.js +++ b/test/core/fixtures/transformation/es6.modules-system/get-module-name-option/expected.js @@ -1,8 +1,8 @@ System.register("my custom module name", [], function (_export) { + "use strict"; + return { setters: [], - execute: function () { - "use strict"; - } + execute: function () {} }; -}); \ No newline at end of file +}); diff --git a/test/core/fixtures/transformation/es6.modules-system/hoist-function-exports/expected.js b/test/core/fixtures/transformation/es6.modules-system/hoist-function-exports/expected.js index 4056aa7a5e..ad3421dd2e 100644 --- a/test/core/fixtures/transformation/es6.modules-system/hoist-function-exports/expected.js +++ b/test/core/fixtures/transformation/es6.modules-system/hoist-function-exports/expected.js @@ -1,4 +1,6 @@ System.register(["./evens"], function (_export) { + "use strict"; + var isEven, p, isOdd; _export("nextOdd", nextOdd); @@ -12,8 +14,6 @@ System.register(["./evens"], function (_export) { isEven = _evens.isEven; }], execute: function () { - "use strict"; - p = 5; _export("p", p); @@ -27,4 +27,4 @@ System.register(["./evens"], function (_export) { _export("isOdd", isOdd); } }; -}); \ No newline at end of file +}); diff --git a/test/core/fixtures/transformation/es6.modules-system/imports-default/expected.js b/test/core/fixtures/transformation/es6.modules-system/imports-default/expected.js index 2cb90409c2..16a71b2ed4 100644 --- a/test/core/fixtures/transformation/es6.modules-system/imports-default/expected.js +++ b/test/core/fixtures/transformation/es6.modules-system/imports-default/expected.js @@ -1,12 +1,12 @@ System.register(["foo"], function (_export) { + "use strict"; + var foo, foo2; return { setters: [function (_foo) { foo = _foo["default"]; foo2 = _foo["default"]; }], - execute: function () { - "use strict"; - } + execute: function () {} }; -}); \ No newline at end of file +}); diff --git a/test/core/fixtures/transformation/es6.modules-system/imports-glob/expected.js b/test/core/fixtures/transformation/es6.modules-system/imports-glob/expected.js index 67e60e45ca..5df9008d7c 100644 --- a/test/core/fixtures/transformation/es6.modules-system/imports-glob/expected.js +++ b/test/core/fixtures/transformation/es6.modules-system/imports-glob/expected.js @@ -1,11 +1,11 @@ System.register(["foo"], function (_export) { + "use strict"; + var foo; return { setters: [function (_foo) { foo = _foo; }], - execute: function () { - "use strict"; - } + execute: function () {} }; -}); \ No newline at end of file +}); diff --git a/test/core/fixtures/transformation/es6.modules-system/imports-mixing/expected.js b/test/core/fixtures/transformation/es6.modules-system/imports-mixing/expected.js index 9ac0cd5ce2..786d2e6869 100644 --- a/test/core/fixtures/transformation/es6.modules-system/imports-mixing/expected.js +++ b/test/core/fixtures/transformation/es6.modules-system/imports-mixing/expected.js @@ -1,12 +1,12 @@ System.register(["foo"], function (_export) { + "use strict"; + var foo, xyz; return { setters: [function (_foo) { foo = _foo["default"]; xyz = _foo.baz; }], - execute: function () { - "use strict"; - } + execute: function () {} }; -}); \ No newline at end of file +}); diff --git a/test/core/fixtures/transformation/es6.modules-system/imports-named/expected.js b/test/core/fixtures/transformation/es6.modules-system/imports-named/expected.js index b66550bded..e6704667be 100644 --- a/test/core/fixtures/transformation/es6.modules-system/imports-named/expected.js +++ b/test/core/fixtures/transformation/es6.modules-system/imports-named/expected.js @@ -1,4 +1,6 @@ System.register(["foo"], function (_export) { + "use strict"; + var bar, bar2, baz, baz2, baz3, xyz; return { setters: [function (_foo) { @@ -9,8 +11,6 @@ System.register(["foo"], function (_export) { baz3 = _foo.bar; xyz = _foo.xyz; }], - execute: function () { - "use strict"; - } + execute: function () {} }; -}); \ No newline at end of file +}); diff --git a/test/core/fixtures/transformation/es6.modules-system/imports/expected.js b/test/core/fixtures/transformation/es6.modules-system/imports/expected.js index 2b02e610fc..005c4b922f 100644 --- a/test/core/fixtures/transformation/es6.modules-system/imports/expected.js +++ b/test/core/fixtures/transformation/es6.modules-system/imports/expected.js @@ -1,8 +1,8 @@ System.register(["foo", "foo-bar", "./directory/foo-bar"], function (_export) { + "use strict"; + return { setters: [function (_foo) {}, function (_fooBar) {}, function (_directoryFooBar) {}], - execute: function () { - "use strict"; - } + execute: function () {} }; -}); \ No newline at end of file +}); diff --git a/test/core/fixtures/transformation/es6.modules-system/overview/expected.js b/test/core/fixtures/transformation/es6.modules-system/overview/expected.js index b4b80d7d38..c818618f83 100644 --- a/test/core/fixtures/transformation/es6.modules-system/overview/expected.js +++ b/test/core/fixtures/transformation/es6.modules-system/overview/expected.js @@ -1,4 +1,6 @@ System.register(["foo", "foo-bar", "./directory/foo-bar"], function (_export) { + "use strict"; + var foo, foo2, bar, bar2, test2; return { setters: [function (_foo) { @@ -8,8 +10,6 @@ System.register(["foo", "foo-bar", "./directory/foo-bar"], function (_export) { bar2 = _foo.foo; }, function (_fooBar) {}, function (_directoryFooBar) {}], execute: function () { - "use strict"; - _export("test", test); test2 = 5; @@ -19,4 +19,4 @@ System.register(["foo", "foo-bar", "./directory/foo-bar"], function (_export) { _export("default", test); } }; -}); \ No newline at end of file +}); diff --git a/test/core/fixtures/transformation/es6.modules-system/remap/expected.js b/test/core/fixtures/transformation/es6.modules-system/remap/expected.js index c0922ff2b4..7bedb706ab 100644 --- a/test/core/fixtures/transformation/es6.modules-system/remap/expected.js +++ b/test/core/fixtures/transformation/es6.modules-system/remap/expected.js @@ -1,10 +1,10 @@ System.register([], function (_export) { + "use strict"; + var test, a, b, d; return { setters: [], execute: function () { - "use strict"; - test = 2; _export("test", test); @@ -39,4 +39,4 @@ System.register([], function (_export) { _export("f", _export("e", d = 4)); } }; -}); \ No newline at end of file +}); diff --git a/test/core/fixtures/transformation/es7.decorators/class-getter-and-setter/expected.js b/test/core/fixtures/transformation/es7.decorators/class-getter-and-setter/expected.js index 8e9b70a100..8aa07f0846 100644 --- a/test/core/fixtures/transformation/es7.decorators/class-getter-and-setter/expected.js +++ b/test/core/fixtures/transformation/es7.decorators/class-getter-and-setter/expected.js @@ -8,8 +8,8 @@ var Foo = (function () { babelHelpers.createDecoratedClass(Foo, [{ key: "foo", decorators: [bar, foo], - get: function get() {}, - set: function set(bar) {} + get: function () {}, + set: function (bar) {} }]); return Foo; })(); diff --git a/test/core/fixtures/transformation/es7.decorators/class-getter/expected.js b/test/core/fixtures/transformation/es7.decorators/class-getter/expected.js index 06b1d2294e..8c7d3a793d 100644 --- a/test/core/fixtures/transformation/es7.decorators/class-getter/expected.js +++ b/test/core/fixtures/transformation/es7.decorators/class-getter/expected.js @@ -8,7 +8,7 @@ var Foo = (function () { babelHelpers.createDecoratedClass(Foo, [{ key: "foo", decorators: [bar], - get: function get() {} + get: function () {} }]); return Foo; })(); diff --git a/test/core/fixtures/transformation/es7.decorators/class-init-instance-props/expected.js b/test/core/fixtures/transformation/es7.decorators/class-init-instance-props/expected.js index e564a5f47e..db03a7b153 100644 --- a/test/core/fixtures/transformation/es7.decorators/class-init-instance-props/expected.js +++ b/test/core/fixtures/transformation/es7.decorators/class-init-instance-props/expected.js @@ -11,7 +11,7 @@ var Foo = (function () { babelHelpers.createDecoratedClass(Foo, [{ key: "foo", decorators: [bar], - initializer: function initializer() { + initializer: function () { return "Bar"; }, enumerable: true diff --git a/test/core/fixtures/transformation/es7.decorators/class-init-static-props/expected.js b/test/core/fixtures/transformation/es7.decorators/class-init-static-props/expected.js index 8bdff77924..6c0c573906 100644 --- a/test/core/fixtures/transformation/es7.decorators/class-init-static-props/expected.js +++ b/test/core/fixtures/transformation/es7.decorators/class-init-static-props/expected.js @@ -10,7 +10,7 @@ var Foo = (function () { babelHelpers.createDecoratedClass(Foo, null, [{ key: "foo", decorators: [bar], - initializer: function initializer() { + initializer: function () { return "Bar"; }, enumerable: true diff --git a/test/core/fixtures/transformation/es7.decorators/class-setter/expected.js b/test/core/fixtures/transformation/es7.decorators/class-setter/expected.js index 57426dd80c..7b9537b539 100644 --- a/test/core/fixtures/transformation/es7.decorators/class-setter/expected.js +++ b/test/core/fixtures/transformation/es7.decorators/class-setter/expected.js @@ -8,7 +8,7 @@ var Foo = (function () { babelHelpers.createDecoratedClass(Foo, [{ key: "foo", decorators: [bar], - set: function set(arg) {} + set: function (arg) {} }]); return Foo; })(); diff --git a/test/core/fixtures/transformation/es7.decorators/object-getter-and-setter/actual.js b/test/core/fixtures/transformation/es7.decorators/object-getter-and-setter/actual.js index 772c63c875..37a0b6a98f 100644 --- a/test/core/fixtures/transformation/es7.decorators/object-getter-and-setter/actual.js +++ b/test/core/fixtures/transformation/es7.decorators/object-getter-and-setter/actual.js @@ -5,7 +5,7 @@ var obj = { }, @foo - set foo() { + set foo(bar) { } }; diff --git a/test/core/fixtures/transformation/es7.decorators/object-getter-and-setter/expected.js b/test/core/fixtures/transformation/es7.decorators/object-getter-and-setter/expected.js index 117515628e..68c9af550f 100644 --- a/test/core/fixtures/transformation/es7.decorators/object-getter-and-setter/expected.js +++ b/test/core/fixtures/transformation/es7.decorators/object-getter-and-setter/expected.js @@ -3,6 +3,6 @@ var obj = babelHelpers.createDecoratedObject([{ key: "foo", decorators: [foo, foo], - get: function get() {}, - set: function set() {} + get: function () {}, + set: function (bar) {} }]); diff --git a/test/core/fixtures/transformation/es7.decorators/object-getter/expected.js b/test/core/fixtures/transformation/es7.decorators/object-getter/expected.js index bb651cf283..e0aa727de6 100644 --- a/test/core/fixtures/transformation/es7.decorators/object-getter/expected.js +++ b/test/core/fixtures/transformation/es7.decorators/object-getter/expected.js @@ -3,5 +3,5 @@ var obj = babelHelpers.createDecoratedObject([{ key: "foo", decorators: [foo], - get: function get() {} + get: function () {} }]); diff --git a/test/core/fixtures/transformation/es7.decorators/object-setter/actual.js b/test/core/fixtures/transformation/es7.decorators/object-setter/actual.js index ec760bb339..52eb95db88 100644 --- a/test/core/fixtures/transformation/es7.decorators/object-setter/actual.js +++ b/test/core/fixtures/transformation/es7.decorators/object-setter/actual.js @@ -1,6 +1,6 @@ var obj = { @foo - set foo() { + set foo(bar) { } }; diff --git a/test/core/fixtures/transformation/es7.decorators/object-setter/expected.js b/test/core/fixtures/transformation/es7.decorators/object-setter/expected.js index 6b16d5c65c..ee3dc12281 100644 --- a/test/core/fixtures/transformation/es7.decorators/object-setter/expected.js +++ b/test/core/fixtures/transformation/es7.decorators/object-setter/expected.js @@ -3,5 +3,5 @@ var obj = babelHelpers.createDecoratedObject([{ key: "foo", decorators: [foo], - set: function set() {} + set: function (bar) {} }]); diff --git a/test/core/fixtures/transformation/es7.decorators/object/expected.js b/test/core/fixtures/transformation/es7.decorators/object/expected.js index efe805cf25..7a7cc30560 100644 --- a/test/core/fixtures/transformation/es7.decorators/object/expected.js +++ b/test/core/fixtures/transformation/es7.decorators/object/expected.js @@ -3,18 +3,18 @@ var obj = babelHelpers.createDecoratedObject([{ key: "bar", decorators: [foo], - initializer: function initializer() { - return function () {}; + initializer: function () { + return function bar() {}; } }, { key: "foo", decorators: [bar], - initializer: function initializer() { + initializer: function () { return "lol"; } }, { key: "yes", - initializer: function initializer() { + initializer: function () { return "wow"; } }]); diff --git a/test/core/fixtures/transformation/runtime/full/expected.js b/test/core/fixtures/transformation/runtime/full/expected.js index 2f08b10a1c..3f3795a497 100644 --- a/test/core/fixtures/transformation/runtime/full/expected.js +++ b/test/core/fixtures/transformation/runtime/full/expected.js @@ -1,20 +1,21 @@ "use strict"; -var _Object$defineProperty = require("babel-runtime/core-js/object/define-property")["default"]; - -var _Symbol = require("babel-runtime/core-js/symbol")["default"]; - -var _regeneratorRuntime = require("babel-runtime/regenerator")["default"]; - -var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"]; - -var _interopRequireWildcard = require("babel-runtime/helpers/interop-require-wildcard")["default"]; - _Object$defineProperty(exports, "__esModule", { value: true }); exports.giveWord = giveWord; + +var _regeneratorRuntime = require("babel-runtime/regenerator")["default"]; + +var _Object$defineProperty = require("babel-runtime/core-js/object/define-property")["default"]; + +var _Symbol = require("babel-runtime/core-js/symbol")["default"]; + +var _interopRequireDefault = require("babel-runtime/helpers/interop-require-default")["default"]; + +var _interopRequireWildcard = require("babel-runtime/helpers/interop-require-wildcard")["default"]; + var marked0$0 = [giveWord].map(_regeneratorRuntime.mark); var _someModule = require("someModule"); @@ -41,4 +42,4 @@ function giveWord() { } _someModule2["default"]; -bar; \ No newline at end of file +bar; diff --git a/test/core/fixtures/transformation/source-maps/class/expected.js b/test/core/fixtures/transformation/source-maps/class/expected.js index c9b2c12183..25517b3e99 100644 --- a/test/core/fixtures/transformation/source-maps/class/expected.js +++ b/test/core/fixtures/transformation/source-maps/class/expected.js @@ -7,7 +7,7 @@ var Test = (function () { babelHelpers.createClass(Test, [{ key: "bar", - get: function get() { + get: function () { throw new Error("wow"); } }]); From 8292d6d8ad8319c550f9338fafac7d409a8b3b7f Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 22:52:38 +0100 Subject: [PATCH 22/30] fix replacement requeue exiting too early --- src/babel/traversal/path/index.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/babel/traversal/path/index.js b/src/babel/traversal/path/index.js index 1cbe84ce59..bf9dd5688f 100644 --- a/src/babel/traversal/path/index.js +++ b/src/babel/traversal/path/index.js @@ -717,19 +717,18 @@ export default class TraversalPath { // call the function with the params (node, parent, scope, state) var replacement = fn.call(this, node, this.parent, this.scope, this.state); + var previousType = this.type; if (replacement) { - var previousType = this.type; - this.replaceWith(replacement, true); - - if (previousType !== this.type) { - this.queueNode(this); - return; - } } if (this.shouldStop || this.shouldSkip || this.removed) return; + + if (replacement && previousType !== this.type) { + this.queueNode(this); + return; + } } } From b376b6b33bc55421c9c98c8899ebce95cff33640 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 22:53:03 +0100 Subject: [PATCH 23/30] store uncollapsed transformer pass stack so we have access to it when calling pre and post methods --- src/babel/transformation/file/index.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/babel/transformation/file/index.js b/src/babel/transformation/file/index.js index e3757ac860..7b2a8f1e10 100644 --- a/src/babel/transformation/file/index.js +++ b/src/babel/transformation/file/index.js @@ -86,10 +86,7 @@ export default class File { "interop-require", ]; - static soloHelpers = [ - "ludicrous-proxy-create", - "ludicrous-proxy-directory" - ]; + static soloHelpers = []; static options = require("./options"); @@ -224,7 +221,7 @@ export default class File { stack = beforePlugins.concat(stack, afterPlugins); // build transformer stack - stack = stack.concat(secondaryStack); + this.uncollapsedTransformerStack = stack = stack.concat(secondaryStack); // build dependency graph for (var pass of (stack: Array)) { @@ -557,10 +554,8 @@ export default class File { } call(key: string) { - var stack = this.transformerStack; - for (var i = 0; i < stack.length; i++) { - var transformer = stack[i].transformer; - var fn = transformer[key]; + for (var pass of (this.uncollapsedTransformerStack: Array)) { + var fn = pass.transformer[key]; if (fn) fn(this); } } From 8f9d02d6891dd9f8a829b91ec362476e650944dc Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 22:53:31 +0100 Subject: [PATCH 24/30] further work splitting up transformers into their own "category" in order of what they need and what they actually do --- .../es3/member-expression-literals.js | 2 +- .../transformers/es3/property-literals.js | 2 +- .../transformers/es5/properties.mutators.js | 38 ++++++++--------- .../transformers/es6/destructuring.js | 4 ++ .../transformers/es6/properties.computed.js | 4 +- .../transformers/es6/tail-call.js | 4 ++ .../transformation/transformers/index.js | 41 ++++++++++++------- .../transformers/internal/block-hoist.js | 2 +- .../transformers/internal/modules.js | 4 ++ .../transformers/internal/shadow-functions.js | 2 +- .../transformers/internal/validation.js | 4 ++ .../minification/dead-code-elimination.js | 3 +- .../member-expression-literals.js | 2 +- .../minification/property-literals.js | 2 +- .../transformers/other/regenerator.js | 10 ++--- .../transformers/other/runtime/index.js | 4 +- .../transformers/spec/function-name.js | 4 ++ .../utility/inline-environment-variables.js | 3 +- .../utility/inline-expressions.js | 3 +- .../transformers/utility/remove-console.js | 3 +- .../transformers/utility/remove-debugger.js | 3 +- 21 files changed, 88 insertions(+), 56 deletions(-) diff --git a/src/babel/transformation/transformers/es3/member-expression-literals.js b/src/babel/transformation/transformers/es3/member-expression-literals.js index d4465fde70..e80f5c62d1 100644 --- a/src/babel/transformation/transformers/es3/member-expression-literals.js +++ b/src/babel/transformation/transformers/es3/member-expression-literals.js @@ -1,7 +1,7 @@ import * as t from "../../../types"; export var metadata = { - category: "builtin-cleanup" + category: "builtin-trailing" }; export var MemberExpression = { diff --git a/src/babel/transformation/transformers/es3/property-literals.js b/src/babel/transformation/transformers/es3/property-literals.js index ecfd63c8dd..9fa015e82b 100644 --- a/src/babel/transformation/transformers/es3/property-literals.js +++ b/src/babel/transformation/transformers/es3/property-literals.js @@ -1,7 +1,7 @@ import * as t from "../../../types"; export var metadata = { - category: "builtin-cleanup" + category: "builtin-trailing" }; export var Property = { diff --git a/src/babel/transformation/transformers/es5/properties.mutators.js b/src/babel/transformation/transformers/es5/properties.mutators.js index 7fe77c7f41..a3161efae8 100644 --- a/src/babel/transformation/transformers/es5/properties.mutators.js +++ b/src/babel/transformation/transformers/es5/properties.mutators.js @@ -1,26 +1,24 @@ import * as defineMap from "../../helpers/define-map"; import * as t from "../../../types"; -export var ObjectExpression = { - exit(node, parent, scope, file) { - var mutatorMap = {}; - var hasAny = false; +export function ObjectExpression(node, parent, scope, file) { + var mutatorMap = {}; + var hasAny = false; - node.properties = node.properties.filter(function (prop) { - if (prop.kind === "get" || prop.kind === "set") { - hasAny = true; - defineMap.push(mutatorMap, prop, prop.kind, file); - return false; - } else { - return true; - } - }); + node.properties = node.properties.filter(function (prop) { + if (prop.kind === "get" || prop.kind === "set") { + hasAny = true; + defineMap.push(mutatorMap, prop, prop.kind, file); + return false; + } else { + return true; + } + }); - if (!hasAny) return; + if (!hasAny) return; - return t.callExpression( - t.memberExpression(t.identifier("Object"), t.identifier("defineProperties")), - [node, defineMap.toDefineObject(mutatorMap)] - ); - } -}; + return t.callExpression( + t.memberExpression(t.identifier("Object"), t.identifier("defineProperties")), + [node, defineMap.toDefineObject(mutatorMap)] + ); +} diff --git a/src/babel/transformation/transformers/es6/destructuring.js b/src/babel/transformation/transformers/es6/destructuring.js index 5fb2df518b..53e7b2d22b 100644 --- a/src/babel/transformation/transformers/es6/destructuring.js +++ b/src/babel/transformation/transformers/es6/destructuring.js @@ -1,6 +1,10 @@ import * as messages from "../../../messages"; import * as t from "../../../types"; +export var metadata = { + category: "builtin-advanced" +}; + export function ForOfStatement(node, parent, scope, file) { var left = node.left; diff --git a/src/babel/transformation/transformers/es6/properties.computed.js b/src/babel/transformation/transformers/es6/properties.computed.js index d944844ca0..9c477f8348 100644 --- a/src/babel/transformation/transformers/es6/properties.computed.js +++ b/src/babel/transformation/transformers/es6/properties.computed.js @@ -67,8 +67,8 @@ export var ObjectExpression = { exit(node, parent, scope, file) { var hasComputed = false; - for (var i = 0; i < node.properties.length; i++) { - hasComputed = t.isProperty(node.properties[i], { computed: true, kind: "init" }); + for (var prop of (node.properties: Array)) { + hasComputed = t.isProperty(prop, { computed: true, kind: "init" }); if (hasComputed) break; } diff --git a/src/babel/transformation/transformers/es6/tail-call.js b/src/babel/transformation/transformers/es6/tail-call.js index 12fb5a8a8d..e3a9482067 100644 --- a/src/babel/transformation/transformers/es6/tail-call.js +++ b/src/babel/transformation/transformers/es6/tail-call.js @@ -6,6 +6,10 @@ import * as util from "../../../util"; import map from "lodash/collection/map"; import * as t from "../../../types"; +export var metadata = { + category: "builtin-trailing" +}; + exports.Function = function (node, parent, scope, file) { if (node.generator || node.async) return; var tailCall = new TailCallTransformer(this, scope, file); diff --git a/src/babel/transformation/transformers/index.js b/src/babel/transformation/transformers/index.js index a4e0317b84..7977ee9e9f 100644 --- a/src/babel/transformation/transformers/index.js +++ b/src/babel/transformation/transformers/index.js @@ -1,20 +1,24 @@ export default { - // builtin-basic + //- builtin-setup + _validation: require("./internal/validation"), "utility.removeDebugger": require("./utility/remove-debugger"), "utility.removeConsole": require("./utility/remove-console"), "utility.inlineEnvironmentVariables": require("./utility/inline-environment-variables"), "utility.inlineExpressions": require("./utility/inline-expressions"), "minification.deadCodeElimination": require("./minification/dead-code-elimination"), _modules: require("./internal/modules"), + "spec.functionName": require("./spec/function-name"), + + //- builtin-basic + // this is where the bulk of the ES6 transformations take place, none of them require traversal state + // so they can all be concatenated together for performance "es7.classProperties": require("./es7/class-properties"), "es7.trailingFunctionCommas": require("./es7/trailing-function-commas"), "es7.asyncFunctions": require("./es7/async-functions"), "es7.decorators": require("./es7/decorators"), strict: require("./other/strict"), - _validation: require("./internal/validation"), "validation.undeclaredVariableCheck": require("./validation/undeclared-variable-check"), "validation.react": require("./validation/react"), - "spec.functionName": require("./spec/function-name"), "es6.arrowFunctions": require("./es6/arrow-functions"), "spec.blockScopedFunctions": require("./spec/block-scoped-functions"), "optimisation.react.constantElements": require("./optimisation/react.constant-elements"), @@ -41,30 +45,37 @@ export default { "es6.parameters.rest": require("./es6/parameters.rest"), "es6.spread": require("./es6/spread"), "es6.parameters.default": require("./es6/parameters.default"), - "es6.destructuring": require("./es6/destructuring"), - "es6.tailCall": require("./es6/tail-call"), "es7.exportExtensions": require("./es7/export-extensions"), "spec.protoToAssign": require("./spec/proto-to-assign"), - _shadowFunctions: require("./internal/shadow-functions"), "es7.doExpressions": require("./es7/do-expressions"), "es6.spec.symbols": require("./es6/spec.symbols"), - ludicrous: require("./other/ludicrous"), "spec.undefinedToVoid": require("./spec/undefined-to-void"), jscript: require("./other/jscript"), flow: require("./other/flow"), _hoistDirectives: require("./internal/hoist-directives"), - // builtin-modules - "es6.modules": require("./es6/modules"), - regenerator: require("./other/regenerator"), - runtime: require("./other/runtime"), - _moduleFormatter: require("./internal/module-formatter"), - - // builtin-advanced + //- builtin-advanced + "es6.destructuring": require("./es6/destructuring"), "es6.blockScoping": require("./es6/block-scoping"), "es6.spec.blockScoping": require("./es6/spec.block-scoping"), - // builtin-cleanup + // es6 syntax transformation is **forbidden** past this point since regenerator will chuck a massive + // hissy fit + + //- regenerator + regenerator: require("./other/regenerator"), + + //- builtin-modules + runtime: require("./other/runtime"), + "es6.modules": require("./es6/modules"), + _moduleFormatter: require("./internal/module-formatter"), + + //- builtin-trailing + // these clean up the output and do finishing up transformations, it's important to note that by this + // stage you can't import any new modules or insert new ES6 as all those transformers have already + // been ran + "es6.tailCall": require("./es6/tail-call"), + _shadowFunctions: require("./internal/shadow-functions"), "es3.propertyLiterals": require("./es3/property-literals"), "es3.memberExpressionLiterals": require("./es3/member-expression-literals"), "minification.memberExpressionLiterals": require("./minification/member-expression-literals"), diff --git a/src/babel/transformation/transformers/internal/block-hoist.js b/src/babel/transformation/transformers/internal/block-hoist.js index 700d91b2a9..2ab60a0755 100644 --- a/src/babel/transformation/transformers/internal/block-hoist.js +++ b/src/babel/transformation/transformers/internal/block-hoist.js @@ -1,7 +1,7 @@ import sortBy from "lodash/collection/sortBy"; export var metadata = { - category: "builtin-cleanup" + category: "builtin-trailing" }; // Priority: diff --git a/src/babel/transformation/transformers/internal/modules.js b/src/babel/transformation/transformers/internal/modules.js index 6d3dfe83c8..71d51e7a25 100644 --- a/src/babel/transformation/transformers/internal/modules.js +++ b/src/babel/transformation/transformers/internal/modules.js @@ -6,6 +6,10 @@ import * as t from "../../../types"; +export var metadata = { + category: "builtin-setup" +}; + export function ImportDeclaration(node, parent, scope, file) { if (node.source) { node.source.value = file.resolveModuleSource(node.source.value); diff --git a/src/babel/transformation/transformers/internal/shadow-functions.js b/src/babel/transformation/transformers/internal/shadow-functions.js index decec95409..d082fd1ba8 100644 --- a/src/babel/transformation/transformers/internal/shadow-functions.js +++ b/src/babel/transformation/transformers/internal/shadow-functions.js @@ -86,7 +86,7 @@ function aliasFunction(getBody, path, scope) { // crawling the entire function tree export var metadata = { - category: "builtin-cleanup" + category: "builtin-trailing" }; export var Program = { diff --git a/src/babel/transformation/transformers/internal/validation.js b/src/babel/transformation/transformers/internal/validation.js index da830eabef..31dfabc78e 100644 --- a/src/babel/transformation/transformers/internal/validation.js +++ b/src/babel/transformation/transformers/internal/validation.js @@ -1,6 +1,10 @@ import * as messages from "../../../messages"; import * as t from "../../../types"; +export var metadata = { + category: "builtin-setup" +}; + export function ForOfStatement(node, parent, scope, file) { var left = node.left; if (t.isVariableDeclaration(left)) { diff --git a/src/babel/transformation/transformers/minification/dead-code-elimination.js b/src/babel/transformation/transformers/minification/dead-code-elimination.js index 2d840f991e..58524530bb 100644 --- a/src/babel/transformation/transformers/minification/dead-code-elimination.js +++ b/src/babel/transformation/transformers/minification/dead-code-elimination.js @@ -18,7 +18,8 @@ function toStatements(node) { } export var metadata = { - optional: true + optional: true, + category: "builtin-setup" }; export function Identifier(node, parent, scope) { diff --git a/src/babel/transformation/transformers/minification/member-expression-literals.js b/src/babel/transformation/transformers/minification/member-expression-literals.js index a7d9823535..333bd02201 100644 --- a/src/babel/transformation/transformers/minification/member-expression-literals.js +++ b/src/babel/transformation/transformers/minification/member-expression-literals.js @@ -2,7 +2,7 @@ import * as t from "../../../types"; export var metadata = { optional: true, - category: "builtin-cleanup" + category: "builtin-trailing" }; export var MemberExpression = { diff --git a/src/babel/transformation/transformers/minification/property-literals.js b/src/babel/transformation/transformers/minification/property-literals.js index d1d682fbdb..4bdc31ae59 100644 --- a/src/babel/transformation/transformers/minification/property-literals.js +++ b/src/babel/transformation/transformers/minification/property-literals.js @@ -2,7 +2,7 @@ import * as t from "../../../types"; export var metadata = { optional: true, - category: "builtin-cleanup" + category: "builtin-trailing" }; export var Property = { diff --git a/src/babel/transformation/transformers/other/regenerator.js b/src/babel/transformation/transformers/other/regenerator.js index 9d1b17e675..d276ec9908 100644 --- a/src/babel/transformation/transformers/other/regenerator.js +++ b/src/babel/transformation/transformers/other/regenerator.js @@ -2,11 +2,9 @@ import regenerator from "regenerator"; import * as t from "../../../types"; export var metadata = { - category: "builtin-modules" + category: "regenerator" }; -export var Program = { - exit(ast) { - regenerator.transform(ast); - } -}; +export function Program(ast) { + regenerator.transform(ast); +} diff --git a/src/babel/transformation/transformers/other/runtime/index.js b/src/babel/transformation/transformers/other/runtime/index.js index 3fa283268d..5d9a0dbc44 100644 --- a/src/babel/transformation/transformers/other/runtime/index.js +++ b/src/babel/transformation/transformers/other/runtime/index.js @@ -11,10 +11,10 @@ const RUNTIME_MODULE_NAME = "babel-runtime"; export var metadata = { optional: true, - category: "builtin-modules" + category: "builtin-post-modules" }; -export function Program(node, parent, scope, file) { +export function pre(file) { file.set("helperGenerator", function (name) { return file.addImport(`${RUNTIME_MODULE_NAME}/helpers/${name}`, name, "absoluteDefault"); }); diff --git a/src/babel/transformation/transformers/spec/function-name.js b/src/babel/transformation/transformers/spec/function-name.js index 928036e0be..d45d2a4165 100644 --- a/src/babel/transformation/transformers/spec/function-name.js +++ b/src/babel/transformation/transformers/spec/function-name.js @@ -1,3 +1,7 @@ +export var metadata = { + category: "builtin-setup" +}; + export { bare as FunctionExpression, bare as ArrowFunctionExpression diff --git a/src/babel/transformation/transformers/utility/inline-environment-variables.js b/src/babel/transformation/transformers/utility/inline-environment-variables.js index 97725fbc51..5c00d13ccc 100644 --- a/src/babel/transformation/transformers/utility/inline-environment-variables.js +++ b/src/babel/transformation/transformers/utility/inline-environment-variables.js @@ -1,7 +1,8 @@ import * as t from "../../../types"; export var metadata = { - optional: true + optional: true, + category: "builtin-setup" }; var match = t.buildMatchMemberExpression("process.env"); diff --git a/src/babel/transformation/transformers/utility/inline-expressions.js b/src/babel/transformation/transformers/utility/inline-expressions.js index 437cce640d..5fbb8de75c 100644 --- a/src/babel/transformation/transformers/utility/inline-expressions.js +++ b/src/babel/transformation/transformers/utility/inline-expressions.js @@ -1,7 +1,8 @@ import * as t from "../../../types"; export var metadata = { - optional: true + optional: true, + category: "builtin-setup" }; export function Expression(node, parent, scope) { diff --git a/src/babel/transformation/transformers/utility/remove-console.js b/src/babel/transformation/transformers/utility/remove-console.js index 317840ce3e..88106ee69a 100644 --- a/src/babel/transformation/transformers/utility/remove-console.js +++ b/src/babel/transformation/transformers/utility/remove-console.js @@ -1,7 +1,8 @@ import * as t from "../../../types"; export var metadata = { - optional: true + optional: true, + category: "builtin-setup" }; export function CallExpression(node, parent) { diff --git a/src/babel/transformation/transformers/utility/remove-debugger.js b/src/babel/transformation/transformers/utility/remove-debugger.js index f7d84d0e81..b797c700cc 100644 --- a/src/babel/transformation/transformers/utility/remove-debugger.js +++ b/src/babel/transformation/transformers/utility/remove-debugger.js @@ -1,7 +1,8 @@ import * as t from "../../../types"; export var metadata = { - optional: true + optional: true, + category: "builtin-setup" }; export function ExpressionStatement(node) { From 2fd1b2a484fd888591ff4ea7a5f10006a73b1682 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 22:54:15 +0100 Subject: [PATCH 25/30] rename category metadata option to group --- src/babel/transformation/file/index.js | 8 ++++---- src/babel/transformation/index.js | 2 +- .../transformers/es3/member-expression-literals.js | 2 +- .../transformation/transformers/es3/property-literals.js | 2 +- .../transformation/transformers/es6/block-scoping.js | 2 +- .../transformation/transformers/es6/destructuring.js | 2 +- src/babel/transformation/transformers/es6/modules.js | 2 +- .../transformation/transformers/es6/spec.block-scoping.js | 2 +- src/babel/transformation/transformers/es6/tail-call.js | 2 +- .../transformation/transformers/internal/block-hoist.js | 2 +- .../transformers/internal/module-formatter.js | 2 +- src/babel/transformation/transformers/internal/modules.js | 2 +- .../transformers/internal/shadow-functions.js | 2 +- .../transformation/transformers/internal/validation.js | 2 +- .../transformers/minification/dead-code-elimination.js | 2 +- .../minification/member-expression-literals.js | 2 +- .../transformers/minification/property-literals.js | 2 +- .../transformation/transformers/other/regenerator.js | 2 +- .../transformation/transformers/other/runtime/index.js | 2 +- .../transformation/transformers/spec/function-name.js | 2 +- .../transformers/utility/inline-environment-variables.js | 2 +- .../transformers/utility/inline-expressions.js | 2 +- .../transformation/transformers/utility/remove-console.js | 2 +- .../transformers/utility/remove-debugger.js | 2 +- 24 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/babel/transformation/file/index.js b/src/babel/transformation/file/index.js index 7b2a8f1e10..27f0453ed8 100644 --- a/src/babel/transformation/file/index.js +++ b/src/babel/transformation/file/index.js @@ -242,17 +242,17 @@ export default class File { // been merged if (ignore.indexOf(pass) >= 0) continue; - var category = pass.transformer.metadata.category; + var group = pass.transformer.metadata.group; // can't merge - if (!pass.canTransform() || !category) { + if (!pass.canTransform() || !group) { stack.push(pass); continue; } var mergeStack = []; for (let pass of (_stack: Array)) { - if (pass.transformer.metadata.category === category) { + if (pass.transformer.metadata.group === group) { mergeStack.push(pass); ignore.push(pass); } @@ -263,7 +263,7 @@ export default class File { visitors.push(pass.handlers); } var visitor = traverse.visitors.merge(visitors); - var mergeTransformer = new Transformer(category, visitor); + var mergeTransformer = new Transformer(group, visitor); //console.log(mergeTransformer); stack.push(mergeTransformer.buildPass(this)); } diff --git a/src/babel/transformation/index.js b/src/babel/transformation/index.js index 5a523a4ea2..11b0780fd1 100644 --- a/src/babel/transformation/index.js +++ b/src/babel/transformation/index.js @@ -9,7 +9,7 @@ import transformers from "./transformers"; for (var key in transformers) { var transformer = transformers[key]; var metadata = transformer.metadata = transformer.metadata || {}; - metadata.category = metadata.category || "builtin-basic"; + metadata.group = metadata.group || "builtin-basic"; } pipeline.addTransformers(transformers); diff --git a/src/babel/transformation/transformers/es3/member-expression-literals.js b/src/babel/transformation/transformers/es3/member-expression-literals.js index e80f5c62d1..af026a5171 100644 --- a/src/babel/transformation/transformers/es3/member-expression-literals.js +++ b/src/babel/transformation/transformers/es3/member-expression-literals.js @@ -1,7 +1,7 @@ import * as t from "../../../types"; export var metadata = { - category: "builtin-trailing" + group: "builtin-trailing" }; export var MemberExpression = { diff --git a/src/babel/transformation/transformers/es3/property-literals.js b/src/babel/transformation/transformers/es3/property-literals.js index 9fa015e82b..ffb13ddc64 100644 --- a/src/babel/transformation/transformers/es3/property-literals.js +++ b/src/babel/transformation/transformers/es3/property-literals.js @@ -1,7 +1,7 @@ import * as t from "../../../types"; export var metadata = { - category: "builtin-trailing" + group: "builtin-trailing" }; export var Property = { diff --git a/src/babel/transformation/transformers/es6/block-scoping.js b/src/babel/transformation/transformers/es6/block-scoping.js index 515c0711e9..8d8f8a8f88 100644 --- a/src/babel/transformation/transformers/es6/block-scoping.js +++ b/src/babel/transformation/transformers/es6/block-scoping.js @@ -38,7 +38,7 @@ function standardizeLets(declars) { } export var metadata = { - category: "builtin-advanced" + group: "builtin-advanced" }; export function VariableDeclaration(node, parent, scope, file) { diff --git a/src/babel/transformation/transformers/es6/destructuring.js b/src/babel/transformation/transformers/es6/destructuring.js index 53e7b2d22b..5c779cac21 100644 --- a/src/babel/transformation/transformers/es6/destructuring.js +++ b/src/babel/transformation/transformers/es6/destructuring.js @@ -2,7 +2,7 @@ import * as messages from "../../../messages"; import * as t from "../../../types"; export var metadata = { - category: "builtin-advanced" + group: "builtin-advanced" }; export function ForOfStatement(node, parent, scope, file) { diff --git a/src/babel/transformation/transformers/es6/modules.js b/src/babel/transformation/transformers/es6/modules.js index 80772e3163..688fcf2baa 100644 --- a/src/babel/transformation/transformers/es6/modules.js +++ b/src/babel/transformation/transformers/es6/modules.js @@ -9,7 +9,7 @@ function keepBlockHoist(node, nodes) { } export var metadata = { - category: "builtin-modules" + group: "builtin-modules" }; export function ImportDeclaration(node, parent, scope, file) { diff --git a/src/babel/transformation/transformers/es6/spec.block-scoping.js b/src/babel/transformation/transformers/es6/spec.block-scoping.js index 6906b1d7c1..f7fc4ff0ab 100644 --- a/src/babel/transformation/transformers/es6/spec.block-scoping.js +++ b/src/babel/transformation/transformers/es6/spec.block-scoping.js @@ -29,7 +29,7 @@ var visitor = traverse.explode({ export var metadata = { optional: true, - category: "builtin-advanced" + group: "builtin-advanced" }; export var BlockStatement = { diff --git a/src/babel/transformation/transformers/es6/tail-call.js b/src/babel/transformation/transformers/es6/tail-call.js index e3a9482067..4da3e46365 100644 --- a/src/babel/transformation/transformers/es6/tail-call.js +++ b/src/babel/transformation/transformers/es6/tail-call.js @@ -7,7 +7,7 @@ import map from "lodash/collection/map"; import * as t from "../../../types"; export var metadata = { - category: "builtin-trailing" + group: "builtin-trailing" }; exports.Function = function (node, parent, scope, file) { diff --git a/src/babel/transformation/transformers/internal/block-hoist.js b/src/babel/transformation/transformers/internal/block-hoist.js index 2ab60a0755..934d21b1e2 100644 --- a/src/babel/transformation/transformers/internal/block-hoist.js +++ b/src/babel/transformation/transformers/internal/block-hoist.js @@ -1,7 +1,7 @@ import sortBy from "lodash/collection/sortBy"; export var metadata = { - category: "builtin-trailing" + group: "builtin-trailing" }; // Priority: diff --git a/src/babel/transformation/transformers/internal/module-formatter.js b/src/babel/transformation/transformers/internal/module-formatter.js index da48d94c6d..4235eeb4fb 100644 --- a/src/babel/transformation/transformers/internal/module-formatter.js +++ b/src/babel/transformation/transformers/internal/module-formatter.js @@ -1,7 +1,7 @@ import * as strict from "../../helpers/strict"; export var metadata = { - category: "builtin-modules" + group: "builtin-modules" }; export var Program = { diff --git a/src/babel/transformation/transformers/internal/modules.js b/src/babel/transformation/transformers/internal/modules.js index 71d51e7a25..ac64b0e455 100644 --- a/src/babel/transformation/transformers/internal/modules.js +++ b/src/babel/transformation/transformers/internal/modules.js @@ -7,7 +7,7 @@ import * as t from "../../../types"; export var metadata = { - category: "builtin-setup" + group: "builtin-setup" }; export function ImportDeclaration(node, parent, scope, file) { diff --git a/src/babel/transformation/transformers/internal/shadow-functions.js b/src/babel/transformation/transformers/internal/shadow-functions.js index d082fd1ba8..04d11f7811 100644 --- a/src/babel/transformation/transformers/internal/shadow-functions.js +++ b/src/babel/transformation/transformers/internal/shadow-functions.js @@ -86,7 +86,7 @@ function aliasFunction(getBody, path, scope) { // crawling the entire function tree export var metadata = { - category: "builtin-trailing" + group: "builtin-trailing" }; export var Program = { diff --git a/src/babel/transformation/transformers/internal/validation.js b/src/babel/transformation/transformers/internal/validation.js index 31dfabc78e..626c236fee 100644 --- a/src/babel/transformation/transformers/internal/validation.js +++ b/src/babel/transformation/transformers/internal/validation.js @@ -2,7 +2,7 @@ import * as messages from "../../../messages"; import * as t from "../../../types"; export var metadata = { - category: "builtin-setup" + group: "builtin-setup" }; export function ForOfStatement(node, parent, scope, file) { diff --git a/src/babel/transformation/transformers/minification/dead-code-elimination.js b/src/babel/transformation/transformers/minification/dead-code-elimination.js index 58524530bb..8f17b338df 100644 --- a/src/babel/transformation/transformers/minification/dead-code-elimination.js +++ b/src/babel/transformation/transformers/minification/dead-code-elimination.js @@ -19,7 +19,7 @@ function toStatements(node) { export var metadata = { optional: true, - category: "builtin-setup" + group: "builtin-setup" }; export function Identifier(node, parent, scope) { diff --git a/src/babel/transformation/transformers/minification/member-expression-literals.js b/src/babel/transformation/transformers/minification/member-expression-literals.js index 333bd02201..877a924b11 100644 --- a/src/babel/transformation/transformers/minification/member-expression-literals.js +++ b/src/babel/transformation/transformers/minification/member-expression-literals.js @@ -2,7 +2,7 @@ import * as t from "../../../types"; export var metadata = { optional: true, - category: "builtin-trailing" + group: "builtin-trailing" }; export var MemberExpression = { diff --git a/src/babel/transformation/transformers/minification/property-literals.js b/src/babel/transformation/transformers/minification/property-literals.js index 4bdc31ae59..c6cf4e7538 100644 --- a/src/babel/transformation/transformers/minification/property-literals.js +++ b/src/babel/transformation/transformers/minification/property-literals.js @@ -2,7 +2,7 @@ import * as t from "../../../types"; export var metadata = { optional: true, - category: "builtin-trailing" + group: "builtin-trailing" }; export var Property = { diff --git a/src/babel/transformation/transformers/other/regenerator.js b/src/babel/transformation/transformers/other/regenerator.js index d276ec9908..957fc6af94 100644 --- a/src/babel/transformation/transformers/other/regenerator.js +++ b/src/babel/transformation/transformers/other/regenerator.js @@ -2,7 +2,7 @@ import regenerator from "regenerator"; import * as t from "../../../types"; export var metadata = { - category: "regenerator" + group: "regenerator" }; export function Program(ast) { diff --git a/src/babel/transformation/transformers/other/runtime/index.js b/src/babel/transformation/transformers/other/runtime/index.js index 5d9a0dbc44..27dd6c7a15 100644 --- a/src/babel/transformation/transformers/other/runtime/index.js +++ b/src/babel/transformation/transformers/other/runtime/index.js @@ -11,7 +11,7 @@ const RUNTIME_MODULE_NAME = "babel-runtime"; export var metadata = { optional: true, - category: "builtin-post-modules" + group: "builtin-post-modules" }; export function pre(file) { diff --git a/src/babel/transformation/transformers/spec/function-name.js b/src/babel/transformation/transformers/spec/function-name.js index d45d2a4165..2b384fcddb 100644 --- a/src/babel/transformation/transformers/spec/function-name.js +++ b/src/babel/transformation/transformers/spec/function-name.js @@ -1,5 +1,5 @@ export var metadata = { - category: "builtin-setup" + group: "builtin-setup" }; export { diff --git a/src/babel/transformation/transformers/utility/inline-environment-variables.js b/src/babel/transformation/transformers/utility/inline-environment-variables.js index 5c00d13ccc..e40ed44d17 100644 --- a/src/babel/transformation/transformers/utility/inline-environment-variables.js +++ b/src/babel/transformation/transformers/utility/inline-environment-variables.js @@ -2,7 +2,7 @@ import * as t from "../../../types"; export var metadata = { optional: true, - category: "builtin-setup" + group: "builtin-setup" }; var match = t.buildMatchMemberExpression("process.env"); diff --git a/src/babel/transformation/transformers/utility/inline-expressions.js b/src/babel/transformation/transformers/utility/inline-expressions.js index 5fbb8de75c..858a696a90 100644 --- a/src/babel/transformation/transformers/utility/inline-expressions.js +++ b/src/babel/transformation/transformers/utility/inline-expressions.js @@ -2,7 +2,7 @@ import * as t from "../../../types"; export var metadata = { optional: true, - category: "builtin-setup" + group: "builtin-setup" }; export function Expression(node, parent, scope) { diff --git a/src/babel/transformation/transformers/utility/remove-console.js b/src/babel/transformation/transformers/utility/remove-console.js index 88106ee69a..cdbeb53a38 100644 --- a/src/babel/transformation/transformers/utility/remove-console.js +++ b/src/babel/transformation/transformers/utility/remove-console.js @@ -2,7 +2,7 @@ import * as t from "../../../types"; export var metadata = { optional: true, - category: "builtin-setup" + group: "builtin-setup" }; export function CallExpression(node, parent) { diff --git a/src/babel/transformation/transformers/utility/remove-debugger.js b/src/babel/transformation/transformers/utility/remove-debugger.js index b797c700cc..e2d8c7dbe1 100644 --- a/src/babel/transformation/transformers/utility/remove-debugger.js +++ b/src/babel/transformation/transformers/utility/remove-debugger.js @@ -2,7 +2,7 @@ import * as t from "../../../types"; export var metadata = { optional: true, - category: "builtin-setup" + group: "builtin-setup" }; export function ExpressionStatement(node) { From 590a165776bcc754be1705c98c994fe4d3bc59bd Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 23:09:45 +0100 Subject: [PATCH 26/30] move hoistDirectives transformer to builtin-setup --- src/babel/transformation/transformers/index.js | 2 +- .../transformation/transformers/internal/hoist-directives.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/babel/transformation/transformers/index.js b/src/babel/transformation/transformers/index.js index 7977ee9e9f..93551c5181 100644 --- a/src/babel/transformation/transformers/index.js +++ b/src/babel/transformation/transformers/index.js @@ -1,6 +1,7 @@ export default { //- builtin-setup _validation: require("./internal/validation"), + _hoistDirectives: require("./internal/hoist-directives"), "utility.removeDebugger": require("./utility/remove-debugger"), "utility.removeConsole": require("./utility/remove-console"), "utility.inlineEnvironmentVariables": require("./utility/inline-environment-variables"), @@ -52,7 +53,6 @@ export default { "spec.undefinedToVoid": require("./spec/undefined-to-void"), jscript: require("./other/jscript"), flow: require("./other/flow"), - _hoistDirectives: require("./internal/hoist-directives"), //- builtin-advanced "es6.destructuring": require("./es6/destructuring"), diff --git a/src/babel/transformation/transformers/internal/hoist-directives.js b/src/babel/transformation/transformers/internal/hoist-directives.js index 8c0c1280cf..a3dbe27811 100644 --- a/src/babel/transformation/transformers/internal/hoist-directives.js +++ b/src/babel/transformation/transformers/internal/hoist-directives.js @@ -1,5 +1,9 @@ import * as t from "../../../types"; +export var metadata = { + group: "builtin-setup" +}; + export var BlockStatement = { exit(node) { for (var i = 0; i < node.body.length; i++) { From b02a1112bcbfee975c88e2b58e61711579a313bc Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 23:10:02 +0100 Subject: [PATCH 27/30] change ClassExpression visitor to enter instead of exist in the es6.classes transformer --- src/babel/transformation/transformers/es6/classes.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/babel/transformation/transformers/es6/classes.js b/src/babel/transformation/transformers/es6/classes.js index e1bb106659..90ca984e7f 100644 --- a/src/babel/transformation/transformers/es6/classes.js +++ b/src/babel/transformation/transformers/es6/classes.js @@ -17,11 +17,9 @@ export function ClassDeclaration(node, parent, scope, file) { ]); } -export var ClassExpression = { - exit(node, parent, scope, file) { - return new ClassTransformer(this, file).run(); - } -}; +export function ClassExpression(node, parent, scope, file) { + return new ClassTransformer(this, file).run(); +} var collectPropertyReferencesVisitor = { Identifier: { From f0bfdfb699b68c8456ad5f7b1bf289843d125f8e Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 23:13:27 +0100 Subject: [PATCH 28/30] skip traversing back into ReturnStatement replacement when rewriting loops in the es6.blockScoping transformer --- src/babel/transformation/transformers/es6/block-scoping.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/babel/transformation/transformers/es6/block-scoping.js b/src/babel/transformation/transformers/es6/block-scoping.js index 8d8f8a8f88..8d1a5948a3 100644 --- a/src/babel/transformation/transformers/es6/block-scoping.js +++ b/src/babel/transformation/transformers/es6/block-scoping.js @@ -233,6 +233,7 @@ var loopVisitor = { if (replace) { replace = t.returnStatement(replace); + this.skip(); return t.inherits(replace, node); } } From 920c84a1f226462fc502620f7095596e99529cd3 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 23:33:20 +0100 Subject: [PATCH 29/30] move shadow function visitors to entrance instead of exit --- .../transformers/internal/shadow-functions.js | 26 ++++++++----------- .../es6.arrow-functions/arguments/expected.js | 8 +++--- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/babel/transformation/transformers/internal/shadow-functions.js b/src/babel/transformation/transformers/internal/shadow-functions.js index 04d11f7811..92ab2f9687 100644 --- a/src/babel/transformation/transformers/internal/shadow-functions.js +++ b/src/babel/transformation/transformers/internal/shadow-functions.js @@ -89,21 +89,17 @@ export var metadata = { group: "builtin-trailing" }; -export var Program = { - exit(node, parent, scope) { - aliasFunction(function () { - return node.body; - }, this, scope); - } -}; +export function Program(node, parent, scope) { + aliasFunction(function () { + return node.body; + }, this, scope); +} -export var FunctionDeclaration = { - exit(node, parent, scope) { - aliasFunction(function () { - t.ensureBlock(node); - return node.body.body; - }, this, scope); - } -}; +export function FunctionDeclaration(node, parent, scope) { + aliasFunction(function () { + t.ensureBlock(node); + return node.body.body; + }, this, scope); +} export { FunctionDeclaration as FunctionExpression }; diff --git a/test/core/fixtures/transformation/es6.arrow-functions/arguments/expected.js b/test/core/fixtures/transformation/es6.arrow-functions/arguments/expected.js index 2972f6b9b1..3ddd69015f 100644 --- a/test/core/fixtures/transformation/es6.arrow-functions/arguments/expected.js +++ b/test/core/fixtures/transformation/es6.arrow-functions/arguments/expected.js @@ -11,17 +11,17 @@ function one() { one(1, 2); function two() { - var _arguments3 = arguments; + var _arguments2 = arguments; var inner = function inner() { - return _arguments3; + return _arguments2; }; var another = function another() { - var _arguments2 = arguments; + var _arguments3 = arguments; var inner2 = function inner2() { - return _arguments2; + return _arguments3; }; }; From 89e31085d2ee6cd4c135f9f6be90faf3c6522d48 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 8 May 2015 23:33:30 +0100 Subject: [PATCH 30/30] ensure dynamic imports are hoisted --- .../transformers/internal/module-formatter.js | 5 +++++ .../fixtures/transformation/runtime/full/expected.js | 11 +++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/babel/transformation/transformers/internal/module-formatter.js b/src/babel/transformation/transformers/internal/module-formatter.js index 4235eeb4fb..36f6206d72 100644 --- a/src/babel/transformation/transformers/internal/module-formatter.js +++ b/src/babel/transformation/transformers/internal/module-formatter.js @@ -7,6 +7,11 @@ export var metadata = { export var Program = { exit(program, parent, scope, file) { strict.wrap(program, function () { + // ensure that these are at the top, just like normal imports + for (var node of (file.dynamicImports: Array)) { + node._blockHoist = 3; + } + program.body = file.dynamicImports.concat(program.body); }); diff --git a/test/core/fixtures/transformation/runtime/full/expected.js b/test/core/fixtures/transformation/runtime/full/expected.js index 3f3795a497..d83975b0db 100644 --- a/test/core/fixtures/transformation/runtime/full/expected.js +++ b/test/core/fixtures/transformation/runtime/full/expected.js @@ -1,11 +1,5 @@ "use strict"; -_Object$defineProperty(exports, "__esModule", { - value: true -}); - -exports.giveWord = giveWord; - var _regeneratorRuntime = require("babel-runtime/regenerator")["default"]; var _Object$defineProperty = require("babel-runtime/core-js/object/define-property")["default"]; @@ -16,6 +10,11 @@ var _interopRequireDefault = require("babel-runtime/helpers/interop-require-defa var _interopRequireWildcard = require("babel-runtime/helpers/interop-require-wildcard")["default"]; +_Object$defineProperty(exports, "__esModule", { + value: true +}); + +exports.giveWord = giveWord; var marked0$0 = [giveWord].map(_regeneratorRuntime.mark); var _someModule = require("someModule");