From a1ed47928deec9ac5ec79b706e4490f83064ee0e Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Fri, 10 Jul 2015 07:42:03 -0400 Subject: [PATCH] reliably prevent statements appearing before earlier statements from same module --- src/Bundle.js | 47 +++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/src/Bundle.js b/src/Bundle.js index 8e18fcb..8e37efa 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -248,22 +248,39 @@ export default class Bundle { let sorted = []; let included = blank(); + function include ( statement ) { + if ( included[ statement.id ] ) return; + included[ statement.id ] = true; + + const len = sorted.length; + let i = 0; + let alreadyIncluded = false; + + for ( i = 0; i < len; i += 1 ) { + // ensure that this statement appears above later statements + // from the same module - in rare situations (#34) they can + // become jumbled + const existing = sorted[i]; + if ( existing.module === statement.module && existing.index > statement.index ) { + sorted.splice( i, 0, statement ); + alreadyIncluded = true; + } + } + + if ( !alreadyIncluded ) sorted.push( statement ); + } + this.statements.forEach( statement => { - strongDeps[ statement.id ].forEach( place ); + strongDeps[ statement.id ].forEach( includeStrongDependency ); - function place ( dependency ) { + function includeStrongDependency ( dependency ) { if ( !stronglyDependsOn[ dependency.id ][ statement.id ] && !included[ dependency.id ] ) { - strongDeps[ dependency.id ].forEach( place ); - sorted.push( dependency ); - - included[ dependency.id ] = true; + strongDeps[ dependency.id ].forEach( includeStrongDependency ); + include( dependency ); } } - if ( !included[ statement.id ] ) { - sorted.push( statement ); - included[ statement.id ] = true; - } + include( statement ); }); this.statements = sorted; @@ -316,16 +333,6 @@ export default class Bundle { let previousIndex = -1; let previousMargin = 0; - this.statements.forEach( ( statement, i ) => { - statement.bundleIndex = i; - }); - - this.statements.sort( ( a, b ) => { - return a.module !== b.module ? - a.bundleIndex - b.bundleIndex : - a.index - b.index; - }); - this.statements.forEach( statement => { // skip `export { foo, bar, baz }` if ( statement.node.type === 'ExportNamedDeclaration' && statement.node.specifiers.length ) {