Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new
Style/DocumentDynamicEvalDefinition
cop
- Loading branch information
Showing
8 changed files
with
179 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* [#8940](https://github.com/rubocop-hq/rubocop/pull/8940): Add new `Style/DocumentDynamicEvalDefinition` cop. ([@fatkodima][]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# frozen_string_literal: true | ||
|
||
module RuboCop | ||
module Cop | ||
module Style | ||
# When using `class_eval` (or other `eval`) with string interpolation, | ||
# add a comment block showing its appearance if interpolated (a practice used in Rails code). | ||
# | ||
# @example | ||
# # from activesupport/lib/active_support/core_ext/string/output_safety.rb | ||
# | ||
# # bad | ||
# UNSAFE_STRING_METHODS.each do |unsafe_method| | ||
# if 'String'.respond_to?(unsafe_method) | ||
# class_eval <<-EOT, __FILE__, __LINE__ + 1 | ||
# def #{unsafe_method}(*params, &block) | ||
# to_str.#{unsafe_method}(*params, &block) | ||
# end | ||
# | ||
# def #{unsafe_method}!(*params) | ||
# @dirty = true | ||
# super | ||
# end | ||
# EOT | ||
# end | ||
# end | ||
# | ||
# # good | ||
# UNSAFE_STRING_METHODS.each do |unsafe_method| | ||
# if 'String'.respond_to?(unsafe_method) | ||
# class_eval <<-EOT, __FILE__, __LINE__ + 1 | ||
# def #{unsafe_method}(*params, &block) # def capitalize(*params, &block) | ||
# to_str.#{unsafe_method}(*params, &block) # to_str.capitalize(*params, &block) | ||
# end # end | ||
# | ||
# def #{unsafe_method}!(*params) # def capitalize!(*params) | ||
# @dirty = true # @dirty = true | ||
# super # super | ||
# end # end | ||
# EOT | ||
# end | ||
# end | ||
# | ||
class DocumentDynamicEvalDefinition < Base | ||
MSG = 'Add a comment block showing its appearance if interpolated.' | ||
|
||
RESTRICT_ON_SEND = %i[eval class_eval module_eval instance_eval].freeze | ||
|
||
def on_send(node) | ||
arg_node = node.first_argument | ||
return unless arg_node&.dstr_type? | ||
|
||
add_offense(node.loc.selector) unless comment_docs?(arg_node) | ||
end | ||
|
||
private | ||
|
||
def comment_docs?(node) | ||
node.each_child_node(:begin).all? do |begin_node| | ||
source_line = processed_source.lines[begin_node.first_line - 1] | ||
source_line.match?(/\s*#[^{]+/) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
36 changes: 36 additions & 0 deletions
36
spec/rubocop/cop/style/document_dynamic_eval_definition_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# frozen_string_literal: true | ||
|
||
RSpec.describe RuboCop::Cop::Style::DocumentDynamicEvalDefinition do | ||
subject(:cop) { described_class.new } | ||
|
||
it 'registers an offense when using eval-type method with string interpolation without comment docs' do | ||
expect_offense(<<~RUBY) | ||
class_eval <<-EOT, __FILE__, __LINE__ + 1 | ||
^^^^^^^^^^ Add a comment block showing its appearance if interpolated. | ||
def \#{unsafe_method}(*params, &block) | ||
to_str.\#{unsafe_method}(*params, &block) | ||
end | ||
EOT | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using eval-type method without string interpolation' do | ||
expect_no_offenses(<<~RUBY) | ||
class_eval <<-EOT, __FILE__, __LINE__ + 1 | ||
def capitalize(*params, &block) | ||
to_str.capitalize(*params, &block) | ||
end | ||
EOT | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using eval-type method with string interpolation with comment docs' do | ||
expect_no_offenses(<<~RUBY) | ||
class_eval <<-EOT, __FILE__, __LINE__ + 1 | ||
def \#{unsafe_method}(*params, &block) # def capitalize(*params, &block) | ||
to_str.\#{unsafe_method}(*params, &block) # to_str.capitalize(*params, &block) | ||
end # end | ||
EOT | ||
RUBY | ||
end | ||
end |