Browse Source

separate running from calling

gh-438-b
Rich-Harris 9 years ago
parent
commit
557c7baa34
  1. 83
      src/utils/run.js

83
src/utils/run.js

@ -44,7 +44,56 @@ simdTypes.forEach( t => {
).forEach( name => pureFunctions[ name ] = true );
// TODO add others to this list from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects
function call ( callee, scope, statement, strongDependencies ) {
let hasSideEffect;
while ( callee.type === 'ParenthesizedExpression' ) callee = callee.expression;
if ( callee.type === 'Identifier' ) {
const declaration = scope.findDeclaration( callee.name ) ||
statement.module.trace( callee.name );
if ( declaration ) {
if ( declaration.run( strongDependencies ) ) {
hasSideEffect = true;
}
} else if ( !pureFunctions[ callee.name ] ) {
hasSideEffect = true;
}
}
else if ( callee.type === 'MemberExpression' ) {
const flattened = flatten( callee );
if ( flattened ) {
// if we're calling e.g. Object.keys(thing), there are no side-effects
// TODO make pureFunctions configurable
const declaration = scope.findDeclaration( flattened.name ) || statement.module.trace( flattened.name );
if ( !!declaration || !pureFunctions[ flattened.keypath ] ) {
hasSideEffect = true;
}
} else {
// is not a keypath like `foo.bar.baz` – could be e.g.
// `foo[bar].baz()`. Err on the side of caution
hasSideEffect = true;
}
}
else if ( /FunctionExpression/.test( callee.type ) ) {
if ( run( callee.body, scope, statement, strongDependencies ) ) {
hasSideEffect = true;
}
}
else {
// huh?
console.log( 'callee', callee )
throw new Error( 'Cannot call a non-function' );
}
return hasSideEffect;
}
export default function run ( node, scope, statement, strongDependencies, force ) {
let hasSideEffect = false;
@ -78,39 +127,7 @@ export default function run ( node, scope, statement, strongDependencies, force
}
else if ( node.type === 'CallExpression' || node.type === 'NewExpression' ) {
if ( node.callee.type === 'Identifier' ) {
const declaration = scope.findDeclaration( node.callee.name ) ||
statement.module.trace( node.callee.name );
if ( declaration ) {
if ( declaration.run( strongDependencies ) ) {
hasSideEffect = true;
}
} else if ( !pureFunctions[ node.callee.name ] ) {
hasSideEffect = true;
}
}
else if ( node.callee.type === 'MemberExpression' ) {
const flattened = flatten( node.callee );
if ( flattened ) {
// if we're calling e.g. Object.keys(thing), there are no side-effects
// TODO make pureFunctions configurable
const declaration = scope.findDeclaration( flattened.name ) || statement.module.trace( flattened.name );
if ( !!declaration || !pureFunctions[ flattened.keypath ] ) {
hasSideEffect = true;
}
} else {
// is not a keypath like `foo.bar.baz` – could be e.g.
// `foo[bar].baz()`. Err on the side of caution
hasSideEffect = true;
}
}
// otherwise we're probably dealing with a function expression
else if ( run( node.callee, scope, statement, strongDependencies, true ) ) {
if ( call( node.callee, scope, statement, strongDependencies ) ) {
hasSideEffect = true;
}
}

Loading…
Cancel
Save