Skip to content

Commit

Permalink
Support autocorrection for Naming/InclusiveLanguage
Browse files Browse the repository at this point in the history
This PR makes `Naming/InclusiveLanguage` support autocorrection
when there is only one suggestion.
When there are multiple suggestions, the best suggestion cannot be
identified and will not be autocorrected.
  • Loading branch information
koic authored and bbatsov committed Mar 18, 2023
1 parent 6c4579f commit 09e71c2
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#11703](https://github.com/rubocop/rubocop/pull/11703): Make `Naming/InclusiveLanguage` support autocorrection when there is only one suggestion. ([@koic][])
2 changes: 1 addition & 1 deletion config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2779,7 +2779,7 @@ Naming/InclusiveLanguage:
Description: 'Recommend the use of inclusive language instead of problematic terms.'
Enabled: false
VersionAdded: '1.18'
VersionChanged: '1.21'
VersionChanged: '<<next>>'
CheckIdentifiers: true
CheckConstants: true
CheckVariables: true
Expand Down
23 changes: 20 additions & 3 deletions lib/rubocop/cop/naming/inclusive_language.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ module Naming
# `WholeWord: true` can be set on a flagged term to indicate the cop should only match when
# a term matches the whole word (partial matches will not be offenses).
#
# The cop supports autocorrection when there is only one suggestion. When there are multiple
# suggestions, the best suggestion cannot be identified and will not be autocorrected.
#
# @example FlaggedTerms: { whitelist: { Suggestions: ['allowlist'] } }
# # Suggest replacing identifier whitelist with allowlist
#
Expand Down Expand Up @@ -68,6 +71,7 @@ module Naming
# TeslaVehicle
class InclusiveLanguage < Base
include RangeHelp
extend AutoCorrector

EMPTY_ARRAY = [].freeze
MSG = "Consider replacing '%<term>s'%<suffix>s."
Expand Down Expand Up @@ -104,9 +108,16 @@ def investigate_tokens

def add_offenses_for_token(token, word_locations)
word_locations.each do |word_location|
start_position = token.pos.begin_pos + token.pos.source.index(word_location.word)
range = range_between(start_position, start_position + word_location.word.length)
add_offense(range, message: create_message(word_location.word))
word = word_location.word
range = offense_range(token, word)

add_offense(range, message: create_message(word)) do |corrector|
suggestions = find_flagged_term(word)['Suggestions']

next unless suggestions.is_a?(String)

corrector.replace(range, suggestions)
end
end
end

Expand Down Expand Up @@ -264,6 +275,12 @@ def format_suggestions(suggestions)
end
" with #{suggestion_str}"
end

def offense_range(token, word)
start_position = token.pos.begin_pos + token.pos.source.index(word)

range_between(start_position, start_position + word.length)
end
end
end
end
Expand Down
44 changes: 44 additions & 0 deletions spec/rubocop/cop/naming/inclusive_language_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
whitelist = %w(user1 user2)
^^^^^^^^^ Consider replacing 'whitelist' with another term.
RUBY

expect_no_corrections
end

it 'registers an offense when using a flagged term with mixed case' do
Expand All @@ -19,6 +21,8 @@ class WhiteList
^^^^^^^^^ Consider replacing 'WhiteList' with another term.
end
RUBY

expect_no_corrections
end

it 'registers an offense for a partial word match' do
Expand All @@ -27,6 +31,8 @@ class Nodewhitelist
^^^^^^^^^ Consider replacing 'whitelist' with another term.
end
RUBY

expect_no_corrections
end

context 'disable default flagged term' do
Expand All @@ -39,6 +45,8 @@ class Nodewhitelist
# working on replacing whitelist and blacklist
^^^^^^^^^ Consider replacing 'blacklist' with another term.
RUBY

expect_no_corrections
end
end

Expand All @@ -56,6 +64,8 @@ class Nodewhitelist
^^^^^ Consider replacing 'slave' with 'replica', 'secondary', or 'follower'.
^^^^^^ Consider replacing 'master' with 'main', 'primary', or 'leader'.
RUBY

