rubocop-thread_safety icon indicating copy to clipboard operation
rubocop-thread_safety copied to clipboard

Detect class_eval as class context

Open biinari opened this issue 4 years ago • 0 comments

When checking for class / module context, detect class_eval, module_eval, class_exec, module_exec. The class_* variants are aliases of the module_* variants. It should however be safe to assume class_* would be called on a class and module_* would be called on a module.

I don't think it is worth looking at class_eval or module_eval when given a string argument. Just interested in when any of these are given a block.

A reduced example that inspired this thought:

class Example
  class << self
    attr_reader :separator
  end
end

def separate_with(separator)
  Example.class_eval do
    @separator = separator
  end
end

Given there are multiple cops that need to check for the first class / module context, I think it would be useful to create a mixin module to help with the search. Something like

module RuboCop
  module Cop
    module ThreadSafety
      module Mixin
        module ClassModuleContext
          # return first class or module context in node's ancestors
          def find_context(node)
            # return first node that is a class, module, class_eval, module_eval or similar
          end

          def class_context?(node)
            # return true if node is a class context
          end

          def module_context?(node)
            # return true if node is a module context
          end
        end
      end
    end
  end
end

biinari avatar Jun 29 '20 17:06 biinari