Skip to content

Commit

Permalink
Fix: ignore MemberExpression in VariableDeclarators (fixes #6795) (#6815
Browse files Browse the repository at this point in the history
)

Chained properties on objects will typically not be indented as the rule
expects in variable declarations. For now, ignore variable declarations
(as was done in the previous version of ESLint, where all chained
properties were ignored) and possibly revisit later to offer users
opportunity to enforce alignment and/or sensible indentation.
  • Loading branch information
nzakas committed Aug 1, 2016
1 parent 723432d commit 46b14cd
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 5 deletions.
6 changes: 5 additions & 1 deletion docs/rules/indent.md
Expand Up @@ -73,7 +73,7 @@ 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.
* `"outerIIFEBody"` (default: 1) enforces indentation level for file-level IIFEs.
* `"MemberExpression"` (off by default) enforces indentation level for multi-line property chains
* `"MemberExpression"` (off by default) enforces indentation level for multi-line property chains (except in variable declarations and assignments)

Level of indentation denotes the multiple of the indent specified. Example:

Expand Down Expand Up @@ -274,6 +274,10 @@ Examples of **correct** code for this rule with the `2, { "MemberExpression": 1
foo
.bar
.baz();

// Any indentation is permitted in variable declarations and assignments.
var bip = aardvark.badger
.coyote;
```

## Compatibility
Expand Down
41 changes: 37 additions & 4 deletions lib/rules/indent.js
Expand Up @@ -331,19 +331,40 @@ module.exports = {
}

/**
* Returns the VariableDeclarator based on the current node
* Returns a parent node of given node based on a specified type
* if not present then return null
* @param {ASTNode} node node to examine
* @param {string} type type that is being looked for
* @returns {ASTNode|void} if found then node otherwise null
*/
function getVariableDeclaratorNode(node) {
function getParentNodeByType(node, type) {
let parent = node.parent;

while (parent.type !== "VariableDeclarator" && parent.type !== "Program") {
while (parent.type !== type && parent.type !== "Program") {
parent = parent.parent;
}

return parent.type === "VariableDeclarator" ? parent : null;
return parent.type === type ? parent : null;
}

/**
* Returns the VariableDeclarator based on the current node
* if not present then return null
* @param {ASTNode} node node to examine
* @returns {ASTNode|void} if found then node otherwise null
*/
function getVariableDeclaratorNode(node) {
return getParentNodeByType(node, "VariableDeclarator");
}

/**
* Returns the ExpressionStatement based on the current node
* if not present then return null
* @param {ASTNode} node node to examine
* @returns {ASTNode|void} if found then node otherwise null
*/
function getAssignmentExpressionNode(node) {
return getParentNodeByType(node, "AssignmentExpression");
}

/**
Expand Down Expand Up @@ -816,6 +837,18 @@ module.exports = {
return;
}

// The typical layout of variable declarations and assignments
// alter the expectation of correct indentation. Skip them.
// TODO: Add appropriate configuration options for variable
// declarations and assignments.
if (getVariableDeclaratorNode(node)) {
return;
}

if (getAssignmentExpressionNode(node)) {
return;
}

let propertyIndent = getNodeIndent(node) + indentSize * options.MemberExpression;

let checkNodes = [node.property];
Expand Down
6 changes: 6 additions & 0 deletions tests/lib/rules/indent.js
Expand Up @@ -1389,6 +1389,12 @@ ruleTester.run("indent", rule, {
" .by" +
" .default();",
options: [4]
},
{
code:
"foo = bar.baz()\n" +
" .bip();",
options: [4, {MemberExpression: 1}]
}
],
invalid: [
Expand Down

0 comments on commit 46b14cd

Please sign in to comment.