# <!-- rdoc-file=lib/pp.rb -->
# A pretty-printer for Ruby objects.
#
# ## What PP Does
#
# Standard output by #p returns this:
#     #<PP:0x81fedf0 @genspace=#<Proc:0x81feda0>, @group_queue=#<PrettyPrint::GroupQueue:0x81fed3c @queue=[[#<PrettyPrint::Group:0x81fed78 @breakables=[], @depth=0, @break=false>], []]>, @buffer=[], @newline="\n", @group_stack=[#<PrettyPrint::Group:0x81fed78 @breakables=[], @depth=0, @break=false>], @buffer_width=0, @indent=0, @maxwidth=79, @output_width=2, @output=#<IO:0x8114ee4>>
#
# Pretty-printed output returns this:
#     #<PP:0x81fedf0
#      @buffer=[],
#      @buffer_width=0,
#      @genspace=#<Proc:0x81feda0>,
#      @group_queue=
#       #<PrettyPrint::GroupQueue:0x81fed3c
#        @queue=
#         [[#<PrettyPrint::Group:0x81fed78 @break=false, @breakables=[], @depth=0>],
#          []]>,
#      @group_stack=
#       [#<PrettyPrint::Group:0x81fed78 @break=false, @breakables=[], @depth=0>],
#      @indent=0,
#      @maxwidth=79,
#      @newline="\n",
#      @output=#<IO:0x8114ee4>,
#      @output_width=2>
#
# ## Usage
#
#     pp(obj)             #=> obj
#     pp obj              #=> obj
#     pp(obj1, obj2, ...) #=> [obj1, obj2, ...]
#     pp()                #=> nil
#
# Output `obj(s)` to `$>` in pretty printed format.
#
# It returns `obj(s)`.
#
# ## Output Customization
#
# To define a customized pretty printing function for your classes, redefine
# method `#pretty_print(pp)` in the class. Note that `require 'pp'` is needed
# before redefining `#pretty_print(pp)`.
#
# `#pretty_print` takes the `pp` argument, which is an instance of the PP class.
# The method uses #text, #breakable, #nest, #group and #pp to print the object.
#
# ## Pretty-Print JSON
#
# To pretty-print JSON refer to JSON#pretty_generate.
#
# ## Author
# Tanaka Akira <akr@fsij.org>
#
class PP < PrettyPrint
  interface _PrettyPrint
    def pretty_print: (untyped q) -> untyped

    def pretty_print_cycle: (untyped q) -> untyped

    def is_a?: (Module) -> bool
  end

  interface _LeftShift
    def <<: (untyped obj) -> self
  end

  interface _PPMethodsRequired
    def text: (String obj, ?Integer width) -> void

    def breakable: (?String sep, ?Integer width) -> void

    def group: (?Integer indent, ?String open_obj, ?String close_obj, ?Integer open_width, ?Integer close_width) { () -> untyped } -> void
  end

  # <!-- rdoc-file=lib/pp.rb -->
  # Module that defines helper methods for pretty_print.
  #
  module PPMethods : _PPMethodsRequired
    # <!--
    #   rdoc-file=lib/pp.rb
    #   - guard_inspect_key() { || ... }
    # -->
    # Yields to a block and preserves the previous set of objects being printed.
    #
    def guard_inspect_key: () { () -> untyped } -> void

    # <!--
    #   rdoc-file=lib/pp.rb
    #   - check_inspect_key(id)
    # -->
    # Check whether the object_id `id` is in the current buffer of objects to be
    # pretty printed. Used to break cycles in chains of objects to be pretty
    # printed.
    #
    def check_inspect_key: (_PrettyPrint id) -> bool

    # <!--
    #   rdoc-file=lib/pp.rb
    #   - push_inspect_key(id)
    # -->
    # Adds the object_id `id` to the set of objects being pretty printed, so as to
    # not repeat objects.
    #
    def push_inspect_key: (_PrettyPrint id) -> void

    # <!--
    #   rdoc-file=lib/pp.rb
    #   - pop_inspect_key(id)
    # -->
    # Removes an object from the set of objects being pretty printed.
    #
    def pop_inspect_key: (_PrettyPrint id) -> void

    # <!--
    #   rdoc-file=lib/pp.rb
    #   - pp(obj)
    # -->
    # Adds `obj` to the pretty printing buffer using Object#pretty_print or
    # Object#pretty_print_cycle.
    #
    # Object#pretty_print_cycle is used when `obj` is already printed, a.k.a the
    # object reference chain has a cycle.
    #
    def pp: (_PrettyPrint obj) -> untyped

    # <!--
    #   rdoc-file=lib/pp.rb
    #   - object_group(obj) { || ... }
    # -->
    # A convenience method which is same as follows:
    #
    #     group(1, '#<' + obj.class.name, '>') { ... }
    #
    def object_group: (untyped obj) { () -> untyped } -> Integer

    # <!--
    #   rdoc-file=lib/pp.rb
    #   - object_address_group(obj, &block)
    # -->
    # A convenience method, like object_group, but also reformats the Object's
    # object_id.
    #
    def object_address_group: (untyped obj) { () -> untyped } -> Integer

    # <!--
    #   rdoc-file=lib/pp.rb
    #   - comma_breakable()
    # -->
    # A convenience method which is same as follows:
    #
    #     text ','
    #     breakable
    #
    def comma_breakable: () -> void

    # <!--
    #   rdoc-file=lib/pp.rb
    #   - seplist(list, sep=nil, iter_method=:each) { |element| ... }
    # -->
    # Adds a separated list. The list is separated by comma with breakable space, by
    # default.
    #
    # #seplist iterates the `list` using `iter_method`. It yields each object to the
    # block given for #seplist. The procedure `separator_proc` is called between
    # each yields.
    #
    # If the iteration is zero times, `separator_proc` is not called at all.
    #
    # If `separator_proc` is nil or not given, +lambda { comma_breakable }+ is used.
    # If `iter_method` is not given, :each is used.
    #
    # For example, following 3 code fragments has similar effect.
    #
    #     q.seplist([1,2,3]) {|v| xxx v }
    #
    #     q.seplist([1,2,3], lambda { q.comma_breakable }, :each) {|v| xxx v }
    #
    #     xxx 1
    #     q.comma_breakable
    #     xxx 2
    #     q.comma_breakable
    #     xxx 3
    #
    def seplist: (untyped list, ?(^() -> void)? sep, ?interned iter_method) { (*untyped, **untyped) -> void } -> void

    # <!--
    #   rdoc-file=lib/pp.rb
    #   - pp_object(obj)
    # -->
    # A present standard failsafe for pretty printing any given Object
    #
    def pp_object: (untyped obj) -> untyped

    # <!--
    #   rdoc-file=lib/pp.rb
    #   - pp_hash(obj)
    # -->
    # A pretty print for a Hash
    #
    def pp_hash: (untyped obj) -> untyped
  end
  include PPMethods

  class SingleLine < ::PrettyPrint::SingleLine
    include PPMethods
  end

  module ObjectMixin : BasicObject
    def pretty_print: (PP q) -> untyped

    def pretty_print_cycle: (PP q) -> untyped

    def pretty_print_instance_variables: () -> Array[Symbol]

    def pretty_print_inspect: () -> untyped
  end

  # <!--
  #   rdoc-file=lib/pp.rb
  #   - width_for(out)
  # -->
  # Returns the usable width for `out`. As the width of `out`:
  # 1.  If `out` is assigned to a tty device, its width is used.
  # 2.  Otherwise, or it could not get the value, the `COLUMN` environment
  #     variable is assumed to be set to the width.
  # 3.  If `COLUMN` is not set to a non-zero number, 80 is assumed.
  #
  # And finally, returns the above width value - 1.
  # *   This -1 is for Windows command prompt, which moves the cursor to the next
  #     line if it reaches the last column.
  #
  def self.width_for: (untyped out) -> Integer

  # <!--
  #   rdoc-file=lib/pp.rb
  #   - pp(obj, out=$>, width=width_for(out))
  # -->
  # Outputs `obj` to `out` in pretty printed format of `width` columns in width.
  #
  # If `out` is omitted, `$>` is assumed. If `width` is omitted, the width of
  # `out` is assumed (see width_for).
  #
  # PP.pp returns `out`.
  #
  def self.pp: (_PrettyPrint obj, ?_LeftShift out, ?Integer width) -> untyped

  # <!--
  #   rdoc-file=lib/pp.rb
  #   - singleline_pp(obj, out=$>)
  # -->
  # Outputs `obj` to `out` like PP.pp but with no indent and newline.
  #
  # PP.singleline_pp returns `out`.
  #
  def self.singleline_pp: (_PrettyPrint obj, ?_LeftShift out) -> untyped
  def self.mcall: (untyped obj, Module mod, interned meth, *untyped args) ?{ (*untyped, **untyped) -> untyped } -> untyped

  # <!--
  #   rdoc-file=lib/pp.rb
  #   - sharing_detection()
  # -->
  # Returns the sharing detection flag as a boolean value. It is false (nil) by
  # default.
  # ----
  # <!--
  #   rdoc-file=lib/pp.rb
  #   - sharing_detection=(b)
  # -->
  # Sets the sharing detection flag to b.
  #
  attr_accessor self.sharing_detection: bool?
end

%a{annotate:rdoc:skip}
class RubyVM::AbstractSyntaxTree::Node
  # <!--
  #   rdoc-file=lib/pp.rb
  #   - pretty_print_children(q, names = [])
  # -->
  #
  def pretty_print_children: (PP q, ?Array[untyped] names) -> void
end

%a{annotate:rdoc:skip}
class Object
  include PP::ObjectMixin
end

%a{annotate:rdoc:skip}
module Kernel
  # <!--
  #   rdoc-file=lib/pp.rb
  #   - pretty_inspect()
  # -->
  # Returns a pretty printed object as a string.
  #
  # See the PP module for more information.
  #
  def pretty_inspect: () -> String
end
