eslint 0.5.0 → 0.6.2

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.
Files changed (48) hide show
  1. package/README.md +2 -8
  2. package/conf/environments.json +29 -12
  3. package/conf/eslint.json +7 -0
  4. package/lib/cli.js +21 -12
  5. package/lib/config.js +36 -13
  6. package/lib/eslint.js +218 -63
  7. package/lib/formatters/checkstyle.js +4 -6
  8. package/lib/formatters/compact.js +2 -5
  9. package/lib/formatters/junit.js +2 -5
  10. package/lib/formatters/stylish.js +2 -1
  11. package/lib/formatters/tap.js +3 -6
  12. package/lib/load-rules.js +3 -1
  13. package/lib/options.js +56 -47
  14. package/lib/rules/block-scoped-var.js +38 -4
  15. package/lib/rules/brace-style.js +6 -2
  16. package/lib/rules/default-case.js +64 -0
  17. package/lib/rules/eqeqeq.js +4 -0
  18. package/lib/rules/new-cap.js +1 -1
  19. package/lib/rules/no-comma-dangle.js +1 -1
  20. package/lib/rules/no-constant-condition.js +2 -1
  21. package/lib/rules/no-delete-var.js +1 -1
  22. package/lib/rules/no-else-return.js +1 -1
  23. package/lib/rules/no-extend-native.js +6 -2
  24. package/lib/rules/no-extra-parens.js +68 -33
  25. package/lib/rules/no-extra-strict.js +1 -1
  26. package/lib/rules/no-fallthrough.js +8 -0
  27. package/lib/rules/no-inner-declarations.js +70 -0
  28. package/lib/rules/no-invalid-regexp.js +2 -2
  29. package/lib/rules/no-lonely-if.js +28 -0
  30. package/lib/rules/no-mixed-requires.js +1 -1
  31. package/lib/rules/no-new-require.js +23 -0
  32. package/lib/rules/no-redeclare.js +4 -1
  33. package/lib/rules/no-restricted-modules.js +72 -0
  34. package/lib/rules/no-sequences.js +92 -0
  35. package/lib/rules/no-shadow-restricted-names.js +4 -2
  36. package/lib/rules/no-shadow.js +1 -1
  37. package/lib/rules/no-spaced-func.js +5 -3
  38. package/lib/rules/no-sparse-arrays.js +1 -3
  39. package/lib/rules/no-unused-vars.js +10 -4
  40. package/lib/rules/no-use-before-define.js +11 -2
  41. package/lib/rules/semi.js +11 -3
  42. package/lib/rules/sort-vars.js +1 -1
  43. package/lib/rules/space-after-keywords.js +64 -0
  44. package/lib/rules/space-infix-ops.js +11 -9
  45. package/lib/rules/space-return-throw-case.js +11 -3
  46. package/lib/rules/space-unary-word-ops.js +3 -2
  47. package/lib/rules/valid-jsdoc.js +18 -3
  48. package/package.json +8 -5
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @fileoverview Rule to disallow use of new operator with the `require` function
3
+ * @author Wil Moore III
4
+ */
5
+
6
+ //------------------------------------------------------------------------------
7
+ // Rule Definition
8
+ //------------------------------------------------------------------------------
9
+
10
+ module.exports = function(context) {
11
+
12
+ "use strict";
13
+
14
+ return {
15
+
16
+ "NewExpression": function(node) {
17
+ if (node.callee.type === "Identifier" && node.callee.name === "require") {
18
+ context.report(node, "Unexpected use of new with require.");
19
+ }
20
+ }
21
+ };
22
+
23
+ };
@@ -16,7 +16,10 @@ module.exports = function(context) {
16
16
 
17
17
  scope.variables.forEach(function(variable) {
18
18
  if (variable.identifiers && variable.identifiers.length > 1) {
19
- variable.identifiers.sort(function(a, b) { return a.range[1] - b.range[1];});
19
+ variable.identifiers.sort(function(a, b) {
20
+ return a.range[1] - b.range[1];
21
+ });
22
+
20
23
  for (var i = 1, l = variable.identifiers.length; i < l; i++) {
21
24
  context.report(variable.identifiers[i], "{{a}} is already defined", {a: variable.name});
22
25
  }
@@ -0,0 +1,72 @@
1
+ /**
2
+ * @fileoverview Restrict usage of specified node modules.
3
+ * @author Christian Schulz
4
+ */
5
+ "use strict";
6
+
7
+ //------------------------------------------------------------------------------
8
+ // Rule Definition
9
+ //------------------------------------------------------------------------------
10
+
11
+ module.exports = function (context) {
12
+ // trim restricted module names
13
+ var restrictedModules = context.options;
14
+
15
+ // if no modules are restricted we don't need to check the CallExpressions
16
+ if (restrictedModules.length === 0) {
17
+ return {};
18
+ }
19
+
20
+ /**
21
+ * Function to check if a node is a string literal.
22
+ * @param {ASTNode} node The node to check.
23
+ * @returns {boolean} If the node is a string literal.
24
+ */
25
+ function isString(node) {
26
+ return node && node.type === "Literal" && typeof node.value === "string";
27
+ }
28
+
29
+ /**
30
+ * Function to check if a node is a require call.
31
+ * @param {ASTNode} node The node to check.
32
+ * @returns {boolean} If the node is a require call.
33
+ */
34
+ function isRequireCall(node) {
35
+ return node.callee.type === "Identifier" && node.callee.name === "require";
36
+ }
37
+
38
+ /**
39
+ * Function to check if a node has an argument that is an restricted module and return its name.
40
+ * @param {ASTNode} node The node to check
41
+ * @returns {undefined|String} restricted module name or undefined if node argument isn't restricted.
42
+ */
43
+ function getRestrictedModuleName(node) {
44
+ var moduleName;
45
+
46
+ // node has arguments and first argument is string
47
+ if (node.arguments.length && isString(node.arguments[0])) {
48
+ var argumentValue = node.arguments[0].value.trim();
49
+
50
+ // check if argument value is in restricted modules array
51
+ if (restrictedModules.indexOf(argumentValue) !== -1) {
52
+ moduleName = argumentValue;
53
+ }
54
+ }
55
+
56
+ return moduleName;
57
+ }
58
+
59
+ return {
60
+ "CallExpression": function (node) {
61
+ if (isRequireCall(node)) {
62
+ var restrictedModuleName = getRestrictedModuleName(node);
63
+
64
+ if (restrictedModuleName) {
65
+ context.report(node, "'{{moduleName}}' module is restricted from being used.", {
66
+ moduleName: restrictedModuleName
67
+ });
68
+ }
69
+ }
70
+ }
71
+ };
72
+ };
@@ -0,0 +1,92 @@
1
+ /**
2
+ * @fileoverview Rule to flag use of comma operator
3
+ * @author Brandon Mills
4
+ */
5
+
6
+ //------------------------------------------------------------------------------
7
+ // Rule Definition
8
+ //------------------------------------------------------------------------------
9
+
10
+ module.exports = function(context) {
11
+
12
+ "use strict";
13
+
14
+ /**
15
+ * Parts of the grammar that are required to have parens.
16
+ */
17
+ var parenthesized = {
18
+ "DoWhileStatement": "test",
19
+ "IfStatement": "test",
20
+ "SwitchStatement": "discriminant",
21
+ "WhileStatement": "test",
22
+ "WithStatement": "object"
23
+
24
+ // Omitting CallExpression - commas are parsed as argument separators
25
+ // Omitting NewExpression - commas are parsed as argument separators
26
+ // Omitting ForInStatement - parts aren't individually parenthesised
27
+ // Omitting ForStatement - parts aren't individually parenthesised
28
+ };
29
+
30
+ /**
31
+ * Determines whether a node is required by the grammar to be wrapped in
32
+ * parens, e.g. the test of an if statement.
33
+ * @param {ASTNode} node - The AST node
34
+ * @returns {boolean} True if parens around node belong to parent node.
35
+ */
36
+ function requiresExtraParens(node) {
37
+ return node.parent && parenthesized[node.parent.type] !== undefined &&
38
+ node === node.parent[parenthesized[node.parent.type]];
39
+ }
40
+
41
+ /**
42
+ * Check if a node is wrapped in parens.
43
+ * @param {ASTNode} node - The AST node
44
+ * @returns {boolean} True if the node has a paren on each side.
45
+ */
46
+ function isParenthesised(node) {
47
+ var previousToken = context.getTokenBefore(node),
48
+ nextToken = context.getTokenAfter(node);
49
+
50
+ return previousToken && nextToken &&
51
+ previousToken.value === "(" && previousToken.range[1] <= node.range[0] &&
52
+ nextToken.value === ")" && nextToken.range[0] >= node.range[1];
53
+ }
54
+
55
+ /**
56
+ * Check if a node is wrapped in two levels of parens.
57
+ * @param {ASTNode} node - The AST node
58
+ * @returns {boolean} True if two parens surround the node on each side.
59
+ */
60
+ function isParenthesisedTwice(node) {
61
+ var previousToken = context.getTokenBefore(node, 1),
62
+ nextToken = context.getTokenAfter(node, 1);
63
+
64
+ return isParenthesised(node) && previousToken && nextToken &&
65
+ previousToken.value === "(" && previousToken.range[1] <= node.range[0] &&
66
+ nextToken.value === ")" && nextToken.range[0] >= node.range[1];
67
+ }
68
+
69
+ return {
70
+ "SequenceExpression": function(node) {
71
+ // Always allow sequences in for statement update
72
+ if (node.parent.type === "ForStatement" &&
73
+ (node === node.parent.init || node === node.parent.update)) {
74
+ return;
75
+ }
76
+
77
+ // Wrapping a sequence in extra parens indicates intent
78
+ if (requiresExtraParens(node)) {
79
+ if (isParenthesisedTwice(node)) {
80
+ return;
81
+ }
82
+ } else {
83
+ if (isParenthesised(node)) {
84
+ return;
85
+ }
86
+ }
87
+
88
+ context.report(node, "Unexpected use of comma operator.");
89
+ }
90
+ };
91
+
92
+ };
@@ -13,7 +13,7 @@ module.exports = function(context) {
13
13
  var RESTRICTED = ["undefined", "NaN", "Infinity", "arguments", "eval"];
14
14
 
15
15
  function checkForViolation(id) {
16
- if(RESTRICTED.indexOf(id.name) > -1) {
16
+ if (RESTRICTED.indexOf(id.name) > -1) {
17
17
  context.report(id, "Shadowing of global property \"" + id.name + "\".");
18
18
  }
19
19
  }
@@ -23,7 +23,9 @@ module.exports = function(context) {
23
23
  checkForViolation(node.id);
24
24
  },
25
25
  "FunctionExpression": function(node) {
26
- if(node.id) { checkForViolation(node.id); }
26
+ if (node.id) {
27
+ checkForViolation(node.id);
28
+ }
27
29
  [].map.call(node.params, checkForViolation);
28
30
  },
29
31
  "FunctionDeclaration": function(node) {
@@ -39,7 +39,7 @@ module.exports = function(context) {
39
39
  });
40
40
  }
41
41
 
42
- while(upper) {
42
+ while (upper) {
43
43
  findDups(variables);
44
44
  upper = upper.upper;
45
45
  }
@@ -15,7 +15,7 @@ module.exports = function(context) {
15
15
  var i, token, hasArgumentList = false, numOpen = 0;
16
16
 
17
17
  // start at the end of the token stream; skip over argument list contents
18
- for(i = tokens.length - 1; i >= 0; --i) {
18
+ for (i = tokens.length - 1; i >= 0; --i) {
19
19
  token = tokens[i];
20
20
  if (token.value === "(") {
21
21
  --numOpen;
@@ -36,11 +36,13 @@ module.exports = function(context) {
36
36
  callee = tokens[openParenIndex - 1];
37
37
 
38
38
  // openParenIndex will be undefined for a NewExpression with no argument list
39
- if (!openParenIndex) { return; }
39
+ if (!openParenIndex) {
40
+ return;
41
+ }
40
42
 
41
43
  // look for a space between the callee and the open paren
42
44
  if (callee.range[1] !== openParen.range[0]) {
43
- context.report(node, "Spaced function application is not allowed.");
45
+ context.report(node, "Unexpected space between function name and paren.");
44
46
  }
45
47
  }
46
48
 
@@ -19,9 +19,7 @@ module.exports = function(context) {
19
19
 
20
20
  "ArrayExpression": function(node) {
21
21
 
22
- var emptySpot = node.elements.some(function(value) {
23
- return value === null;
24
- });
22
+ var emptySpot = node.elements.indexOf(null) > -1;
25
23
 
26
24
  if (emptySpot) {
27
25
  context.report(node, "Unexpected comma in middle of array.");
@@ -12,9 +12,10 @@
12
12
  module.exports = function(context) {
13
13
 
14
14
  var config = {
15
- vars: "local",
15
+ vars: "all",
16
16
  args: "after-used"
17
17
  };
18
+
18
19
  if (context.options[0]) {
19
20
  if (typeof(context.options[0]) === "string") {
20
21
  config.vars = context.options[0];
@@ -27,6 +28,7 @@ module.exports = function(context) {
27
28
  var allowUnusedGlobals = (config.vars !== "all"),
28
29
  variables = {};
29
30
 
31
+
30
32
  function lookupVariableName(name) {
31
33
 
32
34
  // Convoluted check in case name is "hasOwnProperty"
@@ -40,9 +42,7 @@ module.exports = function(context) {
40
42
  var candidates = lookupVariableName(variable.name);
41
43
  if (candidates) {
42
44
  return candidates.filter(function (candidate) {
43
- return variable.identifiers.some(function (identifier) {
44
- return candidate.node === identifier;
45
- });
45
+ return variable.identifiers.indexOf(candidate.node) > -1;
46
46
  })[0];
47
47
  }
48
48
  return candidates;
@@ -101,6 +101,12 @@ module.exports = function(context) {
101
101
  return lookupVariable(scopeVariable[0]);
102
102
  }
103
103
 
104
+ /**
105
+ * Determines if the given node represents a function.
106
+ * @param {ASTNode} node The node to check.
107
+ * @returns {boolean} True if the node represents a function, false if not.
108
+ * @private
109
+ */
104
110
  function isFunction(node) {
105
111
  return node && node.type && (node.type === "FunctionDeclaration" || node.type === "FunctionExpression");
106
112
  }
@@ -3,6 +3,12 @@
3
3
  * @author Ilya Volodin
4
4
  */
5
5
 
6
+ //------------------------------------------------------------------------------
7
+ // Constants
8
+ //------------------------------------------------------------------------------
9
+
10
+ var NO_FUNC = "nofunc";
11
+
6
12
  //------------------------------------------------------------------------------
7
13
  // Rule Definition
8
14
  //------------------------------------------------------------------------------
@@ -26,10 +32,13 @@ module.exports = function(context) {
26
32
 
27
33
  function findVariables() {
28
34
  var scope = context.getScope();
35
+ var typeOption = context.options[0];
29
36
 
30
37
  function checkLocationAndReport(reference, declaration) {
31
- if (declaration.identifiers[0].range[1] > reference.identifier.range[1]) {
32
- context.report(reference.identifier, "{{a}} was used before it was defined", {a: reference.identifier.name});
38
+ if (typeOption !== NO_FUNC || declaration.defs[0].type !== "FunctionName") {
39
+ if (declaration.identifiers[0].range[1] > reference.identifier.range[1]) {
40
+ context.report(reference.identifier, "{{a}} was used before it was defined", {a: reference.identifier.name});
41
+ }
33
42
  }
34
43
  }
35
44
 
package/lib/rules/semi.js CHANGED
@@ -9,6 +9,8 @@
9
9
  //------------------------------------------------------------------------------
10
10
  module.exports = function(context) {
11
11
 
12
+ var OPT_OUT_PATTERN = /[\[\(\/\+\-]/;
13
+
12
14
  var always = context.options[0] !== "never";
13
15
 
14
16
  //--------------------------------------------------------------------------
@@ -21,7 +23,8 @@ module.exports = function(context) {
21
23
  * @returns {void}
22
24
  */
23
25
  function checkForSemicolon(node) {
24
- var lastToken = context.getLastToken(node);
26
+ var lastToken = context.getLastToken(node),
27
+ nextToken = context.getTokenAfter(node);
25
28
 
26
29
  if (always) {
27
30
  if (lastToken.type !== "Punctuator" || lastToken.value !== ";") {
@@ -29,7 +32,11 @@ module.exports = function(context) {
29
32
  }
30
33
  } else {
31
34
  if (lastToken.type === "Punctuator" && lastToken.value === ";") {
32
- context.report(node, node.loc.end, "Extra semicolon.");
35
+
36
+ if (!nextToken || !(OPT_OUT_PATTERN.test(nextToken.value))) {
37
+ context.report(node, node.loc.end, "Extra semicolon.");
38
+ }
39
+
33
40
  }
34
41
  }
35
42
  }
@@ -69,7 +76,8 @@ module.exports = function(context) {
69
76
 
70
77
  if (!always) {
71
78
  nextToken = context.getTokenAfter(node) || context.getLastToken(node);
72
- if (!(/[\[\(\/\+\-]/.test(nextToken.value))) {
79
+
80
+ if (!(OPT_OUT_PATTERN.test(nextToken.value))) {
73
81
  context.report(node, "Extra semicolon.");
74
82
  }
75
83
  }
@@ -14,7 +14,7 @@ module.exports = function(context) {
14
14
  return {
15
15
  "VariableDeclaration": function(node) {
16
16
  node.declarations.reduce(function(memo, decl) {
17
- if(decl.id.name < memo.id.name) {
17
+ if (decl.id.name < memo.id.name) {
18
18
  context.report(decl, "Variables within the same declaration block should be sorted alphabetically");
19
19
  return memo;
20
20
  } else {
@@ -0,0 +1,64 @@
1
+ /**
2
+ * @fileoverview Rule to enforce the number of spaces after certain keywords
3
+ * @author Nick Fisher
4
+ */
5
+ "use strict";
6
+
7
+ //------------------------------------------------------------------------------
8
+ // Rule Definition
9
+ //------------------------------------------------------------------------------
10
+
11
+ module.exports = function(context) {
12
+
13
+ // unless the first option is `"never"`, then a space is required
14
+ var requiresSpace = context.options[0] !== "never";
15
+
16
+ /**
17
+ * Check if the separation of two adjacent tokens meets the spacing rules, and report a problem if not.
18
+ *
19
+ * @param {ASTNode} node The node to which the potential problem belongs.
20
+ * @param {Token} left The first token.
21
+ * @param {Token} right The second token
22
+ * @returns {void}
23
+ */
24
+ function checkTokens(node, left, right) {
25
+ var hasSpace = left.range[1] < right.range[0],
26
+ value = left.value;
27
+
28
+ if (hasSpace !== requiresSpace) {
29
+ context.report(node, "Keyword \"{{value}}\" must {{not}}be followed by whitespace.", {
30
+ value: value,
31
+ not: requiresSpace ? "" : "not "
32
+ });
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Check if the given node (`if`, `for`, `while`, etc), has the correct spacing after it.
38
+ * @param {ASTNode} node The node to check.
39
+ * @returns {void}
40
+ */
41
+ function check(node) {
42
+ var tokens = context.getFirstTokens(node, 2);
43
+ checkTokens(node, tokens[0], tokens[1]);
44
+
45
+ // check the `else` of an `if`.
46
+ if (tokens[0].value === "if" && node.alternate) {
47
+ checkTokens(node.alternate, context.getTokenBefore(node.alternate), context.getFirstToken(node.alternate));
48
+ }
49
+ }
50
+
51
+ return {
52
+ "IfStatement": check,
53
+ "ForStatement": check,
54
+ "ForOfStatement": check,
55
+ "ForInStatement": check,
56
+ "WhileStatement": check,
57
+ "DoWhileStatement": check,
58
+ "SwitchStatement": check,
59
+ "TryStatement": check,
60
+ "CatchStatement": check,
61
+ "WithStatement": check
62
+ };
63
+ };
64
+
@@ -19,9 +19,9 @@ module.exports = function(context) {
19
19
 
20
20
  function isSpaced(left, right) {
21
21
  var op, tokens = context.getTokens({range: [left.range[1], right.range[0]]}, 1, 1);
22
- for(var i = 1, l = tokens.length - 1; i < l; ++i) {
22
+ for (var i = 1, l = tokens.length - 1; i < l; ++i) {
23
23
  op = tokens[i];
24
- if(
24
+ if (
25
25
  op.type === "Punctuator" &&
26
26
  OPERATORS.indexOf(op.value) >= 0 &&
27
27
  (tokens[i - 1].range[1] >= op.range[0] || op.range[1] >= tokens[i + 1].range[0])
@@ -34,9 +34,9 @@ module.exports = function(context) {
34
34
 
35
35
  function isRightSpaced(left, right) {
36
36
  var op, tokens = context.getTokens({range: [left.range[1], right.range[0]]}, 1, 1);
37
- for(var i = 1, l = tokens.length - 1; i < l; ++i) {
37
+ for (var i = 1, l = tokens.length - 1; i < l; ++i) {
38
38
  op = tokens[i];
39
- if(
39
+ if (
40
40
  op.type === "Punctuator" &&
41
41
  OPERATORS.indexOf(op.value) >= 0 &&
42
42
  op.range[1] >= tokens[i + 1].range[0]
@@ -52,12 +52,14 @@ module.exports = function(context) {
52
52
  }
53
53
 
54
54
  function checkBinary(node) {
55
- if(!isSpaced(node.left, node.right)) { report(node); }
55
+ if (!isSpaced(node.left, node.right)) {
56
+ report(node);
57
+ }
56
58
  }
57
59
 
58
60
  function checkSequence(node) {
59
- for(var i = 0, l = node.expressions.length - 1; i < l; ++i) {
60
- if(!isRightSpaced(node.expressions[i], node.expressions[i + 1])) {
61
+ for (var i = 0, l = node.expressions.length - 1; i < l; ++i) {
62
+ if (!isRightSpaced(node.expressions[i], node.expressions[i + 1])) {
61
63
  report(node);
62
64
  break;
63
65
  }
@@ -65,13 +67,13 @@ module.exports = function(context) {
65
67
  }
66
68
 
67
69
  function checkConditional(node) {
68
- if(!isSpaced(node.test, node.consequent) || !isSpaced(node.consequent, node.alternate)) {
70
+ if (!isSpaced(node.test, node.consequent) || !isSpaced(node.consequent, node.alternate)) {
69
71
  report(node);
70
72
  }
71
73
  }
72
74
 
73
75
  function checkVar(node) {
74
- if(node.init && !isSpaced(node.id, node.init)) {
76
+ if (node.init && !isSpaced(node.id, node.init)) {
75
77
  report(node);
76
78
  }
77
79
  }
@@ -14,14 +14,22 @@ module.exports = function(context) {
14
14
  var tokens = context.getFirstTokens(node, 2),
15
15
  value = tokens[0].value;
16
16
 
17
- if(tokens[0].range[1] >= tokens[1].range[0]) {
17
+ if (tokens[0].range[1] >= tokens[1].range[0]) {
18
18
  context.report(node, "Keyword \"" + value + "\" must be followed by whitespace.");
19
19
  }
20
20
  }
21
21
 
22
22
  return {
23
- "ReturnStatement": function(node) { if(node.argument) { check(node); } },
24
- "SwitchCase": function(node) { if(node.test) { check(node); } },
23
+ "ReturnStatement": function(node) {
24
+ if (node.argument) {
25
+ check(node);
26
+ }
27
+ },
28
+ "SwitchCase": function(node) {
29
+ if (node.test) {
30
+ check(node);
31
+ }
32
+ },
25
33
  "ThrowStatement": check
26
34
  };
27
35
 
@@ -13,14 +13,15 @@ module.exports = function(context) {
13
13
  function check(node) {
14
14
  var tokens;
15
15
  tokens = context.getFirstTokens(node, 2);
16
- if(tokens[0].range[1] >= tokens[1].range[0]) {
17
- switch(tokens[0].value) {
16
+ if (tokens[0].range[1] >= tokens[1].range[0]) {
17
+ switch (tokens[0].value) {
18
18
  case "delete":
19
19
  case "new":
20
20
  case "typeof":
21
21
  case "void":
22
22
  context.report(node, "Unary word operator \"" + tokens[0].value + "\" must be followed by whitespace.");
23
23
  break;
24
+ // no default
24
25
  }
25
26
  }
26
27
  }
@@ -18,7 +18,10 @@ module.exports = function(context) {
18
18
 
19
19
  var options = context.options[0] || {},
20
20
  prefer = options.prefer || {},
21
- requireReturn = options.requireReturn === false ? false : true;
21
+
22
+ // these both default to true, so you have to explicitly make them false
23
+ requireReturn = options.requireReturn === false ? false : true,
24
+ requireParamDescription = options.requireParamDescription === false ? false : true;
22
25
 
23
26
  //--------------------------------------------------------------------------
24
27
  // Helpers
@@ -27,11 +30,21 @@ module.exports = function(context) {
27
30
  // Using a stack to store if a function returns or not (handling nested functions)
28
31
  var fns = [];
29
32
 
30
- // When parsing a new function, store it in our function stack
33
+ /**
34
+ * When parsing a new function, store it in our function stack.
35
+ * @returns {void}
36
+ * @private
37
+ */
31
38
  function startFunction() {
32
39
  fns.push({returnPresent: false});
33
40
  }
34
41
 
42
+ /**
43
+ * Indicate that return has been found in the current function.
44
+ * @param {ASTNode} node The return node.
45
+ * @returns {void}
46
+ * @private
47
+ */
35
48
  function addReturn(node) {
36
49
  var functionState = fns[fns.length - 1];
37
50
 
@@ -44,6 +57,7 @@ module.exports = function(context) {
44
57
  * Validate the JSDoc node and output warnings if anything is wrong.
45
58
  * @param {ASTNode} node The AST node to check.
46
59
  * @returns {void}
60
+ * @private
47
61
  */
48
62
  function checkJSDoc(node) {
49
63
  var jsdocNode = context.getJSDocComment(node),
@@ -82,7 +96,7 @@ module.exports = function(context) {
82
96
  context.report(jsdocNode, "Missing JSDoc parameter type for '{{name}}'.", { name: tag.name });
83
97
  }
84
98
 
85
- if (!tag.description) {
99
+ if (!tag.description && requireParamDescription) {
86
100
  context.report(jsdocNode, "Missing JSDoc parameter description for '{{name}}'.", { name: tag.name });
87
101
  }
88
102
 
@@ -115,6 +129,7 @@ module.exports = function(context) {
115
129
  hasConstructor = true;
116
130
  break;
117
131
 
132
+ // no default
118
133
  }
119
134
 
120
135
  // check tag preferences
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint",
3
- "version": "0.5.0",
3
+ "version": "0.6.2",
4
4
  "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
5
5
  "description": "An Esprima-based pattern checker for JavaScript.",
6
6
  "bin": {
@@ -32,9 +32,9 @@
32
32
  "homepage": "http://eslint.org",
33
33
  "bugs": "https://github.com/eslint/eslint/issues/",
34
34
  "dependencies": {
35
- "optionator": "~0.3.0",
35
+ "optionator": "^0.4.0",
36
36
  "estraverse": "~1.3.0",
37
- "esprima": "~1.1.1",
37
+ "esprima": "^1.2.0",
38
38
  "escope": "~1.0.0",
39
39
  "glob": "~3.2.7",
40
40
  "text-table": "~0.2.0",
@@ -55,7 +55,7 @@
55
55
  "browserify": "~3.20.0",
56
56
  "mocha-phantomjs": "~3.3.1",
57
57
  "phantomjs": "~1.9.2-6",
58
- "eslint-tester": "latest",
58
+ "eslint-tester": "^0.1.0",
59
59
  "brfs": "0.0.9",
60
60
  "through": "~2.3.4",
61
61
  "beefy": "~1.0.0",
@@ -68,5 +68,8 @@
68
68
  "ecmascript"
69
69
  ],
70
70
  "preferGlobal": true,
71
- "license": "MIT"
71
+ "license": "MIT",
72
+ "engines": {
73
+ "node": ">=0.10"
74
+ }
72
75
  }