eslint 4.1.1 → 4.4.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/bin/eslint.js +5 -4
  3. package/conf/category-list.json +2 -2
  4. package/conf/config-schema.js +3 -1
  5. package/conf/eslint-recommended.js +12 -14
  6. package/lib/cli-engine.js +4 -3
  7. package/lib/cli.js +12 -1
  8. package/lib/config/config-file.js +5 -5
  9. package/lib/config/config-initializer.js +123 -14
  10. package/lib/config/config-validator.js +43 -14
  11. package/lib/config/plugins.js +13 -1
  12. package/lib/linter.js +26 -15
  13. package/lib/rule-context.js +53 -41
  14. package/lib/rules/arrow-parens.js +5 -2
  15. package/lib/rules/comma-dangle.js +40 -40
  16. package/lib/rules/curly.js +1 -1
  17. package/lib/rules/dot-notation.js +9 -0
  18. package/lib/rules/getter-return.js +176 -0
  19. package/lib/rules/id-blacklist.js +7 -3
  20. package/lib/rules/id-match.js +8 -4
  21. package/lib/rules/indent-legacy.js +2 -2
  22. package/lib/rules/indent.js +354 -349
  23. package/lib/rules/key-spacing.js +2 -2
  24. package/lib/rules/multiline-ternary.js +8 -2
  25. package/lib/rules/no-cond-assign.js +7 -3
  26. package/lib/rules/no-constant-condition.js +62 -6
  27. package/lib/rules/no-debugger.js +6 -1
  28. package/lib/rules/no-else-return.js +1 -1
  29. package/lib/rules/no-extra-parens.js +24 -11
  30. package/lib/rules/no-inner-declarations.js +8 -4
  31. package/lib/rules/no-multi-spaces.js +53 -115
  32. package/lib/rules/no-regex-spaces.js +4 -4
  33. package/lib/rules/no-restricted-globals.js +50 -9
  34. package/lib/rules/no-restricted-properties.js +19 -11
  35. package/lib/rules/no-sync.js +15 -3
  36. package/lib/rules/no-tabs.js +8 -4
  37. package/lib/rules/no-underscore-dangle.js +28 -1
  38. package/lib/rules/object-curly-newline.js +18 -0
  39. package/lib/rules/object-curly-spacing.js +1 -1
  40. package/lib/rules/padded-blocks.js +2 -2
  41. package/lib/rules/padding-line-between-statements.js +1 -1
  42. package/lib/rules/prefer-destructuring.js +70 -32
  43. package/lib/rules/prefer-numeric-literals.js +36 -7
  44. package/lib/rules/prefer-reflect.js +8 -4
  45. package/lib/rules/prefer-template.js +2 -2
  46. package/lib/rules/space-infix-ops.js +1 -1
  47. package/lib/rules/spaced-comment.js +2 -2
  48. package/lib/rules/valid-jsdoc.js +15 -7
  49. package/lib/testers/rule-tester.js +23 -30
  50. package/lib/testers/test-parser.js +48 -0
  51. package/lib/util/ajv.js +29 -0
  52. package/lib/util/npm-util.js +9 -8
  53. package/lib/util/source-code-fixer.js +47 -19
  54. package/package.json +11 -7
  55. package/conf/json-schema-schema.json +0 -150
