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.
- package/LICENSE +20 -20
- package/README.md +111 -95
- package/bin/eslint.js +41 -41
- package/conf/environments.js +87 -81
- package/conf/eslint.json +186 -179
- package/lib/api.js +13 -12
- package/lib/cli-engine.js +441 -451
- package/lib/cli.js +196 -196
- package/lib/config-initializer.js +145 -145
- package/lib/config-validator.js +110 -110
- package/lib/config.js +428 -416
- package/lib/eslint.js +1072 -1073
- package/lib/file-finder.js +167 -167
- package/lib/formatters/checkstyle.js +68 -68
- package/lib/formatters/compact.js +53 -53
- package/lib/formatters/jslint-xml.js +40 -40
- package/lib/formatters/junit.js +63 -63
- package/lib/formatters/stylish.js +90 -90
- package/lib/formatters/tap.js +86 -86
- package/lib/ignored-paths.js +137 -137
- package/lib/load-rules.js +39 -39
- package/lib/options.js +132 -126
- package/lib/rule-context.js +107 -107
- package/lib/rules/accessor-pairs.js +65 -65
- package/lib/rules/array-bracket-spacing.js +180 -0
- package/lib/rules/block-scoped-var.js +339 -320
- package/lib/rules/brace-style.js +228 -228
- package/lib/rules/camelcase.js +111 -111
- package/lib/rules/comma-dangle.js +67 -64
- package/lib/rules/comma-spacing.js +191 -191
- package/lib/rules/comma-style.js +195 -195
- package/lib/rules/complexity.js +94 -94
- package/lib/rules/computed-property-spacing.js +144 -0
- package/lib/rules/consistent-return.js +75 -75
- package/lib/rules/consistent-this.js +119 -119
- package/lib/rules/constructor-super.js +108 -0
- package/lib/rules/curly.js +109 -109
- package/lib/rules/default-case.js +66 -66
- package/lib/rules/dot-location.js +63 -63
- package/lib/rules/dot-notation.js +119 -119
- package/lib/rules/eol-last.js +38 -38
- package/lib/rules/eqeqeq.js +96 -96
- package/lib/rules/func-names.js +45 -45
- package/lib/rules/func-style.js +49 -49
- package/lib/rules/generator-star-spacing.js +104 -87
- package/lib/rules/generator-star.js +76 -76
- package/lib/rules/global-strict.js +49 -49
- package/lib/rules/guard-for-in.js +32 -32
- package/lib/rules/handle-callback-err.js +81 -124
- package/lib/rules/indent.js +486 -486
- package/lib/rules/key-spacing.js +325 -325
- package/lib/rules/linebreak-style.js +44 -44
- package/lib/rules/lines-around-comment.js +228 -160
- package/lib/rules/max-depth.js +89 -89
- package/lib/rules/max-len.js +76 -76
- package/lib/rules/max-nested-callbacks.js +73 -73
- package/lib/rules/max-params.js +45 -45
- package/lib/rules/max-statements.js +61 -61
- package/lib/rules/new-cap.js +224 -224
- package/lib/rules/new-parens.js +29 -29
- package/lib/rules/newline-after-var.js +127 -127
- package/lib/rules/no-alert.js +153 -153
- package/lib/rules/no-array-constructor.js +31 -31
- package/lib/rules/no-bitwise.js +57 -57
- package/lib/rules/no-caller.js +29 -29
- package/lib/rules/no-catch-shadow.js +52 -52
- package/lib/rules/no-comma-dangle.js +45 -45
- package/lib/rules/no-cond-assign.js +123 -123
- package/lib/rules/no-console.js +27 -27
- package/lib/rules/no-constant-condition.js +73 -73
- package/lib/rules/no-continue.js +23 -23
- package/lib/rules/no-control-regex.js +58 -58
- package/lib/rules/no-debugger.js +22 -22
- package/lib/rules/no-delete-var.js +25 -25
- package/lib/rules/no-div-regex.js +27 -27
- package/lib/rules/no-dupe-args.js +89 -85
- package/lib/rules/no-dupe-keys.js +43 -43
- package/lib/rules/no-duplicate-case.js +67 -67
- package/lib/rules/no-else-return.js +125 -125
- package/lib/rules/no-empty-character-class.js +43 -43
- package/lib/rules/no-empty-class.js +45 -45
- package/lib/rules/no-empty-label.js +27 -27
- package/lib/rules/no-empty.js +49 -49
- package/lib/rules/no-eq-null.js +29 -29
- package/lib/rules/no-eval.js +26 -26
- package/lib/rules/no-ex-assign.js +42 -42
- package/lib/rules/no-extend-native.js +103 -103
- package/lib/rules/no-extra-bind.js +81 -81
- package/lib/rules/no-extra-boolean-cast.js +71 -71
- package/lib/rules/no-extra-parens.js +368 -355
- package/lib/rules/no-extra-semi.js +70 -23
- package/lib/rules/no-extra-strict.js +86 -86
- package/lib/rules/no-fallthrough.js +97 -97
- package/lib/rules/no-floating-decimal.js +30 -30
- package/lib/rules/no-func-assign.js +83 -83
- package/lib/rules/no-implied-eval.js +76 -76
- package/lib/rules/no-inline-comments.js +49 -49
- package/lib/rules/no-inner-declarations.js +78 -78
- package/lib/rules/no-invalid-regexp.js +53 -53
- package/lib/rules/no-irregular-whitespace.js +135 -135
- package/lib/rules/no-iterator.js +28 -28
- package/lib/rules/no-label-var.js +64 -64
- package/lib/rules/no-labels.js +44 -44
- package/lib/rules/no-lone-blocks.js +106 -27
- package/lib/rules/no-lonely-if.js +30 -30
- package/lib/rules/no-loop-func.js +58 -58
- package/lib/rules/no-mixed-requires.js +165 -165
- package/lib/rules/no-mixed-spaces-and-tabs.js +74 -74
- package/lib/rules/no-multi-spaces.js +119 -119
- package/lib/rules/no-multi-str.js +43 -43
- package/lib/rules/no-multiple-empty-lines.js +98 -98
- package/lib/rules/no-native-reassign.js +62 -62
- package/lib/rules/no-negated-in-lhs.js +25 -25
- package/lib/rules/no-nested-ternary.js +24 -24
- package/lib/rules/no-new-func.js +25 -25
- package/lib/rules/no-new-object.js +25 -25
- package/lib/rules/no-new-require.js +25 -25
- package/lib/rules/no-new-wrappers.js +26 -26
- package/lib/rules/no-new.js +27 -27
- package/lib/rules/no-obj-calls.js +28 -28
- package/lib/rules/no-octal-escape.js +39 -39
- package/lib/rules/no-octal.js +25 -25
- package/lib/rules/no-param-reassign.js +87 -87
- package/lib/rules/no-path-concat.js +39 -39
- package/lib/rules/no-plusplus.js +24 -24
- package/lib/rules/no-process-env.js +30 -30
- package/lib/rules/no-process-exit.js +33 -33
- package/lib/rules/no-proto.js +28 -28
- package/lib/rules/no-redeclare.js +68 -68
- package/lib/rules/no-regex-spaces.js +35 -35
- package/lib/rules/no-reserved-keys.js +56 -56
- package/lib/rules/no-restricted-modules.js +85 -85
- package/lib/rules/no-return-assign.js +53 -24
- package/lib/rules/no-script-url.js +34 -34
- package/lib/rules/no-self-compare.js +29 -29
- package/lib/rules/no-sequences.js +94 -94
- package/lib/rules/no-shadow-restricted-names.js +51 -51
- package/lib/rules/no-shadow.js +181 -136
- package/lib/rules/no-space-before-semi.js +98 -98
- package/lib/rules/no-spaced-func.js +37 -37
- package/lib/rules/no-sparse-arrays.js +33 -33
- package/lib/rules/no-sync.js +30 -30
- package/lib/rules/no-ternary.js +24 -24
- package/lib/rules/no-this-before-super.js +144 -0
- package/lib/rules/no-throw-literal.js +33 -33
- package/lib/rules/no-trailing-spaces.js +74 -63
- package/lib/rules/no-undef-init.js +28 -28
- package/lib/rules/no-undef.js +92 -92
- package/lib/rules/no-undefined.js +27 -27
- package/lib/rules/no-underscore-dangle.js +73 -73
- package/lib/rules/no-unexpected-multiline.js +58 -0
- package/lib/rules/no-unneeded-ternary.js +48 -48
- package/lib/rules/no-unreachable.js +98 -98
- package/lib/rules/no-unused-expressions.js +76 -76
- package/lib/rules/no-unused-vars.js +252 -250
- package/lib/rules/no-use-before-define.js +105 -105
- package/lib/rules/no-var.js +26 -26
- package/lib/rules/no-void.js +28 -28
- package/lib/rules/no-warning-comments.js +102 -102
- package/lib/rules/no-with.js +22 -22
- package/lib/rules/no-wrap-func.js +65 -65
- package/lib/rules/object-curly-spacing.js +231 -206
- package/lib/rules/object-shorthand.js +74 -73
- package/lib/rules/one-var.js +311 -304
- package/lib/rules/operator-assignment.js +118 -118
- package/lib/rules/operator-linebreak.js +114 -114
- package/lib/rules/padded-blocks.js +98 -98
- package/lib/rules/prefer-const.js +91 -0
- package/lib/rules/quote-props.js +72 -72
- package/lib/rules/quotes.js +92 -92
- package/lib/rules/radix.js +41 -41
- package/lib/rules/semi-spacing.js +167 -167
- package/lib/rules/semi.js +136 -136
- package/lib/rules/sort-vars.js +49 -49
- package/lib/rules/space-after-function-name.js +49 -49
- package/lib/rules/space-after-keywords.js +82 -82
- package/lib/rules/space-before-blocks.js +91 -91
- package/lib/rules/space-before-function-paren.js +139 -139
- package/lib/rules/space-before-function-parentheses.js +139 -139
- package/lib/rules/space-in-brackets.js +305 -305
- package/lib/rules/space-in-parens.js +281 -281
- package/lib/rules/space-infix-ops.js +106 -106
- package/lib/rules/space-return-throw-case.js +38 -38
- package/lib/rules/space-unary-ops.js +124 -133
- package/lib/rules/spaced-comment.js +143 -0
- package/lib/rules/spaced-line-comment.js +89 -89
- package/lib/rules/strict.js +242 -242
- package/lib/rules/use-isnan.js +26 -26
- package/lib/rules/valid-jsdoc.js +215 -215
- package/lib/rules/valid-typeof.js +42 -42
- package/lib/rules/vars-on-top.js +115 -115
- package/lib/rules/wrap-iife.js +48 -48
- package/lib/rules/wrap-regex.js +38 -38
- package/lib/rules/yoda.js +242 -225
- package/lib/rules.js +88 -88
- package/lib/timing.js +109 -109
- package/lib/token-store.js +201 -201
- package/lib/util/traverse.js +105 -105
- package/lib/util.js +125 -85
- package/package.json +6 -6
- package/CHANGELOG.md +0 -1638
package/lib/rules/indent.js
CHANGED
@@ -1,486 +1,486 @@
|
|
1
|
-
/**
|
2
|
-
* @fileoverview This option sets a specific tab width for your code
|
3
|
-
* This rule has been ported and modified from JSCS.
|
4
|
-
* @author Dmitriy Shekhovtsov
|
5
|
-
* @copyright 2015 Dmitriy Shekhovtsov. All rights reserved.
|
6
|
-
* @copyright 2013 Dulin Marat and other contributors.
|
7
|
-
*
|
8
|
-
* Permission is hereby granted, free of charge, to any person obtaining
|
9
|
-
* a copy of this software and associated documentation files (the
|
10
|
-
* "Software"), to deal in the Software without restriction, including
|
11
|
-
* without limitation the rights to use, copy, modify, merge, publish,
|
12
|
-
* distribute, sublicense, and/or sell copies of the Software, and to
|
13
|
-
* permit persons to whom the Software is furnished to do so, subject to
|
14
|
-
* the following conditions:
|
15
|
-
*
|
16
|
-
* The above copyright notice and this permission notice shall be
|
17
|
-
* included in all copies or substantial portions of the Software.
|
18
|
-
*
|
19
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
20
|
-
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
21
|
-
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
22
|
-
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
23
|
-
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
24
|
-
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
25
|
-
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
26
|
-
*/
|
27
|
-
/*eslint no-use-before-define:[2, "nofunc"]*/
|
28
|
-
"use strict";
|
29
|
-
|
30
|
-
//------------------------------------------------------------------------------
|
31
|
-
// Rule Definition
|
32
|
-
//------------------------------------------------------------------------------
|
33
|
-
|
34
|
-
module.exports = function (context) {
|
35
|
-
// indentation defaults: 4 spaces
|
36
|
-
var indentChar = " ";
|
37
|
-
var indentSize = 4;
|
38
|
-
var options = {indentSwitchCase: false};
|
39
|
-
|
40
|
-
var lines = null;
|
41
|
-
var indentStack = [0];
|
42
|
-
var linesToCheck = null;
|
43
|
-
var breakIndents = null;
|
44
|
-
|
45
|
-
if (context.options.length) {
|
46
|
-
if (context.options[0] === "tab") {
|
47
|
-
indentChar = "\t";
|
48
|
-
indentSize = 1;
|
49
|
-
} else /* istanbul ignore else : this will be caught by options validation */ if (typeof context.options[0] === "number") {
|
50
|
-
indentSize = context.options[0];
|
51
|
-
}
|
52
|
-
|
53
|
-
if (context.options[1]) {
|
54
|
-
var opts = context.options[1];
|
55
|
-
options.indentSwitchCase = opts.indentSwitchCase === true;
|
56
|
-
}
|
57
|
-
}
|
58
|
-
|
59
|
-
var blockParents = [
|
60
|
-
"IfStatement",
|
61
|
-
"WhileStatement",
|
62
|
-
"DoWhileStatement",
|
63
|
-
"ForStatement",
|
64
|
-
"ForInStatement",
|
65
|
-
"ForOfStatement",
|
66
|
-
"FunctionDeclaration",
|
67
|
-
"FunctionExpression",
|
68
|
-
"ArrowExpression",
|
69
|
-
"CatchClause",
|
70
|
-
"WithStatement"
|
71
|
-
];
|
72
|
-
|
73
|
-
var indentableNodes = {
|
74
|
-
BlockStatement: "body",
|
75
|
-
Program: "body",
|
76
|
-
ObjectExpression: "properties",
|
77
|
-
ArrayExpression: "elements",
|
78
|
-
SwitchStatement: "cases"
|
79
|
-
};
|
80
|
-
|
81
|
-
if (options.indentSwitchCase) {
|
82
|
-
indentableNodes.SwitchCase = "consequent";
|
83
|
-
}
|
84
|
-
|
85
|
-
//--------------------------------------------------------------------------
|
86
|
-
// Helpers
|
87
|
-
//--------------------------------------------------------------------------
|
88
|
-
|
89
|
-
/**
|
90
|
-
* Mark line to be checked
|
91
|
-
* @param {Number} line - line number
|
92
|
-
* @returns {void}
|
93
|
-
*/
|
94
|
-
function markCheckLine(line) {
|
95
|
-
linesToCheck[line].check = true;
|
96
|
-
}
|
97
|
-
|
98
|
-
/**
|
99
|
-
* Mark line with targeted node to be checked
|
100
|
-
* @param {ASTNode} checkNode - targeted node
|
101
|
-
* @returns {void}
|
102
|
-
*/
|
103
|
-
function markCheck(checkNode) {
|
104
|
-
markCheckLine(checkNode.loc.start.line - 1);
|
105
|
-
}
|
106
|
-
|
107
|
-
/**
|
108
|
-
* Sets pushing indent of current node
|
109
|
-
* @param {ASTNode} node - targeted node
|
110
|
-
* @param {Number} indents - indents count to push
|
111
|
-
* @returns {void}
|
112
|
-
*/
|
113
|
-
function markPush(node, indents) {
|
114
|
-
linesToCheck[node.loc.start.line - 1].push.push(indents);
|
115
|
-
}
|
116
|
-
|
117
|
-
/**
|
118
|
-
* Marks line as outdent, end of block statement for example
|
119
|
-
* @param {ASTNode} node - targeted node
|
120
|
-
* @param {Number} outdents - count of outedents in targeted line
|
121
|
-
* @returns {void}
|
122
|
-
*/
|
123
|
-
function markPop(node, outdents) {
|
124
|
-
linesToCheck[node.loc.end.line - 1].pop.push(outdents);
|
125
|
-
}
|
126
|
-
|
127
|
-
/**
|
128
|
-
* Set alt push for current node
|
129
|
-
* @param {ASTNode} node - targeted node
|
130
|
-
* @returns {void}
|
131
|
-
*/
|
132
|
-
function markPushAlt(node) {
|
133
|
-
linesToCheck[node.loc.start.line - 1].pushAltLine.push(node.loc.end.line - 1);
|
134
|
-
}
|
135
|
-
|
136
|
-
/**
|
137
|
-
* Marks end of node block to be checked
|
138
|
-
* and marks targeted node as indent pushing
|
139
|
-
* @param {ASTNode} pushNode - targeted node
|
140
|
-
* @param {Number} indents - indent count to push
|
141
|
-
* @returns {void}
|
142
|
-
*/
|
143
|
-
function markPushAndEndCheck(pushNode, indents) {
|
144
|
-
markPush(pushNode, indents);
|
145
|
-
markCheckLine(pushNode.loc.end.line - 1);
|
146
|
-
}
|
147
|
-
|
148
|
-
/**
|
149
|
-
* Mark node as switch case statement
|
150
|
-
* and set push\pop indentation changes
|
151
|
-
* @param {ASTNode} caseNode - targeted node
|
152
|
-
* @param {ASTNode[]} children - consequent child nodes of case node
|
153
|
-
* @returns {void}
|
154
|
-
*/
|
155
|
-
function markCase(caseNode, children) {
|
156
|
-
var outdentNode = getCaseOutdent(children);
|
157
|
-
|
158
|
-
if (outdentNode) {
|
159
|
-
// If a case statement has a `break` as a direct child and it is the
|
160
|
-
// first one encountered, use it as the example for all future case indentation
|
161
|
-
if (breakIndents === null) {
|
162
|
-
breakIndents = (caseNode.loc.start.column === outdentNode.loc.start.column) ? 1 : 0;
|
163
|
-
}
|
164
|
-
markPop(outdentNode, breakIndents);
|
165
|
-
} else {
|
166
|
-
markPop(caseNode, 0);
|
167
|
-
}
|
168
|
-
}
|
169
|
-
|
170
|
-
/**
|
171
|
-
* Mark child nodes to be checked later of targeted node,
|
172
|
-
* only if child node not in same line as targeted one
|
173
|
-
* (if child and parent nodes wrote in single line)
|
174
|
-
* @param {ASTNode} node - targeted node
|
175
|
-
* @returns {void}
|
176
|
-
*/
|
177
|
-
function markChildren(node) {
|
178
|
-
getChildren(node).forEach(function(childNode) {
|
179
|
-
if (childNode.loc.start.line !== node.loc.start.line || node.type === "Program") {
|
180
|
-
markCheck(childNode);
|
181
|
-
}
|
182
|
-
});
|
183
|
-
}
|
184
|
-
|
185
|
-
/**
|
186
|
-
* Mark child block as scope pushing and mark to check
|
187
|
-
* @param {ASTNode} node - target node
|
188
|
-
* @param {String} property - target node property containing child
|
189
|
-
* @returns {void}
|
190
|
-
*/
|
191
|
-
function markAlternateBlockStatement(node, property) {
|
192
|
-
var child = node[property];
|
193
|
-
if (child && child.type === "BlockStatement") {
|
194
|
-
markCheck(child);
|
195
|
-
}
|
196
|
-
}
|
197
|
-
|
198
|
-
/**
|
199
|
-
* Checks whether node is multiline or single line
|
200
|
-
* @param {ASTNode} node - target node
|
201
|
-
* @returns {boolean} - is multiline node
|
202
|
-
*/
|
203
|
-
function isMultiline(node) {
|
204
|
-
return node.loc.start.line !== node.loc.end.line;
|
205
|
-
}
|
206
|
-
|
207
|
-
/**
|
208
|
-
* Get switch case statement outdent node if any
|
209
|
-
* @param {ASTNode[]} caseChildren - case statement childs
|
210
|
-
* @returns {ASTNode} - outdent node
|
211
|
-
*/
|
212
|
-
function getCaseOutdent(caseChildren) {
|
213
|
-
var outdentNode;
|
214
|
-
caseChildren.some(function(node) {
|
215
|
-
if (node.type === "BreakStatement") {
|
216
|
-
outdentNode = node;
|
217
|
-
return true;
|
218
|
-
}
|
219
|
-
});
|
220
|
-
|
221
|
-
return outdentNode;
|
222
|
-
}
|
223
|
-
|
224
|
-
/**
|
225
|
-
* Returns block containing node
|
226
|
-
* @param {ASTNode} node - targeted node
|
227
|
-
* @returns {ASTNode} - block node
|
228
|
-
*/
|
229
|
-
function getBlockNodeToMark(node) {
|
230
|
-
var parent = node.parent;
|
231
|
-
|
232
|
-
// The parent of an else is the entire if/else block. To avoid over indenting
|
233
|
-
// in the case of a non-block if with a block else, mark push where the else starts,
|
234
|
-
// not where the if starts!
|
235
|
-
if (parent.type === "IfStatement" && parent.alternate === node) {
|
236
|
-
return node;
|
237
|
-
}
|
238
|
-
|
239
|
-
// The end line to check of a do while statement needs to be the location of the
|
240
|
-
// closing curly brace, not the while statement, to avoid marking the last line of
|
241
|
-
// a multiline while as a line to check.
|
242
|
-
if (parent.type === "DoWhileStatement") {
|
243
|
-
return node;
|
244
|
-
}
|
245
|
-
|
246
|
-
// Detect bare blocks: a block whose parent doesn"t expect blocks in its syntax specifically.
|
247
|
-
if (blockParents.indexOf(parent.type) === -1) {
|
248
|
-
return node;
|
249
|
-
}
|
250
|
-
|
251
|
-
return parent;
|
252
|
-
}
|
253
|
-
|
254
|
-
/**
|
255
|
-
* Get node's children
|
256
|
-
* @param {ASTNode} node - current node
|
257
|
-
* @returns {ASTNode[]} - children
|
258
|
-
*/
|
259
|
-
function getChildren(node) {
|
260
|
-
var childrenProperty = indentableNodes[node.type];
|
261
|
-
return node[childrenProperty];
|
262
|
-
}
|
263
|
-
|
264
|
-
/**
|
265
|
-
* Gets indentation in line `i`
|
266
|
-
* @param {Number} i - number of line to get indentation
|
267
|
-
* @returns {Number} - count of indentation symbols
|
268
|
-
*/
|
269
|
-
function getIndentationFromLine(i) {
|
270
|
-
var rNotIndentChar = new RegExp("[^" + indentChar + "]");
|
271
|
-
var firstContent = lines[i].search(rNotIndentChar);
|
272
|
-
if (firstContent === -1) {
|
273
|
-
firstContent = lines[i].length;
|
274
|
-
}
|
275
|
-
return firstContent;
|
276
|
-
}
|
277
|
-
|
278
|
-
/**
|
279
|
-
* Compares expected and actual indentation
|
280
|
-
* and reports any violations
|
281
|
-
* @param {ASTNode} node - node used only for reporting
|
282
|
-
* @returns {void}
|
283
|
-
*/
|
284
|
-
function checkIndentations(node) {
|
285
|
-
linesToCheck.forEach(function(line, i) {
|
286
|
-
var actualIndentation = getIndentationFromLine(i);
|
287
|
-
var expectedIndentation = getExpectedIndentation(line, actualIndentation);
|
288
|
-
|
289
|
-
if (line.check) {
|
290
|
-
|
291
|
-
if (actualIndentation !== expectedIndentation) {
|
292
|
-
context.report(node,
|
293
|
-
{line: i + 1, column: expectedIndentation},
|
294
|
-
"Expected indentation of " + expectedIndentation + " characters.");
|
295
|
-
// correct the indentation so that future lines
|
296
|
-
// can be validated appropriately
|
297
|
-
actualIndentation = expectedIndentation;
|
298
|
-
}
|
299
|
-
}
|
300
|
-
|
301
|
-
if (line.push.length) {
|
302
|
-
pushExpectedIndentations(line, actualIndentation);
|
303
|
-
}
|
304
|
-
});
|
305
|
-
}
|
306
|
-
|
307
|
-
/**
|
308
|
-
* Counts expected indentation for given line number
|
309
|
-
* @param {Number} line - line number
|
310
|
-
* @param {Number} actual - actual indentation
|
311
|
-
* @returns {number} - expected indentation
|
312
|
-
*/
|
313
|
-
function getExpectedIndentation(line, actual) {
|
314
|
-
var outdent = indentSize * Math.max.apply(null, line.pop);
|
315
|
-
|
316
|
-
var idx = indentStack.length - 1;
|
317
|
-
var expected = indentStack[idx];
|
318
|
-
|
319
|
-
if (!Array.isArray(expected)) {
|
320
|
-
expected = [expected];
|
321
|
-
}
|
322
|
-
|
323
|
-
expected = expected.map(function(value) {
|
324
|
-
if (line.pop.length) {
|
325
|
-
value -= outdent;
|
326
|
-
}
|
327
|
-
|
328
|
-
return value;
|
329
|
-
}).reduce(function(previous, current) {
|
330
|
-
// when the expected is an array, resolve the value
|
331
|
-
// back into a Number by checking both values are the actual indentation
|
332
|
-
return actual === current ? current : previous;
|
333
|
-
});
|
334
|
-
|
335
|
-
indentStack[idx] = expected;
|
336
|
-
|
337
|
-
line.pop.forEach(function() {
|
338
|
-
indentStack.pop();
|
339
|
-
});
|
340
|
-
|
341
|
-
return expected;
|
342
|
-
}
|
343
|
-
|
344
|
-
/**
|
345
|
-
* Store in stack expected indentations
|
346
|
-
* @param {Number} line - current line
|
347
|
-
* @param {Number} actualIndentation - actual indentation at current line
|
348
|
-
* @returns {void}
|
349
|
-
*/
|
350
|
-
function pushExpectedIndentations(line, actualIndentation) {
|
351
|
-
var indents = Math.max.apply(null, line.push);
|
352
|
-
var expected = actualIndentation + (indentSize * indents);
|
353
|
-
|
354
|
-
// when a line has alternate indentations, push an array of possible values
|
355
|
-
// on the stack, to be resolved when checked against an actual indentation
|
356
|
-
if (line.pushAltLine.length) {
|
357
|
-
expected = [expected];
|
358
|
-
line.pushAltLine.forEach(function(altLine) {
|
359
|
-
expected.push(getIndentationFromLine(altLine) + (indentSize * indents));
|
360
|
-
});
|
361
|
-
}
|
362
|
-
|
363
|
-
line.push.forEach(function() {
|
364
|
-
indentStack.push(expected);
|
365
|
-
});
|
366
|
-
}
|
367
|
-
|
368
|
-
//--------------------------------------------------------------------------
|
369
|
-
// Public
|
370
|
-
//--------------------------------------------------------------------------
|
371
|
-
|
372
|
-
return {
|
373
|
-
"Program": function (node) {
|
374
|
-
lines = context.getSourceLines();
|
375
|
-
linesToCheck = lines.map(function () {
|
376
|
-
return {
|
377
|
-
push: [],
|
378
|
-
pushAltLine: [],
|
379
|
-
pop: [],
|
380
|
-
check: false
|
381
|
-
};
|
382
|
-
});
|
383
|
-
|
384
|
-
if (!isMultiline(node)) {
|
385
|
-
return;
|
386
|
-
}
|
387
|
-
|
388
|
-
markChildren(node);
|
389
|
-
},
|
390
|
-
"Program:exit": function (node) {
|
391
|
-
checkIndentations(node);
|
392
|
-
},
|
393
|
-
|
394
|
-
"BlockStatement": function (node) {
|
395
|
-
if (!isMultiline(node)) {
|
396
|
-
return;
|
397
|
-
}
|
398
|
-
|
399
|
-
markChildren(node);
|
400
|
-
markPop(node, 1);
|
401
|
-
|
402
|
-
markPushAndEndCheck(getBlockNodeToMark(node), 1);
|
403
|
-
},
|
404
|
-
|
405
|
-
"IfStatement": function (node) {
|
406
|
-
markAlternateBlockStatement(node, "alternate");
|
407
|
-
},
|
408
|
-
|
409
|
-
"TryStatement": function (node) {
|
410
|
-
markAlternateBlockStatement(node, "handler");
|
411
|
-
markAlternateBlockStatement(node, "finalizer");
|
412
|
-
},
|
413
|
-
|
414
|
-
"SwitchStatement": function (node) {
|
415
|
-
if (!isMultiline(node)) {
|
416
|
-
return;
|
417
|
-
}
|
418
|
-
|
419
|
-
var indents = 1;
|
420
|
-
var children = getChildren(node);
|
421
|
-
|
422
|
-
if (children.length && node.loc.start.column === children[0].loc.start.column) {
|
423
|
-
indents = 0;
|
424
|
-
}
|
425
|
-
|
426
|
-
markChildren(node);
|
427
|
-
markPop(node, indents);
|
428
|
-
markPushAndEndCheck(node, indents);
|
429
|
-
},
|
430
|
-
|
431
|
-
"SwitchCase": function (node) {
|
432
|
-
if (!options.indentSwitchCase) {
|
433
|
-
return;
|
434
|
-
}
|
435
|
-
|
436
|
-
if (!isMultiline(node)) {
|
437
|
-
return;
|
438
|
-
}
|
439
|
-
|
440
|
-
var children = getChildren(node);
|
441
|
-
|
442
|
-
if (children.length === 1 && children[0].type === "BlockStatement") {
|
443
|
-
return;
|
444
|
-
}
|
445
|
-
|
446
|
-
markPush(node, 1);
|
447
|
-
markCheck(node);
|
448
|
-
markChildren(node);
|
449
|
-
|
450
|
-
markCase(node, children);
|
451
|
-
},
|
452
|
-
|
453
|
-
// indentations inside of function expressions can be offset from
|
454
|
-
// either the start of the function or the end of the function, therefore
|
455
|
-
// mark all starting lines of functions as potential indentations
|
456
|
-
"FunctionDeclaration": function (node) {
|
457
|
-
markPushAlt(node);
|
458
|
-
},
|
459
|
-
"FunctionExpression": function (node) {
|
460
|
-
markPushAlt(node);
|
461
|
-
}
|
462
|
-
};
|
463
|
-
|
464
|
-
};
|
465
|
-
|
466
|
-
module.exports.schema = [
|
467
|
-
{
|
468
|
-
"oneOf": [
|
469
|
-
{
|
470
|
-
"enum": ["tab"]
|
471
|
-
},
|
472
|
-
{
|
473
|
-
"type": "integer"
|
474
|
-
}
|
475
|
-
]
|
476
|
-
},
|
477
|
-
{
|
478
|
-
"type": "object",
|
479
|
-
"properties": {
|
480
|
-
"indentSwitchCase": {
|
481
|
-
"type": "boolean"
|
482
|
-
}
|
483
|
-
},
|
484
|
-
"additionalProperties": false
|
485
|
-
}
|
486
|
-
];
|
1
|
+
/**
|
2
|
+
* @fileoverview This option sets a specific tab width for your code
|
3
|
+
* This rule has been ported and modified from JSCS.
|
4
|
+
* @author Dmitriy Shekhovtsov
|
5
|
+
* @copyright 2015 Dmitriy Shekhovtsov. All rights reserved.
|
6
|
+
* @copyright 2013 Dulin Marat and other contributors.
|
7
|
+
*
|
8
|
+
* Permission is hereby granted, free of charge, to any person obtaining
|
9
|
+
* a copy of this software and associated documentation files (the
|
10
|
+
* "Software"), to deal in the Software without restriction, including
|
11
|
+
* without limitation the rights to use, copy, modify, merge, publish,
|
12
|
+
* distribute, sublicense, and/or sell copies of the Software, and to
|
13
|
+
* permit persons to whom the Software is furnished to do so, subject to
|
14
|
+
* the following conditions:
|
15
|
+
*
|
16
|
+
* The above copyright notice and this permission notice shall be
|
17
|
+
* included in all copies or substantial portions of the Software.
|
18
|
+
*
|
19
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
20
|
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
21
|
+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
22
|
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
23
|
+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
24
|
+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
25
|
+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
26
|
+
*/
|
27
|
+
/*eslint no-use-before-define:[2, "nofunc"]*/
|
28
|
+
"use strict";
|
29
|
+
|
30
|
+
//------------------------------------------------------------------------------
|
31
|
+
// Rule Definition
|
32
|
+
//------------------------------------------------------------------------------
|
33
|
+
|
34
|
+
module.exports = function (context) {
|
35
|
+
// indentation defaults: 4 spaces
|
36
|
+
var indentChar = " ";
|
37
|
+
var indentSize = 4;
|
38
|
+
var options = {indentSwitchCase: false};
|
39
|
+
|
40
|
+
var lines = null;
|
41
|
+
var indentStack = [0];
|
42
|
+
var linesToCheck = null;
|
43
|
+
var breakIndents = null;
|
44
|
+
|
45
|
+
if (context.options.length) {
|
46
|
+
if (context.options[0] === "tab") {
|
47
|
+
indentChar = "\t";
|
48
|
+
indentSize = 1;
|
49
|
+
} else /* istanbul ignore else : this will be caught by options validation */ if (typeof context.options[0] === "number") {
|
50
|
+
indentSize = context.options[0];
|
51
|
+
}
|
52
|
+
|
53
|
+
if (context.options[1]) {
|
54
|
+
var opts = context.options[1];
|
55
|
+
options.indentSwitchCase = opts.indentSwitchCase === true;
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
var blockParents = [
|
60
|
+
"IfStatement",
|
61
|
+
"WhileStatement",
|
62
|
+
"DoWhileStatement",
|
63
|
+
"ForStatement",
|
64
|
+
"ForInStatement",
|
65
|
+
"ForOfStatement",
|
66
|
+
"FunctionDeclaration",
|
67
|
+
"FunctionExpression",
|
68
|
+
"ArrowExpression",
|
69
|
+
"CatchClause",
|
70
|
+
"WithStatement"
|
71
|
+
];
|
72
|
+
|
73
|
+
var indentableNodes = {
|
74
|
+
BlockStatement: "body",
|
75
|
+
Program: "body",
|
76
|
+
ObjectExpression: "properties",
|
77
|
+
ArrayExpression: "elements",
|
78
|
+
SwitchStatement: "cases"
|
79
|
+
};
|
80
|
+
|
81
|
+
if (options.indentSwitchCase) {
|
82
|
+
indentableNodes.SwitchCase = "consequent";
|
83
|
+
}
|
84
|
+
|
85
|
+
//--------------------------------------------------------------------------
|
86
|
+
// Helpers
|
87
|
+
//--------------------------------------------------------------------------
|
88
|
+
|
89
|
+
/**
|
90
|
+
* Mark line to be checked
|
91
|
+
* @param {Number} line - line number
|
92
|
+
* @returns {void}
|
93
|
+
*/
|
94
|
+
function markCheckLine(line) {
|
95
|
+
linesToCheck[line].check = true;
|
96
|
+
}
|
97
|
+
|
98
|
+
/**
|
99
|
+
* Mark line with targeted node to be checked
|
100
|
+
* @param {ASTNode} checkNode - targeted node
|
101
|
+
* @returns {void}
|
102
|
+
*/
|
103
|
+
function markCheck(checkNode) {
|
104
|
+
markCheckLine(checkNode.loc.start.line - 1);
|
105
|
+
}
|
106
|
+
|
107
|
+
/**
|
108
|
+
* Sets pushing indent of current node
|
109
|
+
* @param {ASTNode} node - targeted node
|
110
|
+
* @param {Number} indents - indents count to push
|
111
|
+
* @returns {void}
|
112
|
+
*/
|
113
|
+
function markPush(node, indents) {
|
114
|
+
linesToCheck[node.loc.start.line - 1].push.push(indents);
|
115
|
+
}
|
116
|
+
|
117
|
+
/**
|
118
|
+
* Marks line as outdent, end of block statement for example
|
119
|
+
* @param {ASTNode} node - targeted node
|
120
|
+
* @param {Number} outdents - count of outedents in targeted line
|
121
|
+
* @returns {void}
|
122
|
+
*/
|
123
|
+
function markPop(node, outdents) {
|
124
|
+
linesToCheck[node.loc.end.line - 1].pop.push(outdents);
|
125
|
+
}
|
126
|
+
|
127
|
+
/**
|
128
|
+
* Set alt push for current node
|
129
|
+
* @param {ASTNode} node - targeted node
|
130
|
+
* @returns {void}
|
131
|
+
*/
|
132
|
+
function markPushAlt(node) {
|
133
|
+
linesToCheck[node.loc.start.line - 1].pushAltLine.push(node.loc.end.line - 1);
|
134
|
+
}
|
135
|
+
|
136
|
+
/**
|
137
|
+
* Marks end of node block to be checked
|
138
|
+
* and marks targeted node as indent pushing
|
139
|
+
* @param {ASTNode} pushNode - targeted node
|
140
|
+
* @param {Number} indents - indent count to push
|
141
|
+
* @returns {void}
|
142
|
+
*/
|
143
|
+
function markPushAndEndCheck(pushNode, indents) {
|
144
|
+
markPush(pushNode, indents);
|
145
|
+
markCheckLine(pushNode.loc.end.line - 1);
|
146
|
+
}
|
147
|
+
|
148
|
+
/**
|
149
|
+
* Mark node as switch case statement
|
150
|
+
* and set push\pop indentation changes
|
151
|
+
* @param {ASTNode} caseNode - targeted node
|
152
|
+
* @param {ASTNode[]} children - consequent child nodes of case node
|
153
|
+
* @returns {void}
|
154
|
+
*/
|
155
|
+
function markCase(caseNode, children) {
|
156
|
+
var outdentNode = getCaseOutdent(children);
|
157
|
+
|
158
|
+
if (outdentNode) {
|
159
|
+
// If a case statement has a `break` as a direct child and it is the
|
160
|
+
// first one encountered, use it as the example for all future case indentation
|
161
|
+
if (breakIndents === null) {
|
162
|
+
breakIndents = (caseNode.loc.start.column === outdentNode.loc.start.column) ? 1 : 0;
|
163
|
+
}
|
164
|
+
markPop(outdentNode, breakIndents);
|
165
|
+
} else {
|
166
|
+
markPop(caseNode, 0);
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
/**
|
171
|
+
* Mark child nodes to be checked later of targeted node,
|
172
|
+
* only if child node not in same line as targeted one
|
173
|
+
* (if child and parent nodes wrote in single line)
|
174
|
+
* @param {ASTNode} node - targeted node
|
175
|
+
* @returns {void}
|
176
|
+
*/
|
177
|
+
function markChildren(node) {
|
178
|
+
getChildren(node).forEach(function(childNode) {
|
179
|
+
if (childNode.loc.start.line !== node.loc.start.line || node.type === "Program") {
|
180
|
+
markCheck(childNode);
|
181
|
+
}
|
182
|
+
});
|
183
|
+
}
|
184
|
+
|
185
|
+
/**
|
186
|
+
* Mark child block as scope pushing and mark to check
|
187
|
+
* @param {ASTNode} node - target node
|
188
|
+
* @param {String} property - target node property containing child
|
189
|
+
* @returns {void}
|
190
|
+
*/
|
191
|
+
function markAlternateBlockStatement(node, property) {
|
192
|
+
var child = node[property];
|
193
|
+
if (child && child.type === "BlockStatement") {
|
194
|
+
markCheck(child);
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
/**
|
199
|
+
* Checks whether node is multiline or single line
|
200
|
+
* @param {ASTNode} node - target node
|
201
|
+
* @returns {boolean} - is multiline node
|
202
|
+
*/
|
203
|
+
function isMultiline(node) {
|
204
|
+
return node.loc.start.line !== node.loc.end.line;
|
205
|
+
}
|
206
|
+
|
207
|
+
/**
|
208
|
+
* Get switch case statement outdent node if any
|
209
|
+
* @param {ASTNode[]} caseChildren - case statement childs
|
210
|
+
* @returns {ASTNode} - outdent node
|
211
|
+
*/
|
212
|
+
function getCaseOutdent(caseChildren) {
|
213
|
+
var outdentNode;
|
214
|
+
caseChildren.some(function(node) {
|
215
|
+
if (node.type === "BreakStatement") {
|
216
|
+
outdentNode = node;
|
217
|
+
return true;
|
218
|
+
}
|
219
|
+
});
|
220
|
+
|
221
|
+
return outdentNode;
|
222
|
+
}
|
223
|
+
|
224
|
+
/**
|
225
|
+
* Returns block containing node
|
226
|
+
* @param {ASTNode} node - targeted node
|
227
|
+
* @returns {ASTNode} - block node
|
228
|
+
*/
|
229
|
+
function getBlockNodeToMark(node) {
|
230
|
+
var parent = node.parent;
|
231
|
+
|
232
|
+
// The parent of an else is the entire if/else block. To avoid over indenting
|
233
|
+
// in the case of a non-block if with a block else, mark push where the else starts,
|
234
|
+
// not where the if starts!
|
235
|
+
if (parent.type === "IfStatement" && parent.alternate === node) {
|
236
|
+
return node;
|
237
|
+
}
|
238
|
+
|
239
|
+
// The end line to check of a do while statement needs to be the location of the
|
240
|
+
// closing curly brace, not the while statement, to avoid marking the last line of
|
241
|
+
// a multiline while as a line to check.
|
242
|
+
if (parent.type === "DoWhileStatement") {
|
243
|
+
return node;
|
244
|
+
}
|
245
|
+
|
246
|
+
// Detect bare blocks: a block whose parent doesn"t expect blocks in its syntax specifically.
|
247
|
+
if (blockParents.indexOf(parent.type) === -1) {
|
248
|
+
return node;
|
249
|
+
}
|
250
|
+
|
251
|
+
return parent;
|
252
|
+
}
|
253
|
+
|
254
|
+
/**
|
255
|
+
* Get node's children
|
256
|
+
* @param {ASTNode} node - current node
|
257
|
+
* @returns {ASTNode[]} - children
|
258
|
+
*/
|
259
|
+
function getChildren(node) {
|
260
|
+
var childrenProperty = indentableNodes[node.type];
|
261
|
+
return node[childrenProperty];
|
262
|
+
}
|
263
|
+
|
264
|
+
/**
|
265
|
+
* Gets indentation in line `i`
|
266
|
+
* @param {Number} i - number of line to get indentation
|
267
|
+
* @returns {Number} - count of indentation symbols
|
268
|
+
*/
|
269
|
+
function getIndentationFromLine(i) {
|
270
|
+
var rNotIndentChar = new RegExp("[^" + indentChar + "]");
|
271
|
+
var firstContent = lines[i].search(rNotIndentChar);
|
272
|
+
if (firstContent === -1) {
|
273
|
+
firstContent = lines[i].length;
|
274
|
+
}
|
275
|
+
return firstContent;
|
276
|
+
}
|
277
|
+
|
278
|
+
/**
|
279
|
+
* Compares expected and actual indentation
|
280
|
+
* and reports any violations
|
281
|
+
* @param {ASTNode} node - node used only for reporting
|
282
|
+
* @returns {void}
|
283
|
+
*/
|
284
|
+
function checkIndentations(node) {
|
285
|
+
linesToCheck.forEach(function(line, i) {
|
286
|
+
var actualIndentation = getIndentationFromLine(i);
|
287
|
+
var expectedIndentation = getExpectedIndentation(line, actualIndentation);
|
288
|
+
|
289
|
+
if (line.check) {
|
290
|
+
|
291
|
+
if (actualIndentation !== expectedIndentation) {
|
292
|
+
context.report(node,
|
293
|
+
{line: i + 1, column: expectedIndentation},
|
294
|
+
"Expected indentation of " + expectedIndentation + " characters.");
|
295
|
+
// correct the indentation so that future lines
|
296
|
+
// can be validated appropriately
|
297
|
+
actualIndentation = expectedIndentation;
|
298
|
+
}
|
299
|
+
}
|
300
|
+
|
301
|
+
if (line.push.length) {
|
302
|
+
pushExpectedIndentations(line, actualIndentation);
|
303
|
+
}
|
304
|
+
});
|
305
|
+
}
|
306
|
+
|
307
|
+
/**
|
308
|
+
* Counts expected indentation for given line number
|
309
|
+
* @param {Number} line - line number
|
310
|
+
* @param {Number} actual - actual indentation
|
311
|
+
* @returns {number} - expected indentation
|
312
|
+
*/
|
313
|
+
function getExpectedIndentation(line, actual) {
|
314
|
+
var outdent = indentSize * Math.max.apply(null, line.pop);
|
315
|
+
|
316
|
+
var idx = indentStack.length - 1;
|
317
|
+
var expected = indentStack[idx];
|
318
|
+
|
319
|
+
if (!Array.isArray(expected)) {
|
320
|
+
expected = [expected];
|
321
|
+
}
|
322
|
+
|
323
|
+
expected = expected.map(function(value) {
|
324
|
+
if (line.pop.length) {
|
325
|
+
value -= outdent;
|
326
|
+
}
|
327
|
+
|
328
|
+
return value;
|
329
|
+
}).reduce(function(previous, current) {
|
330
|
+
// when the expected is an array, resolve the value
|
331
|
+
// back into a Number by checking both values are the actual indentation
|
332
|
+
return actual === current ? current : previous;
|
333
|
+
});
|
334
|
+
|
335
|
+
indentStack[idx] = expected;
|
336
|
+
|
337
|
+
line.pop.forEach(function() {
|
338
|
+
indentStack.pop();
|
339
|
+
});
|
340
|
+
|
341
|
+
return expected;
|
342
|
+
}
|
343
|
+
|
344
|
+
/**
|
345
|
+
* Store in stack expected indentations
|
346
|
+
* @param {Number} line - current line
|
347
|
+
* @param {Number} actualIndentation - actual indentation at current line
|
348
|
+
* @returns {void}
|
349
|
+
*/
|
350
|
+
function pushExpectedIndentations(line, actualIndentation) {
|
351
|
+
var indents = Math.max.apply(null, line.push);
|
352
|
+
var expected = actualIndentation + (indentSize * indents);
|
353
|
+
|
354
|
+
// when a line has alternate indentations, push an array of possible values
|
355
|
+
// on the stack, to be resolved when checked against an actual indentation
|
356
|
+
if (line.pushAltLine.length) {
|
357
|
+
expected = [expected];
|
358
|
+
line.pushAltLine.forEach(function(altLine) {
|
359
|
+
expected.push(getIndentationFromLine(altLine) + (indentSize * indents));
|
360
|
+
});
|
361
|
+
}
|
362
|
+
|
363
|
+
line.push.forEach(function() {
|
364
|
+
indentStack.push(expected);
|
365
|
+
});
|
366
|
+
}
|
367
|
+
|
368
|
+
//--------------------------------------------------------------------------
|
369
|
+
// Public
|
370
|
+
//--------------------------------------------------------------------------
|
371
|
+
|
372
|
+
return {
|
373
|
+
"Program": function (node) {
|
374
|
+
lines = context.getSourceLines();
|
375
|
+
linesToCheck = lines.map(function () {
|
376
|
+
return {
|
377
|
+
push: [],
|
378
|
+
pushAltLine: [],
|
379
|
+
pop: [],
|
380
|
+
check: false
|
381
|
+
};
|
382
|
+
});
|
383
|
+
|
384
|
+
if (!isMultiline(node)) {
|
385
|
+
return;
|
386
|
+
}
|
387
|
+
|
388
|
+
markChildren(node);
|
389
|
+
},
|
390
|
+
"Program:exit": function (node) {
|
391
|
+
checkIndentations(node);
|
392
|
+
},
|
393
|
+
|
394
|
+
"BlockStatement": function (node) {
|
395
|
+
if (!isMultiline(node)) {
|
396
|
+
return;
|
397
|
+
}
|
398
|
+
|
399
|
+
markChildren(node);
|
400
|
+
markPop(node, 1);
|
401
|
+
|
402
|
+
markPushAndEndCheck(getBlockNodeToMark(node), 1);
|
403
|
+
},
|
404
|
+
|
405
|
+
"IfStatement": function (node) {
|
406
|
+
markAlternateBlockStatement(node, "alternate");
|
407
|
+
},
|
408
|
+
|
409
|
+
"TryStatement": function (node) {
|
410
|
+
markAlternateBlockStatement(node, "handler");
|
411
|
+
markAlternateBlockStatement(node, "finalizer");
|
412
|
+
},
|
413
|
+
|
414
|
+
"SwitchStatement": function (node) {
|
415
|
+
if (!isMultiline(node)) {
|
416
|
+
return;
|
417
|
+
}
|
418
|
+
|
419
|
+
var indents = 1;
|
420
|
+
var children = getChildren(node);
|
421
|
+
|
422
|
+
if (children.length && node.loc.start.column === children[0].loc.start.column) {
|
423
|
+
indents = 0;
|
424
|
+
}
|
425
|
+
|
426
|
+
markChildren(node);
|
427
|
+
markPop(node, indents);
|
428
|
+
markPushAndEndCheck(node, indents);
|
429
|
+
},
|
430
|
+
|
431
|
+
"SwitchCase": function (node) {
|
432
|
+
if (!options.indentSwitchCase) {
|
433
|
+
return;
|
434
|
+
}
|
435
|
+
|
436
|
+
if (!isMultiline(node)) {
|
437
|
+
return;
|
438
|
+
}
|
439
|
+
|
440
|
+
var children = getChildren(node);
|
441
|
+
|
442
|
+
if (children.length === 1 && children[0].type === "BlockStatement") {
|
443
|
+
return;
|
444
|
+
}
|
445
|
+
|
446
|
+
markPush(node, 1);
|
447
|
+
markCheck(node);
|
448
|
+
markChildren(node);
|
449
|
+
|
450
|
+
markCase(node, children);
|
451
|
+
},
|
452
|
+
|
453
|
+
// indentations inside of function expressions can be offset from
|
454
|
+
// either the start of the function or the end of the function, therefore
|
455
|
+
// mark all starting lines of functions as potential indentations
|
456
|
+
"FunctionDeclaration": function (node) {
|
457
|
+
markPushAlt(node);
|
458
|
+
},
|
459
|
+
"FunctionExpression": function (node) {
|
460
|
+
markPushAlt(node);
|
461
|
+
}
|
462
|
+
};
|
463
|
+
|
464
|
+
};
|
465
|
+
|
466
|
+
module.exports.schema = [
|
467
|
+
{
|
468
|
+
"oneOf": [
|
469
|
+
{
|
470
|
+
"enum": ["tab"]
|
471
|
+
},
|
472
|
+
{
|
473
|
+
"type": "integer"
|
474
|
+
}
|
475
|
+
]
|
476
|
+
},
|
477
|
+
{
|
478
|
+
"type": "object",
|
479
|
+
"properties": {
|
480
|
+
"indentSwitchCase": {
|
481
|
+
"type": "boolean"
|
482
|
+
}
|
483
|
+
},
|
484
|
+
"additionalProperties": false
|
485
|
+
}
|
486
|
+
];
|