From e5801ae400beb7aed2bd9fba4d6ff62e7daf993d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Segersv=C3=A4rd?= Date: Thu, 27 Aug 2015 15:57:33 +0200 Subject: [PATCH] Implemented 'export *' for internal modules * exporting * from external modules isn't supported yet, and raises a warning. --- src/ExternalModule.js | 3 +++ src/Module.js | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/ExternalModule.js b/src/ExternalModule.js index ff6c731..a237a47 100644 --- a/src/ExternalModule.js +++ b/src/ExternalModule.js @@ -8,6 +8,9 @@ export default class ExternalModule { this.name = id; this.module = this; + // Define the external module's name in the bundle scope. + bundle.scope.define( id, this ); + this.isExternal = true; this.importedByBundle = []; diff --git a/src/Module.js b/src/Module.js index 026d9a0..21681ee 100644 --- a/src/Module.js +++ b/src/Module.js @@ -54,6 +54,37 @@ export default class Module { this.locals = bundle.scope.virtual(); this.exports = bundle.scope.virtual(); + const { reference, inScope } = this.exports; + + this.exports.reference = name => { + // If we have it, grab it. + if ( inScope.call( this.exports, name ) ) return reference.call( this.exports, name ); + + // ... otherwise search exportAlls. + for ( const module of this.exportAlls ) { + if ( module.exports.inScope( name ) ) { + return module.exports.reference( name ); + } + } + + throw new Error( `The name ${name} is never exported!` ); + }; + + this.exports.inScope = name => { + if ( inScope.call( this.exports, name ) ) return true; + + for ( const module of this.exportAlls ) { + if ( module.exports.inScope( name ) ) return true; + } + + return false; + }; + + // Create a unique virtual scope for references to the module. + // const unique = bundle.scope.virtual(); + // unique.define( this.name, this ); + // this.reference = unique.reference( this.name ); + this.exportAlls = []; this.reassignments = []; @@ -77,6 +108,11 @@ export default class Module { if ( node.type === 'ExportAllDeclaration' ) { // Store `export * from '...'` statements in an array of delegates. // When an unknown import is encountered, we see if one of them can satisfy it. + + if ( module.isExternal ) { + throw new Error( `Cannot trace 'export *' references through external modules.` ); + } + this.exportAlls.push( module ); }