diff --git a/src/Bundle.js b/src/Bundle.js index 604fe80..fd8b003 100644 --- a/src/Bundle.js +++ b/src/Bundle.js @@ -89,7 +89,7 @@ export default class Bundle { // Discover conflicts (i.e. two statements in separate modules both define `foo`) this.statements.forEach( statement => { - keys( statement._defines ).forEach( name => { + keys( statement.defines ).forEach( name => { if ( has( definers, name ) ) { conflicts[ name ] = true; } else { @@ -98,7 +98,7 @@ export default class Bundle { // TODO in good js, there shouldn't be duplicate definitions // per module... but some people write bad js - definers[ name ].push( statement._module ); + definers[ name ].push( statement.module ); }); }); @@ -151,17 +151,17 @@ export default class Bundle { this.statements.forEach( statement => { let replacements = {}; - keys( statement._dependsOn ) - .concat( keys( statement._defines ) ) + keys( statement.dependsOn ) + .concat( keys( statement.defines ) ) .forEach( name => { - const canonicalName = statement._module.getCanonicalName( name ); + const canonicalName = statement.module.getCanonicalName( name ); if ( name !== canonicalName ) { replacements[ name ] = canonicalName; } }); - const source = statement._source.clone().trim(); + const source = statement.source.clone().trim(); // modify exports as necessary if ( /^Export/.test( statement.node.type ) ) { @@ -182,7 +182,7 @@ export default class Bundle { } else if ( statement.node.type === 'ExportDefaultDeclaration' ) { - const module = statement._module; + const module = statement.module; const canonicalName = module.getCanonicalName( 'default' ); if ( statement.node.declaration.type === 'Identifier' && canonicalName === module.getCanonicalName( statement.node.declaration.name ) ) { @@ -200,8 +200,8 @@ export default class Bundle { replaceIdentifiers( statement.node, source, replacements ); // add leading comments - if ( statement._leadingComments.length ) { - const commentBlock = statement._leadingComments.map( comment => { + if ( statement.leadingComments.length ) { + const commentBlock = statement.leadingComments.map( comment => { return comment.block ? `/*${comment.text}*/` : `//${comment.text}`; @@ -211,7 +211,7 @@ export default class Bundle { } // add margin - const margin = Math.max( statement._margin[0], previousMargin ); + const margin = Math.max( statement.margin[0], previousMargin ); const newLines = new Array( margin ).join( '\n' ); // add the statement itself @@ -221,7 +221,7 @@ export default class Bundle { }); // add trailing comments - const comment = statement._trailingComment; + const comment = statement.trailingComment; if ( comment ) { const commentBlock = comment.block ? ` /*${comment.text}*/` : @@ -230,7 +230,7 @@ export default class Bundle { magicString.append( commentBlock ); } - previousMargin = statement._margin[1]; + previousMargin = statement.margin[1]; }); // prepend bundle with internal namespaces diff --git a/src/Module.js b/src/Module.js index 4be3d08..689e5ad 100644 --- a/src/Module.js +++ b/src/Module.js @@ -36,7 +36,8 @@ export default class Module { } this.statements = this.ast.body.map( node => { - return new Statement( node ); + const source = this.code.snip( node.start, node.end ); + return new Statement( node, source, this ); }); this.analyse(); @@ -159,11 +160,11 @@ export default class Module { this.modifications = {}; this.statements.forEach( statement => { - Object.keys( statement._defines ).forEach( name => { + Object.keys( statement.defines ).forEach( name => { this.definitions[ name ] = statement; }); - Object.keys( statement._modifies ).forEach( name => { + Object.keys( statement.modifies ).forEach( name => { if ( !has( this.modifications, name ) ) { this.modifications[ name ] = []; } @@ -289,7 +290,7 @@ export default class Module { statement = this.definitions[ name ]; } - if ( statement && !statement._included ) { + if ( statement && !statement.isIncluded ) { promise = this.expandStatement( statement ); } } @@ -299,14 +300,14 @@ export default class Module { } expandStatement ( statement ) { - if ( statement._included ) return emptyArrayPromise; - statement._included = true; + if ( statement.isIncluded ) return emptyArrayPromise; + statement.isIncluded = true; let result = []; // We have a statement, and it hasn't been included yet. First, include // the statements it depends on - const dependencies = Object.keys( statement._dependsOn ); + const dependencies = Object.keys( statement.dependsOn ); return sequence( dependencies, name => { return this.define( name ).then( definition => { @@ -322,12 +323,12 @@ export default class Module { // then include any statements that could modify the // thing(s) this statement defines .then( () => { - return sequence( keys( statement._defines ), name => { + return sequence( keys( statement.defines ), name => { const modifications = has( this.modifications, name ) && this.modifications[ name ]; if ( modifications ) { return sequence( modifications, statement => { - if ( !statement._included ) { + if ( !statement.isIncluded ) { return this.expandStatement( statement ) .then( statements => { result.push.apply( result, statements ); @@ -349,7 +350,7 @@ export default class Module { return sequence( this.statements, statement => { // skip already-included statements - if ( statement._included ) return; + if ( statement.isIncluded ) return; // skip import declarations if ( statement.node.type === 'ImportDeclaration' ) { diff --git a/src/Statement.js b/src/Statement.js index f043f13..1932166 100644 --- a/src/Statement.js +++ b/src/Statement.js @@ -1,7 +1,19 @@ import { keys } from './utils/object'; export default class Statement { - constructor ( node ) { + constructor ( node, source, module ) { this.node = node; + this.module = module; + this.source = source; + + this.defines = {}; + this.modifies = {}; + this.dependsOn = {}; + + this.isIncluded = false; + + this.leadingComments = [] + this.trailingComment = null; + this.margin = [ 0, 0 ]; } } diff --git a/src/ast/analyse.js b/src/ast/analyse.js index 23ac03a..adae223 100644 --- a/src/ast/analyse.js +++ b/src/ast/analyse.js @@ -13,7 +13,7 @@ export default function analyse ( ast, magicString, module ) { scope.add( name, false ); if ( !scope.parent ) { - currentTopLevelStatement._defines[ name ] = true; + currentTopLevelStatement.defines[ name ] = true; } } @@ -22,7 +22,7 @@ export default function analyse ( ast, magicString, module ) { scope.add( name, true ); if ( !scope.parent ) { - currentTopLevelStatement._defines[ name ] = true; + currentTopLevelStatement.defines[ name ] = true; } } @@ -35,18 +35,6 @@ export default function analyse ( ast, magicString, module ) { const node = statement.node; - Object.defineProperties( statement, { - _defines: { value: {} }, - _modifies: { value: {} }, - _dependsOn: { value: {} }, - _included: { value: false, writable: true }, - _module: { value: module }, - _source: { value: magicString.snip( node.start, node.end ) }, // TODO don't use snip, it's a waste of memory - _margin: { value: [ 0, 0 ] }, - _leadingComments: { value: [] }, - _trailingComment: { value: null, writable: true }, - }); - let trailing = !!previousStatement; // TODO surely this can be neater @@ -67,12 +55,12 @@ export default function analyse ( ast, magicString, module ) { // attach any trailing comment to the previous statement if ( trailing && !/\n/.test( magicString.slice( previousStatement.node.end, comment.start ) ) ) { - previousStatement._trailingComment = comment; + previousStatement.trailingComment = comment; } // then attach leading comments to this statement else { - statement._leadingComments.push( comment ); + statement.leadingComments.push( comment ); } commentIndex += 1; @@ -80,14 +68,14 @@ export default function analyse ( ast, magicString, module ) { } while ( module.comments[ commentIndex ] ); // determine margin - const previousEnd = previousStatement ? ( previousStatement._trailingComment || previousStatement.node ).end : 0; - const start = ( statement._leadingComments[0] || node ).start; + const previousEnd = previousStatement ? ( previousStatement.trailingComment || previousStatement.node ).end : 0; + const start = ( statement.leadingComments[0] || node ).start; const gap = magicString.original.slice( previousEnd, start ); const margin = gap.split( '\n' ).length; - if ( previousStatement ) previousStatement._margin[1] = margin; - statement._margin[0] = margin; + if ( previousStatement ) previousStatement.margin[1] = margin; + statement.margin[0] = margin; walk( statement.node, { enter ( node ) { @@ -177,8 +165,8 @@ export default function analyse ( ast, magicString, module ) { const definingScope = scope.findDefiningScope( node.name ); - if ( ( !definingScope || definingScope.depth === 0 ) && !statement._defines[ node.name ] ) { - statement._dependsOn[ node.name ] = true; + if ( ( !definingScope || definingScope.depth === 0 ) && !statement.defines[ node.name ] ) { + statement.dependsOn[ node.name ] = true; } } @@ -202,7 +190,7 @@ export default function analyse ( ast, magicString, module ) { return; } - statement._modifies[ node.name ] = true; + statement.modifies[ node.name ] = true; } if ( node.type === 'AssignmentExpression' ) {