module RBS
  class Subtractor
    type decl_with_members = AST::Declarations::Class | AST::Declarations::Module

    @minuend: Array[AST::Declarations::t]
    @subtrahend: Environment

    def initialize: (Array[AST::Declarations::t] minuend, Environment subtrahend) -> void

    def call: (?Array[AST::Declarations::t], ?context: Resolver::context) -> Array[AST::Declarations::t]

    private def filter_members: (decl_with_members, context: Resolver::context) -> decl_with_members?

    private def member_exist?: (TypeName owner, AST::Members::t, context: Resolver::context) -> boolish

    private def method_exist?: (TypeName owner, Symbol method_name, AST::Members::MethodDefinition::kind) -> boolish

    private def ivar_exist?: (TypeName owner, Symbol ivar_name, AST::Members::Attribute::kind) -> boolish

    private def cvar_exist?: (TypeName owner, Symbol cvar_name) -> boolish

    private def each_member: (TypeName owner) { (AST::Members::t | AST::Declarations::t) -> void } -> void
                           | (TypeName owner) -> Enumerator[(AST::Members::t | AST::Declarations::t), void]

    private def mixin_exist?: (TypeName owner, AST::Members::Include | AST::Members::Extend | AST::Members::Prepend, context: Resolver::context) -> boolish

    private def filter_redundunt_access_modifiers: (Array[AST::Declarations::t | AST::Members::t]) -> Array[AST::Declarations::t | AST::Members::t]

    private def access_modifier?: (AST::Declarations::t | AST::Members::t?) -> bool

    private def update_decl: (decl_with_members, members: Array[AST::Declarations::t | AST::Members::t]) -> decl_with_members

    private def absolute_typename: (TypeName, context: Resolver::context) -> TypeName

    private def typename_candidates: (TypeName, context: Resolver::context) -> Array[TypeName]
  end
end
