-
Notifications
You must be signed in to change notification settings - Fork 42
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
Add support to cuddle assignments for a whole block #163
Add support to cuddle assignments for a whole block #163
Conversation
9d715d8
to
8a4ee0e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great! Very nice using the ast.Inspect
and not keeping track of variables in each scope manually.
I think this looks good as is other than I want it to be an opt-in and not enabled by default. I think we can call it allow-cuddle-used-in-block
or similar.
testdata/src/default_config/fix_cuddle_whole_blocks/fix_cuddle_whole_blocks.go
Outdated
Show resolved
Hide resolved
testdata/src/default_config/fix_cuddle_whole_blocks/fix_cuddle_whole_blocks.go
Outdated
Show resolved
Hide resolved
testdata/src/default_config/fix_cuddle_whole_blocks/fix_cuddle_whole_blocks.go
Outdated
Show resolved
Hide resolved
wsl.go
Outdated
// Contains the union of all variable names used anywhere | ||
// within the block body (if applicable) and is used to check | ||
// if a preceding statement's variables are actually used within | ||
// the block. This helps enforce rules about allowed cuddling. | ||
var blockUsedVars []string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we want to add this as an opt-in and keep the old behavior. Ideally we could use the same code/walk but just return after the first variable is found if we didn't opt in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided to use the old code if the new flag isn't enabled that way we don't introduce any unintended new behavior on accident by using the new ast.Inspect
approach. Lmk if you want to re-visit this.
if firstBodyStatement != nil {
if p.config.CuddleUsedInBlock {
identifiersUsedInBlock = p.findUsedVariablesInStatement(stmt)
} else {
identifiersUsedInBlock = append(p.findLHS(firstBodyStatement), p.findRHS(firstBodyStatement)...)
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But the old behaviour is not what the rule describes: "must be used in the iteration". 🤔
If you wanted to keep the old behaviour it might be better to re-introduce it as a new rule with a more accurate error message so that the different messages can be interpreted more easily, rather than a message which may be misleading/inaccurate depending on the configuration of the rule producing that message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thats why I originally introduced this as a fix rather than a new flag. There was no mention of the "first line only" rule. All the rules just said that it "must be used in the iteration"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tl;dr - there's a bunch of bugs and bad behavior here, no need to adress that for now. I think it should be addressed, but I'm fine isolating this PR to only address the new feature flag and don't try to fix this. The flag kan be added in a minor release directly and we can fix the old stuff in a future breaking change.
Yeah this is a bug and bad documentation, it stems from way back when each different kind of block was seen as separate. Code changed and never really got adapted (which is pretty clear from the whole code base tbh).
The only mention of it is here for range
specifically. It's just a comment on the second example. It's also documented here as code docs, but that's not very clear from a user perspective.
I had a quick look now and it seems to be missing from switch statements but exist for type switch.
There are more bugs with defer
and go
statements passing the whole Body
causing false negatives. These two passes but shouldn't according to the other logc.
y := 1
go func() {
_ = 1
y = 1
}()
y := 1
defer func() {
_ = 1
y = 1
}()
@bombsimon PR suggestions pushed. Please let me know your thoughts! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great, thank you so much!! Didn't expect this to land in the current version so many years later but this is a great solution!
Just a nit on the docs.
CI is not your code, it's related to Go 1.24 which I haven't built this project with yet |
Co-authored-by: Simon Sawert <simon@sawert.se>
Added your doc suggestion! Its ready to merge whenever! |
Support to cuddle assignments for a whole block
Implements #24 #50
Right now you have to use the variable, type or field in the first statement in a block if you want to use it like this:
This PR will update this cuddle check to look in the entire body of the statement to check if the variable is used. Meaning the following will now be allowed: