Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions lib/spoom/sorbet/translate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,16 @@ def sorbet_sigs_to_rbs_comments(
# Converts all the RBS comments in the given Ruby code to `sig` nodes.
# It also handles type members and class annotations.
#: (String ruby_contents, file: String, ?max_line_length: Integer?,
#| ?overloads_strategy: Symbol, ?erase_generic_types: bool) -> String
#| ?overloads_strategy: Symbol, ?erase_generic_types: bool, ?force: bool) -> String
def rbs_comments_to_sorbet_sigs(ruby_contents, file:, max_line_length: nil, overloads_strategy: :translate_all,
erase_generic_types: false)
erase_generic_types: false, force: false)
RBSCommentsToSorbetSigs.rewrite_if_needed(
ruby_contents,
file: file,
max_line_length: max_line_length,
overloads_strategy: overloads_strategy,
erase_generic_types: erase_generic_types,
force: force,
)
end

Expand Down
14 changes: 6 additions & 8 deletions lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,23 @@ class << self
RBS_REWRITE_PATTERN = Regexp.union(["#:", "#|", *RBS_ANNOTATION_MARKERS]).freeze #: Regexp
private_constant :RBS_ANNOTATION_MARKERS, :RBS_REWRITE_PATTERN

#: (String source) -> bool
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,
#| ?erase_generic_types: bool) -> String
#| ?erase_generic_types: bool,
#| ?force: bool) -> String
def rewrite_if_needed(
ruby_contents,
file:,
max_line_length: nil,
overloads_strategy: :translate_all,
erase_generic_types: false
erase_generic_types: false,
force: false
)
return ruby_contents unless contains_rbs_syntax?(ruby_contents)
Comment thread
Morriar marked this conversation as resolved.
return ruby_contents unless ruby_contents.match?(RBS_REWRITE_PATTERN) &&
(force || Sigils.contains_valid_sigil?(ruby_contents))

options = Options.new(
overloads_strategy:,
Expand Down
13 changes: 6 additions & 7 deletions rbi/spoom.rbi
Original file line number Diff line number Diff line change
Expand Up @@ -3241,10 +3241,11 @@ module Spoom::Sorbet::Translate
file: ::String,
max_line_length: T.nilable(::Integer),
overloads_strategy: ::Symbol,
erase_generic_types: T::Boolean
erase_generic_types: T::Boolean,
force: T::Boolean
).returns(::String)
end
def rbs_comments_to_sorbet_sigs(ruby_contents, file:, max_line_length: T.unsafe(nil), overloads_strategy: T.unsafe(nil), erase_generic_types: T.unsafe(nil)); end
def rbs_comments_to_sorbet_sigs(ruby_contents, file:, max_line_length: T.unsafe(nil), overloads_strategy: T.unsafe(nil), erase_generic_types: T.unsafe(nil), force: T.unsafe(nil)); end

sig do
params(
Expand Down Expand Up @@ -3315,19 +3316,17 @@ end

module Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs
class << self
sig { params(source: ::String).returns(T::Boolean) }
def contains_rbs_syntax?(source); end

sig do
params(
ruby_contents: ::String,
file: ::String,
max_line_length: T.nilable(::Integer),
overloads_strategy: ::Symbol,
erase_generic_types: T::Boolean
erase_generic_types: T::Boolean,
force: T::Boolean
).returns(::String)
end
def rewrite_if_needed(ruby_contents, file:, max_line_length: T.unsafe(nil), overloads_strategy: T.unsafe(nil), erase_generic_types: T.unsafe(nil)); end
def rewrite_if_needed(ruby_contents, file:, max_line_length: T.unsafe(nil), overloads_strategy: T.unsafe(nil), erase_generic_types: T.unsafe(nil), force: T.unsafe(nil)); end
end
end

Expand Down
130 changes: 15 additions & 115 deletions test/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1462,139 +1462,39 @@ def foo; end
)
end