expect_no_corrections
end
end

Expand All @@ -69,6 +79,8 @@ class Nodewhitelist
# white-list of IPs
^^^^^^^^^^ Consider replacing 'white-list' with another term.
RUBY

expect_no_corrections
end
end

Expand Down Expand Up @@ -98,6 +110,8 @@ class Nodewhitelist
'database@slave'
^^^^^ Consider replacing 'slave' with another term.
RUBY

expect_no_corrections
end
end
end
Expand Down Expand Up @@ -128,6 +142,8 @@ class Nodewhitelist
barx, foo = method_call
^^^ Consider replacing 'foo' with another term.
RUBY

expect_no_corrections
end
end
end
Expand All @@ -145,6 +161,10 @@ class Nodewhitelist
whitelist = %w(user1 user2)
^^^^^^^^^ Consider replacing 'whitelist' with 'allowlist'.
RUBY

expect_correction(<<~RUBY)
allowlist = %w(user1 user2)
RUBY
end
end

Expand All @@ -160,6 +180,8 @@ class Nodewhitelist
whitelist = %w(user1 user2)
^^^^^^^^^ Consider replacing 'whitelist' with 'allowlist' or 'permit'.
RUBY

expect_no_corrections
end
end

Expand All @@ -178,6 +200,8 @@ class Nodewhitelist
default_branch = 'master'
^^^^^^ Consider replacing 'master' with 'main', 'primary', or 'leader'.
RUBY

expect_no_corrections
end
end
end
Expand All @@ -195,6 +219,8 @@ class Nodewhitelist
whitelist = %w(user1 user2)
^^^^^^^^^ Consider replacing 'whitelist' with another term.
RUBY

expect_no_corrections
end
end

Expand Down Expand Up @@ -222,20 +248,26 @@ class Nodewhitelist
@whitelist = %w(user1 user2)
^^^^^^^^^ Consider replacing 'whitelist' with another term.
RUBY

expect_no_corrections
end

it 'registers offenses for class variables' do
expect_offense(<<~RUBY)
@@whitelist = %w(user1 user2)
^^^^^^^^^ Consider replacing 'whitelist' with another term.
RUBY

expect_no_corrections
end

it 'registers offenses for global variables' do
expect_offense(<<~RUBY)
$whitelist = %w(user1 user2)
^^^^^^^^^ Consider replacing 'whitelist' with another term.
RUBY

expect_no_corrections
end
end

Expand Down Expand Up @@ -263,6 +295,8 @@ class Nodewhitelist
WHITELIST = %w(user1 user2)
^^^^^^^^^ Consider replacing 'WHITELIST' with another term.
RUBY

expect_no_corrections
end
end

Expand Down Expand Up @@ -300,6 +334,8 @@ class Nodewhitelist
primary
secondary"
RUBY

expect_no_corrections
end

it 'registers an offense in a heredoc' do
Expand All @@ -313,6 +349,8 @@ class Nodewhitelist
secondary
TEXT
RUBY

expect_no_corrections
end

it 'does not register offenses and not raise `ArgumentError` for invalid byte sequence in UTF-8' do
Expand Down Expand Up @@ -345,6 +383,8 @@ class Nodewhitelist
config[:master] = {}
^^^^^^ Consider replacing 'master' with another term.
RUBY

expect_no_corrections
end
end

Expand Down Expand Up @@ -372,6 +412,8 @@ class Nodewhitelist
bar = baz # it's a foo!
^^^ Consider replacing 'foo' with another term.
RUBY

expect_no_corrections
end

it 'registers an offense in a block comment' do
Expand All @@ -382,6 +424,8 @@ class Nodewhitelist
bar
=end
RUBY

expect_no_corrections
end

context 'when CheckComments is false' do
Expand Down

0 comments on commit 09e71c2

Please sign in to comment.