Class: RDoc::Parser::RBS
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
self,
Parser
|
|
|
Instance Chain:
self,
Parser
|
|
| Inherits: |
Parser
|
| Defined in: | lib/rdoc/parser/rbs.rb |
Overview
Parse RBS signature files as first-class ::RDoc::RDoc input.
Constant Summary
-
RBS_FILE_EXTENSION =
# File 'lib/rdoc/parser/rbs.rb', line 11/\.rbs$/
Instance Method Summary
- #scan
- #attr_rw_matches?(existing_rw, new_rw) ⇒ Boolean private
- #local_module_name(type_name, context) private
- #merge_attribute_methods(context, name, rw, singleton, comment, type_signature_lines) private
- #merge_comments(object, comment) private
- #merge_documentation(object, comment, type_signature_lines) private
- #parse_attr_decl(decl, context) private
- #parse_class_decl(decl, context) private
- #parse_constant_decl(decl, context) private
- #parse_decl(decl, context) private
- #parse_extend_decl(decl, context) private
- #parse_include_decl(decl, context) private
- #parse_member_decl(decl, context) private
- #parse_method_alias_decl(decl, context) private
- #parse_method_decl(decl, context) private
- #parse_module_decl(decl, context) private
- #rbs_constructor_decl?(decl) ⇒ Boolean private
- #rdoc_comment_for(decl) private
- #rdoc_method_name(decl) private
- #rdoc_method_singleton?(decl) ⇒ Boolean private
- #rdoc_method_visibility(decl) private
- #record_object_location(object, location) private
Instance Method Details
#attr_rw_matches?(existing_rw, new_rw) ⇒ Boolean (private)
# File 'lib/rdoc/parser/rbs.rb', line 91
def attr_rw_matches?(existing_rw, new_rw) existing_rw.each_char.any? { |rw| new_rw.include? rw } end
#local_module_name(type_name, context) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 48
def local_module_name(type_name, context) name = type_name.to_s return name if name.start_with?('::') namespace_names = context == @top_level ? [] : context.full_name.split('::') namespace_names.length.downto(1) do |length| qualified_name = namespace_names.take(length).join('::') if module_name = @top_level.find_module_named("#{qualified_name}::#{name}") return module_name.full_name end end name end
#merge_attribute_methods(context, name, rw, singleton, comment, type_signature_lines) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 95
def merge_attribute_methods(context, name, rw, singleton, comment, type_signature_lines) method_names = [] method_names << name if rw.include?('R') method_names << "#{name}=" if rw.include?('W') methods = method_names.map { |method_name| context.find_method(method_name, singleton) } methods.compact.each do |method| merge_documentation method, comment, type_signature_lines end methods.any? end
#merge_comments(object, comment) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 78
def merge_comments(object, comment) document = Markup::Document.new document.concat object.parse(object.comment).parts document << Markup::Rule.new(1) document.concat comment.parse.parts # Keep this text separator in sync with the Rule node above. merged_comment = Comment.new "#{object.comment}\n---\n#{comment}", comment.location merged_comment.format = 'markdown' merged_comment.document = document merged_comment end
#merge_documentation(object, comment, type_signature_lines) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 64
def merge_documentation(object, comment, type_signature_lines) if comment object.comment = if object.comment.empty? comment else merge_comments object, comment end end # TODO: Track RBS-owned documentation overlays so incremental reparsing can # replace stale comments and signatures from the previous RBS parse. object.type_signature_lines ||= type_signature_lines end
#parse_attr_decl(decl, context) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 126
def parse_attr_decl(decl, context) rw = case decl when ::RBS::AST::Members::AttrReader 'R' when ::RBS::AST::Members::AttrWriter 'W' when ::RBS::AST::Members::AttrAccessor 'RW' end comment = rdoc_comment_for decl type_signature_lines = [decl.type.to_s] name = decl.name.to_s singleton = decl.kind == :singleton if attribute = context.find_attribute(name, singleton) merge_documentation attribute, comment, type_signature_lines if attr_rw_matches? attribute.rw, rw return end if merge_attribute_methods(context, name, rw, singleton, comment, type_signature_lines) return end attribute = Attr.new( name, rw, comment, singleton: singleton ) record_object_location attribute, decl.location attribute.type_signature_lines = type_signature_lines attribute.visibility = decl.visibility if decl.visibility context.add_attribute attribute end
#parse_class_decl(decl, context) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 162
def parse_class_decl(decl, context) owner, name = context.find_or_create_constant_owner_for_path decl.name superclass = decl.super_class&.name&.to_s || '::Object' klass = owner.add_class NormalClass, name, superclass record_object_location klass, decl.location comment = rdoc_comment_for decl klass.add_comment comment, @top_level if comment decl.members.each { |member| parse_decl member, klass } end
#parse_constant_decl(decl, context) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 173
def parse_constant_decl(decl, context) constant = Constant.new decl.name.to_s, decl.type.to_s, rdoc_comment_for(decl) record_object_location constant, decl.location context.add_constant constant end
#parse_decl(decl, context) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 180
def parse_decl(decl, context) case decl when ::RBS::AST::Declarations::Class parse_class_decl decl, context when ::RBS::AST::Declarations::Module, ::RBS::AST::Declarations::Interface parse_module_decl decl, context when ::RBS::AST::Declarations::ClassAlias, ::RBS::AST::Declarations::ModuleAlias # TODO: Add RBS class and module aliases to the RDoc store. nil else parse_member_decl decl, context end end
#parse_extend_decl(decl, context) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 195
def parse_extend_decl(decl, context) extend_decl = Extend.new local_module_name(decl.name, context), rdoc_comment_for(decl) record_object_location extend_decl, decl.location context.add_extend extend_decl end
#parse_include_decl(decl, context) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 202
def parse_include_decl(decl, context) include_decl = Include.new local_module_name(decl.name, context), rdoc_comment_for(decl) record_object_location include_decl, decl.location context.add_include include_decl end
#parse_member_decl(decl, context) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 209
def parse_member_decl(decl, context) case decl when ::RBS::AST::Declarations::Constant parse_constant_decl decl, context when ::RBS::AST::Members::MethodDefinition parse_method_decl decl, context when ::RBS::AST::Members::Alias parse_method_alias_decl decl, context when ::RBS::AST::Members::AttrReader, ::RBS::AST::Members::AttrWriter, ::RBS::AST::Members::AttrAccessor parse_attr_decl decl, context when ::RBS::AST::Members::Include parse_include_decl decl, context when ::RBS::AST::Members::Extend parse_extend_decl decl, context when ::RBS::AST::Members::Private, ::RBS::AST::Members::Public # TODO: Track standalone RBS visibility members. nil end end
#parse_method_alias_decl(decl, context) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 232
def parse_method_alias_decl(decl, context) alias_def = Alias.new( decl.old_name.to_s, decl.new_name.to_s, rdoc_comment_for(decl), singleton: decl.kind == :singleton ) record_object_location alias_def, decl.location context.add_alias alias_def end
#parse_method_decl(decl, context) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 243
def parse_method_decl(decl, context) comment = rdoc_comment_for decl type_signature_lines = decl.overloads.map { |overload| overload.method_type.to_s } method_name = rdoc_method_name(decl) singleton = rdoc_method_singleton?(decl) visibility = rdoc_method_visibility(decl) if method = context.find_method(method_name, singleton) merge_documentation method, comment, type_signature_lines return end method = AnyMethod.new method_name, singleton: singleton record_object_location method, decl.location method.type_signature_lines = type_signature_lines if loc = decl.location method.start_collecting_tokens :ruby method.add_token line_no: loc.start_line, char_no: 1, text: loc.source end method.comment = comment if comment method.visibility = visibility if visibility context.add_method method end
#parse_module_decl(decl, context) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 269
def parse_module_decl(decl, context) mod = context.add_module NormalModule, decl.name.to_s record_object_location mod, decl.location comment = rdoc_comment_for decl mod.add_comment comment, @top_level if comment decl.members.each { |member| parse_decl member, mod } end
#rbs_constructor_decl?(decl) ⇒ Boolean (private)
# File 'lib/rdoc/parser/rbs.rb', line 122
def rbs_constructor_decl?(decl) decl.kind == :instance && decl.name == :initialize end
#rdoc_comment_for(decl) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 37
def rdoc_comment_for(decl) rbs_comment = decl.comment if decl.respond_to?(:comment) return unless rbs_comment # TODO: Run RBS comments through RDoc's directive preprocessor so # directives like :nodoc: affect the documented object. comment = Comment.new rbs_comment.string, @top_level comment.format = 'markdown' comment end
#rdoc_method_name(decl) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 108
def rdoc_method_name(decl) rbs_constructor_decl?(decl) ? 'new' : decl.name.to_s end
#rdoc_method_singleton?(decl) ⇒ Boolean (private)
# File 'lib/rdoc/parser/rbs.rb', line 112
def rdoc_method_singleton?(decl) # TODO: RBS `self?` methods are :singleton_instance and should add both a # singleton method and a private instance method. rbs_constructor_decl?(decl) || decl.singleton? end
#rdoc_method_visibility(decl) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 118
def rdoc_method_visibility(decl) rbs_constructor_decl?(decl) ? :public : decl.visibility end
#record_object_location(object, location) (private)
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 25
def record_object_location(object, location) object.line = location.start_line if location if ClassModule === object @top_level.add_to_classes_or_modules object unless @top_level.classes_or_modules.include? object end object.record_location @top_level object end
#scan
[ GitHub ]# File 'lib/rdoc/parser/rbs.rb', line 15
def scan _, _, decls = ::RBS::Parser.parse_signature(@content) decls.each do |decl| parse_decl decl, @top_level end @top_level end