From 7654edc1c995f48406de369bb465e26eaa3b7669 Mon Sep 17 00:00:00 2001 From: Alexander Momchilov Date: Tue, 16 Jun 2026 18:51:59 -0400 Subject: [PATCH] Introduce `Options` object --- .../translate/rbs_comments_to_sorbet_sigs.rb | 24 ++++++- .../base_translator.rb | 33 +++++---- .../human_readable_translator.rb | 1 + .../rbs_comments_to_sorbet_sigs/options.rb | 72 +++++++++++++++++++ rbi/spoom.rbi | 44 ++++++++++-- .../rbs_comments_to_sorbet_sigs_test.rb | 8 ++- 6 files changed, 161 insertions(+), 21 deletions(-) create mode 100644 lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/options.rb diff --git a/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs.rb b/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs.rb index eb652099..20536293 100644 --- a/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs.rb +++ b/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs.rb @@ -24,11 +24,28 @@ def contains_rbs_syntax?(source) Sigils.contains_valid_sigil?(source) && source.match?(RBS_REWRITE_PATTERN) end - #: (String ruby_contents, file: String, ?max_line_length: Integer?, ?overloads_strategy: Symbol) -> String - def rewrite_if_needed(ruby_contents, file:, max_line_length: nil, overloads_strategy: :translate_all) + #: ( + #| String ruby_contents, + #| file: String, + #| ?max_line_length: Integer?, + # :translate_all | :translate_last | :raise + #| ?overloads_strategy: Symbol) -> String + def rewrite_if_needed( + ruby_contents, + file:, + max_line_length: nil, + overloads_strategy: :translate_all + ) return ruby_contents unless contains_rbs_syntax?(ruby_contents) - HumanReadableTranslator.new(ruby_contents, file:, max_line_length:, overloads_strategy:).rewrite + options = Options.new( + overloads_strategy:, + output_format: HumanReadableRBIFormat.new( + max_line_length:, + ), + ) + + HumanReadableTranslator.new(ruby_contents, file:, options:).rewrite end end end @@ -36,4 +53,5 @@ def rewrite_if_needed(ruby_contents, file:, max_line_length: nil, overloads_stra end end +require "spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/options" require "spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/human_readable_translator" diff --git a/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/base_translator.rb b/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/base_translator.rb index 74979c7d..48f8663c 100644 --- a/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/base_translator.rb +++ b/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/base_translator.rb @@ -9,20 +9,29 @@ module RBSCommentsToSorbetSigs class BaseTranslator < Translator include Spoom::RBS::ExtractRBSComments - ALLOWED_OVERLOAD_STRATEGIES = [:translate_all, :translate_last, :raise].freeze #: Array[Symbol] - - #: (String, file: String, ?max_line_length: Integer?, ?overloads_strategy: Symbol) -> void - def initialize(ruby_contents, file:, max_line_length: nil, overloads_strategy: :translate_all) - super(ruby_contents, file: file) - - unless ALLOWED_OVERLOAD_STRATEGIES.include?(overloads_strategy) - raise ArgumentError, "Unknown overloads_strategy: #{overloads_strategy.inspect}. " \ - "Must be one of: #{ALLOWED_OVERLOAD_STRATEGIES.map(&:inspect).join(", ")}" - end + #: (String, file: String, ?options: Options) -> void + def initialize( + ruby_contents, + file:, + options: Options.default + ) + super(ruby_contents, file:) + + @max_line_length = case (format = options.output_format) + when HumanReadableRBIFormat + format.max_line_length #: Integer? + else + nil + end #: Integer? - @max_line_length = max_line_length - @overloads_strategy = overloads_strategy + @overloads_strategy = options.overloads_strategy #: Symbol @type_translator = RBI::RBS::TypeTranslator.new #: RBI::RBS::TypeTranslator + + # @rbs_translator = RBI::RBS::TypeTranslator.new( + # options: RBI::RBS::TypeTranslator::Options.new( + # associate_origin_rbs_nodes: type_translator_should_associate_origin_rbs_nodes + # ) + # ) #: RBI::RBS::TypeTranslator end # @override diff --git a/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/human_readable_translator.rb b/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/human_readable_translator.rb index 30e10484..4c2ba647 100644 --- a/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/human_readable_translator.rb +++ b/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/human_readable_translator.rb @@ -2,6 +2,7 @@ # frozen_string_literal: true require "spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/base_translator" +require "spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/options" module Spoom module Sorbet diff --git a/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/options.rb b/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/options.rb new file mode 100644 index 00000000..6f3d39af --- /dev/null +++ b/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/options.rb @@ -0,0 +1,72 @@ +# typed: strict +# frozen_string_literal: true + +# require "spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/base_translator" + +module Spoom + module Sorbet + module Translate + module RBSCommentsToSorbetSigs + class BaseRBIFormat # TODO: move to RBI gem + end + + class HumanReadableRBIFormat < BaseRBIFormat # TODO: move to RBI gem + #: Integer? + attr_reader :max_line_length + + #: ( + #| ?max_line_length: Integer?, + #| ) -> void + def initialize(max_line_length: nil) + super() + @max_line_length = max_line_length + + freeze + end + + @default = new #: HumanReadableRBIFormat + class << self + #: HumanReadableRBIFormat + attr_reader :default + end + end + + class Options + #: Symbol + attr_reader :overloads_strategy + + ALLOWED_OVERLOAD_STRATEGIES = [:translate_all, :translate_last, :raise].freeze #: Array[Symbol] + + #: BaseRBIFormat + attr_reader :output_format + + #: ( + # :translate_all | :translate_last | :raise + #| ?overloads_strategy: Symbol, + #| ?output_format: BaseRBIFormat, + #| ) -> void + def initialize( + overloads_strategy: :translate_all, + output_format: HumanReadableRBIFormat.default + ) + unless ALLOWED_OVERLOAD_STRATEGIES.include?(overloads_strategy) + raise ArgumentError, "Unknown overloads_strategy: #{overloads_strategy.inspect}. " \ + "Must be one of: #{ALLOWED_OVERLOAD_STRATEGIES.map(&:inspect).join(", ")}" + end + + @overloads_strategy = overloads_strategy + @output_format = output_format + + freeze + end + + @default = new #: Options + class << self + #: Options + attr_reader :default + end + end + end + end + end +end diff --git a/rbi/spoom.rbi b/rbi/spoom.rbi index 308e511e..5d9e9a2e 100644 --- a/rbi/spoom.rbi +++ b/rbi/spoom.rbi @@ -2937,6 +2937,8 @@ module Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs end end +class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::BaseRBIFormat; end + class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::BaseTranslator < ::Spoom::Sorbet::Translate::Translator include ::Spoom::RBS::ExtractRBSComments @@ -2946,11 +2948,10 @@ class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::BaseTranslator < ::Spoo params( ruby_contents: ::String, file: ::String, - max_line_length: T.nilable(::Integer), - overloads_strategy: ::Symbol + options: ::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::Options ).void end - def initialize(ruby_contents, file:, max_line_length: T.unsafe(nil), overloads_strategy: T.unsafe(nil)); end + def initialize(ruby_contents, file:, options: T.unsafe(nil)); end sig { override.params(node: ::Prism::CallNode).void } def visit_call_node(node); end @@ -3008,9 +3009,44 @@ class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::BaseTranslator < ::Spoo def visit_attr(node); end end -Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::BaseTranslator::ALLOWED_OVERLOAD_STRATEGIES = T.let(T.unsafe(nil), Array) +class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::HumanReadableRBIFormat < ::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::BaseRBIFormat + sig { params(max_line_length: T.nilable(::Integer)).void } + def initialize(max_line_length: T.unsafe(nil)); end + + sig { returns(T.nilable(::Integer)) } + def max_line_length; end + + class << self + sig { returns(::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::HumanReadableRBIFormat) } + def default; end + end +end + class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::HumanReadableTranslator < ::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::BaseTranslator; end +class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::Options + sig do + params( + overloads_strategy: ::Symbol, + output_format: ::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::BaseRBIFormat + ).void + end + def initialize(overloads_strategy: T.unsafe(nil), output_format: T.unsafe(nil)); end + + sig { returns(::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::BaseRBIFormat) } + def output_format; end + + sig { returns(::Symbol) } + def overloads_strategy; end + + class << self + sig { returns(::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::Options) } + def default; end + end +end + +Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::Options::ALLOWED_OVERLOAD_STRATEGIES = T.let(T.unsafe(nil), Array) + class Spoom::Sorbet::Translate::SorbetAssertionsToRBSComments < ::Spoom::Sorbet::Translate::Translator sig do params( diff --git a/test/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs_test.rb b/test/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs_test.rb index 1deb6cf7..f6eaab31 100644 --- a/test/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs_test.rb +++ b/test/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs_test.rb @@ -988,8 +988,12 @@ def rbs_comments_to_sorbet_sigs(ruby_contents, max_line_length: nil, overloads_s RBSCommentsToSorbetSigs::HumanReadableTranslator.new( ruby_contents, file: "test.rb", - max_line_length: max_line_length, - overloads_strategy: overloads_strategy, + options: RBSCommentsToSorbetSigs::Options.new( + overloads_strategy:, + output_format: RBSCommentsToSorbetSigs::HumanReadableRBIFormat.new( + max_line_length:, + ), + ), ).rewrite end