mirror of https://github.com/lukechilds/node.git
Browse Source
PR-URL: https://github.com/nodejs/node/pull/6132 Reviewed-By: Brian White <mscdex@mscdex.net> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: thefourtheye <thechargingvolcano@gmail.com>v4.x
silverwind
9 years ago
committed by
Myles Borins
2040 changed files with 40599 additions and 36892 deletions
File diff suppressed because it is too large
@ -0,0 +1,106 @@ |
|||||
|
/** |
||||
|
* @fileoverview Specify the maximum number of statements allowed per line. |
||||
|
* @author Kenneth Williams |
||||
|
* @copyright 2016 Kenneth Williams. All rights reserved. |
||||
|
* @copyright 2016 Michael Ficarra. All rights reserved. |
||||
|
* See LICENSE file in root directory for full license. |
||||
|
*/ |
||||
|
"use strict"; |
||||
|
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
// Rule Definition
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
module.exports = function(context) { |
||||
|
|
||||
|
var options = context.options[0] || {}, |
||||
|
lastStatementLine = 0, |
||||
|
numberOfStatementsOnThisLine = 0, |
||||
|
maxStatementsPerLine = typeof options.max !== "undefined" ? options.max : 1; |
||||
|
|
||||
|
//--------------------------------------------------------------------------
|
||||
|
// Helpers
|
||||
|
//--------------------------------------------------------------------------
|
||||
|
|
||||
|
/** |
||||
|
* Reports a node |
||||
|
* @param {ASTNode} node The node to report |
||||
|
* @returns {void} |
||||
|
* @private |
||||
|
*/ |
||||
|
function report(node) { |
||||
|
context.report( |
||||
|
node, |
||||
|
"This line has too many statements. Maximum allowed is {{max}}.", |
||||
|
{ max: maxStatementsPerLine }); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Enforce a maximum number of statements per line |
||||
|
* @param {ASTNode} nodes Array of nodes to evaluate |
||||
|
* @returns {void} |
||||
|
* @private |
||||
|
*/ |
||||
|
function enforceMaxStatementsPerLine(nodes) { |
||||
|
if (nodes.length < 1) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
for (var i = 0, l = nodes.length; i < l; ++i) { |
||||
|
var currentStatement = nodes[i]; |
||||
|
|
||||
|
if (currentStatement.loc.start.line === lastStatementLine) { |
||||
|
++numberOfStatementsOnThisLine; |
||||
|
} else { |
||||
|
numberOfStatementsOnThisLine = 1; |
||||
|
lastStatementLine = currentStatement.loc.end.line; |
||||
|
} |
||||
|
if (numberOfStatementsOnThisLine === maxStatementsPerLine + 1) { |
||||
|
report(currentStatement); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Check each line in the body of a node |
||||
|
* @param {ASTNode} node node to evaluate |
||||
|
* @returns {void} |
||||
|
* @private |
||||
|
*/ |
||||
|
function checkLinesInBody(node) { |
||||
|
enforceMaxStatementsPerLine(node.body); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Check each line in the consequent of a switch case |
||||
|
* @param {ASTNode} node node to evaluate |
||||
|
* @returns {void} |
||||
|
* @private |
||||
|
*/ |
||||
|
function checkLinesInConsequent(node) { |
||||
|
enforceMaxStatementsPerLine(node.consequent); |
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------------------
|
||||
|
// Public API
|
||||
|
//--------------------------------------------------------------------------
|
||||
|
|
||||
|
return { |
||||
|
"Program": checkLinesInBody, |
||||
|
"BlockStatement": checkLinesInBody, |
||||
|
"SwitchCase": checkLinesInConsequent |
||||
|
}; |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
module.exports.schema = [ |
||||
|
{ |
||||
|
"type": "object", |
||||
|
"properties": { |
||||
|
"max": { |
||||
|
"type": "integer" |
||||
|
} |
||||
|
}, |
||||
|
"additionalProperties": false |
||||
|
} |
||||
|
]; |
@ -0,0 +1,143 @@ |
|||||
|
|
||||
|
/** |
||||
|
* @fileoverview Rule to require newlines before `return` statement |
||||
|
* @author Kai Cataldo |
||||
|
* @copyright 2016 Kai Cataldo. All rights reserved. |
||||
|
* See LICENSE file in root directory for full license. |
||||
|
*/ |
||||
|
"use strict"; |
||||
|
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
// Rule Definition
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
module.exports = function(context) { |
||||
|
var sourceCode = context.getSourceCode(); |
||||
|
|
||||
|
//--------------------------------------------------------------------------
|
||||
|
// Helpers
|
||||
|
//--------------------------------------------------------------------------
|
||||
|
|
||||
|
/** |
||||
|
* Tests whether node is preceded by supplied tokens |
||||
|
* @param {ASTNode} node - node to check |
||||
|
* @param {array} testTokens - array of tokens to test against |
||||
|
* @returns {boolean} Whether or not the node is preceded by one of the supplied tokens |
||||
|
* @private |
||||
|
*/ |
||||
|
function isPrecededByTokens(node, testTokens) { |
||||
|
var tokenBefore = sourceCode.getTokenBefore(node); |
||||
|
|
||||
|
return testTokens.some(function(token) { |
||||
|
return tokenBefore.value === token; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Checks whether node is the first node after statement or in block |
||||
|
* @param {ASTNode} node - node to check |
||||
|
* @returns {boolean} Whether or not the node is the first node after statement or in block |
||||
|
* @private |
||||
|
*/ |
||||
|
function isFirstNode(node) { |
||||
|
var parentType = node.parent.type; |
||||
|
|
||||
|
if (node.parent.body) { |
||||
|
return Array.isArray(node.parent.body) |
||||
|
? node.parent.body[0] === node |
||||
|
: node.parent.body === node; |
||||
|
} |
||||
|
|
||||
|
if (parentType === "IfStatement") { |
||||
|
return isPrecededByTokens(node, ["else", ")"]); |
||||
|
} else if (parentType === "DoWhileStatement") { |
||||
|
return isPrecededByTokens(node, ["do"]); |
||||
|
} else if (parentType === "SwitchCase") { |
||||
|
return isPrecededByTokens(node, [":"]); |
||||
|
} else { |
||||
|
return isPrecededByTokens(node, [")"]); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns the number of lines of comments that precede the node |
||||
|
* @param {ASTNode} node - node to check for overlapping comments |
||||
|
* @param {token} tokenBefore - previous token to check for overlapping comments |
||||
|
* @returns {number} Number of lines of comments that precede the node |
||||
|
* @private |
||||
|
*/ |
||||
|
function calcCommentLines(node, tokenBefore) { |
||||
|
var comments = sourceCode.getComments(node).leading; |
||||
|
var numLinesComments = 0; |
||||
|
|
||||
|
if (!comments.length) { |
||||
|
return numLinesComments; |
||||
|
} |
||||
|
|
||||
|
comments.forEach(function(comment) { |
||||
|
numLinesComments++; |
||||
|
|
||||
|
if (comment.type === "Block") { |
||||
|
numLinesComments += comment.loc.end.line - comment.loc.start.line; |
||||
|
} |
||||
|
|
||||
|
// avoid counting lines with inline comments twice
|
||||
|
if (comment.loc.start.line === tokenBefore.loc.end.line) { |
||||
|
numLinesComments--; |
||||
|
} |
||||
|
|
||||
|
if (comment.loc.end.line === node.loc.start.line) { |
||||
|
numLinesComments--; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
return numLinesComments; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Checks whether node is preceded by a newline |
||||
|
* @param {ASTNode} node - node to check |
||||
|
* @returns {boolean} Whether or not the node is preceded by a newline |
||||
|
* @private |
||||
|
*/ |
||||
|
function hasNewlineBefore(node) { |
||||
|
var tokenBefore = sourceCode.getTokenBefore(node); |
||||
|
var lineNumTokenBefore = tokenBefore.loc.end.line; |
||||
|
var lineNumNode = node.loc.start.line; |
||||
|
var commentLines = calcCommentLines(node, tokenBefore); |
||||
|
|
||||
|
return (lineNumNode - lineNumTokenBefore - commentLines) > 1; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Reports expected/unexpected newline before return statement |
||||
|
* @param {ASTNode} node - the node to report in the event of an error |
||||
|
* @param {boolean} isExpected - whether the newline is expected or not |
||||
|
* @returns {void} |
||||
|
* @private |
||||
|
*/ |
||||
|
function reportError(node, isExpected) { |
||||
|
var expected = isExpected ? "Expected" : "Unexpected"; |
||||
|
|
||||
|
context.report({ |
||||
|
node: node, |
||||
|
message: expected + " newline before return statement." |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
//--------------------------------------------------------------------------
|
||||
|
// Public
|
||||
|
//--------------------------------------------------------------------------
|
||||
|
|
||||
|
return { |
||||
|
ReturnStatement: function(node) { |
||||
|
if (isFirstNode(node) && hasNewlineBefore(node)) { |
||||
|
reportError(node, false); |
||||
|
} else if (!isFirstNode(node) && !hasNewlineBefore(node)) { |
||||
|
reportError(node, true); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
module.exports.schema = []; |
@ -0,0 +1,126 @@ |
|||||
|
/** |
||||
|
* @fileoverview Restrict usage of duplicate imports. |
||||
|
* @author Simen Bekkhus |
||||
|
* @copyright 2016 Simen Bekkhus. All rights reserved. |
||||
|
* See LICENSE file in root directory for full license. |
||||
|
*/ |
||||
|
"use strict"; |
||||
|
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
// Rule Definition
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
/** |
||||
|
* Returns the name of the module imported or re-exported. |
||||
|
* |
||||
|
* @param {ASTNode} node - A node to get. |
||||
|
* @returns {string} the name of the module, or empty string if no name. |
||||
|
*/ |
||||
|
function getValue(node) { |
||||
|
if (node && node.source && node.source.value) { |
||||
|
return node.source.value.trim(); |
||||
|
} |
||||
|
|
||||
|
return ""; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Checks if the name of the import or export exists in the given array, and reports if so. |
||||
|
* |
||||
|
* @param {RuleContext} context - The ESLint rule context object. |
||||
|
* @param {ASTNode} node - A node to get. |
||||
|
* @param {string} value - The name of the imported or exported module. |
||||
|
* @param {string[]} array - The array containing other imports or exports in the file. |
||||
|
* @param {string} message - A message to be reported after the name of the module |
||||
|
* |
||||
|
* @returns {void} No return value |
||||
|
*/ |
||||
|
function checkAndReport(context, node, value, array, message) { |
||||
|
if (array.indexOf(value) !== -1) { |
||||
|
context.report({ |
||||
|
node: node, |
||||
|
message: "'{{module}}' " + message, |
||||
|
data: {module: value} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @callback nodeCallback |
||||
|
* @param {ASTNode} node - A node to handle. |
||||
|
*/ |
||||
|
|
||||
|
/** |
||||
|
* Returns a function handling the imports of a given file |
||||
|
* |
||||
|
* @param {RuleContext} context - The ESLint rule context object. |
||||
|
* @param {boolean} includeExports - Whether or not to check for exports in addition to imports. |
||||
|
* @param {string[]} importsInFile - The array containing other imports in the file. |
||||
|
* @param {string[]} exportsInFile - The array containing other exports in the file. |
||||
|
* |
||||
|
* @returns {nodeCallback} A function passed to ESLint to handle the statement. |
||||
|
*/ |
||||
|
function handleImports(context, includeExports, importsInFile, exportsInFile) { |
||||
|
return function(node) { |
||||
|
var value = getValue(node); |
||||
|
|
||||
|
if (value) { |
||||
|
checkAndReport(context, node, value, importsInFile, "import is duplicated."); |
||||
|
|
||||
|
if (includeExports) { |
||||
|
checkAndReport(context, node, value, exportsInFile, "import is duplicated as export."); |
||||
|
} |
||||
|
|
||||
|
importsInFile.push(value); |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns a function handling the exports of a given file |
||||
|
* |
||||
|
* @param {RuleContext} context - The ESLint rule context object. |
||||
|
* @param {string[]} importsInFile - The array containing other imports in the file. |
||||
|
* @param {string[]} exportsInFile - The array containing other exports in the file. |
||||
|
* |
||||
|
* @returns {nodeCallback} A function passed to ESLint to handle the statement. |
||||
|
*/ |
||||
|
function handleExports(context, importsInFile, exportsInFile) { |
||||
|
return function(node) { |
||||
|
var value = getValue(node); |
||||
|
|
||||
|
if (value) { |
||||
|
checkAndReport(context, node, value, exportsInFile, "export is duplicated."); |
||||
|
checkAndReport(context, node, value, importsInFile, "export is duplicated as import."); |
||||
|
|
||||
|
exportsInFile.push(value); |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
module.exports = function(context) { |
||||
|
var includeExports = (context.options[0] || {}).includeExports, |
||||
|
importsInFile = [], |
||||
|
exportsInFile = []; |
||||
|
|
||||
|
var handlers = { |
||||
|
"ImportDeclaration": handleImports(context, includeExports, importsInFile, exportsInFile) |
||||
|
}; |
||||
|
|
||||
|
if (includeExports) { |
||||
|
handlers.ExportNamedDeclaration = handleExports(context, importsInFile, exportsInFile); |
||||
|
handlers.ExportAllDeclaration = handleExports(context, importsInFile, exportsInFile); |
||||
|
} |
||||
|
|
||||
|
return handlers; |
||||
|
}; |
||||
|
|
||||
|
module.exports.schema = [{ |
||||
|
"type": "object", |
||||
|
"properties": { |
||||
|
"includeExports": { |
||||
|
"type": "boolean" |
||||
|
} |
||||
|
}, |
||||
|
"additionalProperties": false |
||||
|
}]; |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue