diff --git a/src/babel/transformation/file/index.js b/src/babel/transformation/file/index.js index c3a0d4d424..aa4cb57b79 100644 --- a/src/babel/transformation/file/index.js +++ b/src/babel/transformation/file/index.js @@ -46,10 +46,9 @@ export default class File { this.data = {}; this.uids = {}; - this.lastStatements = []; - this.log = new Logger(this, opts.filename || "unknown"); - this.opts = this.normalizeOptions(opts); - this.ast = {}; + this.log = new Logger(this, opts.filename || "unknown"); + this.opts = this.normalizeOptions(opts); + this.ast = {}; this.buildTransformers(); } @@ -375,10 +374,6 @@ export default class File { return id; } - isConsequenceExpressionStatement(node: Object): boolean { - return t.isExpressionStatement(node) && this.lastStatements.indexOf(node) >= 0; - } - attachAuxiliaryComment(node: Object): Object { var comment = this.opts.auxiliaryComment; if (comment) { @@ -479,9 +474,12 @@ export default class File { parseOpts.strictMode = features.strict; parseOpts.sourceType = "module"; + this.log.debug("Parse start"); + // return parse(parseOpts, code, (tree) => { + this.log.debug("Parse stop"); this.transform(tree); return this.generate(); }); @@ -504,25 +502,25 @@ export default class File { } transform(ast) { - this.log.debug(); - + this.log.debug("Start set AST"); this.setAst(ast); + this.log.debug("End set AST"); - this.lastStatements = t.getLastStatements(ast.program); + 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()) { modFormatter.init(); } - - this.checkPath(this.path); + this.log.debug("End module formatter init"); this.call("pre"); - each(this.transformerStack, function (pass) { pass.transform(); }); - this.call("post"); } @@ -597,10 +595,14 @@ export default class File { if (opts.ast) result.ast = ast; if (!opts.code) return result; + this.log.debug("Generation start"); + var _result = generate(ast, opts, this.code); result.code = _result.code; result.map = _result.map; + this.log.debug("Generation end"); + if (this.shebang) { // add back shebang result.code = `${this.shebang}\n${result.code}`; 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 b09292b3f3..04ffc4c1b3 100644 --- a/src/babel/transformation/helpers/build-binary-assignment-operator-transformer.js +++ b/src/babel/transformation/helpers/build-binary-assignment-operator-transformer.js @@ -12,7 +12,7 @@ export default function (exports, opts) { exports.ExpressionStatement = function (node, parent, scope, file) { // hit the `AssignmentExpression` one below - if (file.isConsequenceExpressionStatement(node)) return; + if (this.isCompletionRecord()) return; var expr = node.expression; if (!isAssignment(expr)) return; diff --git a/src/babel/transformation/helpers/build-conditional-assignment-operator-transformer.js b/src/babel/transformation/helpers/build-conditional-assignment-operator-transformer.js index 1cae5a8c4a..32cffe3245 100644 --- a/src/babel/transformation/helpers/build-conditional-assignment-operator-transformer.js +++ b/src/babel/transformation/helpers/build-conditional-assignment-operator-transformer.js @@ -8,7 +8,7 @@ export default function (exports, opts) { exports.ExpressionStatement = function (node, parent, scope, file) { // hit the `AssignmentExpression` one below - if (file.isConsequenceExpressionStatement(node)) return; + if (this.isCompletionRecord()) return; var expr = node.expression; if (!opts.is(expr, file)) return; diff --git a/src/babel/transformation/helpers/name-method.js b/src/babel/transformation/helpers/name-method.js index 8d3c7693d9..0dc3628a9d 100644 --- a/src/babel/transformation/helpers/name-method.js +++ b/src/babel/transformation/helpers/name-method.js @@ -82,7 +82,7 @@ var visit = function (node, name, scope) { // so we can safely just set the id and move along as it shadows the // bound function id } - } else { + } else if (state.outerDeclar || scope.hasGlobal(name)) { scope.traverse(node, visitor, state); } @@ -104,7 +104,7 @@ export function property(node, file, scope) { var method = node.value; var state = visit(method, name, scope); - node.value = wrap(state, method, id, scope); + node.value = wrap(state, method, id, scope) || method; } export function bare(node, parent, scope) { @@ -128,7 +128,7 @@ export function bare(node, parent, scope) { } else if (t.isIdentifier(id)) { name = id.name; } else { - return; + return node; } name = t.toIdentifier(name); diff --git a/src/babel/transformation/transformer-pass.js b/src/babel/transformation/transformer-pass.js index f9de37890d..c6ce71f05a 100644 --- a/src/babel/transformation/transformer-pass.js +++ b/src/babel/transformation/transformer-pass.js @@ -46,21 +46,17 @@ export default class TransformerPass { var shouldVisit = this.transformer.shouldVisit; if (!shouldVisit) return; - var shouldSkip = !shouldVisit(path.node); - do { - if (path.getData(this.skipKey) !== false) { - path.setData(this.skipKey, shouldSkip); - } - } while(path = path.parentPath); } transform() { var file = this.file; - file.log.debug(`Running transformer ${this.transformer.key}`); + file.log.debug(`Start transformer ${this.transformer.key}`); traverse(file.ast, this.handlers, file.scope, file); + file.log.debug(`Finish transformer ${this.transformer.key}`); + this.ran = true; } } diff --git a/src/babel/transformation/transformers/es6/arrow-functions.js b/src/babel/transformation/transformers/es6/arrow-functions.js index 33a4c10854..5c013af522 100644 --- a/src/babel/transformation/transformers/es6/arrow-functions.js +++ b/src/babel/transformation/transformers/es6/arrow-functions.js @@ -1,6 +1,6 @@ import * as t from "../../../types"; -export var check = t.isArrowFunctionExpression; +export var shouldVisit = t.isArrowFunctionExpression; export function ArrowFunctionExpression(node) { t.ensureBlock(node); diff --git a/src/babel/transformation/transformers/es6/classes.js b/src/babel/transformation/transformers/es6/classes.js index a17a2becff..12fb1765fe 100644 --- a/src/babel/transformation/transformers/es6/classes.js +++ b/src/babel/transformation/transformers/es6/classes.js @@ -11,7 +11,7 @@ import * as t from "../../../types"; const PROPERTY_COLLISION_METHOD_NAME = "__initializeProperties"; -export var check = t.isClass; +export var shouldVisit = t.isClass; export function ClassDeclaration(node, parent, scope, file) { return t.variableDeclaration("let", [ diff --git a/src/babel/transformation/transformers/es6/destructuring.js b/src/babel/transformation/transformers/es6/destructuring.js index d36ba490cf..c6adc78b6c 100644 --- a/src/babel/transformation/transformers/es6/destructuring.js +++ b/src/babel/transformation/transformers/es6/destructuring.js @@ -1,7 +1,7 @@ import * as messages from "../../../messages"; import * as t from "../../../types"; -export var check = t.isPattern; +export var shouldVisit = t.isPattern; export function ForOfStatement(node, parent, scope, file) { var left = node.left; @@ -111,7 +111,7 @@ export function ExpressionStatement(node, parent, scope, file) { var expr = node.expression; if (expr.type !== "AssignmentExpression") return; if (!t.isPattern(expr.left)) return; - if (file.isConsequenceExpressionStatement(node)) return; + if (this.isCompletionRecord()) return; var destructuring = new DestructuringTransformer({ operator: expr.operator, diff --git a/src/babel/transformation/transformers/es6/for-of.js b/src/babel/transformation/transformers/es6/for-of.js index 46b54a8be9..7d007d6465 100644 --- a/src/babel/transformation/transformers/es6/for-of.js +++ b/src/babel/transformation/transformers/es6/for-of.js @@ -2,7 +2,7 @@ import * as messages from "../../../messages"; import * as util from "../../../util"; import * as t from "../../../types"; -export var check = t.isForOfStatement; +export var shouldVisit = t.isForOfStatement; export function ForOfStatement(node, parent, scope, file) { if (this.get("right").isArrayExpression()) { diff --git a/src/babel/transformation/transformers/es6/object-super.js b/src/babel/transformation/transformers/es6/object-super.js index dce80dd2f1..7a08bdb3b3 100644 --- a/src/babel/transformation/transformers/es6/object-super.js +++ b/src/babel/transformation/transformers/es6/object-super.js @@ -1,7 +1,7 @@ import ReplaceSupers from "../../helpers/replace-supers"; import * as t from "../../../types"; -export var check = t.isSuper; +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.rest.js b/src/babel/transformation/transformers/es6/parameters.rest.js index ed9d1c733c..94685ff293 100644 --- a/src/babel/transformation/transformers/es6/parameters.rest.js +++ b/src/babel/transformation/transformers/es6/parameters.rest.js @@ -2,7 +2,7 @@ import isNumber from "lodash/lang/isNumber"; import * as util from "../../../util"; import * as t from "../../../types"; -export var check = t.isRestElement; +export var shouldVisit = t.isRestElement; var memberExpressionOptimisationVisitor = { enter(node, parent, scope, state) { diff --git a/src/babel/transformation/transformers/es6/spread.js b/src/babel/transformation/transformers/es6/spread.js index 5d8abc2f74..a856453ed0 100644 --- a/src/babel/transformation/transformers/es6/spread.js +++ b/src/babel/transformation/transformers/es6/spread.js @@ -44,7 +44,7 @@ function build(props, scope) { return nodes; } -export var check = t.isSpreadElement; +export var shouldVisit = t.isSpreadElement; export function ArrayExpression(node, parent, scope) { var elements = node.elements; diff --git a/src/babel/transformation/transformers/es7/do-expressions.js b/src/babel/transformation/transformers/es7/do-expressions.js index 787dba3219..8f1e18875f 100644 --- a/src/babel/transformation/transformers/es7/do-expressions.js +++ b/src/babel/transformation/transformers/es7/do-expressions.js @@ -5,7 +5,7 @@ export var metadata = { stage: 0 }; -export var check = t.isDoExpression; +export var shouldVisit = t.isDoExpression; export function DoExpression(node) { var body = node.body.body; diff --git a/src/babel/transformation/transformers/optimisation/flow.for-of.js b/src/babel/transformation/transformers/optimisation/flow.for-of.js index 5e0237d700..a7bf59b174 100644 --- a/src/babel/transformation/transformers/optimisation/flow.for-of.js +++ b/src/babel/transformation/transformers/optimisation/flow.for-of.js @@ -1,7 +1,7 @@ import { _ForOfStatementArray } from "../es6/for-of"; import * as t from "../../../types"; -export var check = t.isForOfStatement; +export var shouldVisit = t.isForOfStatement; export var optional = true; export function ForOfStatement(node, parent, scope, file) { diff --git a/src/babel/transformation/transformers/validation/react.js b/src/babel/transformation/transformers/validation/react.js index fd95e7a046..5666f8c299 100644 --- a/src/babel/transformation/transformers/validation/react.js +++ b/src/babel/transformation/transformers/validation/react.js @@ -1,6 +1,10 @@ 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" })); } diff --git a/src/babel/transformation/transformers/validation/undeclared-variable-check.js b/src/babel/transformation/transformers/validation/undeclared-variable-check.js index f8d3b25a78..01f1f4a86c 100644 --- a/src/babel/transformation/transformers/validation/undeclared-variable-check.js +++ b/src/babel/transformation/transformers/validation/undeclared-variable-check.js @@ -2,7 +2,8 @@ import levenshtein from "leven"; import * as messages from "../../../messages"; export var metadata = { - optional: true + optional: true, + readOnly: true }; export function Identifier(node, parent, scope, file) { diff --git a/src/babel/traversal/path/index.js b/src/babel/traversal/path/index.js index f3401a2a20..267dbbd507 100644 --- a/src/babel/traversal/path/index.js +++ b/src/babel/traversal/path/index.js @@ -73,6 +73,7 @@ export default class TraversalPath { // we're entering a new scope so let's construct it! if (path.isScope()) { + var log = path.isProgram(); ourScope = new Scope(path, scope, file); } @@ -236,7 +237,10 @@ export default class TraversalPath { this.type = this.node && this.node.type; + var log = file && this.type === "Program"; + if (log) file.log.debug("Start scope building"); this.setScope(file); + if (log) file.log.debug("End scope building"); } _remove() { @@ -252,7 +256,7 @@ export default class TraversalPath { var removeParent = false; if (this.parentPath) { removeParent ||= this.parentPath.isExpressionStatement(); - removeParent ||= this.parentPath.isSequenceExpression() && this.parent.expressions.length === 1 + removeParent ||= this.parentPath.isSequenceExpression() && this.parent.expressions.length === 1; if (removeParent) return this.parentPath.remove(); } diff --git a/src/babel/traversal/scope.js b/src/babel/traversal/scope.js index 87addd8627..f28592f337 100644 --- a/src/babel/traversal/scope.js +++ b/src/babel/traversal/scope.js @@ -681,7 +681,7 @@ export default class Scope { */ removeOwnBinding(name: string) { - this.bindings[name] = null; + delete this.bindings[name]; } /** diff --git a/test/core/fixtures/transformation/es7.exponentian-operator/assignment/actual.js b/test/core/fixtures/transformation/es7.exponentian-operator/assignment/actual.js index 3119676676..26439c4220 100644 --- a/test/core/fixtures/transformation/es7.exponentian-operator/assignment/actual.js +++ b/test/core/fixtures/transformation/es7.exponentian-operator/assignment/actual.js @@ -1,2 +1,3 @@ +var num = 1; num **= 2; ; diff --git a/test/core/fixtures/transformation/es7.exponentian-operator/assignment/expected.js b/test/core/fixtures/transformation/es7.exponentian-operator/assignment/expected.js index 771217952d..3cc44c2190 100644 --- a/test/core/fixtures/transformation/es7.exponentian-operator/assignment/expected.js +++ b/test/core/fixtures/transformation/es7.exponentian-operator/assignment/expected.js @@ -1,5 +1,6 @@ "use strict"; +var num = 1; num = Math.pow(num, 2); ; diff --git a/test/core/fixtures/transformation/spec.function-name/assignment/actual.js b/test/core/fixtures/transformation/spec.function-name/assignment/actual.js index 584125ac2e..720d84e7de 100644 --- a/test/core/fixtures/transformation/spec.function-name/assignment/actual.js +++ b/test/core/fixtures/transformation/spec.function-name/assignment/actual.js @@ -4,4 +4,5 @@ var i = function () { var j = function () { ({ j } = 5); + ; }; diff --git a/test/core/fixtures/transformation/spec.function-name/assignment/expected.js b/test/core/fixtures/transformation/spec.function-name/assignment/expected.js index be772c66d0..3c4aa618fd 100644 --- a/test/core/fixtures/transformation/spec.function-name/assignment/expected.js +++ b/test/core/fixtures/transformation/spec.function-name/assignment/expected.js @@ -17,4 +17,6 @@ var i = (function (_i) { var j = function j() { var _ = 5; j = _.j; + + ; };