Browse Source

include called functions that mutate their inputs

better-aggressive
Rich-Harris 9 years ago
parent
commit
257403072a
  1. 4
      src/Declaration.js
  2. 2
      src/ast/Scope.js
  3. 12
      src/utils/testForSideEffects.js

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

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

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

Loading…
Cancel
Save