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

Update: fix indentation of parenthesized MemberExpressions (fixes #8924) #8928

Merged
merged 4 commits into from Jul 15, 2017

Conversation

not-an-aardvark
Copy link
Member

What is the purpose of this pull request? (put an "X" next to item)

[x] Bug fix (#8924)

What changes did you make? (Give an overview)

The MemberExpression listener in indent contains some logic to ensure that if the object of a MemberExpression is wrapped in parentheses, the property is offset from the opening paren, not the object itself. Due to a bug, this logic also caused the property to be offset from the opening paren if the entire MemberExpression was wrapped in parentheses, raather than just the object. This commit updates the MemberExpression listener to specifically check for parentheses around the object, not the entire MemberExpression.

Is there anything you'd like reviewers to focus on?

Nothing in particular

The MemberExpression listener in `indent` contains some logic to ensure that if the object of a MemberExpression is wrapped in parentheses, the property is offset from the opening paren, not the object itself. Due to a bug, this logic also caused the property to be offset from the opening paren if the entire MemberExpression was wrapped in parentheses, raather than just the object. This commit updates the MemberExpression listener to specifically check for parentheses around the object, not the entire MemberExpression.
@not-an-aardvark not-an-aardvark added accepted There is consensus among the team that this change meets the criteria for inclusion bug ESLint is working incorrectly indent Relates to the `indent` rule rule Relates to ESLint's core rules labels Jul 12, 2017
@mention-bot
Copy link

@not-an-aardvark, thanks for your PR! By analyzing the history of the files in this pull request, we identified @vitorbal, @gyandeeps and @valorkin to be potential reviewers.

platinumazure
platinumazure previously approved these changes Jul 12, 2017
Copy link
Member

@platinumazure platinumazure left a comment

Choose a reason for hiding this comment

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

Basically LGTM, just one suggestion for maintainability/readability.

@@ -1217,8 +1217,10 @@ module.exports = {
const firstNonObjectToken = sourceCode.getFirstTokenBetween(node.object, node.property, astUtils.isNotClosingParenToken);
const secondNonObjectToken = sourceCode.getTokenAfter(firstNonObjectToken);

const tokenBeforeObject = sourceCode.getTokenBefore(node.object, token => astUtils.isNotOpeningParenToken(token) || parameterParens.has(token));
const firstObjectToken = tokenBeforeObject ? sourceCode.getTokenAfter(tokenBeforeObject) : sourceCode.ast.tokens[0];
const objectParenCount = sourceCode.getTokensBetween(node.object, node.property).findIndex(astUtils.isNotClosingParenToken);
Copy link
Member

Choose a reason for hiding this comment

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

Wondering if something like sourceCode.getTokensAfter(node.object, { filter: astUtils.isClosingParenToken }).length might be more readable here? As it is, I could see some developers being confused about how the index returned from findIndex would correspond to a count of closing parens.

Copy link
Member Author

Choose a reason for hiding this comment

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

It seems like sourceCode.getTokensAfter returns all tokens after the object that match the filter (i.e. it doesn't stop iterating until it reaches the end of the file, or until it reaches the specified token count). So I don't think that will work in this case.

Copy link
Member

Choose a reason for hiding this comment

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

@not-an-aardvark Hmm... Maybe sourceCode.getFirstTokensBetween(node.object, node.property, { filter: astUtils.isClosedParenToken }).length then?

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated to use filter and length. I kept using getTokensBetween rather than getFirstTokensBetween, because I think there's no difference between them when no count is provided.

@platinumazure platinumazure dismissed their stale review July 12, 2017 05:16

Need to change to request changes

Copy link
Member

@platinumazure platinumazure left a comment

Choose a reason for hiding this comment

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

Could you please add a test where the parenthesized object is a computed property (or otherwise has extra closing tokens)?

Something like:

(
    foo[bar]
)
    .baz

@not-an-aardvark
Copy link
Member Author

Updated to add the requested test. The example you gave already passes because the ] is within the range of the outer MemberExpression, even though it's not within the range of the inner MemberExpression.

@platinumazure
Copy link
Member

@not-an-aardvark Thanks, makes sense.

What about something surrounded by inline parens and also outer parens?

(
    (foo.bar)
)
    .baz

@not-an-aardvark
Copy link
Member Author

not-an-aardvark commented Jul 12, 2017

Added that test too. It also passes because there are two sets of parentheses around the object, so .baz is aligned against the second token before the start of the object (i.e. the first ().

@eslint eslint deleted a comment from eslintbot Jul 12, 2017
@eslint eslint deleted a comment from eslintbot Jul 12, 2017
Copy link
Member

@platinumazure platinumazure left a comment

Choose a reason for hiding this comment

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

LGTM so far, would love to see if getFirstTokensBetween suggestion is feasible or not-- ping me when you want me to take another look.

@eslintbot
Copy link

LGTM

@eslint eslint deleted a comment from eslintbot Jul 12, 2017
@not-an-aardvark
Copy link
Member Author

@platinumazure Does the updated implementation look good to you?

Copy link
Member

@platinumazure platinumazure left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for contributing!

@not-an-aardvark not-an-aardvark merged commit 1ea3723 into master Jul 15, 2017
@not-an-aardvark not-an-aardvark deleted the indent-parenthesized-member-expressions branch July 15, 2017 01:11
@eslint-deprecated eslint-deprecated bot locked and limited conversation to collaborators Feb 6, 2018
@eslint-deprecated eslint-deprecated bot added the archived due to age This issue has been archived; please open a new issue for any further discussion label Feb 6, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
accepted There is consensus among the team that this change meets the criteria for inclusion archived due to age This issue has been archived; please open a new issue for any further discussion bug ESLint is working incorrectly indent Relates to the `indent` rule rule Relates to ESLint's core rules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants