Browse Source

more fixes

declarations-and-references
Rich-Harris 9 years ago
parent
commit
997b3abe0a
  1. 10
      src/Bundle.js
  2. 2
      src/ExternalModule.js
  3. 114
      src/Module.js
  4. 8
      src/Statement.js

10
src/Bundle.js

@ -4,7 +4,6 @@ import { blank, keys } from './utils/object';
import Module from './Module';
import ExternalModule from './ExternalModule';
import finalisers from './finalisers/index';
import makeLegalIdentifier from './utils/makeLegalIdentifier';
import ensureArray from './utils/ensureArray';
import { defaultResolver, defaultExternalResolver } from './utils/resolveId';
import { defaultLoader } from './utils/load';
@ -60,7 +59,11 @@ export default class Bundle {
module.markAllSideEffects();
});
this.entryModule.markAllExportStatements();
// mark all export statements
entryModule.getExports().forEach( name => {
const declaration = entryModule.traceExport( name );
declaration.statement.mark();
});
this.markAllModifierStatements();
@ -69,7 +72,7 @@ export default class Bundle {
}
// TODO would be better to deconflict once, rather than per-render
deconflict ( es6 ) {
deconflict () {
let nameCount = blank();
// ensure no conflicts with globals
@ -225,6 +228,7 @@ export default class Bundle {
let stronglyDependsOn = {};
function visit ( module ) {
if ( seen[ module.id ] ) return;
seen[ module.id ] = true;
const { strongDependencies, weakDependencies } = module.consolidateDependencies();

2
src/ExternalModule.js

@ -24,7 +24,7 @@ class ExternalDeclaration {
}
if ( this.name === 'default' ) {
return this.module.needsNamed ?
return !es6 && this.module.needsNamed ?
`${this.module.name}__default` :
this.module.name;
}

114
src/Module.js

@ -8,6 +8,21 @@ import getLocation from './utils/getLocation';
import makeLegalIdentifier from './utils/makeLegalIdentifier';
import SOURCEMAPPING_URL from './utils/sourceMappingURL';
class SyntheticDefaultDeclaration {
constructor ( node, statement, name ) {
this.node = node;
this.statement = statement;
this.name = name;
this.references = [];
}
addReference ( reference ) {
reference.declaration = this;
this.name = reference.name;
}
}
export default class Module {
constructor ({ id, source, ast, bundle }) {
this.source = source;
@ -98,6 +113,11 @@ export default class Module {
isAnonymous,
isModified: false // in case of `export default foo; foo = somethingElse`
};
if ( !identifier ) {
// create a synthetic declaration
this.declarations.default = new SyntheticDefaultDeclaration( node, statement, this.defaultName() );
}
}
// export { foo, bar, baz }
@ -272,69 +292,6 @@ export default class Module {
return keys( exports );
}
mark ( name ) {
// shortcut cycles
if ( this.marked[ name ] ) return;
this.marked[ name ] = true;
// The definition for this name is in a different module
if ( this.imports[ name ] ) {
const importDeclaration = this.imports[ name ];
importDeclaration.isUsed = true;
const module = importDeclaration.module;
// suggest names. TODO should this apply to non default/* imports?
if ( importDeclaration.name === 'default' ) {
// TODO this seems ropey
const localName = importDeclaration.localName;
let suggestion = this.suggestedNames[ localName ] || localName;
// special case - the module has its own import by this name
while ( !module.isExternal && module.imports[ suggestion ] ) {
suggestion = `_${suggestion}`;
}
module.suggestName( 'default', suggestion );
} else if ( importDeclaration.name === '*' ) {
const localName = importDeclaration.localName;
const suggestion = this.suggestedNames[ localName ] || localName;
module.suggestName( '*', suggestion );
module.suggestName( 'default', `${suggestion}__default` );
}
if ( importDeclaration.name === 'default' ) {
module.needsDefault = true;
} else if ( importDeclaration.name === '*' ) {
module.needsAll = true;
} else {
module.needsNamed = true;
}
if ( module.isExternal ) {
module.importedByBundle.push( importDeclaration );
}
else if ( importDeclaration.name === '*' ) {
// we need to create an internal namespace
if ( !~this.bundle.internalNamespaceModules.indexOf( module ) ) {
this.bundle.internalNamespaceModules.push( module );
}
module.markAllExportStatements();
}
else {
module.markExport( importDeclaration.name, name, this );
}
}
else {
const statement = name === 'default' ? this.exports.default.statement : this.definitions[ name ];
if ( statement ) statement.mark();
}
}
markAllSideEffects () {
this.statements.forEach( statement => {
statement.markSideEffect();
@ -370,12 +327,6 @@ export default class Module {
});
}
markAllExportStatements () {
this.statements.forEach( statement => {
if ( statement.isExportDeclaration ) statement.mark();
});
}
markExport ( name, suggestedName, importer ) {
const reexport = this.reexports[ name ];
const exportDeclaration = this.exports[ name ];
@ -517,6 +468,15 @@ export default class Module {
return;
}
// skip `export { foo, bar, baz }`
if ( statement.node.type === 'ExportNamedDeclaration' ) {
// skip `export { foo, bar, baz }`
if ( statement.node.specifiers.length ) {
magicString.remove( statement.start, statement.next );
return;
}
}
statement.references.forEach( reference => {
const declaration = reference.declaration;
@ -526,7 +486,9 @@ export default class Module {
declaration.getName( es6 ) :
declaration.name;
magicString.overwrite( start, start + reference.name.length, name );
if ( reference.name !== name ) {
magicString.overwrite( start, start + reference.name.length, name );
}
}
});
@ -549,8 +511,6 @@ export default class Module {
}
else if ( statement.node.type === 'ExportDefaultDeclaration' ) {
const defaultExport = this.exports.default;
// anonymous functions should be converted into declarations
if ( statement.node.declaration.type === 'FunctionExpression' ) {
magicString.overwrite( statement.node.start, statement.node.declaration.start + 8, `function ${this.defaultName()}` );
@ -594,13 +554,19 @@ export default class Module {
return this.trace( exportDeclaration.identifier );
}
throw new Error( 'TODO default expression exports' );
return this.declarations.default;
}
return this.trace( exportDeclaration.localName );
}
// TODO export *
for ( let i = 0; i < this.exportAlls.length; i += 1 ) {
const exportAll = this.exportAlls[i];
const declaration = exportAll.module.traceExport( name );
if ( declaration ) return declaration;
}
return null;
}
}

8
src/Statement.js

@ -81,10 +81,8 @@ export default class Statement {
declaration.statement = this;
});
let references = this.references;
// find references
let scope = this.scope;
let { references, scope } = this;
walk( this.node, {
enter ( node, parent ) {
@ -140,10 +138,6 @@ export default class Statement {
});
}
replaceIdentifiers ( magicString ) {
return magicString;
}
source () {
return this.module.source.slice( this.start, this.end );
}

Loading…
Cancel
Save