Fix incorrect method visibility when merging with existing store cache#1736
Fix incorrect method visibility when merging with existing store cache#17364lllex wants to merge 1 commit into
Conversation
Running Store#save with already existing cache incorrectly sets method visibility to `:private` on all methods.
|
|
||
| merge_collections method_list, cm.method_list, other_files do |add, meth| | ||
| if add then | ||
| @visibility = meth.visibility |
There was a problem hiding this comment.
Nice catch on the root cause - merge is definitely reusing a stale @visibility left over from marshal_load.
I'd suggest fixing this one level down instead. Visibility is lexical state, and Parser::Ruby already tracks it separately in its own @visibility - it never touches Context#visibility. So add_method overwriting method.visibility with the container's @visibility is a leftover from the old design, and every caller passing in an already-complete method has to work around it:
marshal_loadsets@visibilityjust soadd_methodpicks it upmerge(this bug) inherits whatmarshal_loadleft behindprepare_to_embedassignsself.visibility = code_object.visibilityback onto
the container, with a comment explaining the workaroundParser::Rubyorders its calls carefully:
a.visibility = visibility # should set after adding to container
Dropping the assignment in add_method (and the matching one in add_attribute) fixes this at the root and lets all four workarounds go away.
No new argument needed - AnyMethod already defaults to :public and every caller sets visibility itself, so marshal_load just does method.visibility = visibility directly.
Running
Store#savewith already existing cache incorrectly sets method visibility to:privateon all methods.@visibilitygets set during marshal_load:rdoc/lib/rdoc/code_object/class_module.rb
Lines 440 to 448 in bb8b2d4
and is reused during
merge->add_method:rdoc/lib/rdoc/code_object/class_module.rb
Lines 539 to 542 in bb8b2d4
rdoc/lib/rdoc/code_object/context.rb
Line 494 in bb8b2d4
Example:
Fixes #346