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
Enforce numblock
verification for ALL the cops that check block
nodes
#10915
Enforce numblock
verification for ALL the cops that check block
nodes
#10915
Conversation
4658cf0
to
141993a
Compare
Wow, that's one truly epic PR! The changes look good to me at a superficial examination, but we'll definitely have to think how to simplify the handling of both types of blocks going forward. Perhaps the commissioner can add some callback that gets triggered on both like we've done for some method definitions. |
This adds a lot of changelog noise, which on one hand makes sense because each line is a changed cop, but on the other hand might make it hard to find other things in the changelog. @bbatsov do you think we should collapse the entries? |
@dvandersluis Yeah, that'd be fine by me. I guess we can also collapse all the commits that just add support for numblocks into one. Same with the commits that add ignores for the new internal affairs cop. |
At first I thought that an Notice the integer in the representation, it's the arguments count, but we may want a node object here. ;; clients.map { _1['name'] }
(numblock
(send (send nil :clients) :map)
1
(index (lvar :_1) (str "name"))) For example, the Style/EachWithObject cop does a very clever autocorrection. It changes Differences like this can be tricky to get unified if we try to treat |
I can do that as well. I can add 2 entries and list the changed copes in a single changelog entry if this is fine with you all. To keep it a bit tidier and create only 2 files with the changes – 1 for the fixes and 1 for the rubocop-ast bump as a change, but there was a test enforcing single tries in the files. I think multiple entries per file can be a feature. If you have other ideas about the changelog entry, I'm open to them. |
2571b67
to
7c4236a
Compare
The `InternalAffairs/NumblockHandler` ensures cops that handle `block` nodes will also handle `numblock` nodes or disable it explicitly. We have exceptions for this check like cops that check block parameters but for the majority of the cases we want `numblock` nodes to handled.
While, technically, we can use gemspec definitions like: ``` Gem::Specification.new do _1.metadata['rubygems_mfa_required'] = 'true' end ```
This mixin (`HashTransformMethod`) holds implementation details for the cops Style/HashTransformKeys and Style/HashTransformValues. Their usage is based on named block arguments and destructuring, which is not how one would use numbered arguments. I'll delay (avoid) this implementation.
Both of them use `MethodComplexity` which now supports `define_method` with numblocks.
The autocorrect can and will generate broken code when using numbered arguments as `_1` is not a valid local variable name outside numblocks.
The autocorrection does not remove the return value in `each_with_object`, but the numbered arguments are swapped. Not the best autocorrection, but it is still correct as `each_with_object` ignores the return value of its block.
7c4236a
to
e63c32f
Compare
🚀 |
Ruby 2.7 introduced a new block syntax with access to implicit numbered arguments.
The problem for rubocop is that blocks with numbered arguments
clients.map { _1['name'] }
are parsed with a different AST node callednumblock
and most of the block cops handle onlyblock
nodes and everything's allowed fornumblock
nodes. This is what the AST looks like:Back in #10736, I found out that
Layout/SpaceInsideBlockBraces
wasn't being applied to numblocks. While addingnumblock
support forStyle/BlockDelimiters
in #10749 I figured out we have lots of such cops and decided to fix them all. In one big ass PR, nonetheless! 😅To fix them all, I developed the an internal cop called
InternalAffairs/NumblockHandler
to check for cop definitions that handleblock
nodes but notnumblock
nodes. I found out around 45 offences at first.It is perfectly legitimate to have cops that handle only
block
nodes. We have cops that verify block argument syntax or apply only to blocks without arguments. I decided to keepInternalAffairs/NumblockHandler
enabled for everything and to disable it explicitly for the cops that don't need it. I think this is a good nudge that forces you to think about how block cops should deal with numblocks.Those are the cops that needed to be fixed to support numblocks:
Fix Style/HashEachMethods with numblock
Fix Style/EachWithObject with numblocks
Fix Style/CollectionMethods with numblocks
Fix Style/InverseMethods with numblocks
Fix Style/RedundantSortBy with numblocks
Fix Style/RedundantBegin with numblocks
Fix Style/RedundantSelf with numblocks
Fix Style/Next for numblocks
Fix Style/ObjectThen with numblocks
Fix Style/MultilineBlockChain with numblocks
Fix Style/CombinableLoops with numblocks
Fix Style/TopLevelMethodDefinition
Fix Style/For with numblocks
Fix Style/Proc with numblocks
Fix Style/MethodCalledOnDoEndBlock with numblocks
Fix Metrics/AbcSize with numblocks
Fix Metrics/CyclomaticComplexity with numblocks
Fix Lint/Void with numblocks
Fix Lint/UselessAccessModifier with numblocks
Fix Lint/UnreachableLoop for numblocks
Fix Lint/RedundantWithObject with numblocks
Fix Lint/RedundantWithIndex with numblocks
Fix Lint/NonDeterministicRequireOrder with numblocks
Fix Lint/NextWithoutAccumulator with numblocks
Fix Layout/SpaceBeforeBlockBraces with numblocks
Fix Layout/MultilineBlockLayout with numblocks
Fix Layout/LineLength with numblocks
Fix Layout/IndentationWidth with numblocks
Fix Layout/EmptyLinesAroundBlockBody with numblocks
Fix Layout/EmptyLinesAroundAccessModifier with numblocks
Fix Layout/BlockEndNewline with numblocks
Fix Layout/BlockAlignment with numblocks
Here are the cops I have disabled
InternalAffairs/NumblockHandler
for:Disable InternalAffairs/NumblockComplement for Layout/SpaceAroundKeyword
Disable InternalAffairs/NumblockComplement for HashTransformMethod
Disable InternalAffairs/NumblockComplement for Style/RedundantFetchBlock
Disable InternalAffairs/NumblockComplement for Style/EachForSimpleLoop
Disable InternalAffairs/NumblockComplement for Style/NilLambda
Disable InternalAffairs/NumblockComplement for Style/EmptyLambdaParameter
Disable InternalAffairs/NumblockComplement for Style/EmptyBlockParameter
Disable InternalAffairs/NumblockComplement for Style/SingleLineBlockParams
Disable InternalAffairs/NumblockComplement for Style/TrailingCommaInBlockArgs
Disable InternalAffairs/NumblockComplement for Naming/BlockParameterName
Disable InternalAffairs/NumblockComplement for Lint/EmptyBlock
Disable InternalAffairs/NumblockComplement for Layout/SpaceAroundBlockParameters
Disable InternalAffairs/NumblockComplement for Gemspec/RequireMFA
Along the way, I found a few bugs. One was in the autocompletion of
Layout/LineLength
:Another one was in
MethodDispatchNode#macro?
method not detecting macros in numblocks. I have fixed this in rubocop-ast and @marcandre released1.21.0
with the fix. I have bumped its dependency for rubocop.I know this is a big change but you can review it commit by commit.
I introduced 2 changelog files – one with cops that are fixed to handle numblocks, and one for the rubocop-ast version bump.