class Tapioca::Gem::Listeners::YardDoc
def documentation_comments(name, sigs: [])
def documentation_comments(name, sigs: []) yard_docs = YARD::Registry.at(name) return [] unless yard_docs docstring = yard_docs.docstring return [] if /(copyright|license)/i.match?(docstring) comments = docstring.lines .reject { |line| IGNORED_COMMENTS.any? { |comment| line.include?(comment) } || rbs_comment?(line) } .map! { |line| RBI::Comment.new(line) } tags = yard_docs.tags tags.reject! { |tag| IGNORED_SIG_TAGS.include?(tag.tag_name) } unless sigs.empty? comments << RBI::Comment.new("") if comments.any? && tags.any? tags.sort_by(&:tag_name).each do |tag| line = +"@#{tag.tag_name}" tag_name = tag.name line << " #{tag_name}" if tag_name tag_types = tag.types line << " [#{tag_types.join(", ")}]" if tag_types&.any? tag_text = tag.text if tag_text && !tag_text.empty? text_lines = tag_text.lines # Example are a special case because we want the text to start on the next line line << " #{text_lines.shift&.strip}" unless tag.tag_name == "example" text_lines.each do |text_line| line << "\n #{text_line.strip}" end end comments << RBI::Comment.new(line) end comments end
def ignore?(event)
@override
def ignore?(event) event.is_a?(Tapioca::Gem::ForeignScopeNodeAdded) end
def initialize(pipeline)
def initialize(pipeline) YARD::Registry.clear super(pipeline) pipeline.gem.parse_yard_docs end
def on_const(event)
@override
def on_const(event) event.node.comments = documentation_comments(event.symbol) end
def on_method(event)
@override
def on_method(event) separator = event.constant.singleton_class? ? "." : "#" event.node.comments = documentation_comments( "#{event.symbol}#{separator}#{event.node.name}", sigs: event.node.sigs, ) end
def on_scope(event)
@override
def on_scope(event) event.node.comments = documentation_comments(event.symbol) end
def rbs_comment?(line)
def rbs_comment?(line) line.strip.start_with?(": ", "| ") end