eslint 0.22.0 → 0.24.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 (201) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +111 -95
  3. package/bin/eslint.js +41 -41
  4. package/conf/environments.js +87 -81
  5. package/conf/eslint.json +186 -179
  6. package/lib/api.js +13 -12
  7. package/lib/cli-engine.js +441 -451
  8. package/lib/cli.js +196 -196
  9. package/lib/config-initializer.js +145 -145
  10. package/lib/config-validator.js +110 -110
  11. package/lib/config.js +428 -416
  12. package/lib/eslint.js +1072 -1073
  13. package/lib/file-finder.js +167 -167
  14. package/lib/formatters/checkstyle.js +68 -68
  15. package/lib/formatters/compact.js +53 -53
  16. package/lib/formatters/jslint-xml.js +40 -40
  17. package/lib/formatters/junit.js +63 -63
  18. package/lib/formatters/stylish.js +90 -90
  19. package/lib/formatters/tap.js +86 -86
  20. package/lib/ignored-paths.js +137 -137
  21. package/lib/load-rules.js +39 -39
  22. package/lib/options.js +132 -126
  23. package/lib/rule-context.js +107 -107
  24. package/lib/rules/accessor-pairs.js +65 -65
  25. package/lib/rules/array-bracket-spacing.js +180 -0
  26. package/lib/rules/block-scoped-var.js +339 -320
  27. package/lib/rules/brace-style.js +228 -228
  28. package/lib/rules/camelcase.js +111 -111
  29. package/lib/rules/comma-dangle.js +67 -64
  30. package/lib/rules/comma-spacing.js +191 -191
  31. package/lib/rules/comma-style.js +195 -195
  32. package/lib/rules/complexity.js +94 -94
  33. package/lib/rules/computed-property-spacing.js +144 -0
  34. package/lib/rules/consistent-return.js +75 -75
  35. package/lib/rules/consistent-this.js +119 -119
  36. package/lib/rules/constructor-super.js +108 -0
  37. package/lib/rules/curly.js +109 -109
  38. package/lib/rules/default-case.js +66 -66
  39. package/lib/rules/dot-location.js +63 -63
  40. package/lib/rules/dot-notation.js +119 -119
  41. package/lib/rules/eol-last.js +38 -38
  42. package/lib/rules/eqeqeq.js +96 -96
  43. package/lib/rules/func-names.js +45 -45
  44. package/lib/rules/func-style.js +49 -49
  45. package/lib/rules/generator-star-spacing.js +104 -87
  46. package/lib/rules/generator-star.js +76 -76
  47. package/lib/rules/global-strict.js +49 -49
  48. package/lib/rules/guard-for-in.js +32 -32
  49. package/lib/rules/handle-callback-err.js +81 -124
  50. package/lib/rules/indent.js +486 -486
  51. package/lib/rules/key-spacing.js +325 -325
  52. package/lib/rules/linebreak-style.js +44 -44
  53. package/lib/rules/lines-around-comment.js +228 -160
  54. package/lib/rules/max-depth.js +89 -89
  55. package/lib/rules/max-len.js +76 -76
  56. package/lib/rules/max-nested-callbacks.js +73 -73
  57. package/lib/rules/max-params.js +45 -45
  58. package/lib/rules/max-statements.js +61 -61
  59. package/lib/rules/new-cap.js +224 -224
  60. package/lib/rules/new-parens.js +29 -29
  61. package/lib/rules/newline-after-var.js +127 -127
  62. package/lib/rules/no-alert.js +153 -153
  63. package/lib/rules/no-array-constructor.js +31 -31
  64. package/lib/rules/no-bitwise.js +57 -57
  65. package/lib/rules/no-caller.js +29 -29
  66. package/lib/rules/no-catch-shadow.js +52 -52
  67. package/lib/rules/no-comma-dangle.js +45 -45
  68. package/lib/rules/no-cond-assign.js +123 -123
  69. package/lib/rules/no-console.js +27 -27
  70. package/lib/rules/no-constant-condition.js +73 -73
  71. package/lib/rules/no-continue.js +23 -23
  72. package/lib/rules/no-control-regex.js +58 -58
  73. package/lib/rules/no-debugger.js +22 -22
  74. package/lib/rules/no-delete-var.js +25 -25
  75. package/lib/rules/no-div-regex.js +27 -27
  76. package/lib/rules/no-dupe-args.js +89 -85
  77. package/lib/rules/no-dupe-keys.js +43 -43
  78. package/lib/rules/no-duplicate-case.js +67 -67
  79. package/lib/rules/no-else-return.js +125 -125
  80. package/lib/rules/no-empty-character-class.js +43 -43
  81. package/lib/rules/no-empty-class.js +45 -45
  82. package/lib/rules/no-empty-label.js +27 -27
  83. package/lib/rules/no-empty.js +49 -49
  84. package/lib/rules/no-eq-null.js +29 -29
  85. package/lib/rules/no-eval.js +26 -26
  86. package/lib/rules/no-ex-assign.js +42 -42
  87. package/lib/rules/no-extend-native.js +103 -103
  88. package/lib/rules/no-extra-bind.js +81 -81
  89. package/lib/rules/no-extra-boolean-cast.js +71 -71
  90. package/lib/rules/no-extra-parens.js +368 -355
  91. package/lib/rules/no-extra-semi.js +70 -23
  92. package/lib/rules/no-extra-strict.js +86 -86
  93. package/lib/rules/no-fallthrough.js +97 -97
  94. package/lib/rules/no-floating-decimal.js +30 -30
  95. package/lib/rules/no-func-assign.js +83 -83
  96. package/lib/rules/no-implied-eval.js +76 -76
  97. package/lib/rules/no-inline-comments.js +49 -49
  98. package/lib/rules/no-inner-declarations.js +78 -78
  99. package/lib/rules/no-invalid-regexp.js +53 -53
  100. package/lib/rules/no-irregular-whitespace.js +135 -135
  101. package/lib/rules/no-iterator.js +28 -28
  102. package/lib/rules/no-label-var.js +64 -64
  103. package/lib/rules/no-labels.js +44 -44
  104. package/lib/rules/no-lone-blocks.js +106 -27
  105. package/lib/rules/no-lonely-if.js +30 -30
  106. package/lib/rules/no-loop-func.js +58 -58
  107. package/lib/rules/no-mixed-requires.js +165 -165
  108. package/lib/rules/no-mixed-spaces-and-tabs.js +74 -74
  109. package/lib/rules/no-multi-spaces.js +119 -119
  110. package/lib/rules/no-multi-str.js +43 -43
  111. package/lib/rules/no-multiple-empty-lines.js +98 -98
  112. package/lib/rules/no-native-reassign.js +62 -62
  113. package/lib/rules/no-negated-in-lhs.js +25 -25
  114. package/lib/rules/no-nested-ternary.js +24 -24
  115. package/lib/rules/no-new-func.js +25 -25
  116. package/lib/rules/no-new-object.js +25 -25
  117. package/lib/rules/no-new-require.js +25 -25
  118. package/lib/rules/no-new-wrappers.js +26 -26
  119. package/lib/rules/no-new.js +27 -27
  120. package/lib/rules/no-obj-calls.js +28 -28
  121. package/lib/rules/no-octal-escape.js +39 -39
  122. package/lib/rules/no-octal.js +25 -25
  123. package/lib/rules/no-param-reassign.js +87 -87
  124. package/lib/rules/no-path-concat.js +39 -39
  125. package/lib/rules/no-plusplus.js +24 -24
  126. package/lib/rules/no-process-env.js +30 -30
  127. package/lib/rules/no-process-exit.js +33 -33
  128. package/lib/rules/no-proto.js +28 -28
  129. package/lib/rules/no-redeclare.js +68 -68
  130. package/lib/rules/no-regex-spaces.js +35 -35
  131. package/lib/rules/no-reserved-keys.js +56 -56
  132. package/lib/rules/no-restricted-modules.js +85 -85
  133. package/lib/rules/no-return-assign.js +53 -24
  134. package/lib/rules/no-script-url.js +34 -34
  135. package/lib/rules/no-self-compare.js +29 -29
  136. package/lib/rules/no-sequences.js +94 -94
  137. package/lib/rules/no-shadow-restricted-names.js +51 -51
  138. package/lib/rules/no-shadow.js +181 -136
  139. package/lib/rules/no-space-before-semi.js +98 -98
  140. package/lib/rules/no-spaced-func.js +37 -37
  141. package/lib/rules/no-sparse-arrays.js +33 -33
  142. package/lib/rules/no-sync.js +30 -30
  143. package/lib/rules/no-ternary.js +24 -24
  144. package/lib/rules/no-this-before-super.js +144 -0
  145. package/lib/rules/no-throw-literal.js +33 -33
  146. package/lib/rules/no-trailing-spaces.js +74 -63
  147. package/lib/rules/no-undef-init.js +28 -28
  148. package/lib/rules/no-undef.js +92 -92
  149. package/lib/rules/no-undefined.js +27 -27
  150. package/lib/rules/no-underscore-dangle.js +73 -73
  151. package/lib/rules/no-unexpected-multiline.js +58 -0
  152. package/lib/rules/no-unneeded-ternary.js +48 -48
  153. package/lib/rules/no-unreachable.js +98 -98
  154. package/lib/rules/no-unused-expressions.js +76 -76
  155. package/lib/rules/no-unused-vars.js +252 -250
  156. package/lib/rules/no-use-before-define.js +105 -105
  157. package/lib/rules/no-var.js +26 -26
  158. package/lib/rules/no-void.js +28 -28
  159. package/lib/rules/no-warning-comments.js +102 -102
  160. package/lib/rules/no-with.js +22 -22
  161. package/lib/rules/no-wrap-func.js +65 -65
  162. package/lib/rules/object-curly-spacing.js +231 -206
  163. package/lib/rules/object-shorthand.js +74 -73
  164. package/lib/rules/one-var.js +311 -304
  165. package/lib/rules/operator-assignment.js +118 -118
  166. package/lib/rules/operator-linebreak.js +114 -114
  167. package/lib/rules/padded-blocks.js +98 -98
  168. package/lib/rules/prefer-const.js +91 -0
  169. package/lib/rules/quote-props.js +72 -72
  170. package/lib/rules/quotes.js +92 -92
  171. package/lib/rules/radix.js +41 -41
  172. package/lib/rules/semi-spacing.js +167 -167
  173. package/lib/rules/semi.js +136 -136
  174. package/lib/rules/sort-vars.js +49 -49
  175. package/lib/rules/space-after-function-name.js +49 -49
  176. package/lib/rules/space-after-keywords.js +82 -82
  177. package/lib/rules/space-before-blocks.js +91 -91
  178. package/lib/rules/space-before-function-paren.js +139 -139
  179. package/lib/rules/space-before-function-parentheses.js +139 -139
  180. package/lib/rules/space-in-brackets.js +305 -305
  181. package/lib/rules/space-in-parens.js +281 -281
  182. package/lib/rules/space-infix-ops.js +106 -106
  183. package/lib/rules/space-return-throw-case.js +38 -38
  184. package/lib/rules/space-unary-ops.js +124 -133
  185. package/lib/rules/spaced-comment.js +143 -0
  186. package/lib/rules/spaced-line-comment.js +89 -89
  187. package/lib/rules/strict.js +242 -242
  188. package/lib/rules/use-isnan.js +26 -26
  189. package/lib/rules/valid-jsdoc.js +215 -215
  190. package/lib/rules/valid-typeof.js +42 -42
  191. package/lib/rules/vars-on-top.js +115 -115
  192. package/lib/rules/wrap-iife.js +48 -48
  193. package/lib/rules/wrap-regex.js +38 -38
  194. package/lib/rules/yoda.js +242 -225
  195. package/lib/rules.js +88 -88
  196. package/lib/timing.js +109 -109
  197. package/lib/token-store.js +201 -201
  198. package/lib/util/traverse.js +105 -105
  199. package/lib/util.js +125 -85
  200. package/package.json +6 -6
  201. package/CHANGELOG.md +0 -1638
@@ -0,0 +1,144 @@
1
+ /**
2
+ * @fileoverview Disallows or enforces spaces inside computed properties.
3
+ * @author Jamund Ferguson
4
+ * @copyright 2015 Jamund Ferguson. All rights reserved.
5
+ */
6
+ "use strict";
7
+
8
+ //------------------------------------------------------------------------------
9
+ // Rule Definition
10
+ //------------------------------------------------------------------------------
11
+
12
+ module.exports = function(context) {
13
+ var propertyNameMustBeSpaced = context.options[0] === "always"; // default is "never"
14
+
15
+ //--------------------------------------------------------------------------
16
+ // Helpers
17
+ //--------------------------------------------------------------------------
18
+
19
+ /**
20
+ * Determines whether two adjacent tokens are have whitespace between them.
21
+ * @param {Object} left - The left token object.
22
+ * @param {Object} right - The right token object.
23
+ * @returns {boolean} Whether or not there is space between the tokens.
24
+ */
25
+ function isSpaced(left, right) {
26
+ return left.range[1] < right.range[0];
27
+ }
28
+
29
+ /**
30
+ * Determines whether two adjacent tokens are on the same line.
31
+ * @param {Object} left - The left token object.
32
+ * @param {Object} right - The right token object.
33
+ * @returns {boolean} Whether or not the tokens are on the same line.
34
+ */
35
+ function isSameLine(left, right) {
36
+ return left.loc.start.line === right.loc.start.line;
37
+ }
38
+
39
+ /**
40
+ * Reports that there shouldn't be a space after the first token
41
+ * @param {ASTNode} node - The node to report in the event of an error.
42
+ * @param {Token} token - The token to use for the report.
43
+ * @returns {void}
44
+ */
45
+ function reportNoBeginningSpace(node, token) {
46
+ context.report(node, token.loc.start,
47
+ "There should be no space after '" + token.value + "'");
48
+ }
49
+
50
+ /**
51
+ * Reports that there shouldn't be a space before the last token
52
+ * @param {ASTNode} node - The node to report in the event of an error.
53
+ * @param {Token} token - The token to use for the report.
54
+ * @returns {void}
55
+ */
56
+ function reportNoEndingSpace(node, token) {
57
+ context.report(node, token.loc.start,
58
+ "There should be no space before '" + token.value + "'");
59
+ }
60
+
61
+ /**
62
+ * Reports that there should be a space after the first token
63
+ * @param {ASTNode} node - The node to report in the event of an error.
64
+ * @param {Token} token - The token to use for the report.
65
+ * @returns {void}
66
+ */
67
+ function reportRequiredBeginningSpace(node, token) {
68
+ context.report(node, token.loc.start,
69
+ "A space is required after '" + token.value + "'");
70
+ }
71
+
72
+ /**
73
+ * Reports that there should be a space before the last token
74
+ * @param {ASTNode} node - The node to report in the event of an error.
75
+ * @param {Token} token - The token to use for the report.
76
+ * @returns {void}
77
+ */
78
+ function reportRequiredEndingSpace(node, token) {
79
+ context.report(node, token.loc.start,
80
+ "A space is required before '" + token.value + "'");
81
+ }
82
+
83
+ /**
84
+ * Returns a function that checks the spacing of a node on the property name
85
+ * that was passed in.
86
+ * @param {String} propertyName The property on the node to check for spacing
87
+ * @returns {Function} A function that will check spacing on a node
88
+ */
89
+ function checkSpacing(propertyName) {
90
+ return function(node) {
91
+ if (!node.computed) {
92
+ return;
93
+ }
94
+
95
+ var property = node[propertyName];
96
+
97
+ var before = context.getTokenBefore(property),
98
+ first = context.getFirstToken(property),
99
+ last = context.getLastToken(property),
100
+ after = context.getTokenAfter(property);
101
+
102
+ if (isSameLine(before, first)) {
103
+ if (propertyNameMustBeSpaced) {
104
+ if (!isSpaced(before, first) && isSameLine(before, first)) {
105
+ reportRequiredBeginningSpace(node, before);
106
+ }
107
+ } else {
108
+ if (isSpaced(before, first)) {
109
+ reportNoBeginningSpace(node, before);
110
+ }
111
+ }
112
+ }
113
+
114
+ if (isSameLine(last, after)) {
115
+ if (propertyNameMustBeSpaced) {
116
+ if (!isSpaced(last, after) && isSameLine(last, after)) {
117
+ reportRequiredEndingSpace(node, after);
118
+ }
119
+ } else {
120
+ if (isSpaced(last, after)) {
121
+ reportNoEndingSpace(node, after);
122
+ }
123
+ }
124
+ }
125
+ };
126
+ }
127
+
128
+
129
+ //--------------------------------------------------------------------------
130
+ // Public
131
+ //--------------------------------------------------------------------------
132
+
133
+ return {
134
+ Property: checkSpacing("key"),
135
+ MemberExpression: checkSpacing("property")
136
+ };
137
+
138
+ };
139
+
140
+ module.exports.schema = [
141
+ {
142
+ "enum": ["always", "never"]
143
+ }
144
+ ];
@@ -1,75 +1,75 @@
1
- /**
2
- * @fileoverview Rule to flag consistent return values
3
- * @author Nicholas C. Zakas
4
- */
5
- "use strict";
6
-
7
- //------------------------------------------------------------------------------
8
- // Rule Definition
9
- //------------------------------------------------------------------------------
10
-
11
- module.exports = function(context) {
12
-
13
- var functions = [];
14
-
15
- //--------------------------------------------------------------------------
16
- // Helpers
17
- //--------------------------------------------------------------------------
18
-
19
- /**
20
- * Marks entrance into a function by pushing a new object onto the functions
21
- * stack.
22
- * @returns {void}
23
- * @private
24
- */
25
- function enterFunction() {
26
- functions.push({});
27
- }
28
-
29
- /**
30
- * Marks exit of a function by popping off the functions stack.
31
- * @returns {void}
32
- * @private
33
- */
34
- function exitFunction() {
35
- functions.pop();
36
- }
37
-
38
-
39
- //--------------------------------------------------------------------------
40
- // Public
41
- //--------------------------------------------------------------------------
42
-
43
- return {
44
-
45
- "Program": enterFunction,
46
- "FunctionDeclaration": enterFunction,
47
- "FunctionExpression": enterFunction,
48
- "ArrowFunctionExpression": enterFunction,
49
-
50
- "Program:exit": exitFunction,
51
- "FunctionDeclaration:exit": exitFunction,
52
- "FunctionExpression:exit": exitFunction,
53
- "ArrowFunctionExpression:exit": exitFunction,
54
-
55
- "ReturnStatement": function(node) {
56
-
57
- var returnInfo = functions[functions.length - 1],
58
- returnTypeDefined = "type" in returnInfo;
59
-
60
- if (returnTypeDefined) {
61
-
62
- if (returnInfo.type !== !!node.argument) {
63
- context.report(node, "Expected " + (returnInfo.type ? "a" : "no") + " return value.");
64
- }
65
-
66
- } else {
67
- returnInfo.type = !!node.argument;
68
- }
69
-
70
- }
71
- };
72
-
73
- };
74
-
75
- module.exports.schema = [];
1
+ /**
2
+ * @fileoverview Rule to flag consistent return values
3
+ * @author Nicholas C. Zakas
4
+ */
5
+ "use strict";
6
+
7
+ //------------------------------------------------------------------------------
8
+ // Rule Definition
9
+ //------------------------------------------------------------------------------
10
+
11
+ module.exports = function(context) {
12
+
13
+ var functions = [];
14
+
15
+ //--------------------------------------------------------------------------
16
+ // Helpers
17
+ //--------------------------------------------------------------------------
18
+
19
+ /**
20
+ * Marks entrance into a function by pushing a new object onto the functions
21
+ * stack.
22
+ * @returns {void}
23
+ * @private
24
+ */
25
+ function enterFunction() {
26
+ functions.push({});
27
+ }
28
+
29
+ /**
30
+ * Marks exit of a function by popping off the functions stack.
31
+ * @returns {void}
32
+ * @private
33
+ */
34
+ function exitFunction() {
35
+ functions.pop();
36
+ }
37
+
38
+
39
+ //--------------------------------------------------------------------------
40
+ // Public
41
+ //--------------------------------------------------------------------------
42
+
43
+ return {
44
+
45
+ "Program": enterFunction,
46
+ "FunctionDeclaration": enterFunction,
47
+ "FunctionExpression": enterFunction,
48
+ "ArrowFunctionExpression": enterFunction,
49
+
50
+ "Program:exit": exitFunction,
51
+ "FunctionDeclaration:exit": exitFunction,
52
+ "FunctionExpression:exit": exitFunction,
53
+ "ArrowFunctionExpression:exit": exitFunction,
54
+
55
+ "ReturnStatement": function(node) {
56
+
57
+ var returnInfo = functions[functions.length - 1],
58
+ returnTypeDefined = "type" in returnInfo;
59
+
60
+ if (returnTypeDefined) {
61
+
62
+ if (returnInfo.type !== !!node.argument) {
63
+ context.report(node, "Expected " + (returnInfo.type ? "a" : "no") + " return value.");
64
+ }
65
+
66
+ } else {
67
+ returnInfo.type = !!node.argument;
68
+ }
69
+
70
+ }
71
+ };
72
+
73
+ };
74
+
75
+ module.exports.schema = [];
@@ -1,119 +1,119 @@
1
- /**
2
- * @fileoverview Rule to enforce consistent naming of "this" context variables
3
- * @author Raphael Pigulla
4
- * @copyright 2015 Timothy Jones. All rights reserved.
5
- * @copyright 2015 David Aurelio. All rights reserved.
6
- */
7
- "use strict";
8
-
9
- //------------------------------------------------------------------------------
10
- // Rule Definition
11
- //------------------------------------------------------------------------------
12
-
13
- module.exports = function(context) {
14
- var alias = context.options[0];
15
-
16
- /**
17
- * Reports that a variable declarator or assignment expression is assigning
18
- * a non-'this' value to the specified alias.
19
- * @param {ASTNode} node - The assigning node.
20
- * @returns {void}
21
- */
22
- function reportBadAssignment(node) {
23
- context.report(node,
24
- "Designated alias '{{alias}}' is not assigned to 'this'.",
25
- { alias: alias });
26
- }
27
-
28
- /**
29
- * Checks that an assignment to an identifier only assigns 'this' to the
30
- * appropriate alias, and the alias is only assigned to 'this'.
31
- * @param {ASTNode} node - The assigning node.
32
- * @param {Identifier} name - The name of the variable assigned to.
33
- * @param {Expression} value - The value of the assignment.
34
- * @returns {void}
35
- */
36
- function checkAssignment(node, name, value) {
37
- var isThis = value.type === "ThisExpression";
38
-
39
- if (name === alias) {
40
- if (!isThis || node.operator && node.operator !== "=") {
41
- reportBadAssignment(node);
42
- }
43
- } else if (isThis) {
44
- context.report(node,
45
- "Unexpected alias '{{name}}' for 'this'.", { name: name });
46
- }
47
- }
48
-
49
- /**
50
- * Ensures that a variable declaration of the alias in a program or function
51
- * is assigned to the correct value.
52
- * @returns {void}
53
- */
54
- function ensureWasAssigned() {
55
- var scope = context.getScope();
56
-
57
- scope.variables.some(function (variable) {
58
- var lookup;
59
-
60
- if (variable.name === alias) {
61
- if (variable.defs.some(function (def) {
62
- return def.node.type === "VariableDeclarator" &&
63
- def.node.init !== null;
64
- })) {
65
- return true;
66
- }
67
-
68
- lookup = scope.type === "global" ? scope : variable;
69
-
70
- // The alias has been declared and not assigned: check it was
71
- // assigned later in the same scope.
72
- if (!lookup.references.some(function (reference) {
73
- var write = reference.writeExpr;
74
-
75
- if (reference.from === scope &&
76
- write && write.type === "ThisExpression" &&
77
- write.parent.operator === "=") {
78
- return true;
79
- }
80
- })) {
81
- variable.defs.map(function (def) {
82
- return def.node;
83
- }).forEach(reportBadAssignment);
84
- }
85
-
86
- return true;
87
- }
88
- });
89
- }
90
-
91
- return {
92
- "Program:exit": ensureWasAssigned,
93
- "FunctionExpression:exit": ensureWasAssigned,
94
- "FunctionDeclaration:exit": ensureWasAssigned,
95
-
96
- "VariableDeclarator": function (node) {
97
- var id = node.id;
98
- var isDestructuring =
99
- id.type === "ArrayPattern" || id.type === "ObjectPattern";
100
-
101
- if (node.init !== null && !isDestructuring) {
102
- checkAssignment(node, id.name, node.init);
103
- }
104
- },
105
-
106
- "AssignmentExpression": function (node) {
107
- if (node.left.type === "Identifier") {
108
- checkAssignment(node, node.left.name, node.right);
109
- }
110
- }
111
- };
112
-
113
- };
114
-
115
- module.exports.schema = [
116
- {
117
- "type": "string"
118
- }
119
- ];
1
+ /**
2
+ * @fileoverview Rule to enforce consistent naming of "this" context variables
3
+ * @author Raphael Pigulla
4
+ * @copyright 2015 Timothy Jones. All rights reserved.
5
+ * @copyright 2015 David Aurelio. All rights reserved.
6
+ */
7
+ "use strict";
8
+
9
+ //------------------------------------------------------------------------------
10
+ // Rule Definition
11
+ //------------------------------------------------------------------------------
12
+
13
+ module.exports = function(context) {
14
+ var alias = context.options[0];
15
+
16
+ /**
17
+ * Reports that a variable declarator or assignment expression is assigning
18
+ * a non-'this' value to the specified alias.
19
+ * @param {ASTNode} node - The assigning node.
20
+ * @returns {void}
21
+ */
22
+ function reportBadAssignment(node) {
23
+ context.report(node,
24
+ "Designated alias '{{alias}}' is not assigned to 'this'.",
25
+ { alias: alias });
26
+ }
27
+
28
+ /**
29
+ * Checks that an assignment to an identifier only assigns 'this' to the
30
+ * appropriate alias, and the alias is only assigned to 'this'.
31
+ * @param {ASTNode} node - The assigning node.
32
+ * @param {Identifier} name - The name of the variable assigned to.
33
+ * @param {Expression} value - The value of the assignment.
34
+ * @returns {void}
35
+ */
36
+ function checkAssignment(node, name, value) {
37
+ var isThis = value.type === "ThisExpression";
38
+
39
+ if (name === alias) {
40
+ if (!isThis || node.operator && node.operator !== "=") {
41
+ reportBadAssignment(node);
42
+ }
43
+ } else if (isThis) {
44
+ context.report(node,
45
+ "Unexpected alias '{{name}}' for 'this'.", { name: name });
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Ensures that a variable declaration of the alias in a program or function
51
+ * is assigned to the correct value.
52
+ * @returns {void}
53
+ */
54
+ function ensureWasAssigned() {
55
+ var scope = context.getScope();
56
+
57
+ scope.variables.some(function (variable) {
58
+ var lookup;
59
+
60
+ if (variable.name === alias) {
61
+ if (variable.defs.some(function (def) {
62
+ return def.node.type === "VariableDeclarator" &&
63
+ def.node.init !== null;
64
+ })) {
65
+ return true;
66
+ }
67
+
68
+ lookup = scope.type === "global" ? scope : variable;
69
+
70
+ // The alias has been declared and not assigned: check it was
71
+ // assigned later in the same scope.
72
+ if (!lookup.references.some(function (reference) {
73
+ var write = reference.writeExpr;
74
+
75
+ if (reference.from === scope &&
76
+ write && write.type === "ThisExpression" &&
77
+ write.parent.operator === "=") {
78
+ return true;
79
+ }
80
+ })) {
81
+ variable.defs.map(function (def) {
82
+ return def.node;
83
+ }).forEach(reportBadAssignment);
84
+ }
85
+
86
+ return true;
87
+ }
88
+ });
89
+ }
90
+
91
+ return {
92
+ "Program:exit": ensureWasAssigned,
93
+ "FunctionExpression:exit": ensureWasAssigned,
94
+ "FunctionDeclaration:exit": ensureWasAssigned,
95
+
96
+ "VariableDeclarator": function (node) {
97
+ var id = node.id;
98
+ var isDestructuring =
99
+ id.type === "ArrayPattern" || id.type === "ObjectPattern";
100
+
101
+ if (node.init !== null && !isDestructuring) {
102
+ checkAssignment(node, id.name, node.init);
103
+ }
104
+ },
105
+
106
+ "AssignmentExpression": function (node) {
107
+ if (node.left.type === "Identifier") {
108
+ checkAssignment(node, node.left.name, node.right);
109
+ }
110
+ }
111
+ };
112
+
113
+ };
114
+
115
+ module.exports.schema = [
116
+ {
117
+ "type": "string"
118
+ }
119
+ ];
@@ -0,0 +1,108 @@
1
+ /**
2
+ * @fileoverview A rule to verify `super()` callings in constructor.
3
+ * @author Toru Nagashima
4
+ * @copyright 2015 Toru Nagashima. All rights reserved.
5
+ */
6
+
7
+ "use strict";
8
+
9
+ //------------------------------------------------------------------------------
10
+ // Rule Definition
11
+ //------------------------------------------------------------------------------
12
+
13
+ module.exports = function(context) {
14
+
15
+ /**
16
+ * Searches a class node from ancestors of a node.
17
+ * @param {Node} node - A node to get.
18
+ * @returns {ClassDeclaration|ClassExpression|null} the found class node or `null`.
19
+ */
20
+ function getClassInAncestor(node) {
21
+ while (node != null) {
22
+ if (node.type === "ClassDeclaration" || node.type === "ClassExpression") {
23
+ return node;
24
+ }
25
+ node = node.parent;
26
+ }
27
+ /* istanbul ignore next */
28
+ return null;
29
+ }
30
+
31
+ /**
32
+ * Checks whether or not a node is the null literal.
33
+ * @param {Node} node - A node to check.
34
+ * @returns {boolean} whether or not a node is the null literal.
35
+ */
36
+ function isNullLiteral(node) {
37
+ return node != null && node.type === "Literal" && node.value === null;
38
+ }
39
+
40
+ /**
41
+ * Checks whether or not the current traversal context is on constructors.
42
+ * @param {{scope: Scope}} item - A checking context to check.
43
+ * @returns {boolean} whether or not the current traversal context is on constructors.
44
+ */
45
+ function isOnConstructor(item) {
46
+ return item != null && item.scope === context.getScope().variableScope.upper.variableScope;
47
+ }
48
+
49
+ // A stack for checking context.
50
+ var stack = [];
51
+
52
+ return {
53
+ /**
54
+ * Start checking.
55
+ * @param {MethodDefinition} node - A target node.
56
+ * @returns {void}
57
+ */
58
+ "MethodDefinition": function(node) {
59
+ if (node.kind !== "constructor") {
60
+ return;
61
+ }
62
+ stack.push({
63
+ superCallings: [],
64
+ scope: context.getScope().variableScope
65
+ });
66
+ },
67
+
68
+ /**
69
+ * Checks the result, then reports invalid/missing `super()`.
70
+ * @param {MethodDefinition} node - A target node.
71
+ * @returns {void}
72
+ */
73
+ "MethodDefinition:exit": function(node) {
74
+ if (node.kind !== "constructor") {
75
+ return;
76
+ }
77
+ var result = stack.pop();
78
+
79
+ var classNode = getClassInAncestor(node);
80
+ /* istanbul ignore if */
81
+ if (classNode == null) {
82
+ return;
83
+ }
84
+
85
+ if (classNode.superClass === null || isNullLiteral(classNode.superClass)) {
86
+ result.superCallings.forEach(function(superCalling) {
87
+ context.report(superCalling, "unexpected `super()`.");
88
+ });
89
+ } else if (result.superCallings.length === 0) {
90
+ context.report(node.key, "this constructor requires `super()`.");
91
+ }
92
+ },
93
+
94
+ /**
95
+ * Checks the result of checking, then reports invalid/missing `super()`.
96
+ * @param {MethodDefinition} node - A target node.
97
+ * @returns {void}
98
+ */
99
+ "CallExpression": function(node) {
100
+ var item = stack[stack.length - 1];
101
+ if (isOnConstructor(item) && node.callee.type === "Super") {
102
+ item.superCallings.push(node);
103
+ }
104
+ }
105
+ };
106
+ };
107
+
108
+ module.exports.schema = [];