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

Fix: indent false positive with multi-line await expression. #8837

Merged
merged 3 commits into from Jul 4, 2017

Conversation

aladdin-add
Copy link
Member

…tructuring assignment

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

[x] Bug fix (template)

What changes did you make? (Give an overview)
fixes #8815

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

@eslintbot
Copy link

Thanks for the pull request, @aladdin-add! I took a look to make sure it's ready for merging and found some changes are needed:

  • The commit summary must be 72 characters or shorter. Please check out our guide for how to properly format your commit summary and update it on this pull request.

Can you please update the pull request to address these?

(More information can be found in our pull request guide.)

@mention-bot
Copy link

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

@eslintbot
Copy link

Thanks for the pull request, @aladdin-add! I took a look to make sure it's ready for merging and found some changes are needed:

  • The commit summary must be 72 characters or shorter. Please check out our guide for how to properly format your commit summary and update it on this pull request.

Can you please update the pull request to address these?

(More information can be found in our pull request guide.)

@eslintbot
Copy link

Thanks for the pull request, @aladdin-add! I took a look to make sure it's ready for merging and found some changes are needed:

  • The commit summary must be 72 characters or shorter. Please check out our guide for how to properly format your commit summary and update it on this pull request.

Can you please update the pull request to address these?

(More information can be found in our pull request guide.)

@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 Jun 30, 2017
@not-an-aardvark not-an-aardvark self-requested a review June 30, 2017 03:03
@eslintbot
Copy link

Thanks for the pull request, @aladdin-add! I took a look to make sure it's ready for merging and found some changes are needed:

  • The commit summary must be 72 characters or shorter. Please check out our guide for how to properly format your commit summary and update it on this pull request.

Can you please update the pull request to address these?

(More information can be found in our pull request guide.)

@aladdin-add aladdin-add changed the title [WIP]Fix: indent: false positive with multi-line async function call + des… Fix: indent false positive with multi-line await expression. Jun 30, 2017
offsets.matchIndentOf(sourceCode.getTokenBefore(openingParen), openingParen);

// https://github.com/eslint/eslint/issues/8815
const tokenBefore = sourceCode.getTokenBefore(openingParen, node.parent.type === "AwaitExpression" ? astUtils.isKeywordToken : void 0);
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 see tokenBefore is not a good name, someone help me~~ 🆘

@not-an-aardvark
Copy link
Member

Hi @aladdin-add, sorry about the delay in reviewing this. I'm planning to test it out tonight or tomorrow and give some feedback then.

Copy link
Member

@not-an-aardvark not-an-aardvark left a comment

Choose a reason for hiding this comment

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

Thanks for the PR! I left some suggestions.

}
`
},

Copy link
Member

Choose a reason for hiding this comment

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

Can you add tests for these cases too?

        {
            code: unIndent`
                function* test() {
                    const {
                        foo,
                        bar,
                    } = yield doSomethingAsync(
                        1,
                        2,
                        3,
                    );
                }
            `
        },
        {
            code: unIndent`
                ({
                    a: b
                } = +foo(
                    bar
                ));
            `
        },
        {
            code: unIndent`
                const {
                    foo,
                    bar,
                } = typeof foo(
                    1,
                    2,
                    3,
                );
            `
        },
        {
            code: unIndent`
                const {
                    foo,
                    bar,
                } = +(
                    foo
                );
            `
        },

offsets.matchIndentOf(sourceCode.getTokenBefore(openingParen), openingParen);

// https://github.com/eslint/eslint/issues/8815
const tokenBefore = sourceCode.getTokenBefore(openingParen, node.parent.type === "AwaitExpression" ? astUtils.isKeywordToken : void 0);
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this fix is quite correct. I think the problem is actually with the logic for AssignmentExpression and VariableDeclaration nodes, not with CallExpression nodes -- the from the report in #8815 is just a special case that happens to include AwaitExpression and a CallExpression.

For example, the following code is also an error due to this bug, but it's not fixed:

const {
    foo
} = typeof foo(
    1
);

Instead of modifying the logic for CallExpressions, I think the following fix solves the problem:

diff --git a/lib/rules/indent.js b/lib/rules/indent.js
index 6babe29c..fafd1292 100644
--- a/lib/rules/indent.js
+++ b/lib/rules/indent.js
@@ -1030,7 +1030,7 @@ module.exports = {
                 const nodeTokens = getTokensAndComments(node);
                 const tokensFromOperator = nodeTokens.slice(lodash.sortedIndexBy(nodeTokens, operator, token => token.range[0]));

-                offsets.setDesiredOffsets(tokensFromOperator, sourceCode.getFirstToken(node.left), 1);
+                offsets.setDesiredOffsets(tokensFromOperator, sourceCode.getLastToken(node.left), 1);
                 offsets.ignoreToken(tokensFromOperator[0]);
                 offsets.ignoreToken(tokensFromOperator[1]);
             },
@@ -1325,12 +1325,12 @@ module.exports = {
             VariableDeclarator(node) {
                 if (node.init) {
                     const equalOperator = sourceCode.getTokenBefore(node.init, astUtils.isNotOpeningParenToken);
-                    const tokenAfterOperator = sourceCode.getTokenAfter(equalOperator);
+                    const tokensAfterOperator = sourceCode.getTokensAfter(equalOperator, token => token.range[1] <= node.range[1]);

                     offsets.ignoreToken(equalOperator);
-                    offsets.ignoreToken(tokenAfterOperator);
-                    offsets.matchIndentOf(equalOperator, tokenAfterOperator);
-                    offsets.matchIndentOf(sourceCode.getFirstToken(node), equalOperator);
+                    offsets.ignoreToken(tokensAfterOperator[0]);
+                    offsets.setDesiredOffsets(tokensAfterOperator, equalOperator, 1);
+                    offsets.matchIndentOf(sourceCode.getLastToken(node.id), equalOperator);
                 }
             },

There are two parts to the fix:

  1. With AssignmentExpression nodes, the equals sign should be offset from the last token of the AssignmentExpression, not the first token. This prevents token-collapsing bugs like this one.

  2. With VariableDeclarator nodes, all tokens should be indented from the = token, not just the first token after the = token. The problem before was that in a case like this:

    var {
    } = await foo(
    )

    Only the await token's indentation was getting set to be aligned with the }, but the foo token's indentation was not getting aligned properly, so the foo() expression was offset from } when it should have been aligned instead.

@eslintbot
Copy link

Thanks for the pull request, @aladdin-add! I took a look to make sure it's ready for merging and found some changes are needed:

  • The commit summary must be 72 characters or shorter. Please check out our guide for how to properly format your commit summary and update it on this pull request.

Can you please update the pull request to address these?

(More information can be found in our pull request guide.)

Copy link
Member

@not-an-aardvark not-an-aardvark 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!

@not-an-aardvark not-an-aardvark merged commit 931a9f1 into eslint:master Jul 4, 2017
@not-an-aardvark
Copy link
Member

Thanks for contributing!

@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.

[v4] indent: false positive with multi-line async function call + destructuring assignment
4 participants