eslint 1.5.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -104,7 +104,7 @@ The following projects are using ESLint to validate their JavaScript:
104
104
 
105
105
  * [Drupal](https://www.drupal.org/node/2274223)
106
106
  * [Esprima](https://github.com/ariya/esprima)
107
- * [io.js](https://github.com/iojs/io.js/commit/f9dd34d301ab385ae316769b85ef916f9b70b6f6)
107
+ * [Node.js](https://github.com/nodejs/node/commit/f9dd34d301ab385ae316769b85ef916f9b70b6f6)
108
108
  * [WebKit](https://bugs.webkit.org/show_bug.cgi?id=125048)
109
109
 
110
110
  In addition, the following companies are using ESLint internally to validate their JavaScript:
package/lib/config.js CHANGED
@@ -295,14 +295,16 @@ function getLocalConfig(thisConfig, directory) {
295
295
  config = {},
296
296
  localConfigFiles = thisConfig.findLocalConfigFiles(directory),
297
297
  numFiles = localConfigFiles.length,
298
- rootPath;
298
+ rootPath,
299
+ projectConfigPath = path.join(process.cwd(), LOCAL_CONFIG_FILENAME);
299
300
 
300
301
  for (i = 0; i < numFiles; i++) {
301
302
 
302
303
  localConfigFile = localConfigFiles[i];
303
304
 
304
- // Don't consider the personal config file in the home directory.
305
- if (localConfigFile === PERSONAL_CONFIG_PATH) {
305
+ // Don't consider the personal config file in the home directory,
306
+ // except if the home directory is the same as the current working directory
307
+ if (localConfigFile === PERSONAL_CONFIG_PATH && localConfigFile !== projectConfigPath) {
306
308
  continue;
307
309
  }
308
310
 
@@ -12,32 +12,52 @@
12
12
  module.exports = function(context) {
13
13
 
14
14
  var style = context.options[0],
15
- enforceDeclarations = (style === "declaration");
15
+ enforceDeclarations = (style === "declaration"),
16
+ stack = [];
16
17
 
17
18
  return {
19
+ "Program": function() {
20
+ stack = [];
21
+ },
18
22
 
19
23
  "FunctionDeclaration": function(node) {
24
+ stack.push(false);
25
+
20
26
  if (!enforceDeclarations) {
21
27
  context.report(node, "Expected a function expression.");
22
28
  }
23
29
  },
30
+ "FunctionDeclaration:exit": function() {
31
+ stack.pop();
32
+ },
24
33
 
25
- "FunctionExpression": function() {
26
- var parent = context.getAncestors().pop();
34
+ "FunctionExpression": function(node) {
35
+ stack.push(false);
27
36
 
28
- if (enforceDeclarations && parent.type === "VariableDeclarator") {
29
- context.report(parent, "Expected a function declaration.");
37
+ if (enforceDeclarations && node.parent.type === "VariableDeclarator") {
38
+ context.report(node.parent, "Expected a function declaration.");
30
39
  }
31
40
  },
41
+ "FunctionExpression:exit": function() {
42
+ stack.pop();
43
+ },
32
44
 
33
45
  "ArrowFunctionExpression": function() {
34
- var parent = context.getAncestors().pop();
46
+ stack.push(false);
47
+ },
48
+ "ArrowFunctionExpression:exit": function(node) {
49
+ var hasThisExpr = stack.pop();
35
50
 
36
- if (enforceDeclarations && parent.type === "VariableDeclarator") {
37
- context.report(parent, "Expected a function declaration.");
51
+ if (enforceDeclarations && !hasThisExpr && node.parent.type === "VariableDeclarator") {
52
+ context.report(node.parent, "Expected a function declaration.");
38
53
  }
39
- }
54
+ },
40
55
 
56
+ "ThisExpression": function() {
57
+ if (stack.length > 0) {
58
+ stack[stack.length - 1] = true;
59
+ }
60
+ }
41
61
  };
42
62
 
43
63
  };
@@ -2,6 +2,8 @@
2
2
  * @fileoverview Rule to flag duplicate arguments
3
3
  * @author Jamund Ferguson
4
4
  * @copyright 2015 Jamund Ferguson. All rights reserved.
5
+ * @copyright 2015 Toru Nagashima. All rights reserved.
6
+ * See LICENSE file in root directory for full license.
5
7
  */
6
8
 
7
9
  "use strict";
@@ -16,6 +18,15 @@ module.exports = function(context) {
16
18
  // Helpers
17
19
  //--------------------------------------------------------------------------
18
20
 
21
+ /**
22
+ * Checks whether or not a given definition is a parameter's.
23
+ * @param {escope.DefEntry} def - A definition to check.
24
+ * @returns {boolean} `true` if the definition is a parameter's.
25
+ */
26
+ function isParameter(def) {
27
+ return def.type === "Parameter";
28
+ }
29
+
19
30
  /**
20
31
  * Determines if a given node has duplicate parameters.
21
32
  * @param {ASTNode} node The node to check.
@@ -23,56 +34,29 @@ module.exports = function(context) {
23
34
  * @private
24
35
  */
25
36
  function checkParams(node) {
26
- var params = {},
27
- dups = {};
37
+ var variables = context.getDeclaredVariables(node);
38
+ var keyMap = Object.create(null);
28
39
 
40
+ for (var i = 0; i < variables.length; ++i) {
41
+ var variable = variables[i];
29
42
 
30
- /**
31
- * Marks a given param as either seen or duplicated.
32
- * @param {string} name The name of the param to mark.
33
- * @returns {void}
34
- * @private
35
- */
36
- function markParam(name) {
37
- if (params.hasOwnProperty(name)) {
38
- dups[name] = 1;
39
- } else {
40
- params[name] = 1;
43
+ // TODO(nagashima): Remove this duplication check after https://github.com/estools/escope/pull/79
44
+ var key = "$" + variable.name; // to avoid __proto__.
45
+ if (!isParameter(variable.defs[0]) || keyMap[key]) {
46
+ continue;
41
47
  }
42
- }
43
-
44
- // loop through and find each duplicate param
45
- node.params.forEach(function(param) {
46
-
47
- switch (param.type) {
48
- case "Identifier":
49
- markParam(param.name);
50
- break;
51
-
52
- case "ObjectPattern":
53
- param.properties.forEach(function(property) {
54
- markParam(property.key.name);
55
- });
56
- break;
57
-
58
- case "ArrayPattern":
59
- param.elements.forEach(function(element) {
60
-
61
- // Arrays can be sparse (unwanted arguments)
62
- if (element !== null) {
63
- markParam(element.name);
64
- }
65
- });
66
- break;
67
-
68
- // no default
48
+ keyMap[key] = true;
49
+
50
+ // Checks and reports duplications.
51
+ var defs = variable.defs.filter(isParameter);
52
+ if (defs.length >= 2) {
53
+ context.report({
54
+ node: node,
55
+ message: "Duplicate param '{{name}}'.",
56
+ data: {name: variable.name}
57
+ });
69
58
  }
70
- });
71
-
72
- // log an error for each duplicate (not 2 for each)
73
- Object.keys(dups).forEach(function(currentParam) {
74
- context.report(node, "Duplicate param '{{key}}'.", { key: currentParam });
75
- });
59
+ }
76
60
  }
77
61
 
78
62
  //--------------------------------------------------------------------------
@@ -72,7 +72,7 @@ module.exports = function(context) {
72
72
  }
73
73
 
74
74
  options = options || {};
75
- options.allowedPrecedingChars = options.allowedPrecedingChars || [];
75
+ options.allowedPrecedingChars = options.allowedPrecedingChars || [ "{" ];
76
76
  options.requireSpace = typeof options.requireSpace === "undefined" ? SPACE_REQUIRED : options.requireSpace;
77
77
 
78
78
  var hasSpace = sourceCode.isSpaceBetweenTokens(left, right);
@@ -155,7 +155,7 @@ module.exports = function(context) {
155
155
  check(caseNode);
156
156
  });
157
157
  },
158
- ThrowStatement: check,
158
+ "ThrowStatement": check,
159
159
  "TryStatement": function(node) {
160
160
  // try
161
161
  check(node);
@@ -169,7 +169,7 @@ module.exports = function(context) {
169
169
  },
170
170
  "WithStatement": check,
171
171
  "VariableDeclaration": function(node) {
172
- check(node, { allowedPrecedingChars: [ "(" ] });
172
+ check(node, { allowedPrecedingChars: [ "(", "{" ] });
173
173
  },
174
174
  "ReturnStatement": check,
175
175
  "BreakStatement": check,
@@ -177,25 +177,18 @@ module.exports = function(context) {
177
177
  "ContinueStatement": check,
178
178
  "FunctionDeclaration": check,
179
179
  "FunctionExpression": function(node) {
180
-
181
180
  var left = context.getTokenBefore(node);
181
+ var right = context.getFirstToken(node);
182
182
 
183
- // Check to see if the function expression is a class method
184
- if (node.parent && node.parent.type === "MethodDefinition") {
185
- return;
186
- }
187
-
188
- // Check to see if the function expression is an object literal shorthand method
189
- if (node.parent && node.parent.method && node.parent.type === "Property") {
183
+ // If it's a method, a getter, or a setter, the first token is not the `function` keyword.
184
+ if (right.type !== "Keyword") {
190
185
  return;
191
186
  }
192
187
 
193
- var right = context.getFirstToken(node);
194
-
195
- checkTokens(node, left, right, { allowedPrecedingChars: [ "(" ] });
188
+ checkTokens(node, left, right, { allowedPrecedingChars: [ "(", "{" ] });
196
189
  },
197
190
  "YieldExpression": function(node) {
198
- check(node, { allowedPrecedingChars: [ "(" ] });
191
+ check(node, { allowedPrecedingChars: [ "(", "{" ] });
199
192
  },
200
193
  "ForOfStatement": check,
201
194
  "ClassBody": function(node) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
5
5
  "description": "An AST-based pattern checker for JavaScript.",
6
6
  "bin": {
@@ -38,7 +38,7 @@
38
38
  "chalk": "^1.0.0",
39
39
  "concat-stream": "^1.4.6",
40
40
  "debug": "^2.1.1",
41
- "doctrine": "^0.6.2",
41
+ "doctrine": "^0.7.0",
42
42
  "escape-string-regexp": "^1.0.2",
43
43
  "escope": "^3.2.0",
44
44
  "espree": "^2.2.4",