class RBS::CLI::Validate

def validate_class_module_definition

def validate_class_module_definition
  @env.class_decls.each do |name, entry|
    RBS.logger.info "Validating class/module definition: `#{name}`..."
    @builder.build_instance(name).each_type do |type|
      @validator.validate_type type, context: nil
    rescue BaseError => error
      @errors.add(error)
    end
    @builder.build_singleton(name).each_type do |type|
      @validator.validate_type type, context: nil
    rescue BaseError => error
      @errors.add(error)
    end
    case entry
    when Environment::ClassEntry
      entry.decls.each do |decl|
        if super_class = decl.decl.super_class
          super_class.args.each do |arg|
            void_type_context_validator(arg, true)
            no_self_type_validator(arg)
            no_classish_type_validator(arg)
            @validator.validate_type(arg, context: nil)
          end
        end
      end
    when Environment::ModuleEntry
      entry.decls.each do |decl|
        decl.decl.self_types.each do |self_type|
          self_type.args.each do |arg|
            void_type_context_validator(arg, true)
            no_self_type_validator(arg)
            no_classish_type_validator(arg)
            @validator.validate_type(arg, context: nil)
          end
          self_params =
            if self_type.name.class?
              @env.normalized_module_entry(self_type.name)&.type_params
            else
              @env.interface_decls[self_type.name]&.decl&.type_params
            end
          if self_params
            InvalidTypeApplicationError.check!(type_name: self_type.name, params: self_params, args: self_type.args, location: self_type.location)
          end
        end
      end
    end
    d = entry.primary.decl
    @validator.validate_type_params(
      d.type_params,
      type_name: name,
      location: d.location&.aref(:type_params)
    )
    d.type_params.each do |param|
      if ub = param.upper_bound_type
        void_type_context_validator(ub)
        no_self_type_validator(ub)
        no_classish_type_validator(ub)
        @validator.validate_type(ub, context: nil)
      end
      if dt = param.default_type
        void_type_context_validator(dt, true)
        no_self_type_validator(dt)
        no_classish_type_validator(dt)
        @validator.validate_type(dt, context: nil)
      end
    end
    TypeParamDefaultReferenceError.check!(d.type_params)
    entry.decls.each do |d|
      d.decl.each_member do |member|
        case member
        when AST::Members::MethodDefinition
          @validator.validate_method_definition(member, type_name: name)
          member.overloads.each do |ov|
            void_type_context_validator(ov.method_type)
          end
        when AST::Members::Attribute
          void_type_context_validator(member.type)
        when AST::Members::Mixin
          member.args.each do |arg|
            no_self_type_validator(arg)
            unless arg.is_a?(Types::Bases::Void)
              void_type_context_validator(arg, true)
            end
          end
          params =
            if member.name.class?
              module_decl = @env.normalized_module_entry(member.name) or raise
              module_decl.type_params
            else
              interface_decl = @env.interface_decls.fetch(member.name)
              interface_decl.decl.type_params
            end
          InvalidTypeApplicationError.check!(type_name: member.name, params: params, args: member.args, location: member.location)
        when AST::Members::Var
          @validator.validate_variable(member)
          void_type_context_validator(member.type)
          if member.is_a?(AST::Members::ClassVariable)
            no_self_type_validator(member.type)
          end
        end
      end
    end
  rescue BaseError => error
    @errors.add(error)
  end
end