def test_contains_rbs_syntax_returns_true_for_supported_rbs_annotations
[
"# @abstract",
"# @interface",
"# @sealed",
"# @final",
"# @requires_ancestor:",
"# @override",
"# @override(allow_incompatible: true)",
"# @override(allow_incompatible: false)",
"# @override(allow_incompatible: :visibility)",
"# @overridable",
"# @without_runtime",
].each do |marker|
assert(
RBSCommentsToSorbetSigs.contains_rbs_syntax?(<<~RB),
# typed: true

#{marker}
class Foo; end
RB
"#contains_rbs_syntax? should return true for files containing #{marker}",
)
end
end

def test_contains_rbs_syntax_returns_true_for_supported_typed_sigils
[
"# typed: ignore",
"# typed: false",
"# typed: true",
"# typed: strict",
"# typed: strong",
"# typed: __STDLIB_INTERNAL",
].each do |sigil|
assert(
RBSCommentsToSorbetSigs.contains_rbs_syntax?(<<~RB),
#{sigil}

#: -> void
def foo; end
RB
"#contains_rbs_syntax? should return true for files containing #{sigil}",
)
end
end

def test_contains_rbs_syntax_returns_true_when_typed_sigil_is_after_other_magic_comments
assert(RBSCommentsToSorbetSigs.contains_rbs_syntax?(<<~RB))
# frozen_string_literal: true
# typed: true

class Foo
#: -> String
def foo; end
end
RB

assert(RBSCommentsToSorbetSigs.contains_rbs_syntax?(<<~RB))
# frozen_string_literal: true

# typed: true

class Foo
#: -> String
def foo; end
end
RB
end

def test_contains_rbs_syntax_returns_true_for_rbs_comments
assert(RBSCommentsToSorbetSigs.contains_rbs_syntax?(<<~RB))
def test_rewrite_does_not_call_new_for_files_without_rbs_syntax
source = <<~RB
# typed: true

class Foo
#: -> String
def foo; end
end
RB
end

def test_contains_rbs_syntax_returns_true_for_multiline_rbs_comments
assert(RBSCommentsToSorbetSigs.contains_rbs_syntax?(<<~RB))
# typed: true

class Foo
#: -> Array[
#| String
#| ]
def foo; end
end
RB
RBSCommentsToSorbetSigs::HumanReadableTranslator.stub(:new, ->(*) { flunk("should not be called") }) do
assert_equal(source, RBSCommentsToSorbetSigs.rewrite_if_needed(source, file: "test.rb"))
end
end

def test_contains_rbs_syntax_returns_false_for_files_without_typed_sigil
refute(RBSCommentsToSorbetSigs.contains_rbs_syntax?(<<~RB))
def test_rewrite_does_not_translate_files_without_typed_sigil_by_default
source = <<~RB
#: -> void
def foo; end
RB
end

def test_contains_rbs_syntax_returns_false_for_files_without_rbs_syntax
refute(RBSCommentsToSorbetSigs.contains_rbs_syntax?(<<~RB))
# typed: true

class Foo
def foo; end
end
RB
assert_equal(source, RBSCommentsToSorbetSigs.rewrite_if_needed(source, file: "test.rb"))
end

def test_contains_rbs_syntax_returns_false_for_unrelated_yard_tags
refute(RBSCommentsToSorbetSigs.contains_rbs_syntax?(<<~RB))
# typed: true

# @param value [String]
# @return [String]
def foo(value); end
RB
end

def test_rewrite_does_not_call_new_for_files_without_rbs_syntax
def test_rewrite_force_translates_files_without_typed_sigil
source = <<~RB
# typed: true

class Foo
def foo; end
end
#: -> void
def foo; end
RB

RBSCommentsToSorbetSigs::HumanReadableTranslator.stub(:new, ->(*) { flunk("should not be called") }) do
assert_equal(source, RBSCommentsToSorbetSigs.rewrite_if_needed(source, file: "test.rb"))
end
assert_equal(<<~RB, RBSCommentsToSorbetSigs.rewrite_if_needed(source, file: "test.rb", force: true))
sig { void }
def foo; end
RB
end

private
Expand Down
Loading