Commit f4db99c
committed
Stop lazy alias resolver from overwriting real classes
Fixes #1662.
PR #1621 made RDoc::Constant#is_alias_for fall through to a lazy
find_alias_for lookup that returned whatever class the constant's value
named in the current store. The lazy result then flowed into
RDoc::ClassModule#update_aliases, which unconditionally wrote a dup'd
alias copy into @store.classes_hash, with two safeguards present
elsewhere bypassed:
* Context#add_module_alias refuses to clobber an existing class entry
(the historic BasicObject = BlankSlate guard), but update_aliases
did not.
* The prism parser only registers an alias when the constant has
document_self set (so :nodoc: is honored), but the lazy resolver
ignored it.
In combination these meant `Foo = Bar # :nodoc:`, where a real `Foo`
class was parsed elsewhere, would silently replace the real class's
documentation with an alias copy of `Bar` -- the literal failure mode
in #1662 (the prism shim's `Ripper = Prism::Translation::Ripper`
clobbering the real Ripper class docs).
Architectural fix
-----------------
Split RDoc::Constant#is_alias_for back into a pure accessor and a
separate Constant#resolved_alias_target lookup. is_alias_for now
returns only what was recorded explicitly (by Context#add_module_alias,
by ClassModule#update_aliases, or by ri marshal load) and never mutates
state. resolved_alias_target is the opportunistic forward-reference
lookup, used only by update_aliases as a fallback when no explicit
alias is recorded; it honors document_self so :nodoc: constants
don't lazy-resolve.
The lazy lookup itself uses a new Constant#is_alias_for_path attribute
populated by the parsers, instead of regex-matching #value at lookup
time. Both the prism parser (via ConstantReadNode/ConstantPathNode
detection in constant_path_string) and the legacy ripper parser (via
on_const-only token accumulation in parse_constant_body) already know
whether the RHS is a constant reference at parse time; we now propagate
that explicitly rather than rediscovering it from a stringly-typed
value.
Mechanical fix
--------------
ClassModule#update_aliases falls back to const.resolved_alias_target
when const.is_alias_for is unset, and gates the destination write
behind a collision check that mirrors the one in
Context#add_module_alias: skip if classes_hash/modules_hash already
holds a real (non-alias) class at the destination name. The guard now
applies uniformly to both the explicit and lazy paths.
When the fallback resolves a forward-reference target, the resolved
class is also written back to const.is_alias_for so downstream
consumers (RDoc::Stats#report_constants, RDoc::Constant#marshal_dump)
observe the alias relationship the lazy lookup found -- otherwise
forward-ref aliases get reported as undocumented and the alias slot is
serialized as nil into ri data.
For that guard to compose with add_module_alias's pre-registration
flow (which already places an alias copy at the destination expecting
update_aliases to overwrite it with the properly-marked version),
add_module_alias now sets is_alias_for on the alias copy at creation
time. Existing alias copies are therefore distinguishable from real
classes by the unconditional guard.
Tests
-----
Parser-level regressions cover :nodoc: assignment, real-class
collision, the combined :nodoc:-plus-collision scenario from #1662,
the :stopdoc:/:startdoc: workaround path, an explicit alias followed
by a same-named class re-open (which under the new guard preserves
both the alias target's methods and the methods added by the re-open),
and the post-Store#complete is_alias_for persistence on a
forward-reference alias. Each asserts both the negative (the would-be
alias didn't clobber) and the positive (the alias target keeps its
own methods and aliases list). Unit tests on update_aliases assert
the same. The two existing PR #1621 tests
(test_constant_alias_reverse_order, test_repeated_constant_alias) are
updated to exercise the renamed resolved_alias_target API; the
underlying forward-reference behavior is preserved.1 parent c5247f7 commit f4db99c
7 files changed
Lines changed: 260 additions & 25 deletions
File tree
- lib/rdoc
- code_object
- parser
- test/rdoc
- code_object
- parser
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
847 | 847 | | |
848 | 848 | | |
849 | 849 | | |
850 | | - | |
| 850 | + | |
| 851 | + | |
| 852 | + | |
| 853 | + | |
| 854 | + | |
| 855 | + | |
| 856 | + | |
| 857 | + | |
| 858 | + | |
851 | 859 | | |
852 | 860 | | |
853 | 861 | | |
| |||
866 | 874 | | |
867 | 875 | | |
868 | 876 | | |
| 877 | + | |
| 878 | + | |
| 879 | + | |
| 880 | + | |
| 881 | + | |
| 882 | + | |
| 883 | + | |
| 884 | + | |
869 | 885 | | |
870 | 886 | | |
871 | 887 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
29 | 37 | | |
30 | 38 | | |
31 | 39 | | |
| |||
35 | 43 | | |
36 | 44 | | |
37 | 45 | | |
38 | | - | |
39 | | - | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
40 | 49 | | |
41 | 50 | | |
42 | 51 | | |
| |||
83 | 92 | | |
84 | 93 | | |
85 | 94 | | |
86 | | - | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
87 | 99 | | |
88 | 100 | | |
89 | 101 | | |
| |||
92 | 104 | | |
93 | 105 | | |
94 | 106 | | |
95 | | - | |
| 107 | + | |
96 | 108 | | |
97 | 109 | | |
98 | 110 | | |
99 | | - | |
100 | | - | |
101 | | - | |
102 | | - | |
103 | | - | |
104 | | - | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
105 | 123 | | |
106 | 124 | | |
107 | 125 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
544 | 544 | | |
545 | 545 | | |
546 | 546 | | |
| 547 | + | |
547 | 548 | | |
548 | 549 | | |
549 | 550 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
767 | 767 | | |
768 | 768 | | |
769 | 769 | | |
770 | | - | |
| 770 | + | |
771 | 771 | | |
772 | 772 | | |
773 | 773 | | |
| |||
776 | 776 | | |
777 | 777 | | |
778 | 778 | | |
| 779 | + | |
779 | 780 | | |
780 | 781 | | |
781 | 782 | | |
782 | 783 | | |
| 784 | + | |
783 | 785 | | |
784 | | - | |
785 | | - | |
| 786 | + | |
| 787 | + | |
786 | 788 | | |
787 | | - | |
| 789 | + | |
788 | 790 | | |
789 | 791 | | |
790 | 792 | | |
791 | | - | |
| 793 | + | |
792 | 794 | | |
793 | 795 | | |
794 | 796 | | |
| |||
1056 | 1058 | | |
1057 | 1059 | | |
1058 | 1060 | | |
| 1061 | + | |
1059 | 1062 | | |
1060 | 1063 | | |
1061 | | - | |
| 1064 | + | |
1062 | 1065 | | |
1063 | | - | |
| 1066 | + | |
| 1067 | + | |
1064 | 1068 | | |
1065 | 1069 | | |
1066 | 1070 | | |
1067 | 1071 | | |
1068 | 1072 | | |
1069 | 1073 | | |
1070 | 1074 | | |
| 1075 | + | |
1071 | 1076 | | |
1072 | 1077 | | |
1073 | | - | |
| 1078 | + | |
1074 | 1079 | | |
1075 | | - | |
| 1080 | + | |
| 1081 | + | |
1076 | 1082 | | |
1077 | 1083 | | |
1078 | 1084 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
170 | 170 | | |
171 | 171 | | |
172 | 172 | | |
| 173 | + | |
173 | 174 | | |
174 | 175 | | |
175 | 176 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1459 | 1459 | | |
1460 | 1460 | | |
1461 | 1461 | | |
| 1462 | + | |
| 1463 | + | |
| 1464 | + | |
| 1465 | + | |
| 1466 | + | |
| 1467 | + | |
| 1468 | + | |
| 1469 | + | |
| 1470 | + | |
| 1471 | + | |
| 1472 | + | |
| 1473 | + | |
| 1474 | + | |
| 1475 | + | |
| 1476 | + | |
| 1477 | + | |
| 1478 | + | |
| 1479 | + | |
| 1480 | + | |
| 1481 | + | |
| 1482 | + | |
| 1483 | + | |
| 1484 | + | |
| 1485 | + | |
| 1486 | + | |
| 1487 | + | |
| 1488 | + | |
| 1489 | + | |
| 1490 | + | |
| 1491 | + | |
| 1492 | + | |
| 1493 | + | |
| 1494 | + | |
| 1495 | + | |
| 1496 | + | |
| 1497 | + | |
| 1498 | + | |
| 1499 | + | |
| 1500 | + | |
| 1501 | + | |
| 1502 | + | |
| 1503 | + | |
| 1504 | + | |
| 1505 | + | |
| 1506 | + | |
| 1507 | + | |
| 1508 | + | |
| 1509 | + | |
| 1510 | + | |
| 1511 | + | |
1462 | 1512 | | |
1463 | 1513 | | |
1464 | 1514 | | |
| |||
0 commit comments