class Tapioca::Gem::Listeners::SorbetTypeVariables

def compile_type_variable_declarations(tree, constant)

def compile_type_variable_declarations(tree, constant)
  # Try to find the type variables defined on this constant, bail if we can't
  type_variables = Runtime::GenericTypeRegistry.lookup_type_variables(constant)
  return unless type_variables
  # Map each type variable to its string representation.
  #
  # Each entry of `type_variables` maps a Module to a String, or
  # is a `has_attached_class!` declaration, and the order they are inserted
  # into the hash is the order they should be defined in the source code.
  type_variable_declarations = type_variables.filter_map do |type_variable|
    node = node_from_type_variable(type_variable)
    next unless node
    tree << node
  end
  return if type_variable_declarations.empty?
  tree << RBI::Extend.new("T::Generic")
end

def ignore?(event)

def ignore?(event)
  event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded)
end

def node_from_type_variable(type_variable)

def node_from_type_variable(type_variable)
  case type_variable.type
  when Tapioca::TypeVariableModule::Type::HasAttachedClass
    RBI::Send.new(type_variable.serialize)
  else
    type_variable_name = type_variable.name
    return unless type_variable_name
    RBI::TypeMember.new(type_variable_name, type_variable.serialize)
  end
end

def on_scope(event)

def on_scope(event)
  constant = event.constant
  node = event.node
  compile_type_variable_declarations(node, constant)
  sclass = RBI::SingletonClass.new
  compile_type_variable_declarations(sclass, singleton_class_of(constant))
  node << sclass if sclass.nodes.length > 1
end