Skip to content
Draft
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
19 changes: 17 additions & 2 deletions lib/tapioca/rbs/rewriter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,21 @@ def load_iseq(path)
# Bootsnap is not in the bundle, we don't need to do anything.
end

module Tapioca
module RBS
module Rewriter
TYPED_SIGIL_PATTERN = /^\s*#\s*typed: (ignore|false|true|strict|strong|__STDLIB_INTERNAL)/

class << self
#: (String source) -> bool
def rewrite?(source)
source.match?(TYPED_SIGIL_PATTERN) && (source.include?("#:") || source.include?("#|"))
end
end
end
end
end

# We need to include `T::Sig` very early to make sure that the `sig` method is available since gems using RBS comments
# are unlikely to include `T::Sig` in their own classes.
Module.include(T::Sig)
Expand All @@ -45,8 +60,8 @@ def load_iseq(path)
# The source is most likely nil since no `source_transform` hook was triggered before this one.
source ||= File.read(path, encoding: "UTF-8")

# For performance reasons, we only rewrite files that use Sorbet.
if source =~ /^\s*#\s*typed: (ignore|false|true|strict|strong|__STDLIB_INTERNAL)/
# For performance reasons, we only rewrite typed files that contain RBS comments.
if Tapioca::RBS::Rewriter.rewrite?(source)
Spoom::Sorbet::Translate.rbs_comments_to_sorbet_sigs(source, file: path)
end
rescue Spoom::Sorbet::Translate::Error
Expand Down
68 changes: 68 additions & 0 deletions spec/tapioca/rbs/rewriter_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# typed: strict
# frozen_string_literal: true

require "spec_helper"

module Tapioca
module RBS
class RewriterSpec < Minitest::Spec
def described_class
Tapioca::RBS::Rewriter
end

describe Tapioca::RBS::Rewriter do
it "rewrites typed files with RBS signature comments" do
source = <<~RUBY
# typed: strict

#: (String) -> Integer
def parse(value)
value.to_i
end
RUBY

assert(described_class.rewrite?(source))
end

it "rewrites typed files with multiline RBS comments" do
source = <<~RUBY
# typed: strict

#| (String,
#| Integer) -> String
def format(value, count)
value * count
end
RUBY

assert(described_class.rewrite?(source))
end

it "skips typed files without RBS comments" do
source = <<~RUBY
# typed: strict

def parse(value)
value.to_i
end
RUBY

refute(described_class.rewrite?(source))
end

it "skips files with RBS-looking comments but without a typed sigil" do
source = <<~RUBY
# frozen_string_literal: true

#: (String) -> Integer
def parse(value)
value.to_i
end
RUBY

refute(described_class.rewrite?(source))
end
end
end
end
end
Loading