Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

eslint

Package Overview
Dependencies
Maintainers
2
Versions
373
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint - npm Package Compare versions

Comparing version 0.23.0 to 0.24.0

lib/rules/array-bracket-spacing.js

4

conf/eslint.json

@@ -97,2 +97,3 @@ {

"no-trailing-spaces": 2,
"no-this-before-super": 0,
"no-throw-literal": 0,

@@ -102,2 +103,3 @@ "no-undef": 2,

"no-undefined": 0,
"no-unexpected-multiline": 0,
"no-underscore-dangle": 2,

@@ -116,2 +118,3 @@ "no-unneeded-ternary": 0,

"array-bracket-spacing": [0, "never"],
"accessor-pairs": 0,

@@ -128,2 +131,3 @@ "block-scoped-var": 0,

"consistent-this": [0, "that"],
"constructor-super": 0,
"curly": [2, "all"],

@@ -130,0 +134,0 @@ "default-case": 0,

6

lib/eslint.js

@@ -28,6 +28,2 @@ /**

// TODO: Remove when estraverse is updated
estraverse.Syntax.Super = "Super";
estraverse.VisitorKeys.Super = [];
/**

@@ -780,3 +776,3 @@ * Parses a list of "name:boolean_value" or/and "name" options divided by comma or

Object.keys(opts || {}).forEach(function (key) {
var rx = new RegExp("{{" + escapeRegExp(key) + "}}", "g");
var rx = new RegExp(escapeRegExp("{{" + key + "}}"), "g");
message = message.replace(rx, opts[key]);

@@ -783,0 +779,0 @@ });

@@ -81,3 +81,3 @@ /**

if (getDirectoryEntries(directory).indexOf(name) !== -1) {
if (getDirectoryEntries(directory).indexOf(name) !== -1 && fs.statSync(path.resolve(directory, name)).isFile()) {
filePath = path.resolve(directory, name);

@@ -141,3 +141,3 @@ break;

if (getDirectoryEntries(directory).indexOf(name) !== -1) {
if (getDirectoryEntries(directory).indexOf(name) !== -1 && fs.statSync(path.resolve(directory, name)).isFile()) {
filePath = path.resolve(directory, name);

@@ -144,0 +144,0 @@

@@ -125,3 +125,9 @@ /**

description: "Specify filename to process STDIN as"
},
{
option: "init",
type: "Boolean",
default: "false",
description: "Run config initialization wizard"
}]
});

@@ -28,3 +28,3 @@ /**

length = items.length,
nodeIsMultiLine = node.loc.start.line !== node.loc.end.line,
lastTokenOnNewLine,
lastItem,

@@ -43,5 +43,6 @@ penultimateToken,

} else if (allowDangle === "always-multiline") {
if (hasDanglingComma && !nodeIsMultiLine) {
lastTokenOnNewLine = node.loc.end.line !== penultimateToken.loc.end.line;
if (hasDanglingComma && !lastTokenOnNewLine) {
context.report(lastItem, penultimateToken.loc.start, UNEXPECTED_MESSAGE);
} else if (!hasDanglingComma && nodeIsMultiLine) {
} else if (!hasDanglingComma && lastTokenOnNewLine) {
context.report(lastItem, penultimateToken.loc.end, MISSING_MESSAGE);

@@ -48,0 +49,0 @@ }

@@ -16,8 +16,13 @@ /**

var mode = {
before: { before: true, after: false },
after: { before: false, after: true },
both: { before: true, after: true },
neither: { before: false, after: false }
}[context.options[0] || "before"];
var mode = (function(option) {
if (option == null || typeof option === "string") {
return {
before: { before: true, after: false },
after: { before: false, after: true },
both: { before: true, after: true },
neither: { before: false, after: false }
}[option || "before"];
}
return option;
}(context.options[0]));

@@ -86,4 +91,16 @@ /**

{
"enum": ["before", "after", "both", "neither"]
"oneOf": [
{
"enum": ["before", "after", "both", "neither"]
},
{
"type": "object",
"properties": {
"before": {"type": "boolean"},
"after": {"type": "boolean"}
},
"additionalProperties": false
}
]
}
];
/**
* @fileoverview Ensure handling of errors when we know they exist.
* @author Jamund Ferguson
* @copyright 2015 Mathias Schreck.
* @copyright 2014 Jamund Ferguson. All rights reserved.

@@ -16,4 +17,2 @@ */

var errorArgument = context.options[0] || "err";
var callbacks = [];
var scopes = 0;

@@ -44,43 +43,13 @@ /**

/**
* Check the arguments to see if we need to start tracking the error object.
* @param {ASTNode} node The AST node to check.
* @returns {void}
* Get the parameters of a given function scope.
* @param {object} scope The function scope.
* @returns {array} All parameters of the given scope.
*/
function startFunction(node) {
// keep track of nested scopes
scopes++;
// check if the first argument matches our argument name
var firstArg = node.params && node.params[0];
if (firstArg && matchesConfiguredErrorName(firstArg.name)) {
callbacks.push({handled: false, depth: scopes, errorVariableName: firstArg.name});
}
function getParameters(scope) {
return scope.variables.filter(function (variable) {
return variable.defs[0] && variable.defs[0].type === "Parameter";
});
}
/**
* At the end of a function check to see if the error was handled.
* @param {ASTNode} node The AST node to check.
* @returns {void}
*/
function endFunction(node) {
var callback = callbacks[callbacks.length - 1] || {};
// check if a callback is ending, if so pop it off the stack
if (callback.depth === scopes) {
callbacks.pop();
// check if there were no handled errors since the last callback
if (!callback.handled) {
context.report(node, "Expected error to be handled.");
}
}
// less nested functions
scopes--;
}
/**
* Check to see if we're handling the error object properly.

@@ -91,17 +60,9 @@ * @param {ASTNode} node The AST node to check.

function checkForError(node) {
if (callbacks.length > 0) {
var callback = callbacks[callbacks.length - 1] || {};
var scope = context.getScope(),
parameters = getParameters(scope),
firstParameter = parameters[0];
// make sure the node's name matches our error argument name
var isAboutError = node.name === callback.errorVariableName;
// we don't consider these use cases as "handling" the error
var doNotCount = ["FunctionDeclaration", "ArrowFunctionExpression", "FunctionExpression", "CatchClause"];
// make sure this identifier isn't used as part of one of them
var isHandled = doNotCount.indexOf(node.parent.type) === -1;
if (isAboutError && isHandled) {
// record that this callback handled its error
callback.handled = true;
if (firstParameter && matchesConfiguredErrorName(firstParameter.name)) {
if (firstParameter.references.length === 0) {
context.report(node, "Expected error to be handled.");
}

@@ -112,9 +73,5 @@ }

return {
"FunctionDeclaration": startFunction,
"FunctionExpression": startFunction,
"ArrowFunctionExpression": startFunction,
"Identifier": checkForError,
"FunctionDeclaration:exit": endFunction,
"FunctionExpression:exit": endFunction,
"ArrowFunctionExpression:exit": endFunction
"FunctionDeclaration": checkForError,
"FunctionExpression": checkForError,
"ArrowFunctionExpression": checkForError
};

@@ -121,0 +78,0 @@

@@ -63,2 +63,4 @@ /**

options.afterBlockComment = options.afterBlockComment || false;
options.allowBlockStart = options.allowBlockStart || false;
options.allowBlockEnd = options.allowBlockEnd || false;

@@ -88,2 +90,34 @@ /**

/**
* Returns whether or not comments are at the block start or not.
* @param {ASTNode} node The Comment node.
* @returns {boolean} True if the comment is at block start.
*/
function isCommentAtBlockStart(node) {
var ancestors = context.getAncestors();
var parent;
if (ancestors.length) {
parent = ancestors.pop();
}
return parent && (parent.type === "BlockStatement" || parent.body.type === "BlockStatement") &&
node.loc.start.line - parent.loc.start.line === 1;
}
/**
* Returns whether or not comments are at the block end or not.
* @param {ASTNode} node The Comment node.
* @returns {boolean} True if the comment is at block end.
*/
function isCommentAtBlockEnd(node) {
var ancestors = context.getAncestors();
var parent;
if (ancestors.length) {
parent = ancestors.pop();
}
return parent && (parent.type === "BlockStatement" || parent.body.type === "BlockStatement") &&
parent.loc.end.line - node.loc.end.line === 1;
}
/**
* Checks if a comment node has lines around it (ignores inline comments)

@@ -112,2 +146,5 @@ * @param {ASTNode} node The Comment node.

var blockStartAllowed = options.allowBlockStart && isCommentAtBlockStart(node),
blockEndAllowed = options.allowBlockEnd && isCommentAtBlockEnd(node);
// ignore top of the file and bottom of the file

@@ -127,3 +164,3 @@ if (prevLineNum < 1) {

// check for newline before
if (before && !contains(prevLineNum, commentAndEmptyLines)) {
if (!blockStartAllowed && before && !contains(prevLineNum, commentAndEmptyLines)) {
context.report(node, "Expected line before comment.");

@@ -133,3 +170,3 @@ }

// check for newline after
if (after && !contains(nextLineNum, commentAndEmptyLines)) {
if (!blockEndAllowed && after && !contains(nextLineNum, commentAndEmptyLines)) {
context.report(node, "Expected line after comment.");

@@ -166,1 +203,28 @@ }

};
module.exports.schema = [
{
"type": "object",
"properties": {
"beforeBlockComment": {
"type": "boolean"
},
"afterBlockComment": {
"type": "boolean"
},
"beforeLineComment": {
"type": "boolean"
},
"afterLineComment": {
"type": "boolean"
},
"allowBlockStart": {
"type": "boolean"
},
"allowBlockEnd": {
"type": "boolean"
}
},
"additionalProperties": false
}
];

@@ -60,3 +60,7 @@ /**

param.elements.forEach(function(element) {
markParam(element.name);
// Arrays can be sparse (unwanted arguments)
if (element !== null) {
markParam(element.name);
}
});

@@ -63,0 +67,0 @@ break;

@@ -204,4 +204,13 @@ /**

"ArrowFunctionExpression": function(node) {
if (node.body.type !== "BlockStatement" && hasExcessParens(node.body) && precedence(node.body) >= precedence({type: "AssignmentExpression"})) {
report(node.body);
if (node.body.type !== "BlockStatement") {
if (node.body.type !== "ObjectExpression" && hasExcessParens(node.body) && precedence(node.body) >= precedence({type: "AssignmentExpression"})) {
report(node.body);
return;
}
// Object literals *must* be parenthesized
if (node.body.type === "ObjectExpression" && hasDoubleExcessParens(node.body)) {
report(node.body);
return;
}
}

@@ -208,0 +217,0 @@ },

@@ -14,6 +14,53 @@ /**

/**
* Reports an unnecessary semicolon error.
* @param {Node|Token} nodeOrToken - A node or a token to be reported.
* @returns {void}
*/
function report(nodeOrToken) {
context.report(nodeOrToken, "Unnecessary semicolon.");
}
/**
* Checks for a part of a class body.
* This checks tokens from a specified token to a next MethodDefinition or the end of class body.
*
* @param {Token} firstToken - The first token to check.
* @returns {void}
*/
function checkForPartOfClassBody(firstToken) {
for (var token = firstToken;
token.type === "Punctuator" && token.value !== "}";
token = context.getTokenAfter(token)
) {
if (token.value === ";") {
report(token);
}
}
}
return {
/**
* Reports this empty statement.
* @param {Node} node - A EmptyStatement node to be reported.
* @returns {void}
*/
"EmptyStatement": report,
"EmptyStatement": function(node) {
context.report(node, "Unnecessary semicolon.");
/**
* Checks tokens from the head of this class body to the first MethodDefinition or the end of this class body.
* @param {Node} node - A ClassBody node to check.
* @returns {void}
*/
"ClassBody": function(node) {
checkForPartOfClassBody(context.getFirstToken(node, 1)); // 0 is `{`.
},
/**
* Checks tokens from this MethodDefinition to the next MethodDefinition or the end of this class body.
* @param {Node} node - A MethodDefinition node of the start point.
* @returns {void}
*/
"MethodDefinition": function(node) {
checkForPartOfClassBody(context.getTokenAfter(node));
}

@@ -20,0 +67,0 @@ };

@@ -8,2 +8,28 @@ /**

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Checks whether or not a node is an `AssignmentExpression`.
* @param {Node|null} node - A node to check.
* @returns {boolean} Whether or not the node is an `AssignmentExpression`.
*/
function isAssignment(node) {
return node != null && node.type === "AssignmentExpression";
}
/**
* Checks whether or not a node is enclosed in parentheses.
* @param {Node|null} node - A node to check.
* @param {RuleContext} context - The current context.
* @returns {boolean} Whether or not the node is enclosed in parentheses.
*/
function isEnclosedInParens(node, context) {
var prevToken = context.getTokenBefore(node);
var nextToken = context.getTokenAfter(node);
return prevToken.value === "(" && nextToken.value === ")";
}
//------------------------------------------------------------------------------
// Rule Definition

@@ -13,7 +39,7 @@ //------------------------------------------------------------------------------

module.exports = function(context) {
var always = (context.options[0] || "except-parens") !== "except-parens";
return {
"ReturnStatement": function(node) {
if (node.argument && node.argument.type === "AssignmentExpression") {
if (isAssignment(node.argument) && (always || !isEnclosedInParens(node.argument, context))) {
context.report(node, "Return statement should not contain assignment.");

@@ -23,5 +49,8 @@ }

};
};
module.exports.schema = [];
module.exports.schema = [
{
"enum": ["except-parens", "always"]
}
];

@@ -112,5 +112,8 @@ /**

* @param {Object} scope The scope to be checked.
* @returns {void}
* @returns {Array} Variables which are not declared in the given scope.
*/
function checkShadowsInScope(variables, scope) {
var passedVars = [];
variables.forEach(function (variable) {

@@ -123,4 +126,8 @@ // "arguments" is a special case that has no identifiers (#1759)

{name: variable.name});
} else {
passedVars.push(variable);
}
});
return passedVars;
}

@@ -143,11 +150,6 @@

// Checking is needless if there aren't variables.
if (variables.length === 0) {
return;
}
// iterate through the array of variables and find duplicates with the upper scope
var upper = scope.upper;
while (upper) {
checkShadowsInScope(variables, upper);
while (upper && variables.length) {
variables = checkShadowsInScope(variables, upper);
upper = upper.upper;

@@ -154,0 +156,0 @@ }

@@ -31,2 +31,3 @@ /**

spaced: spaced,
arraysInObjectsException: isOptionSet("arraysInObjects"),
objectsInObjectsException: isOptionSet("objectsInObjects")

@@ -103,3 +104,2 @@ };

/**

@@ -116,4 +116,5 @@ * Determines if spacing in curly braces is valid.

var closingCurlyBraceMustBeSpaced =
options.arraysInObjectsException && penultimate.value === "]" ||
options.objectsInObjectsException && penultimate.value === "}"
? !options.spaced : options.spaced;
? !options.spaced : options.spaced;

@@ -216,1 +217,19 @@ if (isSameLine(first, second)) {

};
module.exports.schema = [
{
"enum": ["always", "never"]
},
{
"type": "object",
"properties": {
"arraysInObjects": {
"type": "boolean"
},
"objectsInObjects": {
"type": "boolean"
}
},
"additionalProperties": false
}
];

@@ -51,3 +51,3 @@ /**

if (node.value.type === "FunctionExpression" && APPLY_TO_METHODS) {
if (node.value.type === "FunctionExpression" && node.value.id == null && APPLY_TO_METHODS) {

@@ -54,0 +54,0 @@ // {x: function(){}} should be written as {x() {}}

@@ -141,2 +141,19 @@ /**

/**
* Determines the current scope (function or block)
* @param {string} statementType node.kind, one of: "var", "let", or "const"
* @returns {Object} The scope associated with statementType
*/
function getCurrentScope(statementType) {
var currentScope;
if (statementType === "var") {
currentScope = functionStack[functionStack.length - 1];
} else if (statementType === "let") {
currentScope = blockStack[blockStack.length - 1].let;
} else if (statementType === "const") {
currentScope = blockStack[blockStack.length - 1].const;
}
return currentScope;
}
/**
* Counts the number of initialized and uninitialized declarations in a list of declarations

@@ -167,14 +184,7 @@ * @param {ASTNode[]} declarations List of declarations

function hasOnlyOneStatement(statementType, declarations) {
var currentScope;
var declarationCounts = countDeclarations(declarations);
var currentOptions = options[statementType] || {};
var currentScope = getCurrentScope(statementType);
if (statementType === "var") {
currentScope = functionStack[functionStack.length - 1];
} else if (statementType === "let") {
currentScope = blockStack[blockStack.length - 1].let;
} else if (statementType === "const") {
currentScope = blockStack[blockStack.length - 1].const;
}
if (currentOptions.uninitialized === MODE_ALWAYS && currentOptions.initialized === MODE_ALWAYS) {

@@ -241,17 +251,14 @@ if (currentScope.uninitialized || currentScope.initialized) {

if (parent.type !== "ForStatement" || parent.init !== node) {
if (options[type].initialized === MODE_NEVER && options[type].uninitialized === MODE_NEVER) {
if ((declarationCounts.uninitialized + declarationCounts.initialized) > 1) {
var totalDeclarations = declarationCounts.uninitialized + declarationCounts.initialized;
if (totalDeclarations > 1) {
// both initialized and uninitialized
if (options[type].initialized === MODE_NEVER && options[type].uninitialized === MODE_NEVER) {
context.report(node, "Split '" + type + "' declarations into multiple statements.");
// initialized
} else if (options[type].initialized === MODE_NEVER && declarationCounts.initialized > 0) {
context.report(node, "Split initialized '" + type + "' declarations into multiple statements.");
// uninitialized
} else if (options[type].uninitialized === MODE_NEVER && declarationCounts.uninitialized > 0) {
context.report(node, "Split uninitialized '" + type + "' declarations into multiple statements.");
}
} else {
if (options[type].initialized === MODE_NEVER) {
if (declarationCounts.initialized > 1) {
context.report(node, "Split initialized '" + type + "' declarations into multiple statements.");
}
}
if (options[type].uninitialized === MODE_NEVER) {
if (declarationCounts.uninitialized > 1) {
context.report(node, "Split uninitialized '" + type + "' declarations into multiple statements.");
}
}
}

@@ -258,0 +265,0 @@ }

@@ -62,3 +62,3 @@ /**

// check the `while`
var whileTokens = context.getTokensBefore(node.test, 2);
var whileTokens = context.getTokensAfter(node.body, 2);
checkTokens(node, whileTokens[0], whileTokens[1]);

@@ -65,0 +65,0 @@ },

@@ -68,3 +68,3 @@ /**

if (firstToken.type === "Keyword") {
if ((node.type === "NewExpression" || node.prefix) && firstToken.type === "Keyword") {
checkUnaryWordOperatorForSpaces(node, firstToken, secondToken);

@@ -71,0 +71,0 @@ return void 0;

@@ -21,2 +21,3 @@ /**

var markerMatcher = new RegExp(" ");
var jsDocMatcher = new RegExp("((^(\\*)))[ \\n]");

@@ -50,6 +51,17 @@ // Fetch the options dict

// the markerMatcher includes any markers in the list, followed by space/tab
markerMatcher = new RegExp("((^(" + markers.join("))|(^(") + ")))[ \\t]");
markerMatcher = new RegExp("((^(" + markers.join("))|(^(") + ")))[ \\t\\n]");
}
/**
* Check to see if the block comment is jsDoc comment
* @param {ASTNode} node comment node
* @returns {boolean} True if its jsdoc comment
* @private
*/
function isJsdoc(node) {
// make sure comment type is block and it start with /**\n
return node.type === "Block" && jsDocMatcher.test(node.value);
}
function checkCommentForSpace(node) {

@@ -65,2 +77,7 @@ var commentIdentifier = node.type === "Block" ? "/*" : "//";

// if comment is jsdoc style then ignore it
if (isJsdoc(node)) {
return;
}
// Check for markers now, and short-circuit if found

@@ -67,0 +84,0 @@ if (hasMarkers && markerMatcher.test(node.value)) {

@@ -146,3 +146,3 @@ /**

// check for functions missing @returns
if (!hasReturns && !hasConstructor) {
if (!hasReturns && !hasConstructor && node.parent.kind !== "get") {
if (requireReturn || functionData.returnPresent) {

@@ -149,0 +149,0 @@ context.report(jsdocNode, "Missing JSDoc @returns for function.");

{
"name": "eslint",
"version": "0.23.0",
"version": "0.24.0",
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",

@@ -44,3 +44,3 @@ "description": "An AST-based pattern checker for JavaScript.",

"espree": "^2.0.1",
"estraverse": "^2.0.0",
"estraverse": "^4.1.0",
"estraverse-fb": "^1.3.1",

@@ -68,3 +68,3 @@ "globals": "^8.0.0",

"dateformat": "^1.0.8",
"eslint-tester": "^0.7.0",
"eslint-tester": "^0.8.1",
"esprima-fb": "^10001.1.0-dev-harmony-fb",

@@ -75,3 +75,3 @@ "gh-got": "^1.0.3",

"jsonlint": "^1.6.2",
"markdownlint": "^0.0.5",
"markdownlint": "^0.0.6",
"mocha": "^2.1.0",

@@ -78,0 +78,0 @@ "mocha-phantomjs": "^3.5.0",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc