Commit a05abc5
authored
Resolve retroactive singleton method visibility changes (#781)
Part of #89 and follows #780, which added the `SINGLETON_METHOD_VISIBILITY` bit flag and indexed singleton-flagged `MethodVisibilityDefinition`s.
This PR routes singleton-flagged defs through the singleton class and folds the singleton path into the existing `resolve_method_visibilities` pass. Visibility definitions are processed after the main convergence loop, so the target method declaration is guaranteed to exist by the time we attach visibility.
For inherited targets like `private_class_method :foo` where `foo` comes from a parent class's singleton, we create a child-owned `MethodDeclaration` on the child's singleton class. This matches what #738 did for instance methods, and what Ruby reports when you ask `Child.singleton_class.instance_method(:foo).owner`:
```ruby
class Parent
def self.foo; end
end
class Child < Parent
private_class_method :foo
end
Child.singleton_class.instance_method(:foo).owner
# => #<Class:Child> (Ruby copies the method to Child when visibility changes)
Parent.singleton_class.instance_method(:foo).owner
# => #<Class:Parent> (untouched on the parent)
```
### Why document-scoped diagnostics for the singleton path
When a singleton target doesn't resolve, the diagnostic attaches to the document, not to the singleton declaration. Walking ancestors via `get_or_create_singleton_class(Foo, ...)` can synthesize `Foo::<Foo>` as a side effect, even when it has no real members. For `class Foo; private_class_method :missing; end` where `Foo` has no other singleton methods, that synthetic singleton class only exists to host the diagnostic. Attaching to it would leak the declaration on file delete. Document-scoped clears with the file. Instance-method diagnostics keep their existing declaration scope: their owner can't be synthetic.
### Source-order processing of visibility defs
Ruby applies visibility statements in the order they appear in source, so the later one wins:
```ruby
class Foo
def bar; end
private :bar
public :bar # Ruby: bar is Public
end
```
This was already broken on `main` for instance methods; surfaced while wiring up the singleton path, fixed here for both. `prepare_units` sorted `definitions` and `const_refs` by `(uri_id, offset)` for determinism but left `others` (which holds the visibility defs queued by `handle_remaining_definitions`) in `IdentityHashMap` iteration order, which is bucket-hash order. So `Foo#bar` could end up `Private` because the resolver happened to apply `public` first and `private` second. Same sort applied to `others` so the override-order invariant holds for both instance and singleton paths.
### In this PR
- branch on `is_singleton_method_visibility()` inside `resolve_method_visibilities`: resolve through `get_or_create_singleton_class` for the singleton path, render `"class method"` vs `"method"` in the diagnostic, attach document-scoped (singleton) vs declaration-scoped (instance)
- add `Graph::find_singleton_method_visibility_declaration` and route through it from the existing `Definition::MethodVisibility` arm in `definition_to_declaration_id` when the flag is set
- sort `others` by `(uri_id, offset)` in `prepare_units` so visibility overrides apply in source order4 files changed
Lines changed: 253 additions & 21 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
| 9 | + | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| |||
333 | 333 | | |
334 | 334 | | |
335 | 335 | | |
336 | | - | |
337 | | - | |
338 | | - | |
339 | | - | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
340 | 345 | | |
341 | 346 | | |
342 | 347 | | |
| |||
413 | 418 | | |
414 | 419 | | |
415 | 420 | | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
416 | 442 | | |
417 | 443 | | |
418 | 444 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
604 | 604 | | |
605 | 605 | | |
606 | 606 | | |
607 | | - | |
608 | | - | |
609 | | - | |
610 | | - | |
| 607 | + | |
| 608 | + | |
611 | 609 | | |
612 | 610 | | |
613 | 611 | | |
| |||
622 | 620 | | |
623 | 621 | | |
624 | 622 | | |
625 | | - | |
| 623 | + | |
| 624 | + | |
626 | 625 | | |
627 | 626 | | |
628 | 627 | | |
| |||
638 | 637 | | |
639 | 638 | | |
640 | 639 | | |
| 640 | + | |
641 | 641 | | |
642 | | - | |
| 642 | + | |
643 | 643 | | |
644 | 644 | | |
645 | 645 | | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
646 | 655 | | |
647 | 656 | | |
648 | 657 | | |
| |||
691 | 700 | | |
692 | 701 | | |
693 | 702 | | |
694 | | - | |
| 703 | + | |
695 | 704 | | |
696 | | - | |
697 | | - | |
698 | | - | |
699 | | - | |
700 | | - | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
701 | 717 | | |
702 | 718 | | |
703 | 719 | | |
| |||
1882 | 1898 | | |
1883 | 1899 | | |
1884 | 1900 | | |
1885 | | - | |
| 1901 | + | |
1886 | 1902 | | |
1887 | 1903 | | |
1888 | 1904 | | |
| |||
1922 | 1938 | | |
1923 | 1939 | | |
1924 | 1940 | | |
| 1941 | + | |
| 1942 | + | |
1925 | 1943 | | |
1926 | 1944 | | |
1927 | 1945 | | |
1928 | 1946 | | |
1929 | 1947 | | |
1930 | 1948 | | |
1931 | | - | |
1932 | | - | |
| 1949 | + | |
1933 | 1950 | | |
1934 | 1951 | | |
1935 | 1952 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4926 | 4926 | | |
4927 | 4927 | | |
4928 | 4928 | | |
| 4929 | + | |
| 4930 | + | |
| 4931 | + | |
| 4932 | + | |
| 4933 | + | |
| 4934 | + | |
| 4935 | + | |
| 4936 | + | |
| 4937 | + | |
| 4938 | + | |
| 4939 | + | |
| 4940 | + | |
| 4941 | + | |
| 4942 | + | |
| 4943 | + | |
| 4944 | + | |
| 4945 | + | |
| 4946 | + | |
| 4947 | + | |
4929 | 4948 | | |
4930 | 4949 | | |
4931 | 4950 | | |
| |||
5066 | 5085 | | |
5067 | 5086 | | |
5068 | 5087 | | |
5069 | | - | |
| 5088 | + | |
5070 | 5089 | | |
5071 | 5090 | | |
5072 | 5091 | | |
| |||
5306 | 5325 | | |
5307 | 5326 | | |
5308 | 5327 | | |
| 5328 | + | |
| 5329 | + | |
| 5330 | + | |
| 5331 | + | |
| 5332 | + | |
| 5333 | + | |
| 5334 | + | |
| 5335 | + | |
| 5336 | + | |
| 5337 | + | |
| 5338 | + | |
| 5339 | + | |
| 5340 | + | |
| 5341 | + | |
| 5342 | + | |
| 5343 | + | |
| 5344 | + | |
| 5345 | + | |
| 5346 | + | |
| 5347 | + | |
| 5348 | + | |
| 5349 | + | |
| 5350 | + | |
| 5351 | + | |
| 5352 | + | |
| 5353 | + | |
| 5354 | + | |
| 5355 | + | |
| 5356 | + | |
| 5357 | + | |
| 5358 | + | |
| 5359 | + | |
| 5360 | + | |
| 5361 | + | |
| 5362 | + | |
| 5363 | + | |
| 5364 | + | |
| 5365 | + | |
| 5366 | + | |
| 5367 | + | |
| 5368 | + | |
| 5369 | + | |
| 5370 | + | |
| 5371 | + | |
| 5372 | + | |
| 5373 | + | |
| 5374 | + | |
| 5375 | + | |
| 5376 | + | |
| 5377 | + | |
| 5378 | + | |
| 5379 | + | |
| 5380 | + | |
| 5381 | + | |
| 5382 | + | |
| 5383 | + | |
| 5384 | + | |
| 5385 | + | |
| 5386 | + | |
| 5387 | + | |
| 5388 | + | |
| 5389 | + | |
| 5390 | + | |
| 5391 | + | |
| 5392 | + | |
| 5393 | + | |
| 5394 | + | |
| 5395 | + | |
| 5396 | + | |
| 5397 | + | |
| 5398 | + | |
| 5399 | + | |
| 5400 | + | |
| 5401 | + | |
| 5402 | + | |
| 5403 | + | |
| 5404 | + | |
| 5405 | + | |
| 5406 | + | |
| 5407 | + | |
| 5408 | + | |
| 5409 | + | |
| 5410 | + | |
| 5411 | + | |
| 5412 | + | |
| 5413 | + | |
| 5414 | + | |
| 5415 | + | |
| 5416 | + | |
| 5417 | + | |
| 5418 | + | |
| 5419 | + | |
| 5420 | + | |
| 5421 | + | |
| 5422 | + | |
| 5423 | + | |
| 5424 | + | |
| 5425 | + | |
| 5426 | + | |
| 5427 | + | |
| 5428 | + | |
| 5429 | + | |
| 5430 | + | |
| 5431 | + | |
| 5432 | + | |
| 5433 | + | |
| 5434 | + | |
| 5435 | + | |
| 5436 | + | |
| 5437 | + | |
| 5438 | + | |
| 5439 | + | |
| 5440 | + | |
| 5441 | + | |
| 5442 | + | |
| 5443 | + | |
| 5444 | + | |
| 5445 | + | |
| 5446 | + | |
| 5447 | + | |
| 5448 | + | |
| 5449 | + | |
| 5450 | + | |
| 5451 | + | |
| 5452 | + | |
| 5453 | + | |
| 5454 | + | |
| 5455 | + | |
| 5456 | + | |
| 5457 | + | |
| 5458 | + | |
| 5459 | + | |
| 5460 | + | |
| 5461 | + | |
| 5462 | + | |
5309 | 5463 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
789 | 789 | | |
790 | 790 | | |
791 | 791 | | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
792 | 827 | | |
793 | 828 | | |
794 | 829 | | |
| |||
0 commit comments