Skip to content

Commit 3c1659f

Browse files
committed
Use index from Context
1 parent e7f3e01 commit 3c1659f

5 files changed

Lines changed: 47 additions & 46 deletions

File tree

‎lib/rdoc/code_object/context.rb‎

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@ def add(klass, name, comment)
186186
def add_alias(an_alias)
187187
return an_alias unless @document_self
188188

189-
method_attr = find_method(an_alias.old_name, an_alias.singleton) ||
190-
find_attribute(an_alias.old_name, an_alias.singleton)
189+
method_attr = find_method_from_hash(an_alias.old_name, an_alias.singleton) ||
190+
find_attribute_from_hash(an_alias.old_name, an_alias.singleton)
191191

192192
if method_attr
193193
method_attr.add_alias an_alias, self
@@ -749,6 +749,14 @@ def find_attribute(name, singleton)
749749
@attributes.find { |a| a.name == name && a.singleton == singleton }
750750
end
751751

752+
def find_attribute_from_hash(name, singleton) # :nodoc:
753+
name = name.delete_suffix('=')
754+
key = "#{singleton ? '::' : '#'}#{name}"
755+
attribute = @methods_hash[key]
756+
attribute = @methods_hash["#{key}="] unless RDoc::Attr === attribute
757+
attribute if RDoc::Attr === attribute && attribute.singleton == singleton
758+
end
759+
752760
##
753761
# Finds an attribute with +name+ in this context
754762

@@ -843,6 +851,12 @@ def find_method(name, singleton)
843851
}
844852
end
845853

854+
def find_method_from_hash(name, singleton) # :nodoc:
855+
method = @methods_hash["#{singleton ? '::' : '#'}#{name}"]
856+
# ponytail: keep the fallback until incremental rebuilds make this hash canonical.
857+
RDoc::Attr === method ? find_method(name, singleton) : method
858+
end
859+
846860
##
847861
# Finds a instance or module method with +name+ in this context
848862

‎lib/rdoc/parser/rbs.rb‎

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ class RDoc::Parser::RBS < RDoc::Parser
1111
parse_files_matching RBS_FILE_EXTENSION
1212

1313
def scan
14-
@attributes_by_context = {}
15-
@methods_by_context = {}
1614
_, _, decls = ::RBS::Parser.parse_signature(@content)
1715
decls.each do |decl|
1816
parse_decl decl, @top_level
@@ -92,28 +90,12 @@ def attr_rw_matches?(existing_rw, new_rw)
9290
existing_rw.each_char.any? { |rw| new_rw.include? rw }
9391
end
9492

95-
def attribute_index(context)
96-
index = @attributes_by_context[context] ||= {}
97-
context.attributes[index.length..].each do |attribute|
98-
index[[attribute.name, attribute.singleton]] ||= attribute
99-
end
100-
index
101-
end
102-
103-
def method_index(context)
104-
index = @methods_by_context[context] ||= {}
105-
context.method_list[index.length..].each do |method|
106-
index[[method.name, !!method.singleton]] ||= method
107-
end
108-
index
109-
end
110-
11193
def merge_attribute_methods(context, name, rw, singleton, comment, type_signature_lines)
11294
method_names = []
11395
method_names << name if rw.include?('R')
11496
method_names << "#{name}=" if rw.include?('W')
11597

116-
methods = method_names.map { |method_name| method_index(context)[[method_name, singleton]] }
98+
methods = method_names.map { |method_name| context.find_method_from_hash(method_name, singleton) }
11799
methods.compact.each do |method|
118100
merge_documentation method, comment, type_signature_lines
119101
end
@@ -153,7 +135,7 @@ def parse_attr_decl(decl, context)
153135
type_signature_lines = [decl.type.to_s]
154136
name = decl.name.to_s
155137
singleton = decl.kind == :singleton
156-
if attribute = attribute_index(context)[[name, singleton]]
138+
if attribute = context.find_attribute_from_hash(name, singleton)
157139
merge_documentation attribute, comment, type_signature_lines if
158140
attr_rw_matches? attribute.rw, rw
159141
return
@@ -263,7 +245,7 @@ def parse_method_decl(decl, context)
263245
singleton = rdoc_method_singleton?(decl)
264246
visibility = rdoc_method_visibility(decl)
265247

266-
if method = method_index(context)[[method_name, singleton]]
248+
if method = context.find_method_from_hash(method_name, singleton)
267249
merge_documentation method, comment, type_signature_lines
268250
return
269251
end

‎test/rdoc/parser/rbs_test.rb‎

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -166,47 +166,25 @@ def name: () -> String
166166
assert_equal ['() -> String'], name.type_signature_lines
167167
end
168168

169-
def test_scan_indexes_forward_method_and_attribute_aliases
169+
def test_scan_indexes_forward_attribute_alias
170170
util_parser(<<~RBS).scan
171171
class Sample
172-
# Method alias docs.
173-
alias salutation greet
174172
alias display_name name
175173
176-
def greet: () -> String
177174
# Base attribute docs.
178175
attr_reader name: String
179176
180-
# Dedicated method docs.
181-
def salutation: () -> String
182177
# Dedicated attribute docs.
183178
attr_reader display_name: String
184179
end
185180
RBS
186181

187182
sample = @store.find_class_named 'Sample'
188-
salutation = sample.find_method 'salutation', false
189183
display_name = sample.find_attribute 'display_name', false
190184

191-
assert_equal "Method alias docs.\n---\nDedicated method docs.", salutation.comment.to_s.strip
192185
assert_equal "Base attribute docs.\n---\nDedicated attribute docs.", display_name.comment.to_s.strip
193186
end
194187

195-
def test_scan_treats_legacy_nil_singleton_as_instance_method
196-
ruby_top_level = @store.add_file 'sample.rb'
197-
sample = ruby_top_level.add_class RDoc::NormalClass, 'Sample'
198-
greet = RDoc::AnyMethod.new 'greet', singleton: nil
199-
sample.add_method greet
200-
201-
util_parser(<<~RBS).scan
202-
class Sample
203-
def greet: () -> String
204-
end
205-
RBS
206-
207-
assert_equal ['() -> String'], greet.type_signature_lines
208-
end
209-
210188
def test_scan_preserves_rbs_markdown_when_extending_method_documentation
211189
ruby_top_level = @store.add_file 'sample.rb'
212190
sample = ruby_top_level.add_class RDoc::NormalClass, 'Sample'

‎test/rdoc/parser/ruby_test.rb‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2722,6 +2722,13 @@ def test_read_directive_linear_performance
27222722
end
27232723
end
27242724

2725+
def test_alias_lookup_linear_performance
2726+
assert_linear_performance([1, 10, 100]) do |factor|
2727+
methods = Array.new(factor * 100) { |i| " def m#{i}; end\n alias a#{i} m#{i}" }.join("\n")
2728+
util_parser "class C#{factor}\n#{methods}\nend\n"
2729+
end
2730+
end
2731+
27252732
def test_code_object_token_stream
27262733
util_parser <<~RUBY
27272734
class Foo

‎test/rdoc/rdoc_context_test.rb‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,16 @@ def test_find_attribute_named
541541
assert_equal 'RW', @c1.find_attribute_named('attr_accessor').rw
542542
end
543543

544+
def test_find_attribute_from_hash
545+
singleton = RDoc::Attr.new 'singleton', 'R', nil, singleton: true
546+
@context.add_attribute singleton
547+
548+
assert_same @c1.find_attribute_named('attr_reader'), @c1.find_attribute_from_hash('attr_reader', false)
549+
assert_same @c1.find_attribute_named('attr_writer'), @c1.find_attribute_from_hash('attr_writer=', false)
550+
assert_same singleton, @context.find_attribute_from_hash('singleton', true)
551+
assert_nil @c1.find_attribute_from_hash('attr_reader', true)
552+
end
553+
544554
def test_find_class_method_named
545555
assert_nil @c1.find_class_method_named('none')
546556

@@ -584,6 +594,16 @@ def test_find_method
584594
assert_equal @c2_b, loaded_c2.find_method('b', nil)
585595
end
586596

597+
def test_find_method_from_hash
598+
instance = RDoc::AnyMethod.new 'instance', singleton: nil
599+
@context.add_method instance
600+
601+
assert_same instance, @context.find_method_from_hash('instance', false)
602+
assert_same instance, @context.find_method_from_hash('instance', nil)
603+
assert_same @c1__m, @c1.find_method_from_hash('m', true)
604+
assert_nil @c1.find_method_from_hash('attr', false)
605+
end
606+
587607
def test_find_method_named
588608
assert_equal true, @c1.find_method_named('m').singleton
589609
end

0 commit comments

Comments
 (0)