Method recompilation booboo

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Method recompilation booboo

Blair McGlashan
You may notice that certain class refactorings (or simple class
modifications) that cause a class' methods to be recompiled will mean that
all the its methods will disappear from any browser in which it is selected.
This is to do with the fact that a #methodUpdated: event is now triggered
when a method is recompiled (after all the installed method has actually
been replaced, and so any tool that holds method instances may need to
update). Unfortunately there is a bit of a sequencing issue which means that
the browsers recognise the old method as being in need of replacement, but
the new method fails to pass the "filter" because the class builder has not
yet installed the class at the time it compiles the methods into the "new"
class.

Anyway the workaround is to change selection in the browser in any way that
refreshes the method list.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: Method recompilation booboo

Blair McGlashan
"Blair McGlashan" <[hidden email]> wrote in message
news:[hidden email]...
> You may notice that certain class refactorings (or simple class
> modifications) that cause a class' methods to be recompiled will mean that
> all the its methods will disappear from any browser in which it is
selected.
>...

Actually this is worse than I first discovered. The recompiled classes get
marked as changed too, and this happens before the class has been installed,
which can cause a number of issues. I strongly recommend that everyone
install the following patch, which I will also post as a separate top-level
thread so it is not missed.

Regards

Blair
----------------------------
!PackageManager methodsFor!

getLooseMethods
 "Private - Answer a <LookupTable> of all the <CompiledMethod>s which are
owned by
 packages which do not own the corresponding method class (i.e. those
methods
 added by a package to classes in other packages). The table maps the loose
method to
 the owning package."

 | loose |
 loose := PluggableLookupTable new: 1500 searchPolicy:
CompiledMethodSearchPolicy current.
 self packages do: [:each | loose atAll: each methods put: each].
 ^loose
! !
!PackageManager categoriesFor: #getLooseMethods!helpers!private! !

!Behavior methodsFor!

recompile: aSelector
 "Compile the method associated with the message selector, selector.
 The method is not logged to the change log but the source is re-used
 from the original"

 | oldMethod method stubMethod result error |
 oldMethod := self compiledMethodAt: aSelector.
 oldMethod isNil ifTrue: [^self].
 [result := self compilerClass compile: oldMethod getSource in: self flags:
0]
  on: CompilerErrorNotification
  do:
   [:ex |
   error := ex.
   stubMethod := (MethodCompileFailed with: ex) signal: ex description.
   ex pass].

 "Was a stub method installed?"
 stubMethod notNil ifTrue: [result := stubMethod].
 (result notNil and: [(method := result method) notNil])
  ifTrue:
   ["Add the selector and copy across the old source descriptor and privacy,
as we haven't don't want to change either"
   self addSelector: method selector withMethod: method.
   method
    sourceDescriptor: oldMethod sourceDescriptor;
    isPrivate: oldMethod isPrivate]! !
!Behavior categoriesFor: #recompile:!compiling!public! !

Package manager forgetLooseMethods!