Skip to content

Commit

Permalink
Add new Performance/AncestorsInclude cop
Browse files Browse the repository at this point in the history
  • Loading branch information
fatkodima committed Jun 6, 2020
1 parent 0b666fd commit bf55013
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### New features

* [#123](https://github.com/rubocop-hq/rubocop-performance/pull/123): Add new `Performance/AncestorsInclude` cop. ([@fatkodima][])
* [#125](https://github.com/rubocop-hq/rubocop-performance/pull/125): Support `Range#member?` method for `Performance/RangeInclude` cop. ([@fatkodima][])

## 1.6.1 (2020-06-05)
Expand Down
6 changes: 6 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# This is the default configuration file.

Performance/AncestorsInclude:
Description: 'Use `A <= B` instead of `A.ancestors.include?(B)`.'
Reference: 'https://github.com/JuanitoFatas/fast-ruby#ancestorsinclude-vs--code'
Enabled: true
VersionAdded: '1.7'

Performance/BindCall:
Description: 'Use `bind_call(obj, args, ...)` instead of `bind(obj).call(args, ...)`.'
Enabled: true
Expand Down
1 change: 1 addition & 0 deletions docs/modules/ROOT/pages/cops.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

= Department xref:cops_performance.adoc[Performance]

* xref:cops_performance.adoc#performanceancestorsinclude[Performance/AncestorsInclude]
* xref:cops_performance.adoc#performancebindcall[Performance/BindCall]
* xref:cops_performance.adoc#performancecaller[Performance/Caller]
* xref:cops_performance.adoc#performancecasewhensplat[Performance/CaseWhenSplat]
Expand Down
30 changes: 30 additions & 0 deletions docs/modules/ROOT/pages/cops_performance.adoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
= Performance

== Performance/AncestorsInclude

|===
| Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged

| Enabled
| Yes
| Yes
| 1.7
| -
|===

This cop is used to identify usages of `ancestors.include?` and
change them to use `<=` instead.

=== Examples

[source,ruby]
----
# bad
A.ancestors.include?(B)
# good
A <= B
----

=== References

* https://github.com/JuanitoFatas/fast-ruby#ancestorsinclude-vs--code

== Performance/BindCall

NOTE: Required Ruby version: 2.7
Expand Down
45 changes: 45 additions & 0 deletions lib/rubocop/cop/performance/ancestors_include.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# frozen_string_literal: true

module RuboCop
module Cop
module Performance
# This cop is used to identify usages of `ancestors.include?` and
# change them to use `<=` instead.
#
# @example
# # bad
# A.ancestors.include?(B)
#
# # good
# A <= B
#
class AncestorsInclude < Cop
include RangeHelp

MSG = 'Use `<=` instead of `ancestors.include?`.'

def_node_matcher :ancestors_include_candidate?, <<~PATTERN
(send (send $_subclass :ancestors) :include? $_superclass)
PATTERN

def on_send(node)
return unless ancestors_include_candidate?(node)

location_of_ancestors = node.children[0].loc.selector.begin_pos
end_location = node.loc.selector.end_pos
range = range_between(location_of_ancestors, end_location)

add_offense(node, location: range)
end

def autocorrect(node)
ancestors_include_candidate?(node) do |subclass, superclass|
lambda do |corrector|
corrector.replace(node, "#{subclass.source} <= #{superclass.source}")
end
end
end
end
end
end
end
1 change: 1 addition & 0 deletions lib/rubocop/cop/performance_cops.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require_relative 'mixin/regexp_metacharacter'

require_relative 'performance/ancestors_include'
require_relative 'performance/bind_call'
require_relative 'performance/caller'
require_relative 'performance/case_when_splat'
Expand Down
22 changes: 22 additions & 0 deletions spec/rubocop/cop/performance/ancestors_include_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::Performance::AncestorsInclude do
subject(:cop) { described_class.new }

it 'registers an offense and corrects when using `ancestors.include?`' do
expect_offense(<<~RUBY)
Class.ancestors.include?(Kernel)
^^^^^^^^^^^^^^^^^^ Use `<=` instead of `ancestors.include?`.
RUBY

expect_correction(<<~RUBY)
Class <= Kernel
RUBY
end

it 'does not register an offense when using `<=`' do
expect_no_offenses(<<~RUBY)
Class <= Kernel
RUBY
end
end

0 comments on commit bf55013

Please sign in to comment.