Skip to content

Resolve class and method of the same name correctly #853

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 28 additions & 20 deletions lib/rdoc/cross_reference.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class RDoc::CrossReference
#
# See CLASS_REGEXP_STR

METHOD_REGEXP_STR = '([a-z]\w*[!?=]?|%|===?|\[\]=?|<<|>>|\+@|-@|-|\+|\*)(?:\([\w.+*/=<>-]*\))?'
METHOD_REGEXP_STR = '([A-Za-z]\w*[!?=]?|%|===?|\[\]=?|<<|>>|\+@|-@|-|\+|\*)(?:\([\w.+*/=<>-]*\))?'

##
# Regular expressions matching text that should potentially have
Expand All @@ -34,12 +34,6 @@ class RDoc::CrossReference
# A::B::C.meth
#{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR}

# Stand-alone method (preceded by a #)
| \\?\##{METHOD_REGEXP_STR}

# Stand-alone method (preceded by ::)
| ::#{METHOD_REGEXP_STR}

# A::B::C
# The stuff after CLASS_REGEXP_STR is a
# nasty hack. CLASS_REGEXP_STR unfortunately matches
Expand All @@ -56,6 +50,12 @@ class RDoc::CrossReference
# marker.
| #{CLASS_REGEXP_STR}(?=[@\s).?!,;<\000]|\z)

# Stand-alone method (preceded by a #)
| \\?\##{METHOD_REGEXP_STR}

# Stand-alone method (preceded by ::)
| ::#{METHOD_REGEXP_STR}

# Things that look like filenames
# The key thing is that there must be at least
# one special character (period, slash, or
Expand All @@ -82,12 +82,12 @@ class RDoc::CrossReference
# A::B::C.meth
#{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR}

# Stand-alone method
| \\?#{METHOD_REGEXP_STR}

# A::B::C
| #{CLASS_REGEXP_STR}(?=[@\s).?!,;<\000]|\z)

# Stand-alone method
| \\?#{METHOD_REGEXP_STR}

# Things that look like filenames
| (?:\.\.\/)*[-\/\w]+[_\/.][-\w\/.]+

Expand Down Expand Up @@ -115,15 +115,8 @@ def initialize context
@seen = {}
end

##
# Returns a reference to +name+.
#
# If the reference is found and +name+ is not documented +text+ will be
# returned. If +name+ is escaped +name+ is returned. If +name+ is not
# found +text+ is returned.

def resolve name, text
return @seen[name] if @seen.include? name
def resolve_method name
ref = nil

if /#{CLASS_REGEXP_STR}([.#]|::)#{METHOD_REGEXP_STR}/o =~ name then
type = $2
Expand Down Expand Up @@ -165,12 +158,27 @@ def resolve name, text
end
end

ref
end

##
# Returns a reference to +name+.
#
# If the reference is found and +name+ is not documented +text+ will be
# returned. If +name+ is escaped +name+ is returned. If +name+ is not
# found +text+ is returned.

def resolve name, text
return @seen[name] if @seen.include? name

