Browse Source

borrow sorting logic from esperanto - fixes #36

contingency-plan
Rich Harris 10 years ago
parent
commit
b7e51064ac
  1. 71
      src/Bundle.js
  2. 3
      src/Statement.js
  3. 3
      test/function/cycles-pathological/_config.js

71
src/Bundle.js

@ -112,6 +112,7 @@ export default class Bundle {
.then( statements => {
this.statements = statements;
this.deconflict();
this.sort();
});
}
@ -200,6 +201,76 @@ export default class Bundle {
}
}
sort () {
// TODO avoid this work whenever possible...
let definitions = blank();
// gather definitions
this.statements.forEach( statement => {
keys( statement.defines ).forEach( name => {
const canonicalName = statement.module.getCanonicalName( name );
definitions[ canonicalName ] = statement;
});
});
let strongDeps = blank();
let stronglyDependsOn = blank();
this.statements.forEach( statement => {
const id = statement.id;
strongDeps[ id ] = [];
stronglyDependsOn[ id ] = {};
keys( statement.stronglyDependsOn ).forEach( name => {
if ( statement.defines[ name ] ) return; // TODO seriously... need to fix this
const canonicalName = statement.module.getCanonicalName( name );
const definition = definitions[ canonicalName ];
if ( definition ) strongDeps[ statement.id ].push( definition );
});
});
// add second (and third...) order strong dependencies
this.statements.forEach( statement => {
const id = statement.id;
// add second (and third...) order dependencies
function addStrongDependencies ( dependency ) {
if ( stronglyDependsOn[ id ][ dependency.id ] ) return;
stronglyDependsOn[ id ][ dependency.id ] = true;
strongDeps[ dependency.id ].forEach( addStrongDependencies );
}
strongDeps[ id ].forEach( addStrongDependencies );
});
// reinsert each statement, ensuring its strong dependencies appear first
let sorted = [];
let included = blank();
this.statements.forEach( statement => {
strongDeps[ statement.id ].forEach( place );
function place ( dependency ) {
if ( !stronglyDependsOn[ dependency.id ][ statement.id ] && !included[ dependency.id ] ) {
strongDeps[ dependency.id ].forEach( place );
sorted.push( dependency );
included[ dependency.id ] = true;
}
}
if ( !included[ statement.id ] ) {
sorted.push( statement );
included[ statement.id ] = true;
}
});
this.statements = sorted;
}
generate ( options = {} ) {
let magicString = new MagicString.Bundle({ separator: '' });

3
src/Statement.js

@ -4,14 +4,13 @@ import getLocation from './utils/getLocation';
import walk from './ast/walk';
import Scope from './ast/Scope';
const emptyArrayPromise = Promise.resolve([]);
export default class Statement {
constructor ( node, magicString, module, index ) {
this.node = node;
this.module = module;
this.magicString = magicString;
this.index = index;
this.id = module.path + '#' + index;
this.scope = new Scope();
this.defines = blank();

3
test/function/cycles-pathological/_config.js

@ -14,6 +14,5 @@ module.exports = {
assert.ok( exports.c2.isC );
assert.ok( exports.c2.isD );
assert.ok( exports.d.isD );
},
solo: true
}
};

Loading…
Cancel
Save