Comparing version 1.0.0-rc-2 to 1.0.0-rc-3
@@ -12,3 +12,3 @@ /** | ||
validator: require("./config-validator"), | ||
ESLintTester: require("./lib/testers/eslint-tester") | ||
ESLintTester: require("./testers/eslint-tester") | ||
}; |
@@ -96,7 +96,7 @@ /** | ||
filePath = filePath.replace(scopedPackageShortcutRegex, "$1/eslint-config"); | ||
} else if (filePath.indexOf("eslint-config-") === -1) { | ||
} else if (filePath.split("/")[1].indexOf("eslint-config-") !== 0) { | ||
// for scoped packages, insert the eslint-config after the first / | ||
filePath = filePath.replace(/^@([^\/]+)\/(.*)$/, "@$1/eslint-config-$2"); | ||
} | ||
} else if (filePath.indexOf("eslint-config-") === -1) { | ||
} else if (filePath.indexOf("eslint-config-") !== 0) { | ||
filePath = "eslint-config-" + filePath; | ||
@@ -103,0 +103,0 @@ } |
@@ -36,2 +36,6 @@ /** | ||
// All nodes in ObjectExpression.properties and ObjectPattern.properties are visited as `Property`. | ||
// See Also: https://github.com/estools/estraverse/blob/master/estraverse.js#L687-L688 | ||
estraverse.VisitorKeys.Property.push("argument"); | ||
/** | ||
@@ -38,0 +42,0 @@ * Parses a list of "name:boolean_value" or/and "name" options divided by comma or |
@@ -8,4 +8,2 @@ /** | ||
var globals = require("globals"); | ||
//------------------------------------------------------------------------------ | ||
@@ -15,17 +13,24 @@ // Rule Definition | ||
var NATIVE_OBJECTS = Object.keys(globals.builtin); | ||
module.exports = function(context) { | ||
var config = context.options[0]; | ||
var exceptions = config && config.exceptions; | ||
var forbiddenNames = NATIVE_OBJECTS.reduce(function(retv, builtIn) { | ||
if (exceptions == null || exceptions.indexOf(builtIn) === -1) { | ||
retv[builtIn] = true; | ||
} | ||
return retv; | ||
}, Object.create(null)); | ||
var exceptions = (config && config.exceptions) || []; | ||
/** | ||
* Gets the names of writeable built-in variables. | ||
* @param {escope.Scope} scope - A scope to get. | ||
* @returns {object} A map that its key is variable names. | ||
*/ | ||
function getBuiltinGlobals(scope) { | ||
return scope.variables.reduce(function(retv, variable) { | ||
if (variable.writeable === false && variable.name !== "__proto__") { | ||
retv[variable.name] = true; | ||
} | ||
return retv; | ||
}, Object.create(null)); | ||
} | ||
/** | ||
* Reports if a given reference's name is same as native object's. | ||
* @param {object} builtins - A map that its key is a variable name. | ||
* @param {Reference} reference - A reference to check. | ||
@@ -36,7 +41,8 @@ * @param {int} index - The index of the reference in the references. | ||
*/ | ||
function checkThroughReference(reference, index, references) { | ||
function checkThroughReference(builtins, reference, index, references) { | ||
var identifier = reference.identifier; | ||
if (identifier != null && | ||
forbiddenNames[identifier.name] && | ||
builtins[identifier.name] && | ||
exceptions.indexOf(identifier.name) === -1 && | ||
reference.init === false && | ||
@@ -55,16 +61,2 @@ reference.isWrite() && | ||
/** | ||
* Finds and reports variables that its name is same as native object's. | ||
* @param {Variable} variable - A variable to check. | ||
* @returns {void} | ||
*/ | ||
function checkVariable(variable) { | ||
if (forbiddenNames[variable.name]) { | ||
context.report( | ||
variable.identifiers[0], | ||
"Redefinition of '{{name}}'.", | ||
{name: variable.name}); | ||
} | ||
} | ||
return { | ||
@@ -75,7 +67,5 @@ // Checks assignments of global variables. | ||
"Program": function() { | ||
context.getScope().through.forEach(checkThroughReference); | ||
}, | ||
"VariableDeclaration": function(node) { | ||
context.getDeclaredVariables(node).forEach(checkVariable); | ||
var globalScope = context.getScope(); | ||
var builtins = getBuiltinGlobals(globalScope); | ||
globalScope.through.forEach(checkThroughReference.bind(null, builtins)); | ||
} | ||
@@ -92,3 +82,3 @@ }; | ||
"type": "array", | ||
"items": {"enum": NATIVE_OBJECTS}, | ||
"items": {"type": "string"}, | ||
"uniqueItems": true | ||
@@ -95,0 +85,0 @@ } |
@@ -14,9 +14,21 @@ /** | ||
return { | ||
//-------------------------------------------------------------------------- | ||
// Helpers | ||
//-------------------------------------------------------------------------- | ||
"NewExpression": function(node) { | ||
if (node.callee.name === "Function") { | ||
context.report(node, "The Function constructor is eval."); | ||
} | ||
/** | ||
* Checks if the callee if the Function constructor, and if so, reports an issue. | ||
* @param {ASTNode} node The node to check and report on | ||
* @returns {void} | ||
* @private | ||
*/ | ||
function validateCallee(node) { | ||
if (node.callee.name === "Function") { | ||
context.report(node, "The Function constructor is eval."); | ||
} | ||
} | ||
return { | ||
"NewExpression": validateCallee, | ||
"CallExpression": validateCallee | ||
}; | ||
@@ -23,0 +35,0 @@ |
@@ -13,12 +13,36 @@ /** | ||
module.exports = function(context) { | ||
var options = { | ||
builtinGlobals: Boolean(context.options[0] && context.options[0].builtinGlobals) | ||
}; | ||
/** | ||
* Gets the names of writeable built-in variables. | ||
* @param {escope.Scope} scope - A scope to get. | ||
* @returns {object} A map that its key is a variable name. | ||
*/ | ||
function getBuiltinGlobals(scope) { | ||
return scope.variables.reduce(function(retv, variable) { | ||
if ("writeable" in variable && variable.name !== "__proto__") { | ||
retv[variable.name] = true; | ||
} | ||
return retv; | ||
}, Object.create(null)); | ||
} | ||
/** | ||
* Find variables in a given scope and flag redeclared ones. | ||
* @param {Scope} scope An escope scope object. | ||
* @param {Scope} scope - An escope scope object. | ||
* @param {object} builtins - A map that its key is a variable name. | ||
* @returns {void} | ||
* @private | ||
*/ | ||
function findVariablesInScope(scope) { | ||
function findVariablesInScope(scope, builtins) { | ||
scope.variables.forEach(function(variable) { | ||
if (variable.identifiers && variable.identifiers.length > 1) { | ||
var hasBuiltin = ( | ||
options.builtinGlobals && | ||
("writeable" in variable || Boolean(builtins && builtins[variable.name])) | ||
); | ||
var count = (hasBuiltin ? 1 : 0) + variable.identifiers.length; | ||
if (count >= 2) { | ||
variable.identifiers.sort(function(a, b) { | ||
@@ -28,4 +52,7 @@ return a.range[1] - b.range[1]; | ||
for (var i = 1, l = variable.identifiers.length; i < l; i++) { | ||
context.report(variable.identifiers[i], "{{a}} is already defined", {a: variable.name}); | ||
for (var i = (hasBuiltin ? 0 : 1), l = variable.identifiers.length; i < l; i++) { | ||
context.report( | ||
variable.identifiers[i], | ||
"{{a}} is already defined", | ||
{a: variable.name}); | ||
} | ||
@@ -38,30 +65,40 @@ } | ||
/** | ||
* Find variables in a given node's associated scope. | ||
* @param {ASTNode} node The node to check. | ||
* Find variables in the current scope. | ||
* @returns {void} | ||
* @private | ||
*/ | ||
function findVariables(node) { | ||
function checkForGlobal() { | ||
var scope = context.getScope(); | ||
findVariablesInScope(scope); | ||
// globalReturn means one extra scope to check | ||
if (node.type === "Program" && (context.ecmaFeatures.globalReturn || context.ecmaFeatures.modules)) { | ||
findVariablesInScope(scope.childScopes[0]); | ||
// Nodejs env or modules has a special scope. | ||
// But built-in global variables are not there. | ||
if (context.ecmaFeatures.globalReturn || context.ecmaFeatures.modules) { | ||
var builtins = (options.builtinGlobals ? getBuiltinGlobals(scope) : null); | ||
findVariablesInScope(scope.childScopes[0], builtins); | ||
} else { | ||
findVariablesInScope(scope); | ||
} | ||
} | ||
/** | ||
* Find variables in the current scope. | ||
* @returns {void} | ||
* @private | ||
*/ | ||
function checkForBlock() { | ||
findVariablesInScope(context.getScope()); | ||
} | ||
if (context.ecmaFeatures.blockBindings) { | ||
return { | ||
"Program": findVariables, | ||
"BlockStatement": findVariables, | ||
"SwitchStatement": findVariables | ||
"Program": checkForGlobal, | ||
"BlockStatement": checkForBlock, | ||
"SwitchStatement": checkForBlock | ||
}; | ||
} else { | ||
return { | ||
"Program": findVariables, | ||
"FunctionDeclaration": findVariables, | ||
"FunctionExpression": findVariables, | ||
"ArrowFunctionExpression": findVariables | ||
"Program": checkForGlobal, | ||
"FunctionDeclaration": checkForBlock, | ||
"FunctionExpression": checkForBlock, | ||
"ArrowFunctionExpression": checkForBlock | ||
}; | ||
@@ -71,2 +108,10 @@ } | ||
module.exports.schema = []; | ||
module.exports.schema = [ | ||
{ | ||
"type": "object", | ||
"properties": { | ||
"builtinGlobals": {"type": "boolean"} | ||
}, | ||
"additionalProperties": false | ||
} | ||
]; |
@@ -16,2 +16,3 @@ /** | ||
var options = { | ||
builtinGlobals: Boolean(context.options[0] && context.options[0].builtinGlobals), | ||
hoist: (context.options[0] && context.options[0].hoist) || "functions" | ||
@@ -100,3 +101,3 @@ }; | ||
return ( | ||
scopeVar.identifiers.length > 0 && | ||
(scopeVar.identifiers.length > 0 || (options.builtinGlobals && "writeable" in scopeVar)) && | ||
variable.name === scopeVar.name && | ||
@@ -160,6 +161,11 @@ !isDuplicatedClassNameVariable(scopeVar) && | ||
"Program:exit": function() { | ||
var globalScope = context.getScope(), | ||
stack = globalScope.childScopes.slice(), | ||
scope; | ||
// Nodejs env or modules has a special scope for globals. | ||
var globalScope = context.getScope(); | ||
if (context.ecmaFeatures.globalReturn || context.ecmaFeatures.modules) { | ||
globalScope = globalScope.childScopes[0]; | ||
} | ||
var stack = globalScope.childScopes.slice(); | ||
var scope; | ||
while (stack.length) { | ||
@@ -179,7 +185,7 @@ scope = stack.pop(); | ||
"properties": { | ||
"hoist": { | ||
"enum": ["all", "functions", "never"] | ||
} | ||
} | ||
"builtinGlobals": {"type": "boolean"}, | ||
"hoist": {"enum": ["all", "functions", "never"]} | ||
}, | ||
"additionalProperties": false | ||
} | ||
]; |
@@ -32,2 +32,4 @@ /** | ||
var FUNCTION_TYPE = /^(?:Arrow)?Function(?:Declaration|Expression)$/; | ||
//------------------------------------------------------------------------------ | ||
@@ -60,2 +62,49 @@ // Rule Definition | ||
/** | ||
* Checks whether or not a given node is a directive. | ||
* The directive is a `ExpressionStatement` which has only a string literal. | ||
* @param {ASTNode} node - A node to check. | ||
* @returns {boolean} Whether or not the node is a directive. | ||
* @private | ||
*/ | ||
function isDirective(node) { | ||
return ( | ||
node.type === "ExpressionStatement" && | ||
node.expression.type === "Literal" && | ||
typeof node.expression.value === "string" | ||
); | ||
} | ||
/** | ||
* Checks whether or not a given node is a part of directive prologues. | ||
* See also: http://www.ecma-international.org/ecma-262/6.0/#sec-directive-prologues-and-the-use-strict-directive | ||
* @param {ASTNode} node - A node to check. | ||
* @returns {boolean} Whether or not the node is a part of directive prologues. | ||
* @private | ||
*/ | ||
function isPartOfDirectivePrologue(node) { | ||
if (!isDirective(node.parent)) { | ||
return false; | ||
} | ||
var block = node.parent.parent; | ||
if (block.type !== "Program" && (block.type !== "BlockStatement" || !FUNCTION_TYPE.test(block.parent.type))) { | ||
return false; | ||
} | ||
// Check the node is at a prologue. | ||
for (var i = 0; i < block.body.length; ++i) { | ||
var statement = block.body[i]; | ||
if (statement === node.parent) { | ||
return true; | ||
} | ||
if (!isDirective(statement)) { | ||
break; | ||
} | ||
} | ||
return false; | ||
} | ||
return { | ||
@@ -72,3 +121,3 @@ | ||
if (settings && typeof val === "string") { | ||
isValid = isJSXElement(node.parent) || isSurroundedBy(rawVal, settings.quote); | ||
isValid = (quoteOption === "backtick" && isPartOfDirectivePrologue(node)) || isJSXElement(node.parent) || isSurroundedBy(rawVal, settings.quote); | ||
@@ -75,0 +124,0 @@ if (!isValid && avoidEscape) { |
{ | ||
"name": "eslint", | ||
"version": "1.0.0-rc-2", | ||
"version": "1.0.0-rc-3", | ||
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>", | ||
@@ -38,2 +38,3 @@ "description": "An AST-based pattern checker for JavaScript.", | ||
"dependencies": { | ||
"chai": "^1.9.1", | ||
"chalk": "^1.0.0", | ||
@@ -57,2 +58,3 @@ "concat-stream": "^1.4.6", | ||
"mkdirp": "^0.5.0", | ||
"mocha": "^2.1.0", | ||
"object-assign": "^2.0.0", | ||
@@ -71,3 +73,2 @@ "optionator": "^0.5.0", | ||
"browserify": "^8.1.3", | ||
"chai": "^1.9.1", | ||
"coveralls": "2.11.2", | ||
@@ -83,3 +84,2 @@ "dateformat": "^1.0.8", | ||
"markdownlint": "^0.0.6", | ||
"mocha": "^2.1.0", | ||
"mocha-phantomjs": "3.6.0", | ||
@@ -86,0 +86,0 @@ "npm-license": "^0.2.3", |
[![NPM version][npm-image]][npm-url] | ||
[![build status][travis-image]][travis-url] | ||
[![Build status][appveyor-image]][appveyor-url] | ||
[![Test coverage][coveralls-image]][coveralls-url] | ||
@@ -131,4 +130,2 @@ [![Downloads][downloads-image]][downloads-url] | ||
[travis-url]: https://travis-ci.org/eslint/eslint | ||
[appveyor-image]: https://ci.appveyor.com/api/projects/status/nnjjujvp9535u3cl/branch/master?svg=true | ||
[appveyor-url]: https://ci.appveyor.com/project/nzakas/eslint/branch/master | ||
[coveralls-image]: https://img.shields.io/coveralls/eslint/eslint/master.svg?style=flat-square | ||
@@ -135,0 +132,0 @@ [coveralls-url]: https://coveralls.io/r/eslint/eslint?branch=master |
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
677590
23
17491
28
134
+ Addedchai@^1.9.1
+ Addedmocha@^2.1.0
+ Addedassertion-error@1.0.0(transitive)
+ Addedchai@1.10.0(transitive)
+ Addedcommander@0.6.12.3.0(transitive)
+ Addeddebug@2.2.0(transitive)
+ Addeddeep-eql@0.1.3(transitive)
+ Addeddiff@1.4.0(transitive)
+ Addedescape-string-regexp@1.0.2(transitive)
+ Addedglob@3.2.11(transitive)
+ Addedgrowl@1.9.2(transitive)
+ Addedjade@0.26.3(transitive)
+ Addedlru-cache@2.7.3(transitive)
+ Addedminimatch@0.3.0(transitive)
+ Addedminimist@0.0.8(transitive)
+ Addedmkdirp@0.3.00.5.1(transitive)
+ Addedmocha@2.5.3(transitive)
+ Addedms@0.7.1(transitive)
+ Addedsigmund@1.0.1(transitive)
+ Addedsupports-color@1.2.0(transitive)
+ Addedto-iso-string@0.0.2(transitive)
+ Addedtype-detect@0.1.1(transitive)