Browse Source

remove _private props from Statement

contingency-plan
Rich Harris 10 years ago
parent
commit
1b36c09e50
  1. 24
      src/Bundle.js
  2. 21
      src/Module.js
  3. 14
      src/Statement.js
  4. 34
      src/ast/analyse.js

24
src/Bundle.js

@ -89,7 +89,7 @@ export default class Bundle {
// Discover conflicts (i.e. two statements in separate modules both define `foo`) // Discover conflicts (i.e. two statements in separate modules both define `foo`)
this.statements.forEach( statement => { this.statements.forEach( statement => {
keys( statement._defines ).forEach( name => { keys( statement.defines ).forEach( name => {
if ( has( definers, name ) ) { if ( has( definers, name ) ) {
conflicts[ name ] = true; conflicts[ name ] = true;
} else { } else {
@ -98,7 +98,7 @@ export default class Bundle {
// TODO in good js, there shouldn't be duplicate definitions // TODO in good js, there shouldn't be duplicate definitions
// per module... but some people write bad js // 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 => { this.statements.forEach( statement => {
let replacements = {}; let replacements = {};
keys( statement._dependsOn ) keys( statement.dependsOn )
.concat( keys( statement._defines ) ) .concat( keys( statement.defines ) )
.forEach( name => { .forEach( name => {
const canonicalName = statement._module.getCanonicalName( name ); const canonicalName = statement.module.getCanonicalName( name );
if ( name !== canonicalName ) { if ( name !== canonicalName ) {
replacements[ name ] = canonicalName; replacements[ name ] = canonicalName;
} }
}); });
const source = statement._source.clone().trim(); const source = statement.source.clone().trim();
// modify exports as necessary // modify exports as necessary
if ( /^Export/.test( statement.node.type ) ) { if ( /^Export/.test( statement.node.type ) ) {
@ -182,7 +182,7 @@ export default class Bundle {
} }
else if ( statement.node.type === 'ExportDefaultDeclaration' ) { else if ( statement.node.type === 'ExportDefaultDeclaration' ) {
const module = statement._module; const module = statement.module;
const canonicalName = module.getCanonicalName( 'default' ); const canonicalName = module.getCanonicalName( 'default' );
if ( statement.node.declaration.type === 'Identifier' && canonicalName === module.getCanonicalName( statement.node.declaration.name ) ) { 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 ); replaceIdentifiers( statement.node, source, replacements );
// add leading comments // add leading comments
if ( statement._leadingComments.length ) { if ( statement.leadingComments.length ) {
const commentBlock = statement._leadingComments.map( comment => { const commentBlock = statement.leadingComments.map( comment => {
return comment.block ? return comment.block ?
`/*${comment.text}*/` : `/*${comment.text}*/` :
`//${comment.text}`; `//${comment.text}`;
@ -211,7 +211,7 @@ export default class Bundle {
} }
// add margin // 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' ); const newLines = new Array( margin ).join( '\n' );
// add the statement itself // add the statement itself
@ -221,7 +221,7 @@ export default class Bundle {
}); });
// add trailing comments // add trailing comments
const comment = statement._trailingComment; const comment = statement.trailingComment;
if ( comment ) { if ( comment ) {
const commentBlock = comment.block ? const commentBlock = comment.block ?
` /*${comment.text}*/` : ` /*${comment.text}*/` :
@ -230,7 +230,7 @@ export default class Bundle {
magicString.append( commentBlock ); magicString.append( commentBlock );
} }
previousMargin = statement._margin[1]; previousMargin = statement.margin[1];
}); });
// prepend bundle with internal namespaces // prepend bundle with internal namespaces

21
src/Module.js

@ -36,7 +36,8 @@ export default class Module {
} }
this.statements = this.ast.body.map( node => { 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(); this.analyse();
@ -159,11 +160,11 @@ export default class Module {
this.modifications = {}; this.modifications = {};
this.statements.forEach( statement => { this.statements.forEach( statement => {
Object.keys( statement._defines ).forEach( name => { Object.keys( statement.defines ).forEach( name => {
this.definitions[ name ] = statement; this.definitions[ name ] = statement;
}); });
Object.keys( statement._modifies ).forEach( name => { Object.keys( statement.modifies ).forEach( name => {
if ( !has( this.modifications, name ) ) { if ( !has( this.modifications, name ) ) {
this.modifications[ name ] = []; this.modifications[ name ] = [];
} }
@ -289,7 +290,7 @@ export default class Module {
statement = this.definitions[ name ]; statement = this.definitions[ name ];
} }
if ( statement && !statement._included ) { if ( statement && !statement.isIncluded ) {
promise = this.expandStatement( statement ); promise = this.expandStatement( statement );
} }
} }
@ -299,14 +300,14 @@ export default class Module {
} }
expandStatement ( statement ) { expandStatement ( statement ) {
if ( statement._included ) return emptyArrayPromise; if ( statement.isIncluded ) return emptyArrayPromise;
statement._included = true; statement.isIncluded = true;
let result = []; let result = [];
// We have a statement, and it hasn't been included yet. First, include // We have a statement, and it hasn't been included yet. First, include
// the statements it depends on // the statements it depends on
const dependencies = Object.keys( statement._dependsOn ); const dependencies = Object.keys( statement.dependsOn );
return sequence( dependencies, name => { return sequence( dependencies, name => {
return this.define( name ).then( definition => { return this.define( name ).then( definition => {
@ -322,12 +323,12 @@ export default class Module {
// then include any statements that could modify the // then include any statements that could modify the
// thing(s) this statement defines // thing(s) this statement defines
.then( () => { .then( () => {
return sequence( keys( statement._defines ), name => { return sequence( keys( statement.defines ), name => {
const modifications = has( this.modifications, name ) && this.modifications[ name ]; const modifications = has( this.modifications, name ) && this.modifications[ name ];
if ( modifications ) { if ( modifications ) {
return sequence( modifications, statement => { return sequence( modifications, statement => {
if ( !statement._included ) { if ( !statement.isIncluded ) {
return this.expandStatement( statement ) return this.expandStatement( statement )
.then( statements => { .then( statements => {
result.push.apply( result, statements ); result.push.apply( result, statements );
@ -349,7 +350,7 @@ export default class Module {
return sequence( this.statements, statement => { return sequence( this.statements, statement => {
// skip already-included statements // skip already-included statements
if ( statement._included ) return; if ( statement.isIncluded ) return;
// skip import declarations // skip import declarations
if ( statement.node.type === 'ImportDeclaration' ) { if ( statement.node.type === 'ImportDeclaration' ) {

14
src/Statement.js

@ -1,7 +1,19 @@
import { keys } from './utils/object'; import { keys } from './utils/object';
export default class Statement { export default class Statement {
constructor ( node ) { constructor ( node, source, module ) {
this.node = node; 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 ];
} }
} }

34
src/ast/analyse.js

@ -13,7 +13,7 @@ export default function analyse ( ast, magicString, module ) {
scope.add( name, false ); scope.add( name, false );
if ( !scope.parent ) { 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 ); scope.add( name, true );
if ( !scope.parent ) { 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; 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; let trailing = !!previousStatement;
// TODO surely this can be neater // 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 // attach any trailing comment to the previous statement
if ( trailing && !/\n/.test( magicString.slice( previousStatement.node.end, comment.start ) ) ) { if ( trailing && !/\n/.test( magicString.slice( previousStatement.node.end, comment.start ) ) ) {
previousStatement._trailingComment = comment; previousStatement.trailingComment = comment;
} }
// then attach leading comments to this statement // then attach leading comments to this statement
else { else {
statement._leadingComments.push( comment ); statement.leadingComments.push( comment );
} }
commentIndex += 1; commentIndex += 1;
@ -80,14 +68,14 @@ export default function analyse ( ast, magicString, module ) {
} while ( module.comments[ commentIndex ] ); } while ( module.comments[ commentIndex ] );
// determine margin // determine margin
const previousEnd = previousStatement ? ( previousStatement._trailingComment || previousStatement.node ).end : 0; const previousEnd = previousStatement ? ( previousStatement.trailingComment || previousStatement.node ).end : 0;
const start = ( statement._leadingComments[0] || node ).start; const start = ( statement.leadingComments[0] || node ).start;
const gap = magicString.original.slice( previousEnd, start ); const gap = magicString.original.slice( previousEnd, start );
const margin = gap.split( '\n' ).length; const margin = gap.split( '\n' ).length;
if ( previousStatement ) previousStatement._margin[1] = margin; if ( previousStatement ) previousStatement.margin[1] = margin;
statement._margin[0] = margin; statement.margin[0] = margin;
walk( statement.node, { walk( statement.node, {
enter ( node ) { enter ( node ) {
@ -177,8 +165,8 @@ export default function analyse ( ast, magicString, module ) {
const definingScope = scope.findDefiningScope( node.name ); const definingScope = scope.findDefiningScope( node.name );
if ( ( !definingScope || definingScope.depth === 0 ) && !statement._defines[ node.name ] ) { if ( ( !definingScope || definingScope.depth === 0 ) && !statement.defines[ node.name ] ) {
statement._dependsOn[ node.name ] = true; statement.dependsOn[ node.name ] = true;
} }
} }
@ -202,7 +190,7 @@ export default function analyse ( ast, magicString, module ) {
return; return;
} }
statement._modifies[ node.name ] = true; statement.modifies[ node.name ] = true;
} }
if ( node.type === 'AssignmentExpression' ) { if ( node.type === 'AssignmentExpression' ) {

Loading…
Cancel
Save