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

tools: avoid let in for loops #9049

Closed
wants to merge 1 commit into
base: master
from

Conversation

Projects
None yet
8 participants
@jessqt
Contributor

jessqt commented Oct 12, 2016

Checklist
  • tests and/or benchmarks are included
  • commit message follows commit guidelines
Affected core subsystem(s)

Tools.

Description of change

This adds a new ESLint tool to check for let declarations within the for, forIn, forOf expressions.

Fixes: #9045
Ref: #8873

@not-an-aardvark

Thanks for the PR! This generally looks good to me, aside from one small change.

tools/eslint-rules/restrict-let-in-for-loops.js Outdated
return {
'ForStatement': (node) => testForLoop(node),
'ForInStatement': (node) => testForLoop(node),
'ForOfStatement': (node) => testForLoop(node)

This comment has been minimized.

@not-an-aardvark

not-an-aardvark Oct 12, 2016

Member

The implementation for ForStatement nodes looks good. I think checking ForInStatement and ForOfStatement nodes is a good idea, but I don't think this rule is correctly checking those nodes at the moment, since they don't have an init property. Instead, I think you would want to check the left property.

This comment has been minimized.

@jessqt

jessqt Oct 12, 2016

Contributor

Ah that's right. Thank you for pointing that out! I feel silly about that one. I will update the file.

@MylesBorins

This comment has been minimized.

Member

MylesBorins commented Oct 12, 2016

So it looks like you will need to add an entry into the .eslintrc if you want to get the rule to work

You can check http://eslint.org/docs/developer-guide/working-with-rules#runtime-rules for more details

edit: you may want to alternatively put it in lib/.eslintrc if we only want to test the lib

once the rule is added you will notice TONS of failures in our test / benchmark directories. You will likely want to fix all of those in a separate commit. Once you have done that you will want to rebase the rule to after the changes, so that the repo will always be in a working state.

$ git rebase -i HEAD~5 # start and interactive rebase for the last 5 commits

this will give you a list of commits, you can then move the commits around in that list, save, and close. This will edit the history

tumblr_ob945yoevc1qg2p2fo1_500

You will likely want to compile and test locally to make sure it works.

$ ./configure
$ make -j8
$ make test

Let me know if you have any questions 😄

tools/eslint-rules/restrict-let-in-for-loops.js Outdated
* Report function to test if the for-loop is declared using `let`.
*/
function checkForLet(node) {
if (testForLoop(node) || testForInOfLoop(node)) {

This comment has been minimized.

@MylesBorins

MylesBorins Oct 12, 2016

Member

I don't think that we need to run both checks on every iteration. It may be better to have a bit of repeated code instead of doing an extra evaluation on every for loop.

This comment has been minimized.

@jessqt

jessqt Oct 12, 2016

Contributor

That makes a lot of sense! I will update the test and add it to the .eslintrc. I was wondering if it would be more appropriate to report an error or simply a warning on the rule?

This comment has been minimized.

@MylesBorins

MylesBorins Oct 12, 2016

Member

I'd go with error.

This comment has been minimized.

@jessqt

jessqt Oct 12, 2016

Contributor

@thealphanerd okay! thank you

@cosmosgenius

This comment has been minimized.

Contributor

cosmosgenius commented Oct 12, 2016

Is there any context on why to avoid let in loops?

tools/eslint-rules/restrict-let-in-for-loops.js Outdated
return {
'ForStatement': (node) => checkForLet(node),
'ForInStatement': (node) => checkForLet(node),

This comment has been minimized.

@princejwesley

princejwesley Oct 12, 2016

Contributor

Use checkForLet (point-free style). (node) => checkForLet(node) is a unnecessary wrapper.

This comment has been minimized.

@MylesBorins

MylesBorins Oct 12, 2016

Member

@princejwesley I think this was based on the way a number of other lint rules have been designed

@Trott can you chime in?

This comment has been minimized.

@Trott

Trott Oct 12, 2016

Member

I think the suggestion from @princejwesley is a good one. The other tests that use a wrapper are also passing context because it is out of scope the way they are written, but not this one.

This comment has been minimized.

@jessqt

jessqt Oct 13, 2016

Contributor

Thank you @princejwesley ! I've learned (more formally) about tacit programming from this review. :)

@not-an-aardvark

This comment has been minimized.

Member

not-an-aardvark commented Oct 12, 2016

@cosmosgenius See #8637. At the moment, var has better performance than let.

@Trott

This comment has been minimized.

Member

Trott commented Oct 12, 2016

Nit: To be consistent with naming conventions in ESLint itself, maybe change the name of the rule from restrict-let-in-for-loops to no-let-in-for-loops or no-let-in-for-declarations or something like that.

tools/eslint-rules/restrict-let-in-for-loops.js Outdated
@@ -0,0 +1,41 @@
/**
* @fileoverview Prohibit the use of `let` in `for` loops.

This comment has been minimized.

@Trott

Trott Oct 12, 2016

Member

Nit: Maybe specify that it's just the declarations (or whatever the right terminology is)? I think this makes it sound like we're forbidding it in the body as well, but we're not.

This comment has been minimized.

@MylesBorins

MylesBorins Oct 13, 2016

Member

from the mdn docs

I think it would make sense to refer to it as the prohibit the use of let in for loop initialization

This comment has been minimized.

@jessqt

jessqt Oct 13, 2016

Contributor

@Trott Definitely agree with you. I changed the wording to have Prohibit the use ofletas the loop variable in the initialization of for, and the left-hand iterator in forIn and forOf loops. Which may be too verbose? I just missed @thealphanerd comment before changing this. Let me know what you think!

This comment has been minimized.

@Trott

Trott Oct 13, 2016

Member

I'm OK with comments being verbose. 👍

@Trott

This comment has been minimized.

Member

Trott commented Oct 12, 2016

Aside/question: I know there are benchmarks that show for (let i=0; i<j; i++) is slower than using var. And @ofrobots warns against that usage, I believe. But is it also the case for let in for loop using in and/or of as well?

@Trott

Only change I'd want to see is reporting the right column, although honestly, if that is onerous or controversial, this can land as is.

tools/eslint-rules/restrict-let-in-for-loops.js Outdated
*/
function checkForLet(node) {
if (testForLoop(node) || testForInOfLoop(node)) {
context.report(node, msg);

This comment has been minimized.

@Trott

Trott Oct 12, 2016

Member

Nit: In my opinion, this ends up reporting the wrong column. It indicates the issue is in the column where for starts, but it should really report the column where let occurs. Is it possible to fix that? Maybe instead of returning a boolean, testForLoop() and friends can return the offending node and that can be passed to context.report() rather than the for node?

This comment has been minimized.

@jessqt

jessqt Oct 13, 2016

Contributor

Thanks @Trott, with the review given from @thealphanerd, I broke up this function and returned the offensive node as you suggested to report the correct column!

@Trott

This comment has been minimized.

Member

Trott commented Oct 12, 2016

Oh, and +1 to adding it to lib/.eslintrc only.

@MylesBorins

This comment has been minimized.

Member

MylesBorins commented Oct 13, 2016

thanks for the review @Trott

@jessicaquynh if you move the rule to the lib/ folder you should no longer see any of the errors. Please let me know if you need any support on this at all.

@jessqt jessqt force-pushed the jessqt:issue#9045 branch Oct 13, 2016

@Trott

Trott approved these changes Oct 13, 2016

@Trott

This comment has been minimized.

Member

Trott commented Oct 13, 2016

LGTM.

@Trott

This comment has been minimized.

@MylesBorins

This comment has been minimized.

Member

MylesBorins commented Oct 13, 2016

nit: the subsystem should be tools, not eslint, in the commit message.

Thanks for the patience through the review process @jessicaquynh 🎉

@princejwesley

LGTM

tools: avoid let in for loops
This adds a new ESLint tool to check for let
declarations within the for, forIn, forOf expressions.

Fixes: #9045
Ref: #8873

@jessqt jessqt force-pushed the jessqt:issue#9045 branch to 8b704d6 Oct 14, 2016

@jessqt jessqt changed the title from eslint: avoid let in for loops to tools: avoid let in for loops Oct 14, 2016

@jasnell

LGTM

Trott added a commit to Trott/io.js that referenced this pull request Oct 14, 2016

tools: avoid let in for loops
This adds a new ESLint tool to check for let
declarations within the for, forIn, forOf expressions.

Fixes: nodejs#9045
Ref: nodejs#8873
PR-URL: nodejs#9049
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Teddy Katz <teddy.katz@gmail.com>
Reviewed-By: Prince John Wesley <princejohnwesley@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
@Trott

This comment has been minimized.

Member

Trott commented Oct 14, 2016

Landed in b16a97e

@Trott Trott closed this Oct 14, 2016

jasnell added a commit that referenced this pull request Oct 17, 2016

tools: avoid let in for loops
This adds a new ESLint tool to check for let
declarations within the for, forIn, forOf expressions.

Fixes: #9045
Ref: #8873
PR-URL: #9049
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Teddy Katz <teddy.katz@gmail.com>
Reviewed-By: Prince John Wesley <princejohnwesley@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

MylesBorins added a commit that referenced this pull request Nov 11, 2016

tools: avoid let in for loops
This adds a new ESLint tool to check for let
declarations within the for, forIn, forOf expressions.

Fixes: #9045
Ref: #8873
PR-URL: #9049
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Teddy Katz <teddy.katz@gmail.com>
Reviewed-By: Prince John Wesley <princejohnwesley@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

@MylesBorins MylesBorins referenced this pull request Nov 11, 2016

Closed

Backport removing let in for loop declaration #9553

3 of 3 tasks complete

MylesBorins added a commit to MylesBorins/node that referenced this pull request Nov 11, 2016

tools: avoid let in for loops
This adds a new ESLint tool to check for let
declarations within the for, forIn, forOf expressions.

Fixes: nodejs#9045
Ref: nodejs#9553
Ref: nodejs#8873
PR-URL: nodejs#9049
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Teddy Katz <teddy.katz@gmail.com>
Reviewed-By: Prince John Wesley <princejohnwesley@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

MylesBorins added a commit that referenced this pull request Nov 14, 2016

tools: avoid let in for loops
This adds a new ESLint tool to check for let
declarations within the for, forIn, forOf expressions.

Fixes: #9045
Ref: #9553
Ref: #8873
PR-URL: #9049
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Teddy Katz <teddy.katz@gmail.com>
Reviewed-By: Prince John Wesley <princejohnwesley@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

This was referenced Nov 22, 2016

@not-an-aardvark not-an-aardvark referenced this pull request Jan 13, 2017

Closed

test,util: remove lint workarounds #10785

2 of 2 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment