swh:1:snp:3af1a03cd091600016317ad7197cfc7dfd1319c7
Tip revision: bdd302443dbc94d00dddc95c7097340eb4f39578 authored by Andreas Stuhlmüller on 28 May 2015, 21:15:45 UTC
0.0.11
0.0.11
Tip revision: bdd3024
optimize.js
'use strict';
var esmangle = require('esmangle');
var estraverse = require('estraverse');
var types = require('ast-types');
var build = types.builders;
var Syntax = estraverse.Syntax;
var fail = require('../syntax').fail;
var inProgram = require('../syntax').inProgram;
function createPipeline() {
var pipeline = [
//* 'pass/hoist-variable-to-arguments',
'pass/transform-dynamic-to-static-property-access',
'pass/transform-dynamic-to-static-property-definition',
'pass/transform-immediate-function-call',
'pass/transform-logical-association',
'pass/reordering-function-declarations',
'pass/remove-unused-label',
'pass/remove-empty-statement',
'pass/remove-wasted-blocks',
'pass/transform-to-compound-assignment',
//* 'pass/transform-to-sequence-expression',
'pass/transform-branch-to-expression',
'pass/transform-typeof-undefined',
'pass/reduce-sequence-expression',
'pass/reduce-branch-jump',
'pass/reduce-multiple-if-statements',
'pass/dead-code-elimination',
'pass/remove-side-effect-free-expressions',
'pass/remove-context-sensitive-expressions',
'pass/tree-based-constant-folding',
//* 'pass/concatenate-variable-definition',
'pass/drop-variable-definition',
// 'pass/remove-unreachable-branch',
'pass/eliminate-duplicate-function-declarations'
];
pipeline = [pipeline.map(esmangle.pass.require)];
pipeline.push({
once: true,
pass: [
'post/transform-static-to-dynamic-property-access',
'post/transform-infinity',
'post/rewrite-boolean',
'post/rewrite-conditional-expression',
'post/omit-parens-in-void-context-iife'
].map(esmangle.pass.require)
});
return pipeline;
}
function identifiersEqual(x, y) {
return (types.namedTypes.Identifier.check(x) &&
types.namedTypes.Identifier.check(y) &&
x.name === y.name);
}
function optimize(node) {
switch (node.type) {
case Syntax.BlockStatement:
for (var i = 0; i < node.body.length; i++) {
var ithNode = node.body[i];
// remove 'var x = x' variable declarations
if (types.namedTypes.VariableDeclaration.check(ithNode)) {
var declaration = ithNode.declarations[0];
if (identifiersEqual(declaration.id, declaration.init)) {
node.body.splice(i, 1);
}
}
}
return node;
case Syntax.ExpressionStatement:
// turn immediate anonymous function calls into blocks
if (types.namedTypes.CallExpression.check(node.expression) &&
types.namedTypes.FunctionExpression.check(node.expression.callee)) {
var funcNode = node.expression.callee;
var appNode = node.expression;
var stmts = [];
// for each argument add a variable definition
for (var i = 0; i < appNode.arguments.length; i++) {
var stmt = build.variableDeclaration(
'var', [build.variableDeclarator(funcNode.params[i], appNode.arguments[i])]);
stmts.push(stmt);
}
// finally, add expressionstatement for func body
stmts.push(funcNode.body);
return build.blockStatement(stmts);
} else {
return node;
}
default:
return node;
}
}
function optimizeMain(node) {
return inProgram(function(node) {
return esmangle.optimize(estraverse.replace(node, {
enter: optimize,
leave: optimize
}), createPipeline(), {
inStrictCode: true,
legacy: false
});
})(node, fail('optimize: inBody', node));
}
module.exports = {
optimize: optimizeMain
};