From ae48cc1691433e588636543218c492cb6fc99265 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 16 Jun 2015 17:48:21 -0400 Subject: [PATCH 1/3] failing test for #26 --- test/function/statement-order/_config.js | 15 +++++++++++++++ test/function/statement-order/answer.js | 17 +++++++++++++++++ test/function/statement-order/main.js | 3 +++ 3 files changed, 35 insertions(+) create mode 100644 test/function/statement-order/_config.js create mode 100644 test/function/statement-order/answer.js create mode 100644 test/function/statement-order/main.js diff --git a/test/function/statement-order/_config.js b/test/function/statement-order/_config.js new file mode 100644 index 0000000..7831c04 --- /dev/null +++ b/test/function/statement-order/_config.js @@ -0,0 +1,15 @@ +var assert = require( 'assert' ); + +module.exports = { + description: 'correct statement order is preserved even in weird edge cases', + context: { + getAnswer: function ( obj ) { + return obj.answer; + } + }, + exports: function ( exports ) { + assert.equal( exports, 'right' ); + }, + solo: true, + show: true +}; diff --git a/test/function/statement-order/answer.js b/test/function/statement-order/answer.js new file mode 100644 index 0000000..d49dcae --- /dev/null +++ b/test/function/statement-order/answer.js @@ -0,0 +1,17 @@ +var prop, +answer; + +var foo = { answer: 'wrong' }; +var bar = { answer: 'right' }; + +if ( typeof bar === "object" ) { + for ( prop in bar ) { + if ( bar.hasOwnProperty(prop) ) { + foo[prop] = bar[prop]; + } + } +} + +answer = getAnswer( foo ); + +export default answer; diff --git a/test/function/statement-order/main.js b/test/function/statement-order/main.js new file mode 100644 index 0000000..808b675 --- /dev/null +++ b/test/function/statement-order/main.js @@ -0,0 +1,3 @@ +import answer from './answer'; +var answer2 = answer; +export default answer2; From 207cb9dfbab29ae29a0bf9308d18f25af37df099 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 16 Jun 2015 18:15:37 -0400 Subject: [PATCH 2/3] break apart top-level var declarations with multiple declarators - fixes #26 --- src/Module.js | 55 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/src/Module.js b/src/Module.js index 3fa88fc..f682260 100644 --- a/src/Module.js +++ b/src/Module.js @@ -28,30 +28,59 @@ export default class Module { // Try to extract a list of top-level statements/declarations. If // the parse fails, attach file info and abort + let ast; + try { - const ast = parse( source, { + ast = parse( source, { ecmaVersion: 6, sourceType: 'module', onComment: ( block, text, start, end ) => this.comments.push({ block, text, start, end }) }); - - walk( ast, { - enter: node => { - this.magicString.addSourcemapLocation( node.start ); - this.magicString.addSourcemapLocation( node.end ); - } - }); - - this.statements = ast.body.map( ( node, i ) => { - const magicString = this.magicString.snip( node.start, node.end ).trim(); - return new Statement( node, magicString, this, i ); - }); } catch ( err ) { err.code = 'PARSE_ERROR'; err.file = path; throw err; } + walk( ast, { + enter: node => { + this.magicString.addSourcemapLocation( node.start ); + this.magicString.addSourcemapLocation( node.end ); + } + }); + + this.statements = []; + + ast.body.map( node => { + // special case - top-level var declarations with multiple declarators + // should be split up. Otherwise, we may end up including code we + // don't need, just because an unwanted declarator is included + if ( node.type === 'VariableDeclaration' && node.declarations.length > 1 ) { + node.declarations.forEach( declarator => { + const magicString = this.magicString.snip( declarator.start, declarator.end ).trim(); + magicString.prepend( `${node.kind} ` ).append( ';' ); + + const syntheticNode = { + type: 'VariableDeclaration', + kind: node.kind, + start: node.start, + end: node.end, + declarations: [ declarator ] + }; + + const statement = new Statement( syntheticNode, magicString, this, this.statements.length ); + this.statements.push( statement ); + }); + } + + else { + const magicString = this.magicString.snip( node.start, node.end ).trim(); + const statement = new Statement( node, magicString, this, this.statements.length ); + + this.statements.push( statement ); + } + }); + this.importDeclarations = this.statements.filter( isImportDeclaration ); this.exportDeclarations = this.statements.filter( isExportDeclaration ); From 29b54f9eeab751d9bd2987769b7e10e914a2bcf8 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 16 Jun 2015 18:18:24 -0400 Subject: [PATCH 3/3] tidy up --- test/function/statement-order/_config.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/function/statement-order/_config.js b/test/function/statement-order/_config.js index 7831c04..92efd7d 100644 --- a/test/function/statement-order/_config.js +++ b/test/function/statement-order/_config.js @@ -9,7 +9,5 @@ module.exports = { }, exports: function ( exports ) { assert.equal( exports, 'right' ); - }, - solo: true, - show: true + } };