# typed: strict# frozen_string_literal: truemoduleTapiocamoduleDslclassPipelineextendT::Sig#: T::Enumerable[singleton(Compiler)]attr_reader:active_compilers#: Array[Module]attr_reader:requested_constants#: Array[Pathname]attr_reader:requested_paths#: Array[Module]attr_reader:skipped_constants#: ^(String error) -> voidattr_reader:error_handler#: Array[String]attr_reader:errors#: (requested_constants: Array[Module], ?requested_paths: Array[Pathname], ?requested_compilers: Array[singleton(Compiler)], ?excluded_compilers: Array[singleton(Compiler)], ?error_handler: ^(String error) -> void, ?skipped_constants: Array[Module], ?number_of_workers: Integer?, ?compiler_options: Hash[String, untyped], ?lsp_addon: bool) -> voiddefinitialize(requested_constants:,requested_paths: [],requested_compilers: [],excluded_compilers: [],error_handler: $stderr.method(:puts).to_proc,skipped_constants: [],number_of_workers: nil,compiler_options: {},lsp_addon: false)@active_compilers=gather_active_compilers(requested_compilers,excluded_compilers)#: Enumerable[singleton(Compiler)]@requested_constants=requested_constants@requested_paths=requested_paths@error_handler=error_handler@skipped_constants=skipped_constants@number_of_workers=number_of_workers@compiler_options=compiler_options@lsp_addon=lsp_addon@errors=[]#: Array[String]end#: [T] { (Module constant, RBI::File rbi) -> T } -> Array[T]defrun(&blk)constants_to_process=gather_constants(requested_constants,requested_paths,skipped_constants).select{|c|Module===c}# Filter value constants out.sort_by!{|c|T.must(Runtime::Reflection.name_of(c))}# It's OK if there are no constants to process if we received a valid file/path.ifconstants_to_process.empty?&&requested_paths.none?{|p|File.exist?(p)}report_error(<<~ERROR)
No classes/modules can be matched for RBI generation.
Please check that the requested classes/modules include processable DSL methods.
ERRORraiseThor::Error,""endifdefined?(::ActiveRecord::Base)&&constants_to_process.any?{|c|::ActiveRecord::Base>c}abort_if_pending_migrations!endresult=Executor.new(constants_to_process,number_of_workers: @number_of_workers,).run_in_paralleldo|constant|rbi=rbi_for_constant(constant)nextifrbi.nil?blk.call(constant,rbi)endiferrors.any?errors.eachdo|msg|report_error(msg)endraiseThor::Error,""endresult.compactend#: (String error) -> voiddefadd_error(error)@errors<<errorend#: (String compiler_name) -> booldefcompiler_enabled?(compiler_name)potential_names=Compilers::NAMESPACES.map{|namespace|namespace+compiler_name}active_compilers.any?do|compiler|potential_names.any?(compiler.name)endend#: -> Array[singleton(Compiler)]defcompilers@compilers||=Runtime::Reflection.descendants_of(Compiler).sort_bydo|compiler|T.must(compiler.name)end#: Array[singleton(Compiler)]?endprivate#: (Array[singleton(Compiler)] requested_compilers, Array[singleton(Compiler)] excluded_compilers) -> T::Enumerable[singleton(Compiler)]defgather_active_compilers(requested_compilers,excluded_compilers)active_compilers=compilersactive_compilers-=excluded_compilersactive_compilers&=requested_compilersunlessrequested_compilers.empty?active_compilersend#: (Array[Module] requested_constants, Array[Pathname] requested_paths, Array[Module] skipped_constants) -> Set[Module]defgather_constants(requested_constants,requested_paths,skipped_constants)Compiler.requested_constants=requested_constantsconstants=Set.new.compare_by_identityactive_compilers.eachdo|compiler|constants.merge(compiler.processable_constants)endconstants=filter_anonymous_and_reloaded_constants(constants)constants-=skipped_constantsunlessrequested_constants.empty?&&requested_paths.empty?constants&=requested_constantsrequested_and_skipped=requested_constants&skipped_constantsifrequested_and_skipped.any?$stderr.puts("WARNING: Requested constants are being skipped due to configuration:"\"#{requested_and_skipped}. Check the supplied arguments and your `sorbet/tapioca/config.yml` file.")endendconstantsend#: (Set[Module] constants) -> Set[Module]deffilter_anonymous_and_reloaded_constants(constants)# Group constants by their namesconstants_by_name=constants.group_by{|c|Runtime::Reflection.name_of(c)}.select{|name,_|!name.nil?}constants_by_name=T.cast(constants_by_name,T::Hash[String,T::Array[Module]])# Find the constants that have been reloadedreloaded_constants=constants_by_name.select{|_,constants|constants.size>1}.keysunlessreloaded_constants.empty?||@lsp_addonreloaded_constant_names=reloaded_constants.map{|name|"`#{name}`"}.join(", ")$stderr.puts("WARNING: Multiple constants with the same name: #{reloaded_constant_names}")$stderr.puts("Make sure some object is not holding onto these constants during an app reload.")end# Look up all the constants back from their names. The resulting constant set will be the# set of constants that are actually in memory with those names.filtered_constants=constants_by_name.keys.map{|name|T.cast(Runtime::Reflection.constantize(name),Module)}.select{|mod|Runtime::Reflection.constant_defined?(mod)}Set.new.compare_by_identity.merge(filtered_constants)end#: (Module constant) -> RBI::File?defrbi_for_constant(constant)file=RBI::File.new(strictness: "true")active_compilers.eachdo|compiler_class|nextunlesscompiler_class.handles?(constant)compiler=compiler_class.new(self,file.root,constant,@compiler_options)compiler.decoraterescue$stderr.puts("Error: `#{compiler_class.name}` failed to generate RBI for `#{constant}`")raise# This is an unexpected error, so re-raise itendreturniffile.root.empty?fileend#: (String error) -> voiddefreport_error(error)handler=error_handlerhandler.call(error)end#: -> voiddefabort_if_pending_migrations!# When running within the add-on, we cannot invoke the abort if pending migrations task because that will exit# the process and crash the Rails runtime server. Instead, the Rails add-on checks for pending migrations and# warns the user, so that they are aware they need to migrate their databasereturnif@lsp_addonreturnunlessdefined?(::Rake)Rails.application.load_tasksifRake::Task.task_defined?("db:abort_if_pending_migrations")Rake::Task["db:abort_if_pending_migrations"].invokeendendendendend