class Lookbook::Component::Compiler

def compile(force: false)

def compile(force: false)
  return if compiled? && !force
  return if component_class == Lookbook::Component::Base
  component_class.superclass.compile if should_compile_superclass?
  if template_path.present?
    redefinition_lock.synchronize do
      component_class.silence_redefinition_of_method("call")
      # rubocop:disable Style/EvalWithLocation
      component_class.class_eval <<-RUBY, template_path, 0
      def call
        #{compiled_template(template_path)}
      end
      RUBY
      # rubocop:enable Style/EvalWithLocation
    end
  end
  define_render_template_for
  CompileCache.register(component_class)
end

def compile_template(template, handler)

def compile_template(template, handler)
  template.rstrip!
  if handler.method(:call).parameters.length > 1
    handler.call(component_class, template)
  else
    handler.call(
      OpenStruct.new(
        source: template,
        identifier: component_class.identifier,
        type: component_class.type
      )
    )
  end
end

def compiled?

def compiled?
  CompileCache.compiled?(component_class)
end

def compiled_template(file_path)

def compiled_template(file_path)
  handler = ActionView::Template.handler_for_extension(File.extname(file_path).delete("."))
  template = File.read(file_path)
  compile_template(template, handler)
end

def define_render_template_for

def define_render_template_for
  redefinition_lock.synchronize do
    component_class.silence_redefinition_of_method(:render_template)
    component_class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
  def render_template
    call
  end
    RUBY
  end
end

def development?

def development?
  Rails.env.development? || Rails.env.test?
end

def initialize(component_class)

def initialize(component_class)
  @component_class = component_class
  @redefinition_lock = Mutex.new
end

def should_compile_superclass?

def should_compile_superclass?
  development? && template_path.nil? &&
    !(
      component_class.instance_methods(false).include?(:call) ||
        component_class.private_instance_methods(false).include?(:call)
    )
end

def template_path

def template_path
  component_class.template_path
end