Module: RDoc::RbsHelper
| Relationships & Source Files | |
| Defined in: | lib/rdoc/rbs_helper.rb |
Class Method Summary
-
.load_signatures(*dirs)
Loads RBS signatures from the given directories.
-
.signature_to_html(lines, lookup:, from_path:)
Converts type signature lines to HTML with type names linked to their documentation pages.
-
.valid_method_type?(sig) ⇒ Boolean
Returns true if
sigis a valid RBS method type signature. -
.valid_type?(sig) ⇒ Boolean
Returns true if
sigis a valid RBS type signature. -
.collect_from_type(type, locs)
private
Recursively collects type name locations from an RBS type AST node.
-
.collect_type_name_locations(line)
private
Extracts type name locations from a signature line using the RBS parser.
- .link_type_names_in_line(line, lookup, from_path) private
-
.method_keys_for(class_name, member)
private
def self?.foo: ...produces a member whose kind is :singleton_instance — it defines both {Class.foo} (singleton) and a private {Class#foo} (instance), so we need to register the signature under both keys.
Class Method Details
.collect_from_type(type, locs) (private)
Recursively collects type name locations from an RBS type AST node.
# File 'lib/rdoc/rbs_helper.rb', line 164
def collect_from_type(type, locs) case type when RBS::Types::ClassInstance name = type.name.to_s.delete_prefix('::') if type.location name_loc = type.location[:name] || type.location locs << { name: name, start: name_loc.end_pos - name.length } end type.args.each { |a| collect_from_type(a, locs) } when RBS::Types::Union, RBS::Types::Intersection, RBS::Types::Tuple type.types.each { |t| collect_from_type(t, locs) } when RBS::Types::Optional collect_from_type(type.type, locs) when RBS::Types::Record type.all_fields.each_value { |t| collect_from_type(t, locs) } when RBS::Types::Proc type.type.each_param { |p| collect_from_type(p.type, locs) } collect_from_type(type.type.return_type, locs) end end
.collect_type_name_locations(line) (private)
Extracts type name locations from a signature line using the RBS parser.
# File 'lib/rdoc/rbs_helper.rb', line 136
def collect_type_name_locations(line) locs = [] begin mt = RBS::Parser.parse_method_type(line, require_eof: true) rescue RBS::ParsingError begin type = RBS::Parser.parse_type(line, require_eof: true) collect_from_type(type, locs) return locs rescue RBS::ParsingError return locs end end mt.type.each_param { |p| collect_from_type(p.type, locs) } if mt.block mt.block.type.each_param { |p| collect_from_type(p.type, locs) } collect_from_type(mt.block.type.return_type, locs) end collect_from_type(mt.type.return_type, locs) locs end
.link_type_names_in_line(line, lookup, from_path) (private)
[ GitHub ]# File 'lib/rdoc/rbs_helper.rb', line 105
def link_type_names_in_line(line, lookup, from_path) escaped = ERB::Util.html_escape(line) locs = collect_type_name_locations(line) return escaped if locs.empty? result = escaped.dup # Replace type names with links, working backwards to preserve positions. # HTML escaping (e.g. -> becomes ->) shifts positions, so we # re-escape the prefix to find the correct offset in the result. locs.sort_by { |l| -l[:start] }.each do |loc| name = loc[:name] next unless (target_path = lookup[name]) prefix = ERB::Util.html_escape(line[0...loc[:start]]) escaped_name = ERB::Util.html_escape(name) start_in_escaped = prefix.length end_in_escaped = start_in_escaped + escaped_name.length href = ERB::Util.html_escape(::RDoc::Markup::Formatter.gen_relative_url(from_path, target_path)) result[start_in_escaped...end_in_escaped] = "<a href=\"#{href}\" class=\"rbs-type\">#{escaped_name}</a>" end result end
.load_signatures(*dirs)
Loads RBS signatures from the given directories. Returns a Hash mapping "ClassName#method_name" => ["type sig string", ...].
# File 'lib/rdoc/rbs_helper.rb', line 41
def load_signatures(*dirs) loader = RBS::EnvironmentLoader.new dirs.each { |dir| loader.add(path: Pathname(dir)) } env = RBS::Environment.new loader.load(env: env) signatures = {} env.class_decls.each do |type_name, entry| class_name = type_name.to_s.delete_prefix('::') entry.each_decl do |decl| decl.members.each do |member| case member when RBS::AST::Members::MethodDefinition sigs = member.overloads.map { |o| o.method_type.to_s } method_keys_for(class_name, member).each do |key| signatures[key] ||= sigs end when RBS::AST::Members::AttrReader, RBS::AST::Members::AttrWriter, RBS::AST::Members::AttrAccessor key = member.kind == :singleton ? "#{class_name}.#{member.name}" : "#{class_name}##{member.name}" signatures[key] ||= [member.type.to_s] end end end end signatures end
.method_keys_for(class_name, member) (private)
def self?.foo: ... produces a member whose kind is :singleton_instance —
it defines both Class.foo (singleton) and a private Class#foo (instance),
so we need to register the signature under both keys.
# File 'lib/rdoc/rbs_helper.rb', line 94
def method_keys_for(class_name, member) case member.kind when :singleton ["#{class_name}.#{member.name}"] when :singleton_instance ["#{class_name}.#{member.name}", "#{class_name}##{member.name}"] else ["#{class_name}##{member.name}"] end end
.signature_to_html(lines, lookup:, from_path:)
Converts type signature lines to HTML with type names linked to their documentation pages. Uses the RBS parser to extract type name locations precisely.
lines is an Array of signature line strings.
lookup is a Hash mapping type names to their doc paths.
from_path is the current page path for generating relative URLs.
Returns escaped HTML with -> replaced by →.
# File 'lib/rdoc/rbs_helper.rb', line 83
def signature_to_html(lines, lookup:, from_path:) lines.map { |line| link_type_names_in_line(line, lookup, from_path).gsub('->', '→') }.join("\n") end
.valid_method_type?(sig) ⇒ Boolean
Returns true if sig is a valid RBS method type signature.
# File 'lib/rdoc/rbs_helper.rb', line 20
def valid_method_type?(sig) RBS::Parser.parse_method_type(sig, require_eof: true) true rescue RBS::ParsingError false end
.valid_type?(sig) ⇒ Boolean
Returns true if sig is a valid RBS type signature.
# File 'lib/rdoc/rbs_helper.rb', line 30
def valid_type?(sig) RBS::Parser.parse_type(sig, require_eof: true) true rescue RBS::ParsingError false end