Skip to content

Commit

Permalink
New: add option first for VariableDeclarator in indent (fixes #8976) (
Browse files Browse the repository at this point in the history
#11193)

* New: add option `first` for VariableDeclarator in indent (fixes #8976)

* Chore: skip some lines of code for perf

* Chore: add more tests for indent
  • Loading branch information
g-plane authored and platinumazure committed Dec 23, 2018
1 parent 2b5a602 commit b4395f6
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 23 deletions.
36 changes: 35 additions & 1 deletion docs/rules/indent.md
Expand Up @@ -69,7 +69,7 @@ if (a) {
This rule has an object option:

* `"SwitchCase"` (default: 0) enforces indentation level for `case` clauses in `switch` statements
* `"VariableDeclarator"` (default: 1) enforces indentation level for `var` declarators; can also take an object to define separate rules for `var`, `let` and `const` declarations.
* `"VariableDeclarator"` (default: 1) enforces indentation level for `var` declarators; can also take an object to define separate rules for `var`, `let` and `const` declarations. It can also be `"first"`, indicating all the declarators should be aligned with the first declarator.
* `"outerIIFEBody"` (default: 1) enforces indentation level for file-level IIFEs.
* `"MemberExpression"` (default: 1) enforces indentation level for multi-line property chains. This can also be set to `"off"` to disable checking for MemberExpression indentation.
* `"FunctionDeclaration"` takes an object to define rules for function declarations.
Expand Down Expand Up @@ -213,6 +213,40 @@ const a = 1,
c = 3;
```

Examples of **incorrect** code for this rule with the `2, { "VariableDeclarator": "first" }` options:

```js
/*eslint indent: ["error", 2, { "VariableDeclarator": "first" }]*/
/*eslint-env es6*/

var a,
b,
c;
let a,
b,
c;
const a = 1,
b = 2,
c = 3;
```

Examples of **correct** code for this rule with the `2, { "VariableDeclarator": "first" }` options:

```js
/*eslint indent: ["error", 2, { "VariableDeclarator": "first" }]*/
/*eslint-env es6*/

var a,
b,
c;
let a,
b,
c;
const a = 1,
b = 2,
c = 3;
```

Examples of **correct** code for this rule with the `2, { "VariableDeclarator": { "var": 2, "let": 2, "const": 3 } }` options:

```js
Expand Down
46 changes: 24 additions & 22 deletions lib/rules/indent.js
Expand Up @@ -522,25 +522,13 @@ module.exports = {
},
VariableDeclarator: {
oneOf: [
{
type: "integer",
minimum: 0
},
ELEMENT_LIST_SCHEMA,
{
type: "object",
properties: {
var: {
type: "integer",
minimum: 0
},
let: {
type: "integer",
minimum: 0
},
const: {
type: "integer",
minimum: 0
}
var: ELEMENT_LIST_SCHEMA,
let: ELEMENT_LIST_SCHEMA,
const: ELEMENT_LIST_SCHEMA
},
additionalProperties: false
}
Expand Down Expand Up @@ -661,7 +649,7 @@ module.exports = {
if (context.options[1]) {
lodash.merge(options, context.options[1]);

if (typeof options.VariableDeclarator === "number") {
if (typeof options.VariableDeclarator === "number" || options.VariableDeclarator === "first") {
options.VariableDeclarator = {
var: options.VariableDeclarator,
let: options.VariableDeclarator,
Expand Down Expand Up @@ -1349,10 +1337,27 @@ module.exports = {
},

VariableDeclaration(node) {
const variableIndent = Object.prototype.hasOwnProperty.call(options.VariableDeclarator, node.kind)
let variableIndent = Object.prototype.hasOwnProperty.call(options.VariableDeclarator, node.kind)
? options.VariableDeclarator[node.kind]
: DEFAULT_VARIABLE_INDENT;

const firstToken = sourceCode.getFirstToken(node),
lastToken = sourceCode.getLastToken(node);

if (options.VariableDeclarator[node.kind] === "first") {
if (node.declarations.length > 1) {
addElementListIndent(
node.declarations,
firstToken,
lastToken,
"first"
);
return;
}

variableIndent = DEFAULT_VARIABLE_INDENT;
}

if (node.declarations[node.declarations.length - 1].loc.start.line > node.loc.start.line) {

/*
Expand All @@ -1374,13 +1379,10 @@ module.exports = {
* on the same line as the start of the declaration, provided that there are declarators that
* follow this one.
*/
const firstToken = sourceCode.getFirstToken(node);

offsets.setDesiredOffsets(node.range, firstToken, variableIndent, true);
} else {
offsets.setDesiredOffsets(node.range, sourceCode.getFirstToken(node), variableIndent);
offsets.setDesiredOffsets(node.range, firstToken, variableIndent);
}
const lastToken = sourceCode.getLastToken(node);

if (astUtils.isSemicolonToken(lastToken)) {
offsets.ignoreToken(lastToken);
Expand Down
88 changes: 88 additions & 0 deletions tests/lib/rules/indent.js
Expand Up @@ -614,6 +614,24 @@ ruleTester.run("indent", rule, {
`,
options: [2, { VariableDeclarator: 1 }]
},
{
code: unIndent`
let foo = 'foo',
bar = bar;
const a = 'a',
b = 'b';
`,
options: [2, { VariableDeclarator: "first" }]
},
{
code: unIndent`
let foo = 'foo',
bar = bar // <-- no semicolon here
const a = 'a',
b = 'b' // <-- no semicolon here
`,
options: [2, { VariableDeclarator: "first" }]
},
{
code: unIndent`
var foo = 1,
Expand All @@ -632,6 +650,43 @@ ruleTester.run("indent", rule, {
`,
options: [2, { VariableDeclarator: { var: 2 } }]
},
{
code: unIndent`
var foo = 'foo',
bar = bar;
`,
options: [2, { VariableDeclarator: { var: "first" } }]
},
{
code: unIndent`
var foo = 'foo',
bar = 'bar' // <-- no semicolon here
`,
options: [2, { VariableDeclarator: { var: "first" } }]
},
{
code: unIndent`
let foo = 1,
bar = 2,
baz
`,
options: [2, { VariableDeclarator: "first" }]
},
{
code: unIndent`
let
foo
`,
options: [4, { VariableDeclarator: "first" }]
},
{
code: unIndent`
let foo = 1,
bar =
2
`,
options: [2, { VariableDeclarator: "first" }]
},
{
code: unIndent`
var abc =
Expand Down Expand Up @@ -5933,6 +5988,39 @@ ruleTester.run("indent", rule, {
[2, 4, 2, "Identifier"]
])
},
{
code: unIndent`
let foo = 'foo',
bar = bar;
const a = 'a',
b = 'b';
`,
output: unIndent`
let foo = 'foo',
bar = bar;
const a = 'a',
b = 'b';
`,
options: [2, { VariableDeclarator: "first" }],
errors: expectedErrors([
[2, 4, 2, "Identifier"],
[4, 6, 2, "Identifier"]
])
},
{
code: unIndent`
var foo = 'foo',
bar = bar;
`,
output: unIndent`
var foo = 'foo',
bar = bar;
`,
options: [2, { VariableDeclarator: { var: "first" } }],
errors: expectedErrors([
[2, 4, 2, "Identifier"]
])
},
{
code: unIndent`
if(true)
Expand Down

0 comments on commit b4395f6

Please sign in to comment.