@@ -0,0 +1,176 @@
1
+ /**
2
+ * @fileoverview Enforces that a return statement is present in property getters.
3
+ * @author Aladdin-ADD(hh_2013@foxmail.com)
4
+ */
5
+
6
+ "use strict";
7
+
8
+ //------------------------------------------------------------------------------
9
+ // Requirements
10
+ //------------------------------------------------------------------------------
11
+
12
+ const astUtils = require("../ast-utils");
13
+
14
+ //------------------------------------------------------------------------------
15
+ // Helpers
16
+ //------------------------------------------------------------------------------
17
+ const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/;
18
+
19
+ /**
20
+ * Checks a given code path segment is reachable.
21
+ *
22
+ * @param {CodePathSegment} segment - A segment to check.
23
+ * @returns {boolean} `true` if the segment is reachable.
24
+ */
25
+ function isReachable(segment) {
26
+ return segment.reachable;
27
+ }
28
+
29
+ /**
30
+ * Gets a readable location.
31
+ *
32
+ * - FunctionExpression -> the function name or `function` keyword.
33
+ *
34
+ * @param {ASTNode} node - A function node to get.
35
+ * @returns {ASTNode|Token} The node or the token of a location.
36
+ */
37
+ function getId(node) {
38
+ return node.id || node;
39
+ }
40
+
41
+ //------------------------------------------------------------------------------
42
+ // Rule Definition
43
+ //------------------------------------------------------------------------------
44
+
45
+ module.exports = {
46
+ meta: {
47
+ docs: {
48
+ description: "enforce `return` statements in getters",
49
+ category: "Possible Errors",
50
+ recommended: false
51
+ },
52
+ fixable: null,
53
+ schema: [
54
+ {
55
+ type: "object",
56
+ properties: {
57
+ allowImplicit: {
58
+ type: "boolean"
59
+ }
60
+ },
61
+ additionalProperties: false
62
+ }
63
+ ]
64
+ },
65
+
66
+ create(context) {
67
+
68
+ const options = context.options[0] || { allowImplicit: false };
69
+
70
+ let funcInfo = {
71
+ upper: null,
72
+ codePath: null,
73
+ hasReturn: false,
74
+ shouldCheck: false,
75
+ node: null
76
+ };
77
+
78
+ /**
79
+ * Checks whether or not the last code path segment is reachable.
80
+ * Then reports this function if the segment is reachable.
81
+ *
82
+ * If the last code path segment is reachable, there are paths which are not
83
+ * returned or thrown.
84
+ *
85
+ * @param {ASTNode} node - A node to check.
86
+ * @returns {void}
87
+ */
88
+ function checkLastSegment(node) {
89
+ if (funcInfo.shouldCheck &&
90
+ funcInfo.codePath.currentSegments.some(isReachable)
91
+ ) {
92
+ context.report({
93
+ node,
94
+ loc: getId(node).loc.start,
95
+ message: funcInfo.hasReturn
96
+ ? "Expected {{name}} to always return a value."
97
+ : "Expected to return a value in {{name}}.",
98
+ data: {
99
+ name: astUtils.getFunctionNameWithKind(funcInfo.node)
100
+ }
101
+ });
102
+ }
103
+ }
104
+
105
+ /** Checks whether a node means a getter function.
106
+ * @param {ASTNode} node - a node to check.
107
+ * @returns {boolean} if node means a getter, return true; else return false.
108
+ */
109
+ function isGetter(node) {
110
+ const parent = node.parent;
111
+
112
+ if (TARGET_NODE_TYPE.test(node.type) && node.body.type === "BlockStatement") {
113
+ if (parent.kind === "get") {
114
+ return true;
115
+ }
116
+ if (parent.type === "Property" && astUtils.getStaticPropertyName(parent) === "get" && parent.parent.type === "ObjectExpression") {
117
+
118
+ // Object.defineProperty()
119
+ if (parent.parent.parent.type === "CallExpression" &&
120
+ astUtils.getStaticPropertyName(parent.parent.parent.callee) === "defineProperty") {
121
+ return true;
122
+ }
123
+
124
+ // Object.defineProperties()
125
+ if (parent.parent.parent.type === "Property" &&
126
+ parent.parent.parent.parent.type === "ObjectExpression" &&
127
+ parent.parent.parent.parent.parent.type === "CallExpression" &&
128
+ astUtils.getStaticPropertyName(parent.parent.parent.parent.parent.callee) === "defineProperties") {
129
+ return true;
130
+ }
131
+ }
132
+ }
133
+ return false;
134
+ }
135
+ return {
136
+
137
+ // Stacks this function's information.
138
+ onCodePathStart(codePath, node) {
139
+ funcInfo = {
140
+ upper: funcInfo,
141
+ codePath,
142
+ hasReturn: false,
143
+ shouldCheck: isGetter(node),
144
+ node
145
+ };
146
+ },
147
+
148
+ // Pops this function's information.
149
+ onCodePathEnd() {
150
+ funcInfo = funcInfo.upper;
151
+ },
152
+
153
+ // Checks the return statement is valid.
154
+ ReturnStatement(node) {
155
+ if (funcInfo.shouldCheck) {
156
+ funcInfo.hasReturn = true;
157
+
158
+ // if allowImplicit: false, should also check node.argument
159
+ if (!options.allowImplicit && !node.argument) {
160
+ context.report({
161
+ node,
162
+ message: "Expected to return a value in {{name}}.",
163
+ data: {
164
+ name: astUtils.getFunctionNameWithKind(funcInfo.node)
165
+ }
166
+ });
167
+ }
168
+ }
169
+ },
170
+
171
+ // Reports a given function if the last path is reachable.
172
+ "FunctionExpression:exit": checkLastSegment,
173
+ "ArrowFunctionExpression:exit": checkLastSegment
174
+ };
175
+ }
176
+ };
@@ -67,9 +67,13 @@ module.exports = {
67
67
  * @private
68
68
  */
69
69
  function report(node) {
70
- context.report({ node, message: "Identifier '{{name}}' is blacklisted.", data: {
71
- name: node.name
72
- } });
70
+ context.report({
71
+ node,
72
+ message: "Identifier '{{name}}' is blacklisted.",
73
+ data: {
74
+ name: node.name
75
+ }
76
+ });
73
77
  }
74
78
 
75
79
  return {
@@ -75,10 +75,14 @@ module.exports = {
75
75
  * @private
76
76
  */
77
77
  function report(node) {
78
- context.report({ node, message: "Identifier '{{name}}' does not match the pattern '{{pattern}}'.", data: {
79
- name: node.name,
80
- pattern
81
- } });
78
+ context.report({
79
+ node,
80
+ message: "Identifier '{{name}}' does not match the pattern '{{pattern}}'.",
81
+ data: {
82
+ name: node.name,
83
+ pattern
84
+ }
85
+ });
82
86
  }
83
87
 
84
88
  return {
@@ -729,7 +729,7 @@ module.exports = {
729
729
  if (!parentVarNode || parentVarNode.loc.start.line !== node.loc.start.line) {
730
730
  if (parent.type !== "VariableDeclarator" || parentVarNode === parentVarNode.parent.declarations[0]) {
731
731
  if (parent.type === "VariableDeclarator" && parentVarNode.loc.start.line === parent.loc.start.line) {
732
- nodeIndent = nodeIndent + (indentSize * options.VariableDeclarator[parentVarNode.parent.kind]);
732
+ nodeIndent += (indentSize * options.VariableDeclarator[parentVarNode.parent.kind]);
733
733
  } else if (parent.type === "ObjectExpression" || parent.type === "ArrayExpression") {
734
734
  const parentElements = node.parent.type === "ObjectExpression" ? node.parent.properties : node.parent.elements;
735
735
 
@@ -765,7 +765,7 @@ module.exports = {
765
765
  }
766
766
  }
767
767
  } else if (!parentVarNode && !isFirstArrayElementOnSameLine(parent) && parent.type !== "MemberExpression" && parent.type !== "ExpressionStatement" && parent.type !== "AssignmentExpression" && parent.type !== "Property") {
768
- nodeIndent = nodeIndent + indentSize;
768
+ nodeIndent += indentSize;
769
769
  }
770
770
 
771
771
  checkFirstNodeLineIndent(node, nodeIndent);