ref = case name
when /^\\(#{CLASS_REGEXP_STR})$/o then
@context.find_symbol $1
else
@context.find_symbol name
end unless ref
end

ref = resolve_method name unless ref

# Try a page name
ref = @store.page name if not ref and name =~ /^[\w.]+$/
Expand Down
4 changes: 2 additions & 2 deletions test/rdoc/test_rdoc_class_module.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def test_add_comment_stopdoc
end

def test_ancestors
assert_equal [@parent, "Object"], @child.ancestors
assert_equal [@parent, @object, "BasicObject"], @child.ancestors
end

def test_comment_equals
Expand Down Expand Up @@ -129,7 +129,7 @@ def test_documented_eh
end

def test_each_ancestor
assert_equal [@parent], @child.each_ancestor.to_a
assert_equal [@parent, @object], @child.each_ancestor.to_a
end

def test_each_ancestor_cycle
Expand Down
2 changes: 1 addition & 1 deletion test/rdoc/test_rdoc_context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def test_add_class_basic_object

basic = @c1.find_module_named 'BasicObject'

assert_equal 'Object', basic.superclass
assert_equal @object, basic.superclass
end

def test_add_class_object
Expand Down
9 changes: 9 additions & 0 deletions test/rdoc/test_rdoc_cross_reference.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ def test_resolve_C4_C4
assert_ref @c4_c4, 'C4'
end

def test_resolve_class_and_method_of_the_same_name
assert_ref @c10_class, 'C10'
assert_ref @c10_method, '#C10'
assert_ref @c11_class, 'C11'
assert_ref @c11_method, '#C11'
assert_ref @c10_c11_class, 'C10::C11'
assert_ref @c10_c11_method, 'C10#C11'
end

def test_resolve_class
assert_ref @c1, 'C1'
refute_ref 'H1'
Expand Down
8 changes: 4 additions & 4 deletions test/rdoc/test_rdoc_extend.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def test_module_extended
m1_m2_k0.add_extend e0_m3

assert_equal [e0_m4, e0_m5, e0_m6, e0_m1, e0_m2, e0_m3], m1_m2_k0.extends
assert_equal ['Object'], m1_m2_k0.ancestors
assert_equal [@object, 'BasicObject'], m1_m2_k0.ancestors

m1_k1 = m1.add_class RDoc::NormalClass, 'Klass1'

Expand All @@ -60,7 +60,7 @@ def test_module_extended
m1_k1.add_extend e1_k0_m4

assert_equal [e1_m1, e1_m2, e1_m3, e1_m4, e1_k0_m4], m1_k1.extends
assert_equal ['Object'], m1_k1.ancestors
assert_equal [@object, 'BasicObject'], m1_k1.ancestors

m1_k2 = m1.add_class RDoc::NormalClass, 'Klass2'

Expand All @@ -75,7 +75,7 @@ def test_module_extended
m1_k2.add_extend e2_k0_m4

assert_equal [e2_m1, e2_m3, e2_m2, e2_k0_m4], m1_k2.extends
assert_equal ['Object'], m1_k2.ancestors
assert_equal [@object, 'BasicObject'], m1_k2.ancestors

m1_k3 = m1.add_class RDoc::NormalClass, 'Klass3'

Expand All @@ -88,7 +88,7 @@ def test_module_extended
m1_k3.add_extend e3_m4

assert_equal [e3_m1, e3_m2, e3_m4], m1_k3.extends
assert_equal ['Object'], m1_k3.ancestors
assert_equal [@object, 'BasicObject'], m1_k3.ancestors
end

end
Expand Down
11 changes: 6 additions & 5 deletions test/rdoc/test_rdoc_include.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def test_module_extended

assert_equal [i0_m4, i0_m5, i0_m6, i0_m1, i0_m2, i0_m3], m1_m2_k0.includes
assert_equal [m1_m2_m3, m1_m2, m1, m1_m2_k0_m4_m6, m1_m2_k0_m5,
m1_m2_k0_m4, 'Object'], m1_m2_k0.ancestors
m1_m2_k0_m4, @object, 'BasicObject'], m1_m2_k0.ancestors

m1_k1 = m1.add_class RDoc::NormalClass, 'Klass1'

Expand All @@ -63,8 +63,8 @@ def test_module_extended
m1_k1.add_include i1_k0_m4

assert_equal [i1_m1, i1_m2, i1_m3, i1_m4, i1_k0_m4], m1_k1.includes
assert_equal [m1_m2_k0_m4, m1_m2_m3_m4, m1_m2_m3, m1_m2, m1, 'Object'],
m1_k1.ancestors
assert_equal [m1_m2_k0_m4, m1_m2_m3_m4, m1_m2_m3, m1_m2, m1, @object,
'BasicObject'], m1_k1.ancestors

m1_k2 = m1.add_class RDoc::NormalClass, 'Klass2'

Expand All @@ -79,7 +79,8 @@ def test_module_extended
m1_k2.add_include i2_k0_m4

