Browse Source

actually making some progress, maybe

value-tracking
Rich-Harris 8 years ago
parent
commit
53e5e156b0
  1. 30
      src/ast/nodes/ArrowFunctionExpression.js
  2. 5
      src/ast/nodes/AssignmentExpression.js
  3. 29
      src/ast/nodes/FunctionExpression.js
  4. 5
      src/ast/nodes/MemberExpression.js
  5. 2
      src/ast/nodes/NewExpression.js
  6. 4
      src/ast/nodes/ThrowStatement.js
  7. 7
      src/ast/nodes/VariableDeclaration.js
  8. 2
      src/ast/nodes/VariableDeclarator.js
  9. 6
      src/ast/nodes/shared/FunctionValue.js
  10. 1
      test/form/exclude-unnecessary-modifications/_config.js
  11. 2
      test/form/side-effect-h/_expected/amd.js
  12. 2
      test/form/side-effect-h/_expected/cjs.js
  13. 2
      test/form/side-effect-h/_expected/es.js
  14. 2
      test/form/side-effect-h/_expected/iife.js
  15. 2
      test/form/side-effect-h/_expected/umd.js
  16. 2
      test/form/side-effect-h/main.js

30
src/ast/nodes/ArrowFunctionExpression.js

@ -1,36 +1,13 @@
import Node from '../Node.js';
import Scope from '../scopes/Scope.js';
import extractNames from '../utils/extractNames.js';
import FunctionValue from './shared/FunctionValue.js';
export default class ArrowFunctionExpression extends Node {
bind ( scope ) {
super.bind( this.scope || scope );
}
call ( context, args ) {
// TODO account for `this` and `arguments`
if ( this.isCalling ) return; // recursive functions
this.isCalling = true;
this.body.scope.initialise();
args.forEach( ( arg, i ) => {
const param = this.params[i];
if ( param.type !== 'Identifier' ) {
throw new Error( 'TODO desctructuring' );
}
throw new Error( 'TODO setValue' );
});
for ( const node of this.body.body ) {
node.run();
}
this.isCalling = false;
}
findScope ( functionScope ) {
return this.scope || this.parent.findScope( functionScope );
}
@ -62,8 +39,7 @@ export default class ArrowFunctionExpression extends Node {
super.initialise( this.scope );
}
markReturnStatements () {
// TODO implicit returns
this.returnStatements.forEach( statement => statement.mark() );
run () {
return new FunctionValue( this );
}
}

5
src/ast/nodes/AssignmentExpression.js

@ -43,9 +43,6 @@ export default class AssignmentExpression extends Node {
initialise ( scope ) {
this.scope = scope;
this.module.bundle.potentialEffects.push( this );
super.initialise( scope );
}
@ -54,6 +51,8 @@ export default class AssignmentExpression extends Node {
}
run () {
this.module.bundle.potentialEffects.push( this );
const rightValue = this.right.run();
if ( this.operator === '=' ) {

29
src/ast/nodes/FunctionExpression.js

@ -21,31 +21,6 @@ export default class FunctionExpression extends Node {
this.body.bind();
}
call ( context, args ) {
if ( this.isCalling ) return; // recursive functions
this.isCalling = true;
this.body.scope.initialise();
args.forEach( ( arg, i ) => {
const param = this.params[i];
if ( !param ) return;
if ( param.type !== 'Identifier' ) {
throw new Error( 'TODO desctructuring' );
}
this.body.scope.setValue( param.name, arg );
});
for ( const node of this.body.body ) {
node.run();
}
this.isCalling = false;
}
getName () {
return this.name;
}
@ -74,10 +49,6 @@ export default class FunctionExpression extends Node {
super.mark();
}
markReturnStatements () {
this.returnStatements.forEach( statement => statement.mark() );
}
run () {
return new FunctionValue( this );
}

5
src/ast/nodes/MemberExpression.js

@ -132,6 +132,11 @@ export default class MemberExpression extends Node {
const objectValue = this.object.run();
const propValue = this.computed ? this.property.run() : this.property.name;
if ( !objectValue ) {
console.log( this.object )
console.log( `${this}` )
}
if ( !objectValue.setProperty ) {
console.log( `${this}` )
console.log( objectValue );

2
src/ast/nodes/NewExpression.js

@ -42,6 +42,6 @@ export default class NewExpression extends Node {
}
// TODO context...
return this.callee.call( this.arguments );
return this.callee.call( undefined, this.arguments );
}
}

4
src/ast/nodes/ThrowStatement.js

@ -4,4 +4,8 @@ export default class ThrowStatement extends Node {
hasEffects () {
return true;
}
run () {
this.mark();
}
}

7
src/ast/nodes/VariableDeclaration.js

@ -25,8 +25,6 @@ export default class VariableDeclaration extends Node {
render ( code, es ) {
const treeshake = this.module.bundle.treeshake;
console.group( `rendering ${this}` )
let shouldSeparate = false;
let separator;
@ -46,7 +44,6 @@ export default class VariableDeclaration extends Node {
if ( declarator.id.type === 'Identifier' ) {
const proxy = declarator.proxies.get( declarator.id.name );
const isExportedAndReassigned = !es && proxy.exportName && proxy.isReassigned;
console.log( `declarator.init && declarator.init.isMarked`, declarator.init && declarator.init.isMarked )
if ( isExportedAndReassigned ) {
if ( declarator.init ) {
@ -93,8 +90,6 @@ export default class VariableDeclaration extends Node {
declarator.render( code, es );
}
console.log( `empty`, empty )
if ( treeshake && empty ) {
code.remove( this.leadingCommentStart || this.start, this.next || this.end );
} else {
@ -108,7 +103,5 @@ export default class VariableDeclaration extends Node {
this.insertSemicolon( code );
}
}
console.groupEnd()
}
}

2
src/ast/nodes/VariableDeclarator.js

@ -52,8 +52,6 @@ export default class VariableDeclarator extends Node {
if ( this.activated ) return;
this.activated = true;
console.log( `activating ${this}` )
this.mark();
if ( this.init ) this.init.markChildren();
}

6
src/ast/nodes/shared/FunctionValue.js

@ -34,10 +34,12 @@ export default class FunctionValue {
throw new Error( 'TODO desctructuring' );
}
this.node.body.scope.setValue( param.name, arg );
this.node.body.scope.setValue( param.name, arg.run() );
});
for ( const node of this.node.body.body ) {
const body = this.node.type === 'ArrowFunctionExpression' && this.node.body.type !== 'BlockStatement' ? [ this.node.body ] : this.node.body.body;
for ( const node of body ) {
node.run();
if ( node.type === 'ReturnStatement' ) {
returnValue = node.argument ? node.argument.run() : undefined; // TODO represent undefined

1
test/form/exclude-unnecessary-modifications/_config.js

@ -1,4 +1,3 @@
module.exports = {
solo: true,
description: 'statements that modify definitions within unused functions are excluded'
};

2
test/form/side-effect-h/_expected/amd.js

@ -2,7 +2,7 @@ define(function () { 'use strict';
function foo ( ok ) {
if ( !ok ) {
throw new Error( 'this will be ignored' );
throw new Error( 'this will be included' );
}
}

2
test/form/side-effect-h/_expected/cjs.js

@ -2,7 +2,7 @@
function foo ( ok ) {
if ( !ok ) {
throw new Error( 'this will be ignored' );
throw new Error( 'this will be included' );
}
}

2
test/form/side-effect-h/_expected/es.js

@ -1,6 +1,6 @@
function foo ( ok ) {
if ( !ok ) {
throw new Error( 'this will be ignored' );
throw new Error( 'this will be included' );
}
}

2
test/form/side-effect-h/_expected/iife.js

@ -3,7 +3,7 @@ var myBundle = (function () {
function foo ( ok ) {
if ( !ok ) {
throw new Error( 'this will be ignored' );
throw new Error( 'this will be included' );
}
}

2
test/form/side-effect-h/_expected/umd.js

@ -6,7 +6,7 @@
function foo ( ok ) {
if ( !ok ) {
throw new Error( 'this will be ignored' );
throw new Error( 'this will be included' );
}
}

2
test/form/side-effect-h/main.js

@ -1,6 +1,6 @@
function foo ( ok ) {
if ( !ok ) {
throw new Error( 'this will be ignored' );
throw new Error( 'this will be included' );
}
}

Loading…
Cancel
Save