Skip to content

Commit

Permalink
Handle arrow operator for attr_* and procs
Browse files Browse the repository at this point in the history
  • Loading branch information
KaanOzkan committed Feb 26, 2025
1 parent c92356d commit 1a31b80
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
21 changes: 20 additions & 1 deletion lib/tapioca/gem/listeners/yard_doc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def documentation_comments(name, sigs: [])
.reject { |line| IGNORED_COMMENTS.any? { |comment| line.include?(comment) } }
.map! do |line|
if line.strip.start_with?(RBS_SIGNATURE_PREFIX)
rbs_sigs << RBI::RBSSig.new(line[1..].strip)
rbs_sigs << create_rbs_sig(line)
else
comments << RBI::Comment.new(line)
end
Expand Down Expand Up @@ -107,6 +107,25 @@ def documentation_comments(name, sigs: [])
[comments, rbs_sigs]
end

#: (String line) -> RBI::RBSSig
def create_rbs_sig(line)
sig = T.must(line[1..]).strip

# attr_* methods don't have to specify "->" in their signatures but since we convert it
# to a regular method definitions we need to have "->" to represent the return type.
# Also we need becareful of proc types since they contain a "->" already.
if !sig.include?("->")
sig = "-> #{sig}"
elsif sig.include?("^") # Proc type
# Check if there's a "->" that's not inside a proc type
# A proc type will have the form (^(Arg1, Arg2) -> ReturnType)
outer_arrow_present = !/\([^()]*->[^()]*\)/.match?(sig)
sig = "-> #{sig}" unless outer_arrow_present
end

RBI::RBSSig.new(sig)
end

# @override
#: (NodeAdded event) -> bool
def ignore?(event)
Expand Down
28 changes: 28 additions & 0 deletions spec/tapioca/gem/pipeline_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4550,16 +4550,44 @@ def foo; end
#: -> Integer
def self.bar; end
#: Integer
attr_reader :baz
#: (^(Integer) -> String) -> void
attr_reader :qux
#: (^(Integer) -> String proc) -> void
def quux(proc); end
#: ((^(Integer) -> String proc) -> void) -> void
def corge(nested_proc); end
end
RUBY

output = template(<<~RBI)
# source://#{DEFAULT_GEM_NAME}//lib/foo.rb#1
class Foo
# source://#{DEFAULT_GEM_NAME}//lib/foo.rb#9
#: -> Integer
def baz; end
# source://#{DEFAULT_GEM_NAME}//lib/foo.rb#18
#: ((^(Integer) -> String proc) -> void) -> void
def corge(nested_proc); end
# source://#{DEFAULT_GEM_NAME}//lib/foo.rb#3
#: -> String
def foo; end
# source://#{DEFAULT_GEM_NAME}//lib/foo.rb#15
#: (^(Integer) -> String proc) -> void
def quux(proc); end
# source://#{DEFAULT_GEM_NAME}//lib/foo.rb#12
#: (^(Integer) -> String) -> void
def qux; end
class << self
# source://#{DEFAULT_GEM_NAME}//lib/foo.rb#6
#: -> Integer
Expand Down

0 comments on commit 1a31b80

Please sign in to comment.