Skip to content
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

Detect top-level constant usage like ::Const #8245

Merged
merged 25 commits into from Jul 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
26ccdbe
Detect ::Class.new in EnforceSuperclass mixin
biinari Jul 2, 2020
3bd40a2
Detect top-level ::RUBY_VERSION in gemspec
biinari Jul 6, 2020
6a6894b
Detect top-level constants in NestedMethodDefinition
biinari Jul 6, 2020
ffd8967
Detect ::Dir in NonDeterministicRequireOrder
biinari Jul 6, 2020
04fd2cf
Detect ::Kernel.rand(1)
biinari Jul 6, 2020
85f97f0
Detect redundant ::Array splat
biinari Jul 6, 2020
df92aba
Allow ::NotImplementedError in UnusedMethodArgument
biinari Jul 6, 2020
20ab208
Detect top-level constants in UselessAccessModifier
biinari Jul 6, 2020
5ebcd0b
Detect top-level constants in class/module length cops
biinari Jul 6, 2020
547944b
Allow historic DateTime with ::Date constant
biinari Jul 6, 2020
94c7fd2
Detect top-level ::File in Style/Dir
biinari Jul 6, 2020
228be74
Detect top-level constants in Style/EmptyLiteral
biinari Jul 6, 2020
4879751
Detect ::Proc.new in Style/Proc
biinari Jul 6, 2020
8f80503
Detect ::StandardError in Style/RescueStandardError
biinari Jul 6, 2020
d1ddff6
Detect ::Kernel in Style/SignalException
biinari Jul 6, 2020
4f07167
Detect ::STDERR in Style/StderrPuts
biinari Jul 6, 2020
c2e4ee7
Detect ::Struct in Style/StructInheritance
biinari Jul 6, 2020
c450998
Allow ::Proc.new with arg in Style/SymbolProc
biinari Jul 6, 2020
8b7f481
Allow top-level const in Style/ZeroLengthPredicate
biinari Jul 6, 2020
e2210d6
Detect ::ENV in Style/RedundantFreeze
biinari Jul 6, 2020
d37f461
Detect redundant ::RuntimeError in raise/fail
biinari Jul 6, 2020
ed8ffe3
Detect top-level const in RandomWithOffset
biinari Jul 6, 2020
3d9d75a
Detect top-level const in ExpandPathArguments
biinari Jul 6, 2020
ba1892e
Allow top-level const in MutableConst
biinari Jul 6, 2020
ffd3432
Changelog entry for #8245
biinari Jul 6, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -25,6 +25,7 @@
* [#8156](https://github.com/rubocop-hq/rubocop/issues/8156): **(Breaking)** `rubocop -a / --autocorrect` no longer run unsafe corrections; `rubocop -A / --autocorrect-all` run both safe and unsafe corrections. Options `--safe-autocorrect` is deprecated. ([@marcandre][])
* [#8207](https://github.com/rubocop-hq/rubocop/pull/8207): **(Breaking)** Order for gems names now disregards underscores and dashes unless `ConsiderPunctuation` setting is set to `true`. ([@marcandre][])
* [#8211](https://github.com/rubocop-hq/rubocop/pull/8211): `Style/ClassVars` cop now detects `class_variable_set`. ([@biinari][])
* [#8245](https://github.com/rubocop-hq/rubocop/pull/8245): Detect top-level constants like `::Const` in various cops. ([@biinari][])

## 0.86.0 (2020-06-22)

Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb
Expand Up @@ -28,7 +28,7 @@ module Gemspec
class RubyVersionGlobalsUsage < Cop
MSG = 'Do not use `RUBY_VERSION` in gemspec file.'

def_node_matcher :ruby_version?, '(const nil? :RUBY_VERSION)'
def_node_matcher :ruby_version?, '(const {cbase nil?} :RUBY_VERSION)'

def_node_search :gem_specification?, <<~PATTERN
(block
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/lint/nested_method_definition.rb
Expand Up @@ -96,7 +96,7 @@ def scoping_method_call?(child)
PATTERN

def_node_matcher :class_or_module_or_struct_new_call?, <<~PATTERN
(block (send (const nil? {:Class :Module :Struct}) :new ...) ...)
(block (send (const {nil? cbase} {:Class :Module :Struct}) :new ...) ...)
PATTERN
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/lint/non_deterministic_require_order.rb
Expand Up @@ -69,11 +69,11 @@ def unsorted_dir_loop?(node)
end

def_node_matcher :unsorted_dir_block?, <<~PATTERN
(send (const nil? :Dir) :glob ...)
(send (const {nil? cbase} :Dir) :glob ...)
PATTERN

def_node_matcher :unsorted_dir_each?, <<~PATTERN
(send (send (const nil? :Dir) {:[] :glob} ...) :each)
(send (send (const {nil? cbase} :Dir) {:[] :glob} ...) :each)
PATTERN

def_node_matcher :loop_variable, <<~PATTERN
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/lint/rand_one.rb
Expand Up @@ -25,7 +25,7 @@ class RandOne < Cop
'Perhaps you meant `rand(2)` or `rand`?'

def_node_matcher :rand_one?, <<~PATTERN
(send {(const nil? :Kernel) nil?} :rand {(int {-1 1}) (float {-1.0 1.0})})
(send {(const {nil? cbase} :Kernel) nil?} :rand {(int {-1 1}) (float {-1.0 1.0})})
PATTERN

def on_send(node)
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/lint/redundant_splat_expansion.rb
Expand Up @@ -60,8 +60,8 @@ class RedundantSplatExpansion < Cop

def_node_matcher :array_new?, <<~PATTERN
{
$(send (const nil? :Array) :new ...)
$(block (send (const nil? :Array) :new ...) ...)
$(send (const {nil? cbase} :Array) :new ...)
$(block (send (const {nil? cbase} :Array) :new ...) ...)
}
PATTERN

Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/lint/unused_method_argument.rb
Expand Up @@ -62,7 +62,7 @@ class UnusedMethodArgument < Cop
include UnusedArgument

def_node_matcher :not_implemented?, <<~PATTERN
{(send nil? :raise (const nil? :NotImplementedError))
{(send nil? :raise (const {nil? cbase} :NotImplementedError))
(send nil? :fail ...)}
PATTERN

Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/lint/useless_access_modifier.rb
Expand Up @@ -172,7 +172,7 @@ def autocorrect(node)
PATTERN

def_node_matcher :class_or_module_or_struct_new_call?, <<~PATTERN
(block (send (const nil? {:Class :Module :Struct}) :new ...) ...)
(block (send (const {nil? cbase} {:Class :Module :Struct}) :new ...) ...)
PATTERN

def check_node(node)
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/metrics/class_length.rb
Expand Up @@ -22,7 +22,7 @@ def on_casgn(node)
private

def_node_matcher :class_definition?, <<~PATTERN
(casgn nil? _ (block (send (const nil? :Class) :new) ...))
(casgn nil? _ (block (send (const {nil? cbase} :Class) :new) ...))
PATTERN

def message(length, max_length)
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/metrics/module_length.rb
Expand Up @@ -22,7 +22,7 @@ def on_casgn(node)
private

def_node_matcher :module_definition?, <<~PATTERN
(casgn nil? _ (block (send (const nil? :Module) :new) ...))
(casgn nil? _ (block (send (const {nil? cbase} :Module) :new) ...))
PATTERN

def message(length, max_length)
Expand Down
4 changes: 3 additions & 1 deletion lib/rubocop/cop/mixin/enforce_superclass.rb
Expand Up @@ -10,7 +10,9 @@ def self.included(base)
PATTERN

base.def_node_matcher :class_new_definition, <<~PATTERN
[!^(casgn nil? :#{base::SUPERCLASS} ...) (send (const nil? :Class) :new #{base::BASE_PATTERN})]
[!^(casgn {nil? cbase} :#{base::SUPERCLASS} ...)
!^^(casgn {nil? cbase} :#{base::SUPERCLASS} (block ...))
(send (const {nil? cbase} :Class) :new #{base::BASE_PATTERN})]
PATTERN
end

Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/style/date_time.rb
Expand Up @@ -50,7 +50,7 @@ class DateTime < Cop
PATTERN

def_node_matcher :historic_date?, <<~PATTERN
(send _ _ _ (const (const nil? :Date) _))
(send _ _ _ (const (const {nil? (cbase)} :Date) _))
PATTERN

def_node_matcher :to_datetime?, <<~PATTERN
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/style/dir.rb
Expand Up @@ -21,8 +21,8 @@ class Dir < Cop
"file's directory."

def_node_matcher :dir_replacement?, <<~PATTERN
{(send (const nil? :File) :expand_path (send (const nil? :File) :dirname #file_keyword?))
(send (const nil? :File) :dirname (send (const nil? :File) :realpath #file_keyword?))}
{(send (const {nil? cbase} :File) :expand_path (send (const {nil? cbase} :File) :dirname #file_keyword?))
(send (const {nil? cbase} :File) :dirname (send (const {nil? cbase} :File) :realpath #file_keyword?))}
PATTERN

def on_send(node)
Expand Down
10 changes: 5 additions & 5 deletions lib/rubocop/cop/style/empty_literal.rb
Expand Up @@ -25,13 +25,13 @@ class EmptyLiteral < Cop
STR_MSG = 'Use string literal `%<prefer>s` instead of ' \
'`String.new`.'

def_node_matcher :array_node, '(send (const nil? :Array) :new)'
def_node_matcher :hash_node, '(send (const nil? :Hash) :new)'
def_node_matcher :str_node, '(send (const nil? :String) :new)'
def_node_matcher :array_node, '(send (const {nil? cbase} :Array) :new)'
def_node_matcher :hash_node, '(send (const {nil? cbase} :Hash) :new)'
def_node_matcher :str_node, '(send (const {nil? cbase} :String) :new)'
def_node_matcher :array_with_block,
'(block (send (const nil? :Array) :new) args _)'
'(block (send (const {nil? cbase} :Array) :new) args _)'
def_node_matcher :hash_with_block,
'(block (send (const nil? :Hash) :new) args _)'
'(block (send (const {nil? cbase} :Hash) :new) args _)'

def on_send(node)
add_offense(node, message: ARR_MSG) if offense_array_node?(node)
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/style/expand_path_arguments.rb
Expand Up @@ -53,7 +53,7 @@ class ExpandPathArguments < Cop

def_node_matcher :file_expand_path, <<~PATTERN
(send
(const nil? :File) :expand_path
(const {nil? cbase} :File) :expand_path
$_
$_)
PATTERN
Expand All @@ -69,7 +69,7 @@ class ExpandPathArguments < Cop
(send
(send
(send
(const nil? :Pathname) :new
(const {nil? cbase} :Pathname) :new
$_) :parent) :expand_path)
PATTERN

Expand Down
8 changes: 4 additions & 4 deletions lib/rubocop/cop/style/mutable_constant.rb
Expand Up @@ -150,14 +150,14 @@ def correct_splat_expansion(corrector, expr, splat_value)
def_node_matcher :operation_produces_immutable_object?, <<~PATTERN
{
(const _ _)
(send (const nil? :Struct) :new ...)
(block (send (const nil? :Struct) :new ...) ...)
(send (const {nil? cbase} :Struct) :new ...)
(block (send (const {nil? cbase} :Struct) :new ...) ...)
(send _ :freeze)
(send {float int} {:+ :- :* :** :/ :% :<<} _)
(send _ {:+ :- :* :** :/ :%} {float int})
(send _ {:== :=== :!= :<= :>= :< :>} _)
(send (const nil? :ENV) :[] _)
(or (send (const nil? :ENV) :[] _) _)
(send (const {nil? cbase} :ENV) :[] _)
(or (send (const {nil? cbase} :ENV) :[] _) _)
(send _ {:count :length :size} ...)
(block (send _ {:count :length :size} ...) ...)
}
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/style/proc.rb
Expand Up @@ -17,7 +17,7 @@ class Proc < Cop
MSG = 'Use `proc` instead of `Proc.new`.'

def_node_matcher :proc_new?,
'(block $(send (const nil? :Proc) :new) ...)'
'(block $(send (const {nil? cbase} :Proc) :new) ...)'

def on_block(node)
proc_new?(node) do |block_method|
Expand Down
14 changes: 4 additions & 10 deletions lib/rubocop/cop/style/random_with_offset.rb
Expand Up @@ -31,15 +31,15 @@ class RandomWithOffset < Cop
(send
int {:+ :-}
(send
{nil? (const nil? :Random) (const nil? :Kernel)}
{nil? (const {nil? cbase} :Random) (const {nil? cbase} :Kernel)}
:rand
{int irange erange}))
PATTERN

def_node_matcher :rand_op_integer?, <<~PATTERN
(send
(send
{nil? (const nil? :Random) (const nil? :Kernel)}
{nil? (const {nil? cbase} :Random) (const {nil? cbase} :Kernel)}
:rand
{int irange erange})
{:+ :-}
Expand All @@ -49,7 +49,7 @@ class RandomWithOffset < Cop
def_node_matcher :rand_modified?, <<~PATTERN
(send
(send
{nil? (const nil? :Random) (const nil? :Kernel)}
{nil? (const {nil? cbase} :Random) (const {nil? cbase} :Kernel)}
:rand
{int irange erange})
{:succ :pred :next})
Expand Down Expand Up @@ -128,14 +128,8 @@ def corrected_rand_modified(node)
end
end

def_node_matcher :namespace, <<~PATTERN
{$nil? (const nil? $_)}
PATTERN

def prefix_from_prefix_node(node)
namespace(node) do |namespace|
[namespace, 'rand'].compact.join('.')
end
[node&.source, 'rand'].compact.join('.')
end

def boundaries_from_random_node(random_node)
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/style/redundant_exception.rb
Expand Up @@ -52,11 +52,11 @@ def fix_compact(node)
end

def_node_matcher :exploded?, <<~PATTERN
(send nil? ${:raise :fail} (const nil? :RuntimeError) $_)
(send nil? ${:raise :fail} (const {nil? cbase} :RuntimeError) $_)
PATTERN

def_node_matcher :compact?, <<~PATTERN
(send nil? {:raise :fail} $(send (const nil? :RuntimeError) :new $_))
(send nil? {:raise :fail} $(send (const {nil? cbase} :RuntimeError) :new $_))
PATTERN
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/style/redundant_freeze.rb
Expand Up @@ -56,7 +56,7 @@ def strip_parenthesis(node)
(begin (send {float int} {:+ :- :* :** :/ :% :<<} _))
(begin (send !(str _) {:+ :- :* :** :/ :%} {float int}))
(begin (send _ {:== :=== :!= :<= :>= :< :>} _))
(send (const nil? :ENV) :[] _)
(send (const {nil? cbase} :ENV) :[] _)
(send _ {:count :length :size} ...)
(block (send _ {:count :length :size} ...) ...)
}
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/style/rescue_standard_error.rb
Expand Up @@ -85,7 +85,7 @@ class RescueStandardError < Cop
PATTERN

def_node_matcher :rescue_standard_error?, <<~PATTERN
(resbody $(array (const nil? :StandardError)) _ _)
(resbody $(array (const {nil? cbase} :StandardError)) _ _)
PATTERN

def on_resbody(node)
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/style/signal_exception.rb
Expand Up @@ -111,7 +111,7 @@ class SignalException < Cop
RAISE_MSG = 'Use `raise` instead of `fail` to ' \
'rethrow exceptions.'

def_node_matcher :kernel_call?, '(send (const nil? :Kernel) %1 ...)'
def_node_matcher :kernel_call?, '(send (const {nil? cbase} :Kernel) %1 ...)'
def_node_search :custom_fail_methods,
'{(def :fail ...) (defs _ :fail ...)}'

Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/style/stderr_puts.rb
Expand Up @@ -22,7 +22,7 @@ class StderrPuts < Cop

def_node_matcher :stderr_puts?, <<~PATTERN
(send
{(gvar #stderr_gvar?) (const nil? :STDERR)}
{(gvar #stderr_gvar?) (const {nil? cbase} :STDERR)}
:puts $_
...)
PATTERN
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/style/struct_inheritance.rb
Expand Up @@ -41,8 +41,8 @@ def autocorrect(node)
end

def_node_matcher :struct_constructor?, <<~PATTERN
{(send (const nil? :Struct) :new ...)
(block (send (const nil? :Struct) :new ...) ...)}
{(send (const {nil? cbase} :Struct) :new ...)
(block (send (const {nil? cbase} :Struct) :new ...) ...)}
PATTERN

private
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/style/symbol_proc.rb
Expand Up @@ -19,7 +19,7 @@ class SymbolProc < Cop
'instead of a block.'
SUPER_TYPES = %i[super zsuper].freeze

def_node_matcher :proc_node?, '(send (const nil? :Proc) :new)'
def_node_matcher :proc_node?, '(send (const {nil? cbase} :Proc) :new)'
def_node_matcher :symbol_proc?, <<~PATTERN
(block
${(send ...) (super ...) zsuper}
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/style/zero_length_predicate.rb
Expand Up @@ -108,8 +108,8 @@ def replacement(node)
# implement `#size`, but not `#empty`. We ignore those to
# reduce false positives.
def_node_matcher :non_polymorphic_collection?, <<~PATTERN
{(send (send (send (const nil? :File) :stat _) ...) ...)
(send (send (send (const nil? {:Tempfile :StringIO}) {:new :open} ...) ...) ...)}
{(send (send (send (const {nil? cbase} :File) :stat _) ...) ...)
(send (send (send (const {nil? cbase} {:Tempfile :StringIO}) {:new :open} ...) ...) ...)}
PATTERN
end
end
Expand Down
9 changes: 9 additions & 0 deletions spec/rubocop/cop/gemspec/ruby_version_globals_usage_spec.rb
Expand Up @@ -10,6 +10,15 @@
RUBY
end

it 'registers an offense when using `::RUBY_VERSION`' do
expect_offense(<<~RUBY)
Gem::Specification.new do |spec|
::RUBY_VERSION
^^^^^^^^^^^^^^ Do not use `RUBY_VERSION` in gemspec file.
end
RUBY
end

it 'does not register an offense when no `RUBY_VERSION`' do
expect_no_offenses(<<~RUBY)
Gem::Specification.new do |spec|
Expand Down