1/** 2 * Utility functions common to ESLint rules. 3 */ 4'use strict'; 5 6function isRequireCall(node) { 7 return node.callee.type === 'Identifier' && node.callee.name === 'require'; 8} 9module.exports.isRequireCall = isRequireCall; 10 11module.exports.isString = function(node) { 12 return node && node.type === 'Literal' && typeof node.value === 'string'; 13}; 14 15module.exports.isDefiningError = function(node) { 16 return node.expression && 17 node.expression.type === 'CallExpression' && 18 node.expression.callee && 19 node.expression.callee.name === 'E' && 20 node.expression.arguments.length !== 0; 21}; 22 23/** 24 * Returns true if any of the passed in modules are used in 25 * require calls. 26 */ 27module.exports.isRequired = function(node, modules) { 28 return isRequireCall(node) && node.arguments.length !== 0 && 29 modules.includes(node.arguments[0].value); 30}; 31 32/** 33* Return true if common module is required 34* in AST Node under inspection 35*/ 36const commonModuleRegExp = new RegExp(/^(\.\.\/)*common(\.js)?$/); 37module.exports.isCommonModule = function(node) { 38 return isRequireCall(node) && 39 node.arguments.length !== 0 && 40 commonModuleRegExp.test(node.arguments[0].value); 41}; 42 43/** 44 * Returns true if any of the passed in modules are used in 45 * process.binding() or internalBinding() calls. 46 */ 47module.exports.isBinding = function(node, modules) { 48 const isProcessBinding = node.callee.object && 49 node.callee.object.name === 'process' && 50 node.callee.property.name === 'binding'; 51 52 return (isProcessBinding || node.callee.name === 'internalBinding') && 53 modules.includes(node.arguments[0].value); 54}; 55 56/** 57 * Returns true is the node accesses any property in the properties 58 * array on the 'common' object. 59 */ 60module.exports.usesCommonProperty = function(node, properties) { 61 if (node.name) { 62 return properties.includes(node.name); 63 } 64 if (node.property) { 65 return properties.includes(node.property.name); 66 } 67 return false; 68}; 69 70/** 71 * Returns true if the passed in node is inside an if statement block, 72 * and the block also has a call to skip. 73 */ 74module.exports.inSkipBlock = function(node) { 75 let hasSkipBlock = false; 76 if (node.test && 77 node.test.type === 'UnaryExpression' && 78 node.test.operator === '!') { 79 const consequent = node.consequent; 80 if (consequent.body) { 81 consequent.body.some((expressionStatement) => { 82 if (hasSkip(expressionStatement.expression)) { 83 return hasSkipBlock = true; 84 } 85 return false; 86 }); 87 } else if (hasSkip(consequent.expression)) { 88 hasSkipBlock = true; 89 } 90 } 91 return hasSkipBlock; 92}; 93 94function hasSkip(expression) { 95 return expression && 96 expression.callee && 97 (expression.callee.name === 'skip' || 98 expression.callee.property && 99 expression.callee.property.name === 'skip'); 100} 101