From ac04b8336247436ed462c8169a19947fa753105f Mon Sep 17 00:00:00 2001 From: kzc Date: Fri, 9 Dec 2016 14:39:05 -0500 Subject: [PATCH] fix paren issues with tree shaking (#1101 #1128) --- src/Module.js | 2 +- src/ast/nodes/AssignmentExpression.js | 3 +-- src/ast/nodes/ExportDefaultDeclaration.js | 17 ++++++++++++----- src/ast/nodes/ParenthesizedExpression.js | 11 ----------- src/ast/nodes/UpdateExpression.js | 3 +-- src/ast/nodes/index.js | 2 -- src/ast/nodes/shared/assignTo.js | 2 -- src/ast/nodes/shared/isUsedByBundle.js | 2 -- 8 files changed, 15 insertions(+), 27 deletions(-) delete mode 100644 src/ast/nodes/ParenthesizedExpression.js diff --git a/src/Module.js b/src/Module.js index 81a097c..ae01215 100644 --- a/src/Module.js +++ b/src/Module.js @@ -18,7 +18,7 @@ function tryParse ( code, comments, acornOptions, id ) { ecmaVersion: 7, sourceType: 'module', onComment: ( block, text, start, end ) => comments.push({ block, text, start, end }), - preserveParens: true + preserveParens: false }, acornOptions )); } catch ( err ) { err.code = 'PARSE_ERROR'; diff --git a/src/ast/nodes/AssignmentExpression.js b/src/ast/nodes/AssignmentExpression.js index f1fbcf3..6e4aa2b 100644 --- a/src/ast/nodes/AssignmentExpression.js +++ b/src/ast/nodes/AssignmentExpression.js @@ -5,8 +5,7 @@ import { NUMBER, STRING } from '../values.js'; export default class AssignmentExpression extends Node { bind ( scope ) { - let subject = this.left; - while ( this.left.type === 'ParenthesizedExpression' ) subject = subject.expression; + const subject = this.left; this.subject = subject; disallowIllegalReassignment( scope, subject ); diff --git a/src/ast/nodes/ExportDefaultDeclaration.js b/src/ast/nodes/ExportDefaultDeclaration.js index 81ae1c9..f583682 100644 --- a/src/ast/nodes/ExportDefaultDeclaration.js +++ b/src/ast/nodes/ExportDefaultDeclaration.js @@ -49,11 +49,18 @@ export default class ExportDefaultDeclaration extends Node { const treeshake = this.module.bundle.treeshake; const name = this.getName( es ); + // paren workaround: find first non-whitespace character position after `export default` + let declaration_start; + if ( this.declaration ) { + const statementStr = code.original.slice( this.start, this.end ); + declaration_start = this.start + statementStr.match(/^export\s+default\s*/)[0].length; + } + if ( this.shouldInclude || this.declaration.activated ) { if ( this.activated ) { if ( functionOrClassDeclaration.test( this.declaration.type ) ) { if ( this.declaration.id ) { - code.remove( this.start, this.declaration.start ); + code.remove( this.start, declaration_start ); } else { throw new Error( 'TODO anonymous class/function declaration' ); } @@ -65,14 +72,14 @@ export default class ExportDefaultDeclaration extends Node { code.remove( this.leadingCommentStart || this.start, this.next || this.end ); return; // don't render children. TODO this seems like a bit of a hack } else { - code.overwrite( this.start, this.declaration.start, `${this.module.bundle.varOrConst} ${name} = ` ); + code.overwrite( this.start, declaration_start, `${this.module.bundle.varOrConst} ${name} = ` ); } this.insertSemicolon( code ); } } else { // remove `var foo` from `var foo = bar()`, if `foo` is unused - code.remove( this.start, this.declaration.start ); + code.remove( this.start, declaration_start ); } super.render( code, es ); @@ -82,10 +89,10 @@ export default class ExportDefaultDeclaration extends Node { code.remove( this.leadingCommentStart || this.start, this.next || this.end ); } else { const hasEffects = this.declaration.hasEffects( this.module.scope ); - code.remove( this.start, hasEffects ? this.declaration.start : this.next || this.end ); + code.remove( this.start, hasEffects ? declaration_start : this.next || this.end ); } } else { - code.overwrite( this.start, this.declaration.start, `${this.module.bundle.varOrConst} ${name} = ` ); + code.overwrite( this.start, declaration_start, `${this.module.bundle.varOrConst} ${name} = ` ); } // code.remove( this.start, this.next || this.end ); } diff --git a/src/ast/nodes/ParenthesizedExpression.js b/src/ast/nodes/ParenthesizedExpression.js deleted file mode 100644 index 7037804..0000000 --- a/src/ast/nodes/ParenthesizedExpression.js +++ /dev/null @@ -1,11 +0,0 @@ -import Node from '../Node.js'; - -export default class ParenthesizedExpression extends Node { - getPossibleValues ( values ) { - return this.expression.getPossibleValues( values ); - } - - getValue () { - return this.expression.getValue(); - } -} diff --git a/src/ast/nodes/UpdateExpression.js b/src/ast/nodes/UpdateExpression.js index 656da69..9fcea9d 100644 --- a/src/ast/nodes/UpdateExpression.js +++ b/src/ast/nodes/UpdateExpression.js @@ -5,8 +5,7 @@ import { NUMBER } from '../values.js'; export default class UpdateExpression extends Node { bind ( scope ) { - let subject = this.argument; - while ( this.argument.type === 'ParenthesizedExpression' ) subject = subject.expression; + const subject = this.argument; this.subject = subject; disallowIllegalReassignment( scope, this.argument ); diff --git a/src/ast/nodes/index.js b/src/ast/nodes/index.js index 94d2f4c..1c3ba4c 100644 --- a/src/ast/nodes/index.js +++ b/src/ast/nodes/index.js @@ -24,7 +24,6 @@ import Literal from './Literal.js'; import MemberExpression from './MemberExpression.js'; import NewExpression from './NewExpression.js'; import ObjectExpression from './ObjectExpression.js'; -import ParenthesizedExpression from './ParenthesizedExpression.js'; import ReturnStatement from './ReturnStatement.js'; import Statement from './shared/Statement.js'; import TemplateLiteral from './TemplateLiteral.js'; @@ -63,7 +62,6 @@ export default { MemberExpression, NewExpression, ObjectExpression, - ParenthesizedExpression, ReturnStatement, SwitchStatement: Statement, TemplateLiteral, diff --git a/src/ast/nodes/shared/assignTo.js b/src/ast/nodes/shared/assignTo.js index 03512e1..2ec7d17 100644 --- a/src/ast/nodes/shared/assignTo.js +++ b/src/ast/nodes/shared/assignTo.js @@ -8,8 +8,6 @@ export default function assignToForLoopLeft ( node, scope, value ) { } else { - while ( node.type === 'ParenthesizedExpression' ) node = node.expression; - if ( node.type === 'MemberExpression' ) { // apparently this is legal JavaScript? Though I don't know what // kind of monster would write `for ( foo.bar of thing ) {...}` diff --git a/src/ast/nodes/shared/isUsedByBundle.js b/src/ast/nodes/shared/isUsedByBundle.js index 07e315f..d33561a 100644 --- a/src/ast/nodes/shared/isUsedByBundle.js +++ b/src/ast/nodes/shared/isUsedByBundle.js @@ -1,8 +1,6 @@ import { UNKNOWN } from '../../values.js'; export default function isUsedByBundle ( scope, node ) { - while ( node.type === 'ParenthesizedExpression' ) node = node.expression; - // const expression = node; while ( node.type === 'MemberExpression' ) node = node.object;