Browse Source

Merge branch 'master' of https://github.com/rollup/rollup

gh-786
Rich-Harris 8 years ago
parent
commit
1d83cbf014
  1. 1
      package.json
  2. 43
      src/ast/nodes/IfStatement.js
  3. 3
      test/function/preserves-var-declarations-in-dead-branches/_config.js
  4. 5
      test/function/preserves-var-declarations-in-dead-branches/main.js

1
package.json

@ -51,7 +51,6 @@
"console-group": "^0.3.1",
"eslint": "^2.13.1",
"eslint-plugin-import": "^2.2.0",
"estree-walker": "^0.2.1",
"is-reference": "^1.0.0",
"istanbul": "^0.4.3",
"magic-string": "^0.15.2",

43
src/ast/nodes/IfStatement.js

@ -1,4 +1,5 @@
import Statement from './shared/Statement.js';
import extractNames from '../utils/extractNames.js';
import { UNKNOWN } from '../values.js';
// Statement types which may contain if-statements as direct children.
@ -11,9 +12,34 @@ const statementsWithIfStatements = new Set([
'WhileStatement'
]);
function handleVarDeclarations ( node, scope ) {
const hoistedVars = [];
function visit ( node ) {
if ( node.type === 'VariableDeclaration' && node.kind === 'var' ) {
node.initialise( scope );
node.declarations.forEach( declarator => {
extractNames( declarator.id ).forEach( name => {
if ( !~hoistedVars.indexOf( name ) ) hoistedVars.push( name );
});
});
}
else if ( !/Function/.test( node.type ) ) {
node.eachChild( visit );
}
}
visit( node );
return hoistedVars;
}
// TODO DRY this out
export default class IfStatement extends Statement {
initialise ( scope ) {
this.scope = scope;
this.testValue = this.test.getValue();
if ( this.module.bundle.treeshake ) {
@ -23,11 +49,15 @@ export default class IfStatement extends Statement {
else if ( this.testValue ) {
this.consequent.initialise( scope );
if ( this.alternate ) this.hoistedVars = handleVarDeclarations( this.alternate, scope );
this.alternate = null;
}
else {
if ( this.alternate ) this.alternate.initialise( scope );
this.hoistedVars = handleVarDeclarations( this.consequent, scope );
this.consequent = null;
}
}
@ -49,6 +79,19 @@ export default class IfStatement extends Statement {
// TODO if no block-scoped declarations, remove enclosing
// curlies and dedent block (if there is a block)
if ( this.hoistedVars ) {
const names = this.hoistedVars
.map( name => {
const declaration = this.scope.findDeclaration( name );
return declaration.activated ? declaration.getName() : null;
})
.filter( Boolean );
if ( names.length > 0 ) {
code.insertLeft( this.start, `var ${names.join( ', ' )};\n\n` );
}
}
if ( this.testValue ) {
code.remove( this.start, this.consequent.start );
code.remove( this.consequent.end, this.end );

3
test/function/preserves-var-declarations-in-dead-branches/_config.js

@ -0,0 +1,3 @@
module.exports = {
description: 'preserves var declarations in dead branches (#977)'
};

5
test/function/preserves-var-declarations-in-dead-branches/main.js

@ -0,0 +1,5 @@
if ( false ) {
var foo;
}
assert.equal( foo, undefined );
Loading…
Cancel
Save