Skip to content

Instantly share code, notes, and snippets.

@silvamerica
Created February 1, 2019 02:59
Show Gist options
  • Save silvamerica/5e73f13fef9bdae845fbae278daf14bd to your computer and use it in GitHub Desktop.
Save silvamerica/5e73f13fef9bdae845fbae278daf14bd to your computer and use it in GitHub Desktop.
Singleton Class Include Cop
module RuboCop
module Cop
module Security
# This cop checks for includes/extends/prepends inside of
# class << self blocks
#
# @example
#
# # bad
#
# class User
# class << self
# include SharedFunctionality
# end
# end
#
# @example
#
# # good
#
# class User
# include SharedFunctionality
# class << self
# end
# end
#
class SingletonClassInclude < Cop
MSG = '`%<statement>s` is used inside of `class << self`. Use inside `class` ' \
'or `module`.'.freeze
def_node_matcher :include_statement, <<-PATTERN
(send nil? ${:include :extend :prepend}
const)
PATTERN
def on_send(node)
include_statement(node) do |statement|
add_offense(node, message: format(MSG, statement: statement)) if belongs_to_sclass_block?(node)
end
end
private
def belongs_to_sclass_block?(node)
if !node.parent
false
else
return true if node.parent.sclass_type?
belongs_to_sclass_block?(node.parent)
end
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment