class Dry::Schema::Info::SchemaCompiler

@api private

def assign_type(key, type)

Other tags:
    Api: - private
def assign_type(key, type)
  if keys[key][:type]
    keys[key][:member] = type
  else
    keys[key][:type] = type
  end
end

def call(ast)

Other tags:
    Api: - private
def call(ast)
  visit(ast)
end

def initialize

Other tags:
    Api: - private
def initialize
  @keys = EMPTY_HASH.dup
end

def to_h

Other tags:
    Api: - private
def to_h
  {keys: keys}
end

def visit(node, opts = EMPTY_HASH)

Other tags:
    Api: - private
def visit(node, opts = EMPTY_HASH)
  meth, rest = node
  public_send(:"visit_#{meth}", rest, opts)
end

def visit_and(node, opts = EMPTY_HASH)

Other tags:
    Api: - private
def visit_and(node, opts = EMPTY_HASH)
  left, right = node
  visit(left, opts)
  visit(right, opts)
end

def visit_each(node, opts = EMPTY_HASH)

Other tags:
    Api: - private
def visit_each(node, opts = EMPTY_HASH)
  visit(node, opts.merge(member: true))
end

def visit_implication(node, opts = EMPTY_HASH)

Other tags:
    Api: - private
def visit_implication(node, opts = EMPTY_HASH)
  node.each do |el|
    visit(el, opts.merge(required: false))
  end
end

def visit_key(node, opts = EMPTY_HASH)

Other tags:
    Api: - private
def visit_key(node, opts = EMPTY_HASH)
  name, rest = node
  visit(rest, opts.merge(key: name, required: true))
end

def visit_predicate(node, opts = EMPTY_HASH)

Other tags:
    Api: - private
def visit_predicate(node, opts = EMPTY_HASH)
  name, rest = node
  key = opts[:key]
  if name.equal?(:key?)
    keys[rest[0][1]] = {required: opts.fetch(:required, true)}
  else
    type = PREDICATE_TO_TYPE[name]
    assign_type(key, type) if type
  end
end

def visit_set(node, opts = EMPTY_HASH)

Other tags:
    Api: - private
def visit_set(node, opts = EMPTY_HASH)
  target = (key = opts[:key]) ? self.class.new : self
  node.each { |child| target.visit(child, opts) }
  return unless key
  target_info = opts[:member] ? {member: target.to_h} : target.to_h
  type = opts[:member] ? "array" : "hash"
  keys.update(key => {**keys[key], type: type, **target_info})
end