Skip to content

Commit

Permalink
Chore: Extract generic AST functions to own file
Browse files Browse the repository at this point in the history
  • Loading branch information
Casey Visco committed Aug 13, 2016
1 parent e664406 commit 17cc698
Show file tree
Hide file tree
Showing 13 changed files with 610 additions and 135 deletions.
4 changes: 4 additions & 0 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ rules:
one-var:
- error
- never
func-style:
- error
- declaration
- allowArrowFunctions: true
11 changes: 2 additions & 9 deletions lib/rules/amd-function-arity.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"use strict";

const util = require("../util");
const ast = require("../utils/ast");

module.exports = {
meta: {
Expand Down Expand Up @@ -40,14 +41,6 @@ module.exports = {
const TOO_MANY_PARAMS_MESSAGE = "Too many parameters in {{functionName}} callback (expected {{expected}}, found {{actual}}).";
const TOO_FEW_PARAMS_MESSAGE = "Not enough parameters in {{functionName}} callback (expected {{expected}}, found {{actual}}).";

function isFunctionExpression(node) {
return node.type === "FunctionExpression";
}

function requireHasCallback(node) {
return node.arguments.filter(isFunctionExpression).length;
}

function allUnassignedPathsAreAllowed(dependencyNodes, callbackParams) {
if (typeof allowExtraDependencies === "boolean") {
return allowExtraDependencies;
Expand Down Expand Up @@ -91,7 +84,7 @@ module.exports = {
/* istanbul ignore else: correctly does nothing */
if (util.isDefineCall(node) && util.isAmdDefine(node)) {
checkArity(node, "define");
} else if (util.isRequireCall(node) && requireHasCallback(node)) {
} else if (util.isRequireCall(node) && ast.hasCallback(node)) {
checkArity(node, node.callee.name);
}
}
Expand Down
18 changes: 4 additions & 14 deletions lib/rules/enforce-define.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

const path = require("path");
const util = require("../util");
const ast = require("../utils/ast");

module.exports = {
meta: {
Expand All @@ -33,22 +34,11 @@ module.exports = {
const MESSAGE = "File must be wrapped in a `define` call";
const ignoredFiles = context.options[0] || [];

/**
* Determine if supplied `node` represents an expression of any kind.
*
* @private
* @param {ASTNode} node - node to test
* @returns {Boolean} true if represents an expression statement
*/
function isExpressionStatement(node) {
return node.type === "ExpressionStatement";
}

/**
* Determine if supplied `filename` is allowed to not be wrapped in a
* `define` call.
*
* @param {String} filename - filename to test
* @private
* @param {String} filename - filename to test
* @returns {Boolean} true if filename is allowed
*/
function isIgnoredFile(filename) {
Expand All @@ -67,7 +57,7 @@ module.exports = {
for (let i = 0, length = node.body.length; i < length; i += 1) {
const child = node.body[i];

if (!(isExpressionStatement(child) && util.isDefineCall(child.expression))) {
if (!(ast.isExprStatement(child) && util.isDefineCall(child.expression))) {
context.report(node, MESSAGE);
break;
}
Expand Down
3 changes: 1 addition & 2 deletions lib/rules/no-assign-exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ module.exports = {

/**
* Determine if supplied `node` represents an assignment to `exports`.
*
* @private
* @param {ASTNode} node - AssignmentExpression node to test
* @param {ASTNode} node - AssignmentExpression node to test
* @returns {Boolean} true if represents assignment to `exports`
*/
function isExportsAssignment(node) {
Expand Down
11 changes: 5 additions & 6 deletions lib/rules/no-assign-require.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

"use strict";

const ast = require("../utils/ast");

module.exports = {
meta: {
docs: {},
Expand All @@ -16,36 +18,33 @@ module.exports = {

/**
* Determine if supplied `node` represents a `require` identifier
*
* @private
* @param {ASTNode} node - node to test
* @returns {Boolean} true if `require` identifier
*/
function isRequireIdentifier(node) {
return node.type === "Identifier" && node.name === "require";
return ast.isIdentifier(node) && node.name === "require";
}

/**
* Determine if supplied `node` represents a `window` identifier
*
* @private
* @param {ASTNode} node - node to test
* @returns {Boolean} true if `window` identifier
*/
function isWindowIdentifier(node) {
return node.type === "Identifier" && node.name === "window";
return ast.isIdentifier(node) && node.name === "window";
}

/**
* Determine if supplied `node` represents a `window.require`
* MemberExpression.
*
* @private
* @param {ASTNode} node - node to test
* @returns {Boolean} true if represents `window.require` expression
*/
function isWindowRequireExpr(node) {
return node.type === "MemberExpression" &&
return ast.isMemberExpr(node) &&
isWindowIdentifier(node.object) &&
isRequireIdentifier(node.property);
}
Expand Down
6 changes: 3 additions & 3 deletions lib/rules/no-commonjs-exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"use strict";

const util = require("../util");
const ast = require("../utils/ast");

module.exports = {
meta: {
Expand All @@ -20,13 +21,12 @@ module.exports = {
/**
* Determine if supplied `node` represents an assignment to a property of
* the `exports` object.
*
* @private
* @param {ASTNode} node - AssignmentExpression node to test
* @param {ASTNode} node - AssignmentExpression node to test
* @returns {Boolean} true if represents assignment to property of `exports`
*/
function isExportsPropertyAssignment(node) {
return node.left.type === "MemberExpression" &&
return ast.isMemberExpr(node.left) &&
node.left.object.name === "exports";
}

Expand Down
6 changes: 3 additions & 3 deletions lib/rules/no-commonjs-module-exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"use strict";

const util = require("../util");
const ast = require("../utils/ast");

module.exports = {
meta: {
Expand All @@ -19,13 +20,12 @@ module.exports = {

/**
* Determine if supplied `node` represents an assignment to `module.exports`
*
* @private
* @param {ASTNode} node - AssignmentExpression node to test
* @param {ASTNode} node - AssignmentExpression node to test
* @returns {Boolean} true if represents assignment to `module.exports`
*/
function isModuleExportsAssignment(node) {
return node.left.type === "MemberExpression" &&
return ast.isMemberExpr(node.left) &&
node.left.object.name === "module" &&
node.left.property.name === "exports";
}
Expand Down
2 changes: 0 additions & 2 deletions lib/rules/no-commonjs-return.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ module.exports = {
/**
* Mark entrance into a function by pushing a new object onto the functions
* stack. Store whether function is the actual module definition.
*
* @private
* @param {ASTNode} node - function node to store
* @returns {void}
Expand All @@ -38,7 +37,6 @@ module.exports = {

/**
* Mark exit of a function by popping it off the functions stack.
*
* @private
* @returns {void}
*/
Expand Down
7 changes: 4 additions & 3 deletions lib/rules/no-require-tourl.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"use strict";

const util = require("../util");
const ast = require("../utils/ast");

module.exports = {
meta: {
Expand All @@ -18,10 +19,10 @@ module.exports = {
const NAME_TO_URL_MESSAGE = "Use of `require.nameToUrl` is not allowed.";

function isRequireMemberCall(node, methodName) {
return node.type === "MemberExpression" &&
node.object.type === "Identifier" &&
return ast.isMemberExpr(node) &&
ast.isIdentifier(node.object) &&
util.isRequireIdentifier(node.object) &&
node.property.type === "Identifier" &&
ast.isIdentifier(node.property) &&
node.property.name === methodName;
}

Expand Down
22 changes: 8 additions & 14 deletions lib/rules/one-dependency-per-line.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@
"use strict";

const unique = require("../utils/unique");
const isDefineCall = require("../util").isDefineCall;
const isRequireCall = require("../util").isRequireCall;
const util = require("../util");
const ast = require("../utils/ast");

const isDefineCall = util.isDefineCall;
const isRequireCall = util.isRequireCall;
const isArrayExpr = ast.isArrayExpr;
const isFunctionExpr = ast.isFunctionExpr;
const isStringLiteral = ast.isStringLiteral;

module.exports = {
meta: {
Expand Down Expand Up @@ -60,18 +66,6 @@ module.exports = {

const sourceCode = context.getSourceCode();

function isArrayExpr(node) {
return node.type === "ArrayExpression";
}

function isFunctionExpr(node) {
return node.type === "FunctionExpression";
}

function isStringLiteral(node) {
return node.type === "Literal" && typeof node.value === "string";
}

function lineNum(node) {
return node.loc.start.line;
}
Expand Down
90 changes: 11 additions & 79 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,17 @@

"use strict";

const COMMON_JS_PARAMS = [ "require", "exports", "module" ];
const ast = require("./utils/ast");

/**
* Determine if supplied `node` has no parameter list.
*
* @private
* @param {ASTNode} node - FunctionExpression node to test
* @returns {Boolean} true if has no parameter list
*/
function hasNoParams(node) {
return node.params.length === 0;
}
const hasParams = ast.hasParams;
const isLiteral = ast.isLiteral;
const isStringLiteral = ast.isStringLiteral;
const isArrayExpr = ast.isArrayExpr;
const isObjectExpr = ast.isObjectExpr;
const isFunctionExpr = ast.isFunctionExpr;
const isStringLiteralArray = ast.isStringLiteralArray;

const COMMON_JS_PARAMS = ["require", "exports", "module"];

/**
* Determine if supplied `node` has a parameter list that meets the requirements
Expand All @@ -32,73 +31,6 @@ function hasCommonJsParams(node) {
});
}

/**
* Determine if supplied `node` represents a literal of any kind.
*
* @private
* @param {ASTNode} node - node to test
* @returns {Boolean} true if represents a literal
*/
function isLiteral(node) {
return node && node.type === "Literal";
}

/**
* Determine if supplied `node` represents a string literal.
*
* @private
* @param {ASTNode} node - node to test
* @returns {Boolean} true if represents a string literal
*/
function isStringLiteral(node) {
return node && node.type === "Literal" && typeof node.value === "string";
}

/**
* Determine if supplied `node` represents an array of string literals. Empty
* arrays are also valid here.
*
* @private
* @param {ASTNode} node - ArrayExpression node to test
* @returns {Boolean} true if represents an array of string literals
*/
function isStringLiteralArray(node) {
return node.elements.length === 0 || node.elements.every(isStringLiteral);
}

/**
* Determine if supplied `node` represents an array expression.
*
* @private
* @param {ASTNode} node - node to test
* @returns {Boolean} true if represents an array expression
*/
function isArrayExpr(node) {
return node && node.type === "ArrayExpression";
}

/**
* Determine if supplied `node` represents an object expression.
*
* @private
* @param {ASTNode} node - node to test
* @returns {Boolean} true if represents an object expression
*/
function isObjectExpr(node) {
return node && node.type === "ObjectExpression";
}

/**
* Determine if supplied `node` represents a function expression.
*
* @private
* @param {ASTNode} node - node to test
* @returns {Boolean} true if represents a function expression
*/
function isFunctionExpr(node) {
return node && node.type === "FunctionExpression";
}

/**
* Determine if supplied `node` represents a "simple" function expression. That
* is, one without any parameter list.
Expand All @@ -108,7 +40,7 @@ function isFunctionExpr(node) {
* @returns {Boolean} true if represents a simple function expression
*/
function isSimpleFuncExpr(node) {
return isFunctionExpr(node) && hasNoParams(node);
return isFunctionExpr(node) && !hasParams(node);
}

/**
Expand Down
Loading

0 comments on commit 17cc698

Please sign in to comment.