Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 3 commits into from Dec 23, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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
31 changes: 14 additions & 17 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 @@ -1385,6 +1373,15 @@ module.exports = {
if (astUtils.isSemicolonToken(lastToken)) {
offsets.ignoreToken(lastToken);
}

if (options.VariableDeclarator[node.kind] === "first") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For performance, it might be better to skip the lines above (starting with if (node.declarations... on line 1344) when the offset is first, because those lines would have no effect.

addElementListIndent(
node.declarations,
sourceCode.getFirstToken(node),
sourceCode.getLastToken(node),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of sourceCode.getLastToken here seems a bit strange. Normally, when addElementListIndent, the last token is indented the same way as the first token (e.g. in [foo, bar, baz], the ] is indented the same amount as the [.

It might not be necessary to change this because the last token would be indented properly later on (e.g. in the ArrayExpression listener). However, can you add tests for cases like this?

let foo = 1,
    bar = 2,
    baz
let
    foo
let foo = 1,
    bar =
    2

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you expect the cases above are reporting warnings or not?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, they should be valid.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added those test cases. See the latest commit please.

"first"
);
}
},

VariableDeclarator(node) {
Expand Down
65 changes: 65 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,20 @@ 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`
var abc =
Expand Down Expand Up @@ -5933,6 +5965,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