File tree Expand file tree Collapse file tree 3 files changed +54
-1
lines changed
Expand file tree Collapse file tree 3 files changed +54
-1
lines changed Original file line number Diff line number Diff line change @@ -92,10 +92,18 @@ def is_alias_for
9292 @is_alias_for = found if found
9393 @is_alias_for
9494 else
95- @is_alias_for
95+ @is_alias_for ||= find_alias_for
9696 end
9797 end
9898
99+ # Find alias constant for a value.
100+ # This is used when the constant is parsed before the class or module defined in another file.
101+ # Note that module nesting information is lost, so constant lookup is inaccurate.
102+
103+ def find_alias_for
104+ parent . find_module_named ( value ) if value &.match? ( /\A (::)?([A-Z][A-Za-z0-9_]*)(::[A-Z][A-Za-z0-9_]*)*\z / )
105+ end
106+
99107 def inspect # :nodoc:
100108 "#<%s:0x%x %s::%s>" % [
101109 self . class , object_id ,
Original file line number Diff line number Diff line change @@ -439,6 +439,7 @@ def add_constant(constant)
439439 known . value = constant . value if
440440 known . value . nil? or known . value . strip . empty?
441441
442+ constant . parent = self
442443 known . is_alias_for ||= constant . is_alias_for
443444 else
444445 @constants_hash [ constant . name ] = constant
Original file line number Diff line number Diff line change @@ -1638,6 +1638,50 @@ class Bar; end
16381638 assert_equal 'Foo::C' , klass . find_module_named ( 'C' ) . full_name
16391639 end
16401640
1641+ def test_constant_alias_reverse_order
1642+ util_parser <<~RUBY
1643+ # Parsed first
1644+ class Foo
1645+ A = Bar
1646+ B = Foo::Bar
1647+ C = Baz
1648+ end
1649+
1650+ # Parsed later
1651+ class Foo
1652+ class Bar; end
1653+ end
1654+ class Baz; end
1655+ RUBY
1656+ klass = @top_level . classes . first
1657+ assert_equal 'Foo::Bar' , klass . find_constant_named ( 'A' ) . is_alias_for . full_name
1658+ assert_equal 'Foo::Bar' , klass . find_constant_named ( 'B' ) . is_alias_for . full_name
1659+ assert_equal 'Baz' , klass . find_constant_named ( 'C' ) . is_alias_for . full_name
1660+ end
1661+
1662+ def test_repeated_constant_alias
1663+ util_parser <<~RUBY
1664+ # Parsed first
1665+ class Foo
1666+ if cond
1667+ A = Bar
1668+ B = Baz
1669+ else
1670+ A = Bar
1671+ B = Baz
1672+ end
1673+ end
1674+
1675+ # Parsed later
1676+ class Baz
1677+ end
1678+ RUBY
1679+ klass = @top_level . classes . first
1680+ assert_equal 'Bar' , klass . find_constant_named ( 'A' ) . value
1681+ assert_nil klass . find_constant_named ( 'A' ) . is_alias_for
1682+ assert_equal 'Baz' , klass . find_constant_named ( 'B' ) . is_alias_for . full_name
1683+ end
1684+
16411685 def test_constant_with_singleton_class
16421686 omit if accept_legacy_bug?
16431687 util_parser <<~RUBY
You can’t perform that action at this time.
0 commit comments