From a42b9b62988d26403e713b7be19a55882d62280a Mon Sep 17 00:00:00 2001 From: Sushanth Sathesh Rao <57192414+raosush@users.noreply.github.com> Date: Fri, 24 Jun 2022 23:39:28 +0530 Subject: [PATCH] Init commit - Added code required for RDoc plugin - Currently documentation supported for classes, modules, constant, methods Signed-off-by: Sushanth Sathesh Rao <57192414+raosush@users.noreply.github.com> --- .gitignore | 2 ++ lib/rdoc/discover.rb | 8 +++++ lib/rdoc/parser/rbs.rb | 82 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 lib/rdoc/discover.rb create mode 100644 lib/rdoc/parser/rbs.rb diff --git a/.gitignore b/.gitignore index b1aae9e1c0..41b9bfbd34 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,5 @@ lib/**/*.bundle lib/**/*.so lib/**/*.dll +doc/ +**/.gem diff --git a/lib/rdoc/discover.rb b/lib/rdoc/discover.rb new file mode 100644 index 0000000000..4956c455b8 --- /dev/null +++ b/lib/rdoc/discover.rb @@ -0,0 +1,8 @@ +begin + gem 'rdoc', '~> 6.4.0' + require 'rdoc/parser/rbs' +rescue Gem::LoadError + # Error :sad: +rescue Exception => e + # Exception :sad: +end diff --git a/lib/rdoc/parser/rbs.rb b/lib/rdoc/parser/rbs.rb new file mode 100644 index 0000000000..e6bdd80924 --- /dev/null +++ b/lib/rdoc/parser/rbs.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +require 'rbs' + +class RDoc::Parser::RBS < RDoc::Parser + parse_files_matching(/\.rbs$/) + + def initialize(top_level, file_name, content, options, stats) + super + end + + def scan + ast = ::RBS::Parser.parse_signature(@content) + ast.each do |decl| + parse_member(decl: decl, context: @top_level) + end + klass = @top_level.add_class(RDoc::NormalClass, 'Hello') + comment = RDoc::Comment.new('Hello documentation', @top_level) + klass.add_comment(comment, @top_level) + @stats.add_class(klass) + end + + def parse_member(decl:, context:, outer_name: nil) + case decl + when ::RBS::AST::Declarations::Class + parse_class_decl(decl: decl, context: context, outer_name: outer_name) + when ::RBS::AST::Declarations::Module + parse_module_decl(decl: decl, context: context, outer_name: outer_name) + when ::RBS::AST::Declarations::Constant + context = @top_level.find_class_or_module outer_name.to_s if outer_name + parse_constant_decl(decl: decl, context: context, outer_name: outer_name) + when ::RBS::AST::Members::MethodDefinition + context = @top_level.find_class_or_module outer_name.to_s if outer_name + parse_method_decl(decl: decl, context: context, outer_name: outer_name) + end + end + + def parse_class_decl(decl:, context:, outer_name: nil) + full_name = fully_qualified_name(outer_name: outer_name, decl: decl) + klass = context.add_class(RDoc::NormalClass, full_name.to_s) + klass.add_comment(construct_comment(context: context, comment: decl.comment.string), context) if decl.comment + decl.members.each { |member| parse_member(decl: member, context: context, outer_name: full_name) } + end + + def parse_module_decl(decl:, context:, outer_name: nil) + full_name = fully_qualified_name(outer_name: outer_name, decl: decl) + kmodule = context.add_module(RDoc::NormalModule, full_name.to_s) + kmodule.add_comment(construct_comment(context: context, comment: decl.comment.string), context) if decl.comment + decl.members.each { |member| parse_member(decl: member, context: context, outer_name: outer_name) } + end + + def parse_constant_decl(decl:, context:, outer_name: nil) + comment = decl.comment ? construct_comment(context: context, comment: decl.comment.string) : nil + constant = RDoc::Constant.new(decl.name.to_s, decl.type.to_s, comment) + context.add_constant(constant) + end + + def parse_method_decl(decl:, context:, outer_name: nil) + method = RDoc::AnyMethod.new(nil, decl.name.to_s) + method.singleton = decl.singleton? + method.visibility = decl.visibility + method.call_seq = decl.types.map { |type| "#{decl.name.to_s}#{type.to_s}" }.join("\n") + method.comment = construct_comment(context: context, comment: decl.comment.string) if decl.comment + context.add_method(method) + end + + private + + def construct_comment(context:, comment:) + comment = RDoc::Comment.new(comment, context) + comment.format = "markdown" + comment + end + + def fully_qualified_name(outer_name:, decl:) + if outer_name + (outer_name + decl.name) + else + decl.name + end + end +end