From 257403072a1a033e62c7b29c4b9671315634b657 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Sat, 31 Oct 2015 23:25:51 -0400 Subject: [PATCH] include called functions that mutate their inputs --- src/Declaration.js | 4 +++- src/ast/Scope.js | 2 +- src/utils/testForSideEffects.js | 12 ++++++------ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Declaration.js b/src/Declaration.js index 0abc9af..70f94a8 100644 --- a/src/Declaration.js +++ b/src/Declaration.js @@ -2,7 +2,7 @@ import { blank, keys } from './utils/object.js'; import testForSideEffects from './utils/testForSideEffects.js'; export default class Declaration { - constructor ( node ) { + constructor ( node, isParam ) { if ( node ) { if ( node.type === 'FunctionDeclaration' ) { this.isFunctionDeclaration = true; @@ -15,6 +15,7 @@ export default class Declaration { this.statement = null; this.name = null; + this.isParam = isParam; this.isReassigned = false; this.aliases = []; @@ -32,6 +33,7 @@ export default class Declaration { } testForSideEffects ( strongDependencies ) { + // TODO memoize this if ( !this.statement || !this.functionNode ) return; return testForSideEffects( this.functionNode.body, this.functionNode._scope, this.statement, strongDependencies ); } diff --git a/src/ast/Scope.js b/src/ast/Scope.js index a0d1350..3878c8b 100644 --- a/src/ast/Scope.js +++ b/src/ast/Scope.js @@ -46,7 +46,7 @@ export default class Scope { if ( options.params ) { options.params.forEach( param => { extractNames( param ).forEach( name => { - this.declarations[ name ] = new Declaration(); + this.declarations[ name ] = new Declaration( param, true ); }); }); } diff --git a/src/utils/testForSideEffects.js b/src/utils/testForSideEffects.js index 1a42eba..c92622a 100644 --- a/src/utils/testForSideEffects.js +++ b/src/utils/testForSideEffects.js @@ -8,9 +8,7 @@ let pureFunctions = {}; [ // TODO add others to this list from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects 'Array', 'Array.isArray', - 'Error', 'EvalError', 'InternalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError', - 'Object', 'Object.keys' ].forEach( name => pureFunctions[ name ] = true ); @@ -51,8 +49,6 @@ export default function testForSideEffects ( node, scope, statement, strongDepen } else if ( !pureFunctions[ node.callee.name ] ) { hasSideEffect = true; } - - // TODO does function mutate inputs that are needed? } else if ( node.callee.type === 'MemberExpression' ) { @@ -83,8 +79,12 @@ export default function testForSideEffects ( node, scope, statement, strongDepen let subject = node[ modifierNodes[ node.type ] ]; while ( subject.type === 'MemberExpression' ) subject = subject.object; - if ( !scope.findDeclaration( subject.name ) ) { - const declaration = statement.module.trace( subject.name ); + let declaration = scope.findDeclaration( subject.name ); + + if ( declaration ) { + hasSideEffect = declaration.isParam; + } else { + declaration = statement.module.trace( subject.name ); if ( !declaration || declaration.isExternal || declaration.isUsed ) { hasSideEffect = true;