From 73c08381da9683a7cb9412b307b539a9bd9da0f2 Mon Sep 17 00:00:00 2001 From: Rich-Harris <richard.a.harris@gmail.com> Date: Sat, 3 Oct 2015 22:34:58 -0400 Subject: [PATCH] mark side-effects that apply to included declarations --- src/Bundle.js | 11 ++++++++--- src/Module.js | 6 +++++- src/Statement.js | 17 +++++++++++++---- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index 25831b8..f8408cc 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -55,9 +55,14 @@ export default class Bundle { module.bindReferences(); }); - this.modules.forEach( module => { - module.markAllSideEffects(); - }); + let settled = false; + while ( !settled ) { + settled = true; + + this.modules.forEach( module => { + if ( module.markAllSideEffects() ) settled = false; + }); + } // mark all export statements entryModule.getExports().forEach( name => { diff --git a/src/Module.js b/src/Module.js index 6cc27da..9569878 100644 --- a/src/Module.js +++ b/src/Module.js @@ -297,9 +297,13 @@ export default class Module { } markAllSideEffects () { + let hasSideEffect = false; + this.statements.forEach( statement => { - statement.markSideEffect(); + if ( statement.markSideEffect() ) hasSideEffect = true; }); + + return hasSideEffect; } parse ( ast ) { diff --git a/src/Statement.js b/src/Statement.js index fe1682c..f7b6f28 100644 --- a/src/Statement.js +++ b/src/Statement.js @@ -107,7 +107,7 @@ export default class Statement { this.skip(); // don't descend from `foo.bar.baz` into `foo.bar` } }, - leave: ( node ) => { + leave ( node ) { if ( node._scope ) scope = scope.parent; } }); @@ -125,7 +125,10 @@ export default class Statement { } markSideEffect () { + if ( this.isIncluded ) return; + const statement = this; + let hasSideEffect = false; walk( this.node, { enter ( node, parent ) { @@ -134,7 +137,7 @@ export default class Statement { // If this is a top-level call expression, or an assignment to a global, // this statement will need to be marked if ( node.type === 'CallExpression' || node.type === 'NewExpression' ) { - statement.mark(); + hasSideEffect = true; } else if ( node.type in modifierNodes ) { @@ -143,11 +146,17 @@ export default class Statement { const declaration = statement.module.trace( subject.name ); - // global - if ( !declaration ) statement.mark(); + if ( !declaration || declaration.statement.isIncluded ) { + hasSideEffect = true; + } } + + if ( hasSideEffect ) this.skip(); } }); + + if ( hasSideEffect ) statement.mark(); + return hasSideEffect; } source () {