Browse Source

DRY out code, handle strict vs non-strict

better-aggressive
Rich-Harris 9 years ago
parent
commit
98e890986f
  1. 76
      src/ast/conditions.js
  2. 1
      test/function/skips-dead-branches-f/_config.js
  3. 8
      test/function/skips-dead-branches-g/_config.js
  4. 11
      test/function/skips-dead-branches-g/main.js

76
src/ast/conditions.js

@ -1,65 +1,39 @@
function isEqualTest ( node ) { export function isTruthy ( node ) {
return node.type === 'BinaryExpression' && ( node.operator === '===' || node.operator === '==' ); if ( node.type === 'Literal' ) return !!node.value;
if ( node.type === 'ParenthesizedExpression' ) return isTruthy( node.expression );
if ( node.operator in operators ) return operators[ node.operator ]( node );
} }
function isNotEqualTest ( node ) { export function isFalsy ( node ) {
return node.type === 'BinaryExpression' && ( node.operator === '!==' || node.operator === '!=' ); return not( isTruthy( node ) );
} }
function nodesAreEqual ( a, b ) { function not ( value ) {
if ( a.type !== b.type ) return false; return value === undefined ? value : !value;
if ( a.type === 'Literal' ) return a.value === b.value
if ( a.type === 'Identifier' ) return a.name === b.name && a.name !== 'NaN';
return false;
} }
function nodesAreNotEqual ( a, b ) { function equals ( a, b, strict ) {
if ( a.type !== b.type ) return false; if ( a.type !== b.type ) return undefined;
if ( a.type === 'Literal' ) return a.value != b.value; if ( a.type === 'Identifier' ) return a.name === b.name && a.name !== 'NaN';
if ( a.type === 'Identifier' ) return a.name != b.name || a.name === 'NaN'; if ( a.type === 'Literal' ) return strict ? a.value === b.value : a.value == b.value;
return false;
} }
export function isTruthy ( node ) { const operators = {
if ( node.type === 'Literal' && node.value ) return true; '==': x => {
if ( node.type === 'ParenthesizedExpression' ) return isTruthy( node.expression ); return equals( x.left, x.right, false );
},
if ( isEqualTest( node ) ) return nodesAreEqual( node.left, node.right );
if ( isNotEqualTest( node ) ) return nodesAreNotEqual( node.left, node.right );
if ( node.type === 'UnaryExpression' ) { '!=': x => not( operators['==']( x ) ),
if ( node.operator === '!' ) return isFalsy( node.argument );
return false;
}
if ( node.type === 'LogicalExpression' ) { '===': x => {
if ( node.operator === '&&' ) return isTruthy( node.left ) && isTruthy( node.right ); return equals( x.left, x.right, true );
if ( node.operator === '||' ) return isTruthy( node.left ) || isTruthy( node.right ); },
return false;
}
return false; '!==': x => not( operators['===']( x ) ),
}
export function isFalsy ( node ) { '!': x => isFalsy( x.argument ),
if ( node.type === 'Literal' && !node.value ) return true;
if ( node.type === 'ParenthesizedExpression' ) return isFalsy( node.expression );
if ( isEqualTest( node ) ) return nodesAreNotEqual( node.left, node.right ); '&&': x => isTruthy( x.left ) && isTruthy( x.right ),
if ( isNotEqualTest( node ) ) return nodesAreEqual( node.left, node.right );
if ( node.type === 'UnaryExpression' ) { '||': x => isTruthy( x.left ) || isTruthy( x.right )
if ( node.operator === '!' ) return isTruthy( node.argument ); };
return false;
}
if ( node.type === 'LogicalExpression' ) {
if ( node.operator === '&&' ) return isFalsy( node.left ) || isFalsy( node.right );
if ( node.operator === '||' ) return isFalsy( node.left ) && isFalsy( node.right );
return false;
}
return false;
}

1
test/function/skips-dead-branches-f/_config.js

@ -1,7 +1,6 @@
var assert = require( 'assert' ); var assert = require( 'assert' );
module.exports = { module.exports = {
solo: true,
description: 'skips a dead branch (f)', description: 'skips a dead branch (f)',
code: function ( code ) { code: function ( code ) {
assert.equal( code.indexOf( 'obj.foo = function' ), -1, code ); assert.equal( code.indexOf( 'obj.foo = function' ), -1, code );

8
test/function/skips-dead-branches-g/_config.js

@ -0,0 +1,8 @@
var assert = require( 'assert' );
module.exports = {
description: 'skips a dead branch (g)',
code: function ( code ) {
assert.equal( code.indexOf( 'obj.foo = function' ), -1, code );
}
}

11
test/function/skips-dead-branches-g/main.js

@ -0,0 +1,11 @@
var obj = {};
obj.foo = function () {
console.log( 'this should be excluded' );
}
function bar () {
console.log( 'this should be included' );
}
if ( 42 != '42' ) obj.foo();
bar();
Loading…
Cancel
Save