Comparing version 0.9.1 to 0.9.2
@@ -240,2 +240,3 @@ /** | ||
fatal: false, | ||
severity: 1, | ||
message: "File ignored because of your .eslintignore file. Use --no-ignore to override." | ||
@@ -281,2 +282,18 @@ } | ||
return configHelper.getConfig(filePath); | ||
}, | ||
/** | ||
* Checks if a given path is ignored by ESLint. | ||
* @param {string} filePath The path of the file to check. | ||
* @returns {boolean} Whether or not the given path is ignored. | ||
*/ | ||
isPathIgnored: function (filePath) { | ||
var ignoredPaths; | ||
if (this.options.ignore) { | ||
ignoredPaths = IgnoredPaths.load(this.options); | ||
return ignoredPaths.contains(filePath); | ||
} | ||
return false; | ||
} | ||
@@ -283,0 +300,0 @@ |
@@ -51,6 +51,2 @@ /** | ||
ignorePatterns.forEach(function (pattern) { | ||
ignorePatterns.push(pattern + "/**"); | ||
}); | ||
return ignorePatterns; | ||
@@ -118,9 +114,16 @@ } | ||
filepath = filepath.replace("\\", "/"); | ||
return this.patterns.some(function (pattern) { | ||
var result = minimatch(filepath, pattern); | ||
debug("Minimatch " + result); | ||
return result; | ||
}); | ||
return this.patterns.reduce(function(ignored, pattern) { | ||
var negated = pattern[0] === "!", | ||
matches; | ||
if (negated) { | ||
pattern = pattern.slice(1); | ||
} | ||
matches = minimatch(filepath, pattern) || minimatch(filepath, pattern + "/**"); | ||
return matches ? !negated : ignored; | ||
}, false); | ||
}; | ||
module.exports = IgnoredPaths; |
@@ -13,2 +13,12 @@ /** | ||
/** | ||
* Checks whether a string contains a line terminator as defined in | ||
* http://www.ecma-international.org/ecma-262/5.1/#sec-7.3 | ||
* @param {string} str String to test. | ||
* @returns {boolean} True if str contains a line terminator. | ||
*/ | ||
function containsLineTerminator(str) { | ||
return /[\n\r\u2028\u2029]/.test(str); | ||
} | ||
/** | ||
* Gets an object literal property's key as the identifier name or string value. | ||
@@ -58,7 +68,7 @@ * @param {ASTNode} property Property node whose key to retrieve. | ||
/** | ||
* Gets the spacing around the colon in an object literal property | ||
* @param {ASTNode} property Property node from an object literal | ||
* @returns {Object} Spacing before and after the property's colon | ||
* Gets the whitespace around the colon in an object literal property. | ||
* @param {ASTNode} property Property node from an object literal. | ||
* @returns {Object} Whitespace before and after the property's colon. | ||
*/ | ||
function getPropertySpacing(property) { | ||
function getPropertyWhitespace(property) { | ||
var whitespace = /^(\s*):(\s*)/.exec(context.getSource().slice( | ||
@@ -70,4 +80,4 @@ property.key.range[1], property.value.range[0] | ||
return { | ||
beforeColon: whitespace[1].length, | ||
afterColon: whitespace[2].length | ||
beforeColon: whitespace[1], | ||
afterColon: whitespace[2] | ||
}; | ||
@@ -82,7 +92,10 @@ } | ||
* @param {string} side Side being verified - either "key" or "value". | ||
* @param {int} diff Difference between actual and expected spacing. | ||
* @param {string} whitespace Actual whitespace string. | ||
* @param {int} expected Expected whitespace length. | ||
* @returns {void} | ||
*/ | ||
function report(property, side, diff) { | ||
if (diff) { | ||
function report(property, side, whitespace, expected) { | ||
var diff = whitespace.length - expected; | ||
if (diff && !(expected && containsLineTerminator(whitespace))) { | ||
context.report(property[side], messages[side], { | ||
@@ -103,3 +116,3 @@ error: diff > 0 ? "Extra" : "Missing", | ||
targetWidth = Math.max.apply(null, widths), | ||
i, property, spacing, width; | ||
i, property, whitespace, width; | ||
@@ -111,5 +124,5 @@ // Conditionally include one space before or after colon | ||
property = properties[i]; | ||
spacing = getPropertySpacing(property); | ||
whitespace = getPropertyWhitespace(property); | ||
if (!spacing) { | ||
if (!whitespace) { | ||
continue; // Object literal getters/setters lack a colon | ||
@@ -121,7 +134,7 @@ } | ||
if (align === "value") { | ||
report(property, "key", spacing.beforeColon - beforeColon); | ||
report(property, "value", (width + spacing.afterColon) - targetWidth); | ||
report(property, "key", whitespace.beforeColon, beforeColon); | ||
report(property, "value", whitespace.afterColon, targetWidth - width); | ||
} else { // align = "colon" | ||
report(property, "key", (width + spacing.beforeColon) - targetWidth); | ||
report(property, "value", spacing.afterColon - afterColon); | ||
report(property, "key", whitespace.beforeColon, targetWidth - width); | ||
report(property, "value", whitespace.afterColon, afterColon); | ||
} | ||
@@ -136,6 +149,6 @@ } | ||
"Property": function (node) { | ||
var spacing = getPropertySpacing(node); | ||
if (spacing) { // Object literal getters/setters lack colon spacing | ||
report(node, "key", spacing.beforeColon - beforeColon); | ||
report(node, "value", spacing.afterColon - afterColon); | ||
var whitespace = getPropertyWhitespace(node); | ||
if (whitespace) { // Object literal getters/setters lack colons | ||
report(node, "key", whitespace.beforeColon, beforeColon); | ||
report(node, "value", whitespace.afterColon, afterColon); | ||
} | ||
@@ -142,0 +155,0 @@ } |
@@ -11,3 +11,2 @@ /** | ||
module.exports = function(context) { | ||
"use strict"; | ||
@@ -19,8 +18,77 @@ | ||
function checkForReturnStatement(node, alternate) { | ||
if (node.type === "ReturnStatement") { | ||
context.report(alternate, "Unexpected 'else' after 'return'."); | ||
/** | ||
* Display the context report if rule is violated | ||
* | ||
* @param {Node} node The 'else' node | ||
* @returns {void} | ||
*/ | ||
function displayReport(node) { | ||
context.report(node, "Unexpected 'else' after 'return'."); | ||
} | ||
/** | ||
* Check to see if the node is a ReturnStatement | ||
* | ||
* @param {Node} node The node being evaluated | ||
* @returns {boolean} True if node is a return | ||
*/ | ||
function checkForReturn(node) { | ||
return node.type === "ReturnStatement"; | ||
} | ||
/** | ||
* Naive return checking, does not iterate through the whole | ||
* BlockStatement because we make the assumption that the ReturnStatement | ||
* will be the last node in the body of the BlockStatement. | ||
* | ||
* @param {Node} node The consequent/alternate node | ||
* @returns {boolean} True if it has a return | ||
*/ | ||
function naiveHasReturn(node) { | ||
if (node.type === "BlockStatement") { | ||
var body = node.body; | ||
return checkForReturn(body[body.length - 1]); | ||
} | ||
return checkForReturn(node); | ||
} | ||
/** | ||
* Check to see if the node is valid for evaluation, | ||
* meaning it has an else and not an else-if | ||
* | ||
* @param {Node} node The node being evaluated | ||
* @returns {boolean} True if the node is valid | ||
*/ | ||
function hasElse(node) { | ||
return node.alternate && node.consequent && node.alternate.type !== "IfStatement"; | ||
} | ||
/** | ||
* If the consequent is an IfStatement, check to see if it has an else | ||
* and both its consequent and alternate path return, meaning this is | ||
* a nested case of rule violation. If-Else not considered currently. | ||
* | ||
* @param {Node} node The consequent node | ||
* @returns {boolean} True if this is a nested rule violation | ||
*/ | ||
function checkForIf(node) { | ||
return node.type === "IfStatement" && hasElse(node) && | ||
naiveHasReturn(node.alternate) && naiveHasReturn(node.consequent); | ||
} | ||
/** | ||
* Check the consequent/body node to make sure it is not | ||
* a ReturnStatement or an IfStatement that returns on both | ||
* code paths. If it is, display the context report. | ||
* | ||
* @param {Node} node The consequent or body node | ||
* @param {Node} alternate The alternate node | ||
* @returns {void} | ||
*/ | ||
function checkForReturnOrIf(node, alternate) { | ||
if (checkForReturn(node) || checkForIf(node)) { | ||
displayReport(alternate); | ||
} | ||
} | ||
//-------------------------------------------------------------------------- | ||
@@ -32,18 +100,18 @@ // Public API | ||
"IfStatement": function(node) { | ||
"IfStatement": function (node) { | ||
// Don't bother finding a ReturnStatement, if there's no `else` | ||
// or if the alternate is also an if (indicating an else if). | ||
if (node.alternate && node.consequent && node.alternate.type !== "IfStatement") { | ||
if (hasElse(node)) { | ||
var consequent = node.consequent, | ||
alternate = node.alternate; | ||
// If we have a BlockStatement, check each consequent body node. | ||
if (node.consequent.type === "BlockStatement") { | ||
node.consequent.body.forEach(function (bodyNode) { | ||
checkForReturnStatement(bodyNode, node.alternate); | ||
if (consequent.type === "BlockStatement") { | ||
var body = consequent.body; | ||
body.forEach(function (bodyNode) { | ||
checkForReturnOrIf(bodyNode, alternate); | ||
}); | ||
// If not a block statement, make sure the consequent isn't a | ||
// ReturnStatement | ||
// If not a block statement, make sure the consequent isn't a ReturnStatement | ||
// or an IfStatement with returns on both paths | ||
} else { | ||
checkForReturnStatement(node.consequent, node.alternate); | ||
checkForReturnOrIf(consequent, alternate); | ||
} | ||
@@ -50,0 +118,0 @@ } |
@@ -15,4 +15,13 @@ /** | ||
var smartTabs = context.options[0]; | ||
var smartTabs; | ||
switch (context.options[0]) { | ||
case true: // Support old syntax, maybe add deprecation warning here | ||
case "smart-tabs": | ||
smartTabs = true; | ||
break; | ||
default: | ||
smartTabs = false; | ||
} | ||
var COMMENT_START = /^\s*\/\*/, | ||
@@ -19,0 +28,0 @@ MAYBE_COMMENT = /^\s*\*/; |
@@ -38,3 +38,3 @@ /** | ||
* Checks the given BlockStatement node has a preceding space if it doesn’t start on a new line. | ||
* @param {ASTNode} node The AST node of a BlockStatement. | ||
* @param {ASTNode|Token} node The AST node of a BlockStatement. | ||
* @returns {void} undefined. | ||
@@ -61,6 +61,27 @@ */ | ||
/** | ||
* Checks if the CaseBlock of an given SwitchStatement node has a preceding space. | ||
* @param {ASTNode} node The node of a SwitchStatement. | ||
* @returns {void} undefined. | ||
*/ | ||
function checkSpaceBeforeCaseBlock(node) { | ||
var cases = node.cases, | ||
firstCase, | ||
openingBrace; | ||
if (cases.length > 0) { | ||
firstCase = cases[0]; | ||
openingBrace = context.getTokenBefore(firstCase); | ||
} else { | ||
openingBrace = context.getLastToken(node, 1); | ||
} | ||
checkPrecedingSpace(openingBrace); | ||
} | ||
return { | ||
"BlockStatement": checkPrecedingSpace | ||
"BlockStatement": checkPrecedingSpace, | ||
"SwitchStatement": checkSpaceBeforeCaseBlock | ||
}; | ||
}; |
@@ -34,8 +34,3 @@ /** | ||
try { | ||
stat = fs.statSync(name); | ||
} catch (ex) { | ||
/* istanbul ignore next too hard to make fs.stat fail */ | ||
return; | ||
} | ||
stat = fs.statSync(name); | ||
@@ -93,3 +88,3 @@ function traverse(dir, stack) { | ||
* param {string[]} options.files An array of file and directory paths to traverse. | ||
* param {string[]} options.exclude An array of file and directory paths to ignore. | ||
* param {Function} options.exclude The function to check if file/path should be excluded. | ||
* @param {Function} callback A function to call for each file. | ||
@@ -96,0 +91,0 @@ * @returns {void} |
{ | ||
"name": "eslint", | ||
"version": "0.9.1", | ||
"version": "0.9.2", | ||
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>", | ||
@@ -19,3 +19,4 @@ "description": "An Esprima-based pattern checker for JavaScript.", | ||
"perf": "node Makefile.js perf", | ||
"profile": "beefy tests/bench/bench.js --open -- -t brfs -t ./tests/bench/xform-rules.js" | ||
"profile": "beefy tests/bench/bench.js --open -- -t brfs -t ./tests/bench/xform-rules.js", | ||
"coveralls": "cat ./coverage/lcov.info | coveralls" | ||
}, | ||
@@ -58,2 +59,3 @@ "files": [ | ||
"chai": "^1.9.1", | ||
"coveralls": "2.11.2", | ||
"dateformat": "^1.0.8", | ||
@@ -69,3 +71,3 @@ "eslint-tester": "^0.2.1", | ||
"shelljs-nodecli": "~0.1.0", | ||
"sinon": "^1.10.3", | ||
"sinon": "~1.10.3", | ||
"through": "^2.3.6" | ||
@@ -72,0 +74,0 @@ }, |
[![Build Status](https://travis-ci.org/eslint/eslint.svg?branch=master)](http://travis-ci.org/eslint/eslint) | ||
[![NPM version](https://badge.fury.io/js/eslint.svg)](http://badge.fury.io/js/eslint) | ||
[![Coverage Status](https://img.shields.io/coveralls/eslint/eslint.svg)](https://coveralls.io/r/eslint/eslint) | ||
[![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=282608)](https://www.bountysource.com/trackers/282608-eslint?utm_source=282608&utm_medium=shield&utm_campaign=TRACKER_BADGE) | ||
@@ -4,0 +5,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
378716
9698
66
17