Class: RBS::Annotate::RDocAnnotator
Relationships & Source Files | |
Inherits: | Object |
Defined in: | lib/rbs/annotate/rdoc_annotator.rb |
Class Method Summary
- .new(source:) ⇒ RDocAnnotator constructor
Instance Attribute Summary
- #include_arg_lists rw
- #include_filename rw
- #source readonly
Instance Method Summary
- #annotate_alias(typename, als)
- #annotate_attribute(typename, attr)
- #annotate_class(decl, outer:)
- #annotate_constant(const, outer:)
- #annotate_decls(decls, outer: [])
- #annotate_file(path, preserve:)
- #annotate_method(typename, method)
- #annotations(annots)
- #doc_for_alias(typename, name:, singleton:, tester:)
- #doc_for_attribute(typename, attr_name, require: nil, singleton:, tester:)
- #doc_for_class(name, tester:)
- #doc_for_constant(name, tester:)
- #doc_for_method(typename, instance_method: nil, singleton_method: nil, tester:)
- #doc_for_method0(typename, instance_method: nil, singleton_method: nil, tester:)
- #each_part(subjects, tester:)
- #join_docs(docs, separator: "----")
- #replace_comment(commented, string)
- #resolve_doc_source(copy, tester:)
- #resolve_name(name, outer:)
Constructor Details
.new(source:) ⇒ RDocAnnotator
# File 'lib/rbs/annotate/rdoc_annotator.rb', line 9
def initialize(source:) @source = source @include_arg_lists = true @include_filename = true end
Instance Attribute Details
#include_arg_lists (rw)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 7
attr_accessor :include_arg_lists, :include_filename
#include_filename (rw)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 7
attr_accessor :include_arg_lists, :include_filename
#source (readonly)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 6
attr_reader :source
Instance Method Details
#annotate_alias(typename, als)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 282
def annotate_alias(typename, als) annots = annotations(als) unless annots.skip? text = resolve_doc_source(annots.copy_annotation, tester: annots) do case als.kind when :instance doc_for_method(typename, instance_method: als.new_name, tester: annots) when :singleton doc_for_method(typename, singleton_method: als.new_name, tester: annots) end end end replace_comment(als, text) end
#annotate_attribute(typename, attr)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 341
def annotate_attribute(typename, attr) annots = annotations(attr) unless annots.skip? text = resolve_doc_source(annots.copy_annotation, tester: annots) do # @type var docs: Array[String?] docs = [] case attr.kind when :instance if attr.is_a?(AST::Members::AttrReader) || attr.is_a?(AST::Members::AttrAccessor) docs << doc_for_method(typename, instance_method: attr.name, tester: annots) end if attr.is_a?(AST::Members::AttrWriter) || attr.is_a?(AST::Members::AttrAccessor) docs << doc_for_method(typename, instance_method: :"#{attr.name}=", tester: annots) end when :singleton if attr.is_a?(AST::Members::AttrReader) || attr.is_a?(AST::Members::AttrAccessor) docs << doc_for_method(typename, singleton_method: attr.name, tester: annots) end if attr.is_a?(AST::Members::AttrWriter) || attr.is_a?(AST::Members::AttrAccessor) docs << doc_for_method(typename, singleton_method: :"#{attr.name}=", tester: annots) end end join_docs(docs.uniq) end end replace_comment(attr, text) end
#annotate_class(decl, outer:)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 245
def annotate_class(decl, outer:) annots = annotations(decl) full_name = resolve_name(decl.name, outer: outer) unless annots.skip? text = resolve_doc_source(annots.copy_annotation, tester: annots) { doc_for_class(full_name, tester: annots) } end replace_comment(decl, text) unless annots.skip_all? outer_ = outer + [decl.name.to_namespace] decl.each_member do |member| case member when AST::Members::MethodDefinition annotate_method(full_name, member) when AST::Members::Alias annotate_alias(full_name, member) when AST::Members::AttrReader, AST::Members::AttrAccessor, AST::Members::AttrWriter annotate_attribute(full_name, member) end end annotate_decls(decl.each_decl.to_a, outer: outer_) end end
#annotate_constant(const, outer:)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 273
def annotate_constant(const, outer:) annots = Annotations.new([]) full_name = resolve_name(const.name, outer: outer) text = doc_for_constant(full_name, tester: annots) replace_comment(const, text) end
#annotate_decls(decls, outer: [])
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 28
def annotate_decls(decls, outer: []) decls.each do |decl| case decl when AST::Declarations::Class, AST::Declarations::Module annotate_class(decl, outer: outer) when AST::Declarations::Constant annotate_constant(decl, outer: outer) end end end
#annotate_file(path, preserve:)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 16
def annotate_file(path, preserve:) content = path.read() _, _, decls = Parser.parse_signature(content) annotate_decls(decls) path.open("w") do |io| Writer.new(out: io).preserve!(preserve: preserve).write(decls) end end
#annotate_method(typename, method)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 312
def annotate_method(typename, method) annots = annotations(method) unless annots.skip? text = resolve_doc_source(annots.copy_annotation, tester: annots) { case method.kind when :singleton doc_for_method(typename, singleton_method: method.name, tester: annots) when :instance if method.name == :initialize doc_for_method(typename, instance_method: :initialize, tester: annots) || doc_for_method(typename, singleton_method: :new, tester: annots) else doc_for_method(typename, instance_method: method.name, tester: annots) end when :singleton_instance join_docs( [ doc_for_method(typename, singleton_method: method.name, tester: annots), doc_for_method(typename, instance_method: method.name, tester: annots) ].uniq ) end } end replace_comment(method, text) end
#annotations(annots)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 393
def annotations(annots) # @type var as: Array[Annotations::t] as = _ = annots.annotations.map {|annot| Annotations.parse(annot) }.compact Annotations.new(as) end
#doc_for_alias(typename, name:, singleton:, tester:)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 187
def doc_for_alias(typename, name:, singleton:, tester:) if as = if singleton source.find_method(typename, singleton_method: name) else source.find_method(typename, instance_method: name) end formatter = Formatter.new each_part(as, tester: tester) do |doc, obj| # @type var method: RDoc::AnyMethod method = _ = obj if method.is_alias_for text = Formatter.translate(doc) or next unless text.empty? formatter << "<!-- rdoc-file=#{doc.file} -->" if include_filename formatter << text end end end formatter.format(newline_at_end: true) end end
#doc_for_attribute(typename, attr_name, require: nil, singleton:, tester:)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 215
def doc_for_attribute(typename, attr_name, require: nil, singleton:, tester:) if as = source.find_attribute(typename, attr_name, singleton: singleton) as = as.select do |attr| case require when "R" attr.rw == "R" || attr.rw == "RW" when "W" attr.rw == "W" || attr.rw == "RW" else true end end return if as.empty? formatter = Formatter.new() each_part(as, tester: tester) do |doc, obj| if text = Formatter.translate(doc) unless text.empty? formatter << "<!-- rdoc-file=#{doc.file} -->" if include_filename formatter << text end end end formatter.format(newline_at_end: true) end end
#doc_for_class(name, tester:)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 66
def doc_for_class(name, tester:) if clss = source.find_class(name) formatter = Formatter.new() each_part(clss, tester: tester) do |doc, _| text = Formatter.translate(doc) or next unless text.empty? if include_filename formatter << "<!-- rdoc-file=#{doc.file} -->" end formatter << text formatter.margin end end formatter.format(newline_at_end: true) end end
#doc_for_constant(name, tester:)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 87
def doc_for_constant(name, tester:) if constants = source.find_const(name) formatter = Formatter.new each_part(constants, tester: tester) do |doc, _| text = Formatter.translate(doc) or next unless text.empty? if include_filename formatter << "<!-- rdoc-file=#{doc.file} -->" end formatter << text formatter.margin end end formatter.format(newline_at_end: true) end end
#doc_for_method(typename, instance_method: nil, singleton_method: nil, tester:)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 145
def doc_for_method(typename, instance_method: nil, singleton_method: nil, tester:) formatter = Formatter.new() case when method = instance_method doc = doc_for_alias(typename, name: method, singleton: false, tester: tester) doc = doc_for_method0(typename, instance_method: method, tester: tester) if !doc || doc.empty? if !doc || doc.empty? if (s = method.to_s) =~ /\A[a-zA-Z_]/ # may be attribute doc = if s.end_with?("=") doc_for_attribute(typename, s.delete_suffix("=").to_sym, require: "W", singleton: false, tester: tester) else doc_for_attribute(typename, s.to_sym, require: "R", singleton: false, tester: tester) end end end when method = singleton_method doc = doc_for_alias(typename, name: method, singleton: true, tester: tester) doc = doc_for_method0(typename, singleton_method: method, tester: tester) if !doc || doc.empty? if !doc || doc.empty? if (s = method.to_s) =~ /\A[a-zA-Z_]/ # may be attribute doc = if s.end_with?("=") doc_for_attribute(typename, s.delete_suffix("=").to_sym, require: "W", singleton: true, tester: tester) else doc_for_attribute(typename, s.to_sym, require: "R", singleton: true, tester: tester) end end end else raise end if doc formatter << doc formatter.format(newline_at_end: true) end end
#doc_for_method0(typename, instance_method: nil, singleton_method: nil, tester:)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 109
def doc_for_method0(typename, instance_method: nil, singleton_method: nil, tester:) ms = source.find_method(typename, instance_method: instance_method) if instance_method ms = source.find_method(typename, singleton_method: singleton_method) if singleton_method if ms formatter = Formatter.new each_part(ms, tester: tester) do |doc, method| text = Formatter.translate(doc) or next # @type var as: String? as = (_ = method).arglists if include_arg_lists && as formatter << "<!--" formatter << " rdoc-file=#{doc.file}" if include_filename as.chomp.split("\n").each do |line| formatter << " - #{line.strip}" end formatter << "-->" else if include_filename formatter << "<!-- rdoc-file=#{doc.file} -->" end end unless text.empty? formatter << text end formatter.margin(separator: "----") end formatter.format(newline_at_end: false) end end
#each_part(subjects, tester:)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 39
def each_part(subjects, tester:) if block_given? subjects.each do |subject, docs| Formatter.each_part(subject.comment) do |doc| if tester.test_path(doc.file || raise) yield [doc, subject] end end end else enum_for :each_part, tester: tester end end
#join_docs(docs, separator: "----")
[ GitHub ]#replace_comment(commented, string)
[ GitHub ]#resolve_doc_source(copy, tester:)
[ GitHub ]# File 'lib/rbs/annotate/rdoc_annotator.rb', line 53
def resolve_doc_source(copy, tester:) case when copy && (mn = copy.method_name) && copy.singleton? doc_for_method(copy.type_name, singleton_method: mn, tester: tester) when copy && (mn = copy.method_name) && !copy.singleton? doc_for_method(copy.type_name, instance_method: mn, tester: tester) when copy doc_for_class(copy.type_name, tester: tester) || doc_for_constant(copy.type_name, tester: tester) else yield end end