class Tapioca::Compilers::DslCompiler

Attributes

error_handler[R]
generators[R]
requested_constants[R]

Public Class Methods

new(requested_constants:, requested_generators: [], excluded_generators: [], error_handler: nil) click to toggle source
# File lib/tapioca/compilers/dsl_compiler.rb, line 28
def initialize(requested_constants:, requested_generators: [], excluded_generators: [], error_handler: nil)
  @generators = T.let(
    gather_generators(requested_generators, excluded_generators),
    T::Enumerable[Dsl::Base]
  )
  @requested_constants = requested_constants
  @error_handler = T.let(error_handler || $stderr.method(:puts), T.proc.params(error: String).void)
end

Public Instance Methods

run(&blk) click to toggle source
# File lib/tapioca/compilers/dsl_compiler.rb, line 38
      def run(&blk)
        constants_to_process = gather_constants(requested_constants)

        if constants_to_process.empty?
          report_error(<<~ERROR)
            No classes/modules can be matched for RBI generation.
            Please check that the requested classes/modules include processable DSL methods.
          ERROR
        end

        constants_to_process.sort_by { |c| c.name.to_s }.each do |constant|
          rbi = rbi_for_constant(constant)
          next if rbi.nil?

          blk.call(constant, rbi)
        end
      end

Private Instance Methods

gather_constants(requested_constants) click to toggle source
# File lib/tapioca/compilers/dsl_compiler.rb, line 74
def gather_constants(requested_constants)
  constants = generators.map(&:processable_constants).reduce(Set.new, :union)
  constants &= requested_constants unless requested_constants.empty?
  constants
end
gather_generators(requested_generators, excluded_generators) click to toggle source
# File lib/tapioca/compilers/dsl_compiler.rb, line 64
def gather_generators(requested_generators, excluded_generators)
  generator_klasses = ::Tapioca::Reflection.descendants_of(Dsl::Base).select do |klass|
    (requested_generators.empty? || requested_generators.include?(klass)) &&
      !excluded_generators.include?(klass)
  end.sort_by { |klass| T.must(klass.name) }

  generator_klasses.map(&:new)
end
rbi_for_constant(constant) click to toggle source
# File lib/tapioca/compilers/dsl_compiler.rb, line 81
def rbi_for_constant(constant)
  file = RBI::File.new(strictness: "true")

  generators.each do |generator|
    next unless generator.handles?(constant)
    generator.decorate(file.root, constant)
  end

  return if file.root.empty?

  file.root.nest_non_public_methods!
  file.root.group_nodes!
  file.root.sort_nodes!
  file.string
end
report_error(error) click to toggle source
# File lib/tapioca/compilers/dsl_compiler.rb, line 98
def report_error(error)
  handler = error_handler
  handler.call(error)
  exit(1)
end