eslint
Advanced tools
Comparing version 0.1.3 to 0.1.4
@@ -361,3 +361,4 @@ { | ||
"no-global-strict": 0, | ||
"no-mixed-requires": 2 | ||
"no-mixed-requires": 2, | ||
"no-console": 0 | ||
} | ||
@@ -371,3 +372,14 @@ }, | ||
} | ||
}, | ||
"mocha": { | ||
"globals": { | ||
"describe" : false, | ||
"it" : false, | ||
"before" : false, | ||
"after" : false, | ||
"beforeEach" : false, | ||
"afterEach" : false | ||
} | ||
} | ||
} |
@@ -25,2 +25,3 @@ { | ||
"no-ex-assign": 2, | ||
"no-extra-parens": 0, | ||
"no-extra-semi": 2, | ||
@@ -30,2 +31,3 @@ "no-func-assign": 2, | ||
"no-implied-eval": 2, | ||
"no-invalid-regexp": 2, | ||
"no-with": 2, | ||
@@ -66,5 +68,7 @@ "no-fallthrough": 2, | ||
"no-shadow": 2, | ||
"no-shadow-restricted-names": 2, | ||
"no-use-before-define": 2, | ||
"no-redeclare": 2, | ||
"no-negated-in-lhs": 2, | ||
"no-extend-native": 2, | ||
@@ -92,2 +96,4 @@ "brace-style": 0, | ||
"semi": 2, | ||
"space-return-throw-case": 2, | ||
"space-unary-word-ops": 0, | ||
"strict": 2, | ||
@@ -94,0 +100,0 @@ "unnecessary-strict": 2, |
@@ -6,5 +6,7 @@ /** | ||
"use strict"; | ||
module.exports = { | ||
linter: require("./eslint"), | ||
cli: require("./cli") | ||
}; | ||
}; |
@@ -6,2 +6,4 @@ /** | ||
"use strict"; | ||
/* | ||
@@ -22,5 +24,5 @@ * The CLI object should *not* call process.exit() directly. It should only return | ||
eslint = require("./eslint"), // TODO: More formatters | ||
existsSync = fs.existsSync || path.existsSync, | ||
Config = require("./config"); | ||
var existsSync = fs.existsSync || path.existsSync; | ||
@@ -27,0 +29,0 @@ |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -20,6 +21,37 @@ //------------------------------------------------------------------------------ | ||
//------------------------------------------------------------------------------ | ||
var LOCAL_CONFIG_FILENAME = ".eslintrc"; | ||
//------------------------------------------------------------------------------ | ||
// Helpers | ||
//------------------------------------------------------------------------------ | ||
/** | ||
* Get a local config object. | ||
* @param {string} directory the directory to start looking for a local config | ||
* @return {object} the local config object (empty object if there is no local config) | ||
*/ | ||
function getLocalConfig(helper, directory) { | ||
var localConfigFile = helper.findLocalConfigFile(directory), | ||
config = {}; | ||
if (localConfigFile) { | ||
try { | ||
config = JSON.parse(fs.readFileSync(localConfigFile)); | ||
} catch (e) { | ||
console.error("Cannot read config file:", localConfigFile); | ||
console.error("Error: ", e.message); | ||
} | ||
} | ||
return config; | ||
} | ||
//------------------------------------------------------------------------------ | ||
// API | ||
//------------------------------------------------------------------------------ | ||
/** | ||
* Config | ||
@@ -66,3 +98,3 @@ * @constructor | ||
} else { | ||
userConfig = getLocalConfig.call(this, directory); | ||
userConfig = getLocalConfig(this, directory); | ||
} | ||
@@ -127,23 +159,3 @@ | ||
/** | ||
* Get a local config object. | ||
* @param {string} directory the directory to start looking for a local config | ||
* @return {object} the local config object (empty object if there is no local config) | ||
*/ | ||
function getLocalConfig(directory) { | ||
var localConfigFile = this.findLocalConfigFile(directory), | ||
config = {}; | ||
if (localConfigFile) { | ||
try { | ||
config = JSON.parse(fs.readFileSync(localConfigFile)); | ||
} catch (e) { | ||
console.error("Cannot read config file:", localConfigFile); | ||
console.error("Error: ", e.message); | ||
} | ||
} | ||
return config; | ||
} | ||
module.exports = Config; |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -153,3 +154,3 @@ //------------------------------------------------------------------------------ | ||
function modifyRulesFromComments(ast, config) { | ||
var rules = {}; | ||
var modifiedRules = {}; | ||
@@ -163,4 +164,14 @@ ast.comments.forEach(function(comment) { | ||
value = value.substr(6, value.length - 6); | ||
forEachOption(value, function(name, value) { | ||
rules[name] = JSON.parse(value); | ||
value = value.replace(/([a-z0-9\-]+):/g, "\"$1\":").replace(/(\]|[0-9])\s+(?=")/, "$1,"); | ||
var items = {}; | ||
try { | ||
items = JSON.parse("{" + value + "}"); | ||
} catch(e) { | ||
return; | ||
} | ||
Object.keys(items).forEach(function(name) { | ||
var ruleValue = items[name]; | ||
if (typeof ruleValue === "number" || (Array.isArray(ruleValue) && typeof ruleValue[0] === "number")) { | ||
modifiedRules[name] = ruleValue; | ||
} | ||
}); | ||
@@ -171,3 +182,3 @@ } | ||
var newConfig = util.mergeConfigs(config.rules, rules); | ||
var newConfig = util.mergeConfigs(config.rules, modifiedRules); | ||
return newConfig; | ||
@@ -296,3 +307,3 @@ } | ||
*/ | ||
currentTokens = {}; | ||
currentTokens = []; | ||
ast.tokens.forEach(function(token) { | ||
@@ -398,25 +409,36 @@ currentTokens[token.range[0]] = token; | ||
* @param {ASTNode} [node] The AST node to get the text for. | ||
* @param {int} [beforeCount] The number of characters before the node to retrieve. | ||
* @param {int} [afterCount] The number of characters after the node to retrieve. | ||
* @param {int} [beforeCount] The number of tokens before the node to retrieve. | ||
* @param {int} [afterCount] The number of tokens after the node to retrieve. | ||
* @returns {Object[]} Array of objects representing tokens. | ||
*/ | ||
api.getTokens = function(node, beforeCount, afterCount) { | ||
if (node) { | ||
var startLocation = node.range[0] - (beforeCount || 0); | ||
var endLocation = node.range[1] + (afterCount || 0) ; | ||
var tokens = []; | ||
while (startLocation < endLocation) { | ||
if (currentTokens[startLocation]) { | ||
tokens.push(currentTokens[startLocation]); | ||
startLocation = currentTokens[startLocation].range[1]; | ||
} else { | ||
startLocation += 1; | ||
} | ||
var beforeTokens = [], tokens = [], afterTokens = [], cursor; | ||
cursor = node.range[0] - 1; | ||
while (beforeCount > 0 && cursor >= 0) { | ||
if(currentTokens[cursor]) { | ||
beforeTokens.unshift(currentTokens[cursor]); | ||
--beforeCount; | ||
} | ||
return tokens; | ||
} else { | ||
return Object.keys(currentTokens).map(function(item) { | ||
return item; | ||
}) || null; | ||
--cursor; | ||
} | ||
cursor = node.range[0]; | ||
while (cursor < node.range[1]) { | ||
if(currentTokens[cursor]) { | ||
tokens.push(currentTokens[cursor]); | ||
cursor = currentTokens[cursor].range[1]; | ||
} else { | ||
++cursor; | ||
} | ||
} | ||
cursor = node.range[1]; | ||
while (afterCount > 0 && cursor < currentTokens.length) { | ||
if(currentTokens[cursor]) { | ||
afterTokens.push(currentTokens[cursor]); | ||
--afterCount; | ||
cursor = currentTokens[cursor].range[1]; | ||
} else { | ||
++cursor; | ||
} | ||
} | ||
return beforeTokens.concat(tokens, afterTokens); | ||
}; | ||
@@ -423,0 +445,0 @@ |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -7,0 +8,0 @@ //------------------------------------------------------------------------------ |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -7,0 +8,0 @@ //------------------------------------------------------------------------------ |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -7,0 +8,0 @@ //------------------------------------------------------------------------------ |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -7,0 +8,0 @@ /*jshint node:true*/ |
@@ -0,1 +1,4 @@ | ||
"use strict"; | ||
var fs = require("fs"), | ||
@@ -2,0 +5,0 @@ path = require("path"); |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -7,0 +8,0 @@ //------------------------------------------------------------------------------ |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -7,0 +8,0 @@ //------------------------------------------------------------------------------ |
@@ -5,9 +5,15 @@ /** | ||
*/ | ||
"use strict"; | ||
//------------------------------------------------------------------------------ | ||
// Requirements | ||
//------------------------------------------------------------------------------ | ||
var loadRules = require("./load-rules"); | ||
//------------------------------------------------------------------------------ | ||
// Privates | ||
//------------------------------------------------------------------------------ | ||
var rules = Object.create(null), | ||
loadRules = require("./load-rules"); | ||
var rules = Object.create(null); | ||
@@ -14,0 +20,0 @@ //------------------------------------------------------------------------------ |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -13,3 +14,2 @@ //------------------------------------------------------------------------------ | ||
"use strict"; | ||
var stack = [{}]; // Start with the global block | ||
@@ -49,2 +49,3 @@ | ||
break; | ||
case "FunctionDeclaration": | ||
@@ -57,5 +58,7 @@ declarations = node.params; | ||
break; | ||
case "CatchClause": | ||
declarations = []; | ||
topObject[node.param.name] = 1; | ||
// no default | ||
@@ -93,5 +96,5 @@ } | ||
"FunctionDeclaration": addCommonDeclaration, | ||
"Identifier": checkStackForIdentifier, | ||
"Identifier": checkStackForIdentifier | ||
}; | ||
}; |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -20,4 +21,4 @@ //------------------------------------------------------------------------------ | ||
if (declaration.id.name === alias && | ||
!(declaration.init && declaration.init.type === "ThisExpression") | ||
) { | ||
!(declaration.init && declaration.init.type === "ThisExpression")) { | ||
context.report( | ||
@@ -32,5 +33,5 @@ node, | ||
if (declaration.init && | ||
declaration.init.type === "ThisExpression" && | ||
declaration.id.name !== alias) | ||
{ | ||
declaration.init.type === "ThisExpression" && | ||
declaration.id.name !== alias) { | ||
context.report( | ||
@@ -37,0 +38,0 @@ node, |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -7,0 +8,0 @@ //------------------------------------------------------------------------------ |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -26,4 +27,2 @@ //------------------------------------------------------------------------------ | ||
"use strict"; | ||
return { | ||
@@ -30,0 +29,0 @@ |
@@ -22,3 +22,3 @@ /** | ||
if (nodeType === "RegularExpression") { | ||
source = context.getTokens(node, 1, 1)[0].value; | ||
source = context.getTokens(node)[0].value; | ||
@@ -25,0 +25,0 @@ if (source[1] === "=") { |
/** | ||
* @fileoverview Rule to flag fall-through cases in switch statements. | ||
* @author Matt DuVall<http://mattduvall.com/> | ||
* @author Matt DuVall <http://mattduvall.com/> | ||
*/ | ||
"use strict"; | ||
@@ -14,4 +15,2 @@ /*jshint node:true*/ | ||
"use strict"; | ||
return { | ||
@@ -29,3 +28,3 @@ | ||
for (i = 0, len = cases.length; i < len; i++) { | ||
for (i = 0, len = cases.length; i < len - 1; ++i) { | ||
switchCase = cases[i]; | ||
@@ -44,3 +43,3 @@ consequent = switchCase.consequent; | ||
!isThrowStatement && !hasFallThroughComment) { | ||
context.report(node, "No fall-through without explicit comment."); | ||
context.report(switchCase, "No fall-through without explicit comment."); | ||
} | ||
@@ -47,0 +46,0 @@ } |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -13,4 +14,2 @@ //------------------------------------------------------------------------------ | ||
"use strict"; | ||
return { | ||
@@ -17,0 +16,0 @@ |
@@ -19,14 +19,11 @@ /** | ||
function getBuiltinModules() { | ||
if (process.version.match(/^v0\.[0-7]\./)) { | ||
// The _builtinLibs property we use below was added in 0.8 so we | ||
// can't use it here and fall back to a hardcoded list of modules. | ||
return [ | ||
"assert", "buffer", "child_process", "cluster", "crypto", | ||
"dgram", "dns", "events", "fs", "http", "https", "net", "os", | ||
"path", "querystring", "readline", "repl", "stream", "tls", | ||
"tty", "url", "util", "vm", "zlib" | ||
]; | ||
} else { | ||
return require("repl")._builtinLibs; | ||
} | ||
// This list is generated using `require("repl")._builtinLibs.concat('repl').sort()` | ||
// This particular list was generated using node v0.11.9 | ||
return [ | ||
"assert", "buffer", "child_process", "cluster", "crypto", | ||
"dgram", "dns", "domain", "events", "fs", "http", "https", | ||
"net", "os", "path", "punycode", "querystring", "readline", | ||
"repl", "smalloc", "stream", "string_decoder", "tls", "tty", | ||
"url", "util", "vm", "zlib" | ||
]; | ||
} | ||
@@ -33,0 +30,0 @@ |
@@ -1,3 +0,1 @@ | ||
/*jshint scripturl: true */ | ||
/** | ||
@@ -7,3 +5,7 @@ * @fileoverview Rule to flag when using javascript: urls | ||
*/ | ||
/*jshint scripturl: true */ | ||
/*eslint no-script-url: 0*/ | ||
"use strict"; | ||
//------------------------------------------------------------------------------ | ||
@@ -15,9 +17,14 @@ // Rule Definition | ||
"use strict"; | ||
return { | ||
"Literal": function(node) { | ||
if (node.value && typeof(node.value) === "string" && node.value.toLowerCase().indexOf("javascript:") >= 0) { | ||
context.report(node, "Script URL is a form of eval."); | ||
var value; | ||
if (node.value && typeof(node.value) === "string") { | ||
value = node.value.toLowerCase(); | ||
if (value.indexOf("javascript:") === 0) { | ||
context.report(node, "Script URL is a form of eval."); | ||
} | ||
} | ||
@@ -24,0 +31,0 @@ } |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -28,3 +29,3 @@ //------------------------------------------------------------------------------ | ||
// If it's an implicit global, it must have a `writeable` field (indicating it was declared) | ||
if (!isImplicitGlobal(variable) || Object.hasOwnProperty.call(variable, "writeable")) { | ||
if (!isImplicitGlobal(variable) || {}.hasOwnProperty.call(variable, "writeable")) { | ||
declaredGlobal = variable; | ||
@@ -45,4 +46,2 @@ return true; | ||
"use strict"; | ||
return { | ||
@@ -49,0 +48,0 @@ |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -23,4 +24,2 @@ //------------------------------------------------------------------------------ | ||
"use strict"; | ||
function checkForUnreachable(node) { | ||
@@ -27,0 +26,0 @@ switch (node.type) { |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -13,4 +14,2 @@ //------------------------------------------------------------------------------ | ||
"use strict"; | ||
function isPragma(expression, parent) { | ||
@@ -34,3 +33,3 @@ | ||
!/^(?:Assignment|Call|New|Update)Expression$/.test(type) && | ||
("UnaryExpression" !== type || "delete" !== node.expression.operator) && | ||
("UnaryExpression" !== type || ["delete", "void"].indexOf(node.expression.operator) < 0) && | ||
!isPragma(node.expression, parent) | ||
@@ -37,0 +36,0 @@ ) { |
@@ -11,3 +11,3 @@ /** | ||
module.exports = function(context) { | ||
"use strict"; | ||
@@ -38,15 +38,11 @@ | ||
scope.references.forEach(function(reference) { | ||
//filter out global variables that we add as part of eslint or arguments variable | ||
if (reference.identifier) { | ||
//if the reference is resolved check for declaration location | ||
//if not, it could be function invocation, try to find manually | ||
if (reference.resolved && reference.resolved.identifiers.length > 0) { | ||
checkLocationAndReport(reference, reference.resolved); | ||
} else { | ||
var declaration = findDeclaration(reference.identifier.name, scope); | ||
//if there're no identifiers, this is a global environment variable | ||
if (declaration && declaration.identifiers.length !== 0) { | ||
checkLocationAndReport(reference, declaration); | ||
} | ||
//if the reference is resolved check for declaration location | ||
//if not, it could be function invocation, try to find manually | ||
if (reference.resolved && reference.resolved.identifiers.length > 0) { | ||
checkLocationAndReport(reference, reference.resolved); | ||
} else { | ||
var declaration = findDeclaration(reference.identifier.name, scope); | ||
//if there're no identifiers, this is a global environment variable | ||
if (declaration && declaration.identifiers.length !== 0) { | ||
checkLocationAndReport(reference, declaration); | ||
} | ||
@@ -62,2 +58,2 @@ } | ||
}; | ||
}; | ||
}; |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -13,4 +14,2 @@ //------------------------------------------------------------------------------ | ||
"use strict"; | ||
var scopes = []; | ||
@@ -24,3 +23,3 @@ | ||
function enterScope() { | ||
scopes.push(scopes[scopes.length - 1] || false); | ||
scopes.push(scopes[scopes.length - 1] || false); | ||
} | ||
@@ -27,0 +26,0 @@ |
@@ -5,2 +5,3 @@ /** | ||
*/ | ||
"use strict"; | ||
@@ -13,18 +14,44 @@ //------------------------------------------------------------------------------ | ||
"use strict"; | ||
function directives(block) { | ||
var ds = [], body = block.body, e, i, l; | ||
for(i = 0, l = body.length; i < l; ++i) { | ||
e = body[i]; | ||
if( | ||
e.type === "ExpressionStatement" && | ||
e.expression.type === "Literal" && | ||
typeof e.expression.value === "string" | ||
) { | ||
ds.push(e.expression); | ||
} else { | ||
break; | ||
} | ||
} | ||
return ds; | ||
} | ||
return { | ||
function isStrict(directive) { return directive.value === "use strict"; } | ||
"Literal": function(node) { | ||
if (node.value === "use strict") { | ||
var scope = context.getScope(); | ||
function checkForUnnecessaryUseStrict(node) { | ||
var useStrictDirectives, scope; | ||
useStrictDirectives = directives(node).filter(isStrict); | ||
switch(useStrictDirectives.length) { | ||
case 0: | ||
break; | ||
case 1: | ||
scope = context.getScope(); | ||
if (scope.upper && scope.upper.isStrict) { | ||
context.report(node, "Unnecessary 'use strict'."); | ||
context.report(useStrictDirectives[0], "Unnecessary 'use strict'."); | ||
} | ||
} | ||
break; | ||
default: | ||
context.report(useStrictDirectives[1], "Multiple 'use strict' directives."); | ||
} | ||
} | ||
return { | ||
"Program": checkForUnnecessaryUseStrict, | ||
"FunctionExpression": function(node) { checkForUnnecessaryUseStrict(node.body); }, | ||
"FunctionDeclaration": function(node) { checkForUnnecessaryUseStrict(node.body); } | ||
}; | ||
}; |
@@ -5,2 +5,4 @@ /** | ||
*/ | ||
"use strict"; | ||
/*global describe, it*/ | ||
@@ -50,5 +52,5 @@ /* | ||
module.exports = (function () { | ||
module.exports = { | ||
this.add = function(ruleName, test) { | ||
addRuleTest: function(ruleName, test) { | ||
@@ -87,3 +89,3 @@ var result = {}; | ||
} else { | ||
assert.equal(messages.length, item.errors.length); | ||
assert.equal(messages.length, item.errors.length, "Number of errors"); | ||
@@ -128,5 +130,3 @@ if (messages.length === item.errors.length) { | ||
return result.suite; | ||
}; | ||
return this; | ||
}()); | ||
} | ||
}; |
/** | ||
* @fileoverview Common utilities. | ||
*/ | ||
"use strict"; | ||
@@ -31,4 +32,9 @@ //------------------------------------------------------------------------------ | ||
if (Array.isArray(base[key]) && !Array.isArray(property) && typeof property === "number") { | ||
//assume that we are just overriding first attribute | ||
base[key][0] = custom[key]; | ||
return; | ||
} | ||
if (typeof property === "object" && !Array.isArray(property)) { | ||
// base[key] might not exist, so be careful with recursion here | ||
@@ -35,0 +41,0 @@ base[key] = mergeConfigs(base[key] || {}, custom[key]); |
{ | ||
"name": "eslint", | ||
"version": "0.1.3", | ||
"version": "0.1.4", | ||
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>", | ||
@@ -11,5 +11,7 @@ "description": "An Esprima-based pattern checker for JavaScript.", | ||
"scripts": { | ||
"changelog": "bash scripts/changelog-update.sh", | ||
"test": "node ./node_modules/grunt-cli/bin/grunt test", | ||
"lint": "node ./node_modules/grunt-cli/bin/grunt jshint", | ||
"test": "node Makefile.js test", | ||
"lint": "node Makefile.js lint", | ||
"patch": "node Makefile.js patch", | ||
"minor": "node Makefile.js minor", | ||
"major": "node Makefile.js major", | ||
"bundle": "bash scripts/bundle.sh" | ||
@@ -39,10 +41,6 @@ }, | ||
"chai": "~1.8.1", | ||
"grunt": "~0.4.1", | ||
"grunt-contrib-jshint": "~0.6.4", | ||
"grunt-istanbul-coverage": "0.0.2", | ||
"grunt-istanbul": "~0.2.3", | ||
"grunt-contrib-clean": "~0.5.0", | ||
"grunt-contrib-copy": "~0.4.1", | ||
"grunt-cli": "~0.1.11", | ||
"grunt-mocha-test": "~0.7.0" | ||
"shelljs": "~0.2", | ||
"jsonlint": "~1.6.0", | ||
"jshint": "~2.3", | ||
"istanbul": "~0.1" | ||
}, | ||
@@ -49,0 +47,0 @@ "keywords": [ |
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
191302
8
111
4866
7