Browse Source

fix paren issues with tree shaking (#1101 #1128)

legacy-quote-reserved-properties
kzc 8 years ago
parent
commit
ac04b83362
  1. 2
      src/Module.js
  2. 3
      src/ast/nodes/AssignmentExpression.js
  3. 17
      src/ast/nodes/ExportDefaultDeclaration.js
  4. 11
      src/ast/nodes/ParenthesizedExpression.js
  5. 3
      src/ast/nodes/UpdateExpression.js
  6. 2
      src/ast/nodes/index.js
  7. 2
      src/ast/nodes/shared/assignTo.js
  8. 2
      src/ast/nodes/shared/isUsedByBundle.js

2
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';

3
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 );

17
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 );
}

11
src/ast/nodes/ParenthesizedExpression.js

@ -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();
}
}

3
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 );

2
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,

2
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 ) {...}`

2
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;

Loading…
Cancel
Save