assert_equal [i2_m1, i2_m3, i2_m2, i2_k0_m4], m1_k2.includes
assert_equal [m1_m2_k0_m4, m1_m2, m1_m3, m1, 'Object'], m1_k2.ancestors
assert_equal [m1_m2_k0_m4, m1_m2, m1_m3, m1, @object, 'BasicObject'],
m1_k2.ancestors

m1_k3 = m1.add_class RDoc::NormalClass, 'Klass3'

Expand All @@ -92,7 +93,7 @@ def test_module_extended
m1_k3.add_include i3_m4

assert_equal [i3_m1, i3_m2, i3_m4], m1_k3.includes
assert_equal [m1_m2_m4, m1_m2, m1, 'Object'], m1_k3.ancestors
assert_equal [m1_m2_m4, m1_m2, m1, @object, 'BasicObject'], m1_k3.ancestors
end

def test_store_equals
Expand Down
4 changes: 2 additions & 2 deletions test/rdoc/test_rdoc_normal_class.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ def test_ancestors
sub_klass.superclass = klass
sub_klass.add_include incl

assert_equal [incl.name, klass, 'Object'], sub_klass.ancestors
assert_equal [incl.name, klass, @object, 'BasicObject'], sub_klass.ancestors
end

def test_ancestors_multilevel
c1 = @top_level.add_class RDoc::NormalClass, 'Outer'
c2 = @top_level.add_class RDoc::NormalClass, 'Middle', c1.full_name
c3 = @top_level.add_class RDoc::NormalClass, 'Inner', c2.full_name

assert_equal [c2, c1, 'Object'], c3.ancestors
assert_equal [c2, c1, @object, 'BasicObject'], c3.ancestors
end

def test_aref
Expand Down
6 changes: 4 additions & 2 deletions test/rdoc/test_rdoc_store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,10 @@ def test_add_file_relative

def test_all_classes_and_modules
expected = %w[
C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1 C6 C7 C8 C8::S1 C9 C9::A C9::B
C1 C10 C10::C11 C11 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1 C6 C7 C8 C8::S1 C9 C9::A C9::B
Child
M1 M1::M2
Object
Parent
]

Expand Down Expand Up @@ -212,8 +213,9 @@ def test_class_path

def test_classes
expected = %w[
C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1 C6 C7 C8 C8::S1 C9 C9::A C9::B
C1 C10 C10::C11 C11 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1 C6 C7 C8 C8::S1 C9 C9::A C9::B
Child
Object
Parent
]

Expand Down
4 changes: 2 additions & 2 deletions test/rdoc/test_rdoc_top_level.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def test_add_method
@top_level.add_method method

object = @store.find_class_named 'Object'
assert_equal [method], object.method_list
assert_equal [@c10_method, @c11_method, method], object.method_list
assert_includes object.in_files, @top_level
end

Expand All @@ -101,7 +101,7 @@ def test_add_method_stopdoc
@top_level.add_method method

object = @store.find_class_named('Object')
assert_empty object.method_list
assert_equal [@c10_method, @c11_method], object.method_list
assert_includes object.in_files, @top_level
end

Expand Down
17 changes: 17 additions & 0 deletions test/rdoc/xref_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,23 @@ def bar() end
end
end

class C10
class C11
end

def C11
end
end

def C10
end

class C11
end

def C11
end

module M1
def m
end
Expand Down
8 changes: 8 additions & 0 deletions test/rdoc/xref_test_case.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ def generator.file_dir() nil end
@c9_b_c_foo = @c9_b.method_list.first
@c9_b_i_bar = @c9_b.method_list.last

@object = @xref_data.find_module_named 'Object'
@c10_class = @xref_data.find_module_named 'C10'
@c10_method = @object.find_method_named 'C10'
@c11_class = @xref_data.find_module_named 'C11'
@c10_c11_class = @c10_class.find_module_named 'C11'
@c10_c11_method = @c10_class.find_method_named 'C11'
@c11_method = @object.find_method_named 'C11'

@m1 = @xref_data.find_module_named 'M1'
@m1_m = @m1.method_list.first

Expand Down