Skip to content
Permalink
Browse files

Chore: make minor improvements to `indent` internals (#8947)

* Get rid of an `if` statement whose condition was always true. (With this change, the `indent` rule now has 100% branch coverage.)
* Remove the `matchIndentOf` helper in favor of using `setDesiredOffset` with an offset of 0.
* Fix outdated or misleading comments
* Move some function declarations into methods on the listeners object when possible
  • Loading branch information...
not-an-aardvark committed Jul 15, 2017
1 parent 1ea3723 commit a747b6fb66a11d4d2faaf280f5215ad430a8ce01
Showing with 57 additions and 100 deletions.
  1. +57 −100 lib/rules/indent.js
@@ -252,20 +252,10 @@ class OffsetStorage {
return this._tree.findLe(token.range[0]).value;
}

/**
* Sets the indent of one token to match the indent of another.
* @param {Token} baseToken The first token
* @param {Token} offsetToken The second token, whose indent should be matched to the first token
* @returns {void}
*/
matchIndentOf(baseToken, offsetToken) {
return this.setDesiredOffsets(offsetToken.range, baseToken, 0);
}

/**
* Sets the offset column of token B to match the offset column of token A.
* **WARNING**: This is different from matchIndentOf because it matches a *column*, even if baseToken is not
* the first token on its line. In most cases, `matchIndentOf` should be used instead.
* **WARNING**: This matches a *column*, even if baseToken is not the first token on its line. In
* most cases, `setDesiredOffset` should be used instead.
* @param {Token} baseToken The first token
* @param {Token} offsetToken The second token, whose offset should be matched to the first token
* @returns {void}
@@ -376,6 +366,7 @@ class OffsetStorage {
* descriptor. The tree for the example above would have the following nodes:
*
* * key: 0, value: { offset: 0, from: null }
* * key: 15, value: { offset: 1, from: barToken }
* * key: 30, value: { offset: 1, from: fooToken }
* * key: 43, value: { offset: 2, from: barToken }
* * key: 820, value: { offset: 1, from: bazToken }
@@ -625,16 +616,14 @@ module.exports = {
MemberExpression: 1,
ArrayExpression: 1,
ObjectExpression: 1,
ArrayPattern: 1,
ObjectPattern: 1,
flatTernaryExpressions: false
};

if (context.options.length) {
if (context.options[0] === "tab") {
indentSize = 1;
indentType = "tab";
} else if (typeof context.options[0] === "number") {
} else {
indentSize = context.options[0];
indentType = "space";
}
@@ -686,10 +675,10 @@ module.exports = {

/**
* Reports a given indent violation
* @param {Token} token Node violating the indent rule
* @param {Token} token Token violating the indent rule
* @param {int} neededIndentLevel Expected indentation level
* @param {int} gottenSpaces Indentation space count in the actual node/code
* @param {int} gottenTabs Indentation tab count in the actual node/code
* @param {int} gottenSpaces Actual number of indentation spaces for the token
* @param {int} gottenTabs Actual number of indentation tabs for the token
* @returns {void}
*/
function report(token, neededIndentLevel) {
@@ -794,7 +783,7 @@ module.exports = {
startToken,
offset === "first" ? 1 : offset
);
offsets.matchIndentOf(startToken, endToken);
offsets.setDesiredOffset(endToken, startToken, 0);

// If the preference is "first" but there is no first element (e.g. sparse arrays w/ empty first slot), fall back to 1 level.
if (offset === "first" && elements.length && !elements[0]) {
@@ -820,44 +809,6 @@ module.exports = {
});
}

/**
* Check indentation for blocks and class bodies
* @param {ASTNode} node The BlockStatement or ClassBody node to indent
* @returns {void}
*/
function addBlockIndent(node) {

let blockIndentLevel;

if (node.parent && isOuterIIFE(node.parent)) {
blockIndentLevel = options.outerIIFEBody;
} else if (node.parent && (node.parent.type === "FunctionExpression" || node.parent.type === "ArrowFunctionExpression")) {
blockIndentLevel = options.FunctionExpression.body;
} else if (node.parent && node.parent.type === "FunctionDeclaration") {
blockIndentLevel = options.FunctionDeclaration.body;
} else {
blockIndentLevel = 1;
}

/*
* For blocks that aren't lone statements, ensure that the opening curly brace
* is aligned with the parent.
*/
if (!astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) {
offsets.matchIndentOf(sourceCode.getFirstToken(node.parent), sourceCode.getFirstToken(node));
}
addElementListIndent(node.body, sourceCode.getFirstToken(node), sourceCode.getLastToken(node), blockIndentLevel);
}

/**
* Check indent for array block content or object block content
* @param {ASTNode} node node to examine
* @returns {void}
*/
function addArrayOrObjectIndent(node) {
addElementListIndent(node.elements || node.properties, sourceCode.getFirstToken(node), sourceCode.getLastToken(node), options[node.type]);
}

/**
* Check and decide whether to check for indentation for blockless nodes
* Scenarios are for or while statements without braces around them
@@ -890,7 +841,7 @@ module.exports = {
const lastToken = sourceCode.getLastToken(node);

if (node.type !== "EmptyStatement" && astUtils.isSemicolonToken(lastToken)) {
offsets.matchIndentOf(lastParentToken, lastToken);
offsets.setDesiredOffset(lastToken, lastParentToken, 0);
}
}
}
@@ -912,25 +863,11 @@ module.exports = {

parameterParens.add(openingParen);
parameterParens.add(closingParen);
offsets.matchIndentOf(sourceCode.getTokenBefore(openingParen), openingParen);
offsets.setDesiredOffset(openingParen, sourceCode.getTokenBefore(openingParen), 0);

addElementListIndent(node.arguments, openingParen, closingParen, options.CallExpression.arguments);
}

/**
* Checks the indentation of ClassDeclarations and ClassExpressions
* @param {ASTNode} node A ClassDeclaration or ClassExpression node
* @returns {void}
*/
function addClassIndent(node) {
if (node.superClass) {
const classToken = sourceCode.getFirstToken(node);
const extendsToken = sourceCode.getTokenBefore(node.superClass, astUtils.isNotOpeningParenToken);

offsets.setDesiredOffsets([extendsToken.range[0], node.body.range[0]], classToken, 1);
}
}

/**
* Checks the indentation of parenthesized values, given a list of tokens in a program
* @param {Token[]} tokens A list of tokens
@@ -965,7 +902,7 @@ module.exports = {
});
}

offsets.matchIndentOf(leftParen, rightParen);
offsets.setDesiredOffset(rightParen, leftParen, 0);
});
}

@@ -985,7 +922,7 @@ module.exports = {
if (token === firstTokenOfLine) {
offsets.ignoreToken(token);
} else {
offsets.matchIndentOf(firstTokenOfLine, token);
offsets.setDesiredOffset(token, firstTokenOfLine, 0);
}
}
});
@@ -1022,8 +959,13 @@ module.exports = {
}

return {
ArrayExpression: addArrayOrObjectIndent,
ArrayPattern: addArrayOrObjectIndent,
"ArrayExpression, ArrayPattern"(node) {
addElementListIndent(node.elements, sourceCode.getFirstToken(node), sourceCode.getLastToken(node), options.ArrayExpression);
},

"ObjectExpression, ObjectPattern"(node) {
addElementListIndent(node.properties, sourceCode.getFirstToken(node), sourceCode.getLastToken(node), options.ObjectExpression);
},

ArrowFunctionExpression(node) {
const firstToken = sourceCode.getFirstToken(node);
@@ -1045,7 +987,7 @@ module.exports = {
} else {
arrowToken = sourceCode.getFirstToken(node, astUtils.isArrowToken);
}
offsets.matchIndentOf(sourceCode.getFirstToken(node), arrowToken);
offsets.setDesiredOffset(arrowToken, sourceCode.getFirstToken(node), 0);
},

AssignmentExpression(node) {
@@ -1073,15 +1015,39 @@ module.exports = {
offsets.setDesiredOffsets([tokenAfterOperator.range[1], node.range[1]], tokenAfterOperator, 1);
},

BlockStatement: addBlockIndent,
"BlockStatement, ClassBody"(node) {

let blockIndentLevel;

if (node.parent && isOuterIIFE(node.parent)) {
blockIndentLevel = options.outerIIFEBody;
} else if (node.parent && (node.parent.type === "FunctionExpression" || node.parent.type === "ArrowFunctionExpression")) {
blockIndentLevel = options.FunctionExpression.body;
} else if (node.parent && node.parent.type === "FunctionDeclaration") {
blockIndentLevel = options.FunctionDeclaration.body;
} else {
blockIndentLevel = 1;
}

/*
* For blocks that aren't lone statements, ensure that the opening curly brace
* is aligned with the parent.
*/
if (!astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) {
offsets.setDesiredOffset(sourceCode.getFirstToken(node), sourceCode.getFirstToken(node.parent), 0);
}
addElementListIndent(node.body, sourceCode.getFirstToken(node), sourceCode.getLastToken(node), blockIndentLevel);
},

CallExpression: addFunctionCallIndent,

ClassBody: addBlockIndent,

ClassDeclaration: addClassIndent,
"ClassDeclaration[superClass], ClassExpression[superClass]"(node) {
const classToken = sourceCode.getFirstToken(node);
const extendsToken = sourceCode.getTokenBefore(node.superClass, astUtils.isNotOpeningParenToken);

ClassExpression: addClassIndent,
offsets.setDesiredOffsets([extendsToken.range[0], node.body.range[0]], classToken, 1);
},

ConditionalExpression(node) {
const firstToken = sourceCode.getFirstToken(node);
@@ -1118,7 +1084,7 @@ module.exports = {
* )
*/
if (lastConsequentToken.loc.end.line === firstAlternateToken.loc.start.line) {
offsets.matchIndentOf(firstConsequentToken, firstAlternateToken);
offsets.setDesiredOffset(firstAlternateToken, firstConsequentToken, 0);
} else {

/**
@@ -1138,7 +1104,7 @@ module.exports = {
}
},

DoWhileStatement: node => addBlocklessNodeIndent(node.body),
"DoWhileStatement, WhileStatement, ForInStatement, ForOfStatement": node => addBlocklessNodeIndent(node.body),

ExportNamedDeclaration(node) {
if (node.declaration === null) {
@@ -1155,10 +1121,6 @@ module.exports = {
}
},

ForInStatement: node => addBlocklessNodeIndent(node.body),

ForOfStatement: node => addBlocklessNodeIndent(node.body),

ForStatement(node) {
const forOpeningParen = sourceCode.getFirstToken(node, 1);

@@ -1219,7 +1181,7 @@ module.exports = {
if (node.computed) {

// For computed MemberExpressions, match the closing bracket with the opening bracket.
offsets.matchIndentOf(firstNonObjectToken, sourceCode.getLastToken(node));
offsets.setDesiredOffset(sourceCode.getLastToken(node), firstNonObjectToken, 0);
offsets.setDesiredOffsets(node.property.range, firstNonObjectToken, 1);
}

@@ -1253,8 +1215,8 @@ module.exports = {
offsets.ignoreToken(secondNonObjectToken);

// To ignore the property indentation, ensure that the property tokens depend on the ignored tokens.
offsets.matchIndentOf(offsetBase, firstNonObjectToken);
offsets.matchIndentOf(firstNonObjectToken, secondNonObjectToken);
offsets.setDesiredOffset(firstNonObjectToken, offsetBase, 0);
offsets.setDesiredOffset(secondNonObjectToken, firstNonObjectToken, 0);
}
},

@@ -1266,9 +1228,6 @@ module.exports = {
}
},

ObjectExpression: addArrayOrObjectIndent,
ObjectPattern: addArrayOrObjectIndent,

Property(node) {
if (!node.computed && !node.shorthand && !node.method && node.kind === "init") {
const colon = sourceCode.getFirstTokenBetween(node.key, node.value, astUtils.isColonToken);
@@ -1359,12 +1318,10 @@ module.exports = {
offsets.ignoreToken(equalOperator);
offsets.ignoreToken(tokenAfterOperator);
offsets.setDesiredOffsets([tokenAfterOperator.range[0], node.range[1]], equalOperator, 1);
offsets.matchIndentOf(sourceCode.getLastToken(node.id), equalOperator);
offsets.setDesiredOffset(equalOperator, sourceCode.getLastToken(node.id), 0);
}
},

WhileStatement: node => addBlocklessNodeIndent(node.body),

"*:exit": checkForUnknownNode,

"JSXAttribute[value]"(node) {
@@ -1385,7 +1342,7 @@ module.exports = {

if (node.selfClosing) {
closingToken = sourceCode.getLastToken(node, { skip: 1 });
offsets.matchIndentOf(closingToken, sourceCode.getLastToken(node));
offsets.setDesiredOffset(sourceCode.getLastToken(node), closingToken, 0);
} else {
closingToken = sourceCode.getLastToken(node);
}
@@ -1397,7 +1354,7 @@ module.exports = {
const firstToken = sourceCode.getFirstToken(node);

offsets.setDesiredOffsets(node.name.range, firstToken, 1);
offsets.matchIndentOf(firstToken, sourceCode.getLastToken(node));
offsets.setDesiredOffset(sourceCode.getLastToken(node), firstToken, 0);
},

JSXExpressionContainer(node) {
@@ -1409,7 +1366,7 @@ module.exports = {
openingCurly,
1
);
offsets.matchIndentOf(openingCurly, closingCurly);
offsets.setDesiredOffset(closingCurly, openingCurly, 0);
},

"Program:exit"() {

0 comments on commit a747b6f

Please sign in to comment.
You can’t perform that action at this time.