remove transformer prepass and various other optimisations

This commit is contained in:
Sebastian McKenzie 2015-04-26 05:26:21 +01:00
parent 0f1f5e3565
commit f72782b71c
22 changed files with 52 additions and 40 deletions

View File

@ -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}`;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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", [

View File

@ -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,

View File

@ -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()) {

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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" }));
}

View File

@ -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) {

View File

@ -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();
}

View File

@ -681,7 +681,7 @@ export default class Scope {
*/
removeOwnBinding(name: string) {
this.bindings[name] = null;
delete this.bindings[name];
}
/**

View File

@ -1,2 +1,3 @@
var num = 1;
num **= 2;
;

View File

@ -1,5 +1,6 @@
"use strict";
var num = 1;
num = Math.pow(num, 2);
;

View File

@ -4,4 +4,5 @@ var i = function () {
var j = function () {
({ j } = 5);
;
};

View File

@ -17,4 +17,6 @@ var i = (function (_i) {
var j = function j() {
var _ = 5;
j = _.j;
;
};