mirror of https://github.com/lukechilds/node.git
Browse Source
PR-URL: https://github.com/nodejs/node/pull/8478 Reviewed-By: James M Snell <jasnell@gmail.com>v7.x
Rich Trott
8 years ago
95 changed files with 5347 additions and 403 deletions
File diff suppressed because it is too large
@ -0,0 +1,101 @@ |
|||
/** |
|||
* @fileoverview Rule to enforce the position of line comments |
|||
* @author Alberto Rodríguez |
|||
*/ |
|||
"use strict"; |
|||
|
|||
//------------------------------------------------------------------------------
|
|||
// Rule Definition
|
|||
//------------------------------------------------------------------------------
|
|||
|
|||
module.exports = { |
|||
meta: { |
|||
docs: { |
|||
description: "enforce position of line comments", |
|||
category: "Stylistic Issues", |
|||
recommended: false |
|||
}, |
|||
|
|||
schema: [ |
|||
{ |
|||
oneOf: [ |
|||
{ |
|||
enum: ["above", "beside"] |
|||
}, |
|||
{ |
|||
type: "object", |
|||
properties: { |
|||
position: { |
|||
enum: ["above", "beside"] |
|||
}, |
|||
ignorePattern: { |
|||
type: "string" |
|||
}, |
|||
applyDefaultPatterns: { |
|||
type: "boolean" |
|||
} |
|||
}, |
|||
additionalProperties: false |
|||
} |
|||
] |
|||
} |
|||
] |
|||
}, |
|||
|
|||
create(context) { |
|||
const DEFAULT_IGNORE_PATTERN = "^\\s*(?:eslint|jshint\\s+|jslint\\s+|istanbul\\s+|globals?\\s+|exported\\s+|jscs|falls?\\s?through)"; |
|||
const options = context.options[0]; |
|||
|
|||
let above, |
|||
ignorePattern, |
|||
applyDefaultPatterns = true; |
|||
|
|||
if (!options || typeof option === "string") { |
|||
above = !options || options === "above"; |
|||
|
|||
} else { |
|||
above = options.position === "above"; |
|||
ignorePattern = options.ignorePattern; |
|||
applyDefaultPatterns = options.applyDefaultPatterns !== false; |
|||
} |
|||
|
|||
const defaultIgnoreRegExp = new RegExp(DEFAULT_IGNORE_PATTERN); |
|||
const customIgnoreRegExp = new RegExp(ignorePattern); |
|||
const sourceCode = context.getSourceCode(); |
|||
|
|||
//--------------------------------------------------------------------------
|
|||
// Public
|
|||
//--------------------------------------------------------------------------
|
|||
|
|||
return { |
|||
LineComment(node) { |
|||
if (applyDefaultPatterns && defaultIgnoreRegExp.test(node.value)) { |
|||
return; |
|||
} |
|||
|
|||
if (ignorePattern && customIgnoreRegExp.test(node.value)) { |
|||
return; |
|||
} |
|||
|
|||
const previous = sourceCode.getTokenOrCommentBefore(node); |
|||
const isOnSameLine = previous && previous.loc.end.line === node.loc.start.line; |
|||
|
|||
if (above) { |
|||
if (isOnSameLine) { |
|||
context.report({ |
|||
node, |
|||
message: "Expected comment to be above code." |
|||
}); |
|||
} |
|||
} else { |
|||
if (!isOnSameLine) { |
|||
context.report({ |
|||
node, |
|||
message: "Expected comment to be beside code." |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
} |
|||
}; |
@ -0,0 +1,165 @@ |
|||
/** |
|||
* @fileoverview Require or disallow newlines around directives. |
|||
* @author Kai Cataldo |
|||
*/ |
|||
|
|||
"use strict"; |
|||
|
|||
const astUtils = require("../ast-utils"); |
|||
|
|||
//------------------------------------------------------------------------------
|
|||
// Rule Definition
|
|||
//------------------------------------------------------------------------------
|
|||
|
|||
module.exports = { |
|||
meta: { |
|||
docs: { |
|||
description: "require or disallow newlines around directives", |
|||
category: "Stylistic Issues", |
|||
recommended: false |
|||
}, |
|||
schema: [{ |
|||
oneOf: [ |
|||
{ |
|||
enum: ["always", "never"] |
|||
}, |
|||
{ |
|||
type: "object", |
|||
properties: { |
|||
before: { |
|||
enum: ["always", "never"] |
|||
}, |
|||
after: { |
|||
enum: ["always", "never"] |
|||
}, |
|||
}, |
|||
additionalProperties: false, |
|||
minProperties: 2 |
|||
} |
|||
] |
|||
}] |
|||
}, |
|||
|
|||
create(context) { |
|||
const sourceCode = context.getSourceCode(); |
|||
const config = context.options[0] || "always"; |
|||
const expectLineBefore = typeof config === "string" ? config : config.before; |
|||
const expectLineAfter = typeof config === "string" ? config : config.after; |
|||
|
|||
//--------------------------------------------------------------------------
|
|||
// Helpers
|
|||
//--------------------------------------------------------------------------
|
|||
|
|||
/** |
|||
* Check if node is preceded by a blank newline. |
|||
* @param {ASTNode} node Node to check. |
|||
* @returns {boolean} Whether or not the passed in node is preceded by a blank newline. |
|||
*/ |
|||
function hasNewlineBefore(node) { |
|||
const tokenBefore = sourceCode.getTokenOrCommentBefore(node); |
|||
const tokenLineBefore = tokenBefore ? tokenBefore.loc.end.line : 0; |
|||
|
|||
return node.loc.start.line - tokenLineBefore >= 2; |
|||
} |
|||
|
|||
/** |
|||
* Check if node is followed by a blank newline. |
|||
* @param {ASTNode} node Node to check. |
|||
* @returns {boolean} Whether or not the passed in node is followed by a blank newline. |
|||
*/ |
|||
function hasNewlineAfter(node) { |
|||
const tokenAfter = sourceCode.getTokenOrCommentAfter(node); |
|||
|
|||
return tokenAfter.loc.start.line - node.loc.end.line >= 2; |
|||
} |
|||
|
|||
/** |
|||
* Report errors for newlines around directives. |
|||
* @param {ASTNode} node Node to check. |
|||
* @param {string} location Whether the error was found before or after the directive. |
|||
* @param {boolean} expected Whether or not a newline was expected or unexpected. |
|||
* @returns {void} |
|||
*/ |
|||
function reportError(node, location, expected) { |
|||
context.report({ |
|||
node, |
|||
message: "{{expected}} newline {{location}} \"{{value}}\" directive.", |
|||
data: { |
|||
expected: expected ? "Expected" : "Unexpected", |
|||
value: node.expression.value, |
|||
location |
|||
} |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* Check lines around directives in node |
|||
* @param {ASTNode} node - node to check |
|||
* @returns {void} |
|||
*/ |
|||
function checkDirectives(node) { |
|||
const directives = astUtils.getDirectivePrologue(node); |
|||
|
|||
if (!directives.length) { |
|||
return; |
|||
} |
|||
|
|||
const firstDirective = directives[0]; |
|||
const hasTokenOrCommentBefore = !!sourceCode.getTokenOrCommentBefore(firstDirective); |
|||
|
|||
// Only check before the first directive if it is preceded by a comment or if it is at the top of
|
|||
// the file and expectLineBefore is set to "never". This is to not force a newline at the top of
|
|||
// the file if there are no comments as well as for compatibility with padded-blocks.
|
|||
if ( |
|||
firstDirective.leadingComments && firstDirective.leadingComments.length || |
|||
|
|||
// Shebangs are not added to leading comments but are accounted for by the following.
|
|||
node.type === "Program" && hasTokenOrCommentBefore |
|||
) { |
|||
if (expectLineBefore === "always" && !hasNewlineBefore(firstDirective)) { |
|||
reportError(firstDirective, "before", true); |
|||
} |
|||
|
|||
if (expectLineBefore === "never" && hasNewlineBefore(firstDirective)) { |
|||
reportError(firstDirective, "before", false); |
|||
} |
|||
} else if ( |
|||
node.type === "Program" && |
|||
expectLineBefore === "never" && |
|||
!hasTokenOrCommentBefore && |
|||
hasNewlineBefore(firstDirective) |
|||
) { |
|||
reportError(firstDirective, "before", false); |
|||
} |
|||
|
|||
const lastDirective = directives[directives.length - 1]; |
|||
const statements = node.type === "Program" ? node.body : node.body.body; |
|||
|
|||
// Do not check after the last directive if the body only
|
|||
// contains a directive prologue and isn't followed by a comment to ensure
|
|||
// this rule behaves well with padded-blocks.
|
|||
if (lastDirective === statements[statements.length - 1] && !lastDirective.trailingComments) { |
|||
return; |
|||
} |
|||
|
|||
if (expectLineAfter === "always" && !hasNewlineAfter(lastDirective)) { |
|||
reportError(lastDirective, "after", true); |
|||
} |
|||
|
|||
if (expectLineAfter === "never" && hasNewlineAfter(lastDirective)) { |
|||
reportError(lastDirective, "after", false); |
|||
} |
|||
} |
|||
|
|||
//--------------------------------------------------------------------------
|
|||
// Public
|
|||
//--------------------------------------------------------------------------
|
|||
|
|||
return { |
|||
Program: checkDirectives, |
|||
FunctionDeclaration: checkDirectives, |
|||
FunctionExpression: checkDirectives, |
|||
ArrowFunctionExpression: checkDirectives |
|||
}; |
|||
} |
|||
}; |
@ -0,0 +1,88 @@ |
|||
/** |
|||
* @fileoverview Rule to disallow certain object properties |
|||
* @author Will Klein & Eli White |
|||
*/ |
|||
|
|||
"use strict"; |
|||
|
|||
const astUtils = require("../ast-utils"); |
|||
|
|||
//------------------------------------------------------------------------------
|
|||
// Rule Definition
|
|||
//------------------------------------------------------------------------------
|
|||
|
|||
module.exports = { |
|||
meta: { |
|||
docs: { |
|||
description: "disallow certain properties on certain objects", |
|||
category: "Node.js and CommonJS", |
|||
recommended: false |
|||
}, |
|||
|
|||
schema: { |
|||
type: "array", |
|||
items: { |
|||
type: "object", |
|||
properties: { |
|||
object: { |
|||
type: "string" |
|||
}, |
|||
property: { |
|||
type: "string" |
|||
}, |
|||
message: { |
|||
type: "string" |
|||
} |
|||
}, |
|||
additionalProperties: false, |
|||
required: [ |
|||
"object", |
|||
"property" |
|||
] |
|||
}, |
|||
uniqueItems: true |
|||
} |
|||
}, |
|||
|
|||
create(context) { |
|||
const restrictedCalls = context.options; |
|||
|
|||
if (restrictedCalls.length === 0) { |
|||
return {}; |
|||
} |
|||
|
|||
const restrictedProperties = restrictedCalls.reduce(function(restrictions, option) { |
|||
const objectName = option.object; |
|||
const propertyName = option.property; |
|||
|
|||
if (!restrictions.has(objectName)) { |
|||
restrictions.set(objectName, new Map()); |
|||
} |
|||
|
|||
restrictions.get(objectName).set(propertyName, { |
|||
message: option.message |
|||
}); |
|||
|
|||
return restrictions; |
|||
}, new Map()); |
|||
|
|||
return { |
|||
MemberExpression(node) { |
|||
const objectName = node.object && node.object.name; |
|||
const propertyName = astUtils.getStaticPropertyName(node); |
|||
const matchedObject = restrictedProperties.get(objectName); |
|||
const matchedObjectProperty = matchedObject && matchedObject.get(propertyName); |
|||
|
|||
if (matchedObjectProperty) { |
|||
const message = matchedObjectProperty.message ? " " + matchedObjectProperty.message : ""; |
|||
|
|||
context.report(node, "'{{objectName}}.{{propertyName}}' is restricted from being used.{{message}}", { |
|||
objectName, |
|||
propertyName, |
|||
message |
|||
}); |
|||
} |
|||
} |
|||
}; |
|||
} |
|||
}; |
@ -0,0 +1,62 @@ |
|||
/** |
|||
* @fileoverview Rule to disallow `parseInt()` in favor of binary, octal, and hexadecimal literals |
|||
* @author Annie Zhang, Henry Zhu |
|||
*/ |
|||
|
|||
"use strict"; |
|||
|
|||
//------------------------------------------------------------------------------
|
|||
// Rule Definition
|
|||
//------------------------------------------------------------------------------
|
|||
|
|||
module.exports = { |
|||
meta: { |
|||
docs: { |
|||
description: "disallow `parseInt()` in favor of binary, octal, and hexadecimal literals", |
|||
category: "ECMAScript 6", |
|||
recommended: false |
|||
}, |
|||
|
|||
schema: [] |
|||
}, |
|||
|
|||
create(context) { |
|||
const radixMap = { |
|||
2: "binary", |
|||
8: "octal", |
|||
16: "hexadecimal" |
|||
}; |
|||
|
|||
//--------------------------------------------------------------------------
|
|||
// Public
|
|||
//--------------------------------------------------------------------------
|
|||
|
|||
return { |
|||
|
|||
CallExpression(node) { |
|||
|
|||
// doesn't check parseInt() if it doesn't have a radix argument
|
|||
if (node.arguments.length !== 2) { |
|||
return; |
|||
} |
|||
|
|||
// only error if the radix is 2, 8, or 16
|
|||
const radixName = radixMap[node.arguments[1].value]; |
|||
|
|||
if (node.callee.type === "Identifier" && |
|||
node.callee.name === "parseInt" && |
|||
radixName && |
|||
node.arguments[0].type === "Literal" |
|||
) { |
|||
context.report({ |
|||
node, |
|||
message: "Use {{radixName}} literals instead of parseInt().", |
|||
data: { |
|||
radixName |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
}; |
|||
} |
|||
}; |
@ -0,0 +1,3 @@ |
|||
ESLint couldn't find the plugin "<%- pluginName %>". because there is whitespace in the name. Please check your configuration and remove all whitespace from the plugin name. |
|||
|
|||
If you still can't figure out the problem, please stop by https://gitter.im/eslint/eslint to chat with the team. |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +1,7 @@ |
|||
module.exports = require('util').inherits |
|||
try { |
|||
var util = require('util'); |
|||
if (typeof util.inherits !== 'function') throw ''; |
|||
module.exports = util.inherits; |
|||
} catch (e) { |
|||
module.exports = require('./inherits_browser.js'); |
|||
} |
|||
|
Loading…
Reference in new issue