Skip to content

Commit f71aded

Browse files
soutaroraosush
andcommitted
Adding unit tests
* Refactored RDoc::Parser::RBS to make unit testing easier * Adding some test cases Co-authored-by: Sushanth Sathesh Rao <raosush@users.noreply.github.com>
1 parent cdd8459 commit f71aded

File tree

2 files changed

+285
-140
lines changed

2 files changed

+285
-140
lines changed

lib/rdoc/parser/rbs.rb

Lines changed: 144 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -2,152 +2,167 @@
22

33
require 'rbs'
44

5-
class RDoc::Parser::RBS < RDoc::Parser
6-
parse_files_matching(/\.rbs$/)
5+
module RDoc
6+
class Parser
7+
class RBS < Parser
8+
parse_files_matching(/\.rbs$/)
79

8-
def initialize(top_level, file_name, content, options, stats)
9-
super
10-
end
11-
12-
def scan
13-
ast = ::RBS::Parser.parse_signature(@content)
14-
ast.each do |decl|
15-
parse_member(decl: decl, context: @top_level)
10+
def scan
11+
RBS::RDocPlugin::RBSParser.new(@top_level, @content).scan
12+
end
1613
end
17-
@top_level
1814
end
15+
end
1916

20-
def parse_member(decl:, context:, outer_name: nil)
21-
case decl
22-
when ::RBS::AST::Declarations::Class
23-
parse_class_decl(decl: decl, context: context, outer_name: outer_name)
24-
when ::RBS::AST::Declarations::Module
25-
parse_module_decl(decl: decl, context: context, outer_name: outer_name)
26-
when ::RBS::AST::Declarations::Constant
27-
context = @top_level.find_class_or_module outer_name.to_s if outer_name
28-
parse_constant_decl(decl: decl, context: context, outer_name: outer_name)
29-
when ::RBS::AST::Declarations::Interface
30-
parse_module_decl(decl: decl, context: context, outer_name: outer_name)
31-
when ::RBS::AST::Members::MethodDefinition
32-
context = @top_level.find_class_or_module outer_name.to_s if outer_name
33-
parse_method_decl(decl: decl, context: context, outer_name: outer_name)
34-
when ::RBS::AST::Members::Alias
35-
context = @top_level.find_class_or_module outer_name.to_s if outer_name
36-
parse_method_alias_decl(decl: decl, context: context, outer_name: outer_name)
37-
when ::RBS::AST::Members::AttrReader, ::RBS::AST::Members::AttrWriter, ::RBS::AST::Members::AttrAccessor
38-
context = @top_level.find_class_or_module outer_name.to_s if outer_name
39-
parse_attr_decl(decl: decl, context: context, outer_name: outer_name)
40-
when ::RBS::AST::Members::Include
41-
context = @top_level.find_class_or_module outer_name.to_s if outer_name
42-
parse_include_decl(decl: decl, context: context, outer_name: outer_name)
43-
when ::RBS::AST::Members::Extend
44-
context = @top_level.find_class_or_module outer_name.to_s if outer_name
45-
parse_extend_decl(decl: decl, context: context, outer_name: outer_name)
46-
end
47-
end
17+
module RBS
18+
module RDocPlugin
19+
class RBSParser
20+
attr_reader :top_level, :content
21+
def initialize(top_level, content)
22+
@top_level = top_level
23+
@content = content
24+
end
4825

49-
def parse_class_decl(decl:, context:, outer_name: nil)
50-
full_name = fully_qualified_name(outer_name: outer_name, decl: decl)
51-
klass = context.add_class(RDoc::NormalClass, full_name.to_s, decl.super_class&.name&.to_s || "::Object")
52-
klass.add_comment(construct_comment(context: context, comment: decl.comment.string), context) if decl.comment
53-
decl.members.each { |member| parse_member(decl: member, context: context, outer_name: full_name) }
54-
end
26+
def scan
27+
ast = ::RBS::Parser.parse_signature(@content)
28+
ast.each do |decl|
29+
parse_member(decl: decl, context: @top_level)
30+
end
31+
@top_level
32+
end
5533

56-
def parse_module_decl(decl:, context:, outer_name: nil)
57-
full_name = fully_qualified_name(outer_name: outer_name, decl: _ = decl)
58-
kmodule = context.add_module(RDoc::NormalModule, full_name.to_s)
59-
# @type var comment: RBS::AST::Comment
60-
kmodule.add_comment(construct_comment(context: context, comment: comment.string), context) if (comment = decl.comment)
61-
decl.members.each { |member| parse_member(decl: member, context: context, outer_name: full_name) }
62-
end
34+
def parse_member(decl:, context:, outer_name: nil)
35+
case decl
36+
when ::RBS::AST::Declarations::Class
37+
parse_class_decl(decl: decl, context: context, outer_name: outer_name)
38+
when ::RBS::AST::Declarations::Module
39+
parse_module_decl(decl: decl, context: context, outer_name: outer_name)
40+
when ::RBS::AST::Declarations::Constant
41+
context = @top_level.find_class_or_module outer_name.to_s if outer_name
42+
parse_constant_decl(decl: decl, context: context, outer_name: outer_name)
43+
when ::RBS::AST::Declarations::Interface
44+
parse_module_decl(decl: decl, context: context, outer_name: outer_name)
45+
when ::RBS::AST::Members::MethodDefinition
46+
context = @top_level.find_class_or_module outer_name.to_s if outer_name
47+
parse_method_decl(decl: decl, context: context, outer_name: outer_name)
48+
when ::RBS::AST::Members::Alias
49+
context = @top_level.find_class_or_module outer_name.to_s if outer_name
50+
parse_method_alias_decl(decl: decl, context: context, outer_name: outer_name)
51+
when ::RBS::AST::Members::AttrReader, ::RBS::AST::Members::AttrWriter, ::RBS::AST::Members::AttrAccessor
52+
context = @top_level.find_class_or_module outer_name.to_s if outer_name
53+
parse_attr_decl(decl: decl, context: context, outer_name: outer_name)
54+
when ::RBS::AST::Members::Include
55+
context = @top_level.find_class_or_module outer_name.to_s if outer_name
56+
parse_include_decl(decl: decl, context: context, outer_name: outer_name)
57+
when ::RBS::AST::Members::Extend
58+
context = @top_level.find_class_or_module outer_name.to_s if outer_name
59+
parse_extend_decl(decl: decl, context: context, outer_name: outer_name)
60+
end
61+
end
6362

64-
def parse_constant_decl(decl:, context:, outer_name: nil)
65-
comment = decl.comment ? construct_comment(context: context, comment: decl.comment.string) : nil
66-
constant = RDoc::Constant.new(decl.name.to_s, decl.type.to_s, comment)
67-
context.add_constant(constant)
68-
end
63+
def parse_class_decl(decl:, context:, outer_name: nil)
64+
full_name = fully_qualified_name(outer_name: outer_name, decl: decl)
65+
klass = context.add_class(RDoc::NormalClass, full_name.to_s, decl.super_class&.name&.to_s || "::Object")
66+
klass.add_comment(construct_comment(context: context, comment: decl.comment.string), context) if decl.comment
67+
decl.members.each { |member| parse_member(decl: member, context: context, outer_name: full_name) }
68+
end
6969

70-
def parse_method_decl(decl:, context:, outer_name: nil)
71-
method = RDoc::AnyMethod.new(nil, decl.name.to_s)
72-
method.singleton = decl.singleton?
73-
method.visibility = decl.visibility
74-
method.call_seq = decl.types.map { |type| "#{decl.name.to_s}#{type.to_s}" }.join("\n")
75-
if decl.location
76-
method.start_collecting_tokens
77-
method.add_token({ line_no: 1, char_no: 1, kind: :on_comment, text: "# File #{@top_level.relative_name}, line(s) #{decl.location.start_line}:#{decl.location.end_line}\n" })
78-
method.add_token({ line_no: 1, char_no: 1, text: decl.location.source })
79-
method.line = decl.location.start_line if decl.location
80-
end
81-
method.comment = construct_comment(context: context, comment: decl.comment.string) if decl.comment
82-
context.add_method(method)
83-
end
70+
def parse_module_decl(decl:, context:, outer_name: nil)
71+
full_name = fully_qualified_name(outer_name: outer_name, decl: _ = decl)
72+
kmodule = context.add_module(RDoc::NormalModule, full_name.to_s)
73+
kmodule.add_comment(construct_comment(context: context, comment: decl.comment.string), context) if decl.comment
74+
decl.members.each { |member| parse_member(decl: member, context: context, outer_name: full_name) }
75+
end
8476

85-
def parse_method_alias_decl(decl:, context:, outer_name: nil)
86-
alias_def = RDoc::Alias.new(nil, decl.old_name.to_s, decl.new_name.to_s, nil, decl.kind == :singleton)
87-
alias_def.comment = construct_comment(context: context, comment: decl.comment.string) if decl.comment
88-
context.add_alias(alias_def)
89-
end
77+
def parse_constant_decl(decl:, context:, outer_name: nil)
78+
comment = decl.comment ? construct_comment(context: context, comment: decl.comment.string) : nil
79+
constant = RDoc::Constant.new(decl.name.to_s, decl.type.to_s, comment)
80+
context.add_constant(constant)
81+
end
9082

91-
def parse_attr_decl(decl:, context:, outer_name: nil)
92-
rw = case decl
93-
when ::RBS::AST::Members::AttrReader
94-
'R'
95-
when ::RBS::AST::Members::AttrWriter
96-
'W'
97-
when ::RBS::AST::Members::AttrAccessor
98-
'RW'
99-
end
100-
attribute = RDoc::Attr.new(nil, decl.name.to_s, rw, nil, decl.kind == :singleton)
101-
attribute.visibility = decl.visibility
102-
attribute.comment = construct_comment(context: context, comment: decl.comment.string) if decl.comment
103-
context.add_attribute(attribute)
104-
end
83+
def parse_method_decl(decl:, context:, outer_name: nil)
84+
method = RDoc::AnyMethod.new(nil, decl.name.to_s)
85+
method.singleton = decl.singleton?
86+
method.visibility = decl.visibility
87+
method.call_seq = decl.types.map { |type| "#{decl.name.to_s}#{type.to_s}" }.join("\n")
88+
if decl.location
89+
method.start_collecting_tokens
90+
method.add_token({ line_no: 1, char_no: 1, kind: :on_comment, text: "# File #{@top_level.relative_name}, line(s) #{decl.location.start_line}:#{decl.location.end_line}\n" })
91+
method.add_token({ line_no: 1, char_no: 1, text: decl.location.source })
92+
method.line = decl.location.start_line if decl.location
93+
end
94+
method.comment = construct_comment(context: context, comment: decl.comment.string) if decl.comment
95+
context.add_method(method)
96+
end
10597

106-
def parse_include_decl(decl:, context:, outer_name: nil)
107-
name = decl.name.to_s
108-
outer_names = outer_name ? outer_name.to_s.split("::") : []
109-
qualified_name = ''
110-
outer_names.each do |namespace|
111-
qualified_name += namespace
112-
if (module_name = @top_level.find_module_named((qualified_name += "::") + name))
113-
name = module_name.full_name
114-
break
98+
def parse_method_alias_decl(decl:, context:, outer_name: nil)
99+
alias_def = RDoc::Alias.new(nil, decl.old_name.to_s, decl.new_name.to_s, nil, decl.kind == :singleton)
100+
alias_def.comment = construct_comment(context: context, comment: decl.comment.string) if decl.comment
101+
context.add_alias(alias_def)
115102
end
116-
end
117-
include_decl = RDoc::Include.new(name, nil)
118-
include_decl.comment = construct_comment(context: context, comment: decl.comment.string) if decl.comment
119-
context.add_include(include_decl)
120-
end
121103

122-
def parse_extend_decl(decl:, context:, outer_name: nil)
123-
name = decl.name.to_s
124-
outer_names = outer_name ? outer_name.to_s.split("::") : []
125-
qualified_name = ''
126-
outer_names.each do |namespace|
127-
qualified_name += namespace
128-
if (module_name = @top_level.find_module_named((qualified_name += "::") + name))
129-
name = module_name.full_name
130-
break
104+
def parse_attr_decl(decl:, context:, outer_name: nil)
105+
rw = case decl
106+
when ::RBS::AST::Members::AttrReader
107+
'R'
108+
when ::RBS::AST::Members::AttrWriter
109+
'W'
110+
when ::RBS::AST::Members::AttrAccessor
111+
'RW'
112+
end
113+
attribute = RDoc::Attr.new(nil, decl.name.to_s, rw, nil, decl.kind == :singleton)
114+
attribute.visibility = decl.visibility
115+
attribute.comment = construct_comment(context: context, comment: decl.comment.string) if decl.comment
116+
context.add_attribute(attribute)
131117
end
132-
end
133-
extend_decl = RDoc::Extend.new(name, nil)
134-
extend_decl.comment = construct_comment(context: context, comment: decl.comment.string) if decl.comment
135-
context.add_extend(extend_decl)
136-
end
137118

138-
private
119+
def parse_include_decl(decl:, context:, outer_name: nil)
120+
name = decl.name.to_s
121+
outer_names = outer_name ? outer_name.to_s.split("::") : []
122+
qualified_name = ''
123+
outer_names.each do |namespace|
124+
qualified_name += namespace
125+
if (module_name = @top_level.find_module_named((qualified_name += "::") + name))
126+
name = module_name.full_name
127+
break
128+
end
129+
end
130+
include_decl = RDoc::Include.new(name, nil)
131+
include_decl.comment = construct_comment(context: context, comment: decl.comment.string) if decl.comment
132+
context.add_include(include_decl)
133+
end
139134

140-
def construct_comment(context:, comment:)
141-
comment = RDoc::Comment.new(comment, context)
142-
comment.format = "markdown"
143-
comment
144-
end
135+
def parse_extend_decl(decl:, context:, outer_name: nil)
136+
name = decl.name.to_s
137+
outer_names = outer_name ? outer_name.to_s.split("::") : []
138+
qualified_name = ''
139+
outer_names.each do |namespace|
140+
qualified_name += namespace
141+
if (module_name = @top_level.find_module_named((qualified_name += "::") + name))
142+
name = module_name.full_name
143+
break
144+
end
145+
end
146+
extend_decl = RDoc::Extend.new(name, nil)
147+
extend_decl.comment = construct_comment(context: context, comment: decl.comment.string) if decl.comment
148+
context.add_extend(extend_decl)
149+
end
150+
151+
private
145152

146-
def fully_qualified_name(outer_name:, decl:)
147-
if outer_name
148-
(outer_name + decl.name)
149-
else
150-
decl.name
153+
def construct_comment(context:, comment:)
154+
comment = RDoc::Comment.new(comment, context)
155+
comment.format = "markdown"
156+
comment
157+
end
158+
159+
def fully_qualified_name(outer_name:, decl:)
160+
if outer_name
161+
(outer_name + decl.name)
162+
else
163+
decl.name
164+
end
165+
end
151166
end
152167
end
153168
end

0 commit comments

Comments
 (0)