NewPrerequisitesEngine and Overrides

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

NewPrerequisitesEngine and Overrides

Wolfgang Mayer
We recently discovered that NewPrerequisitesEngine may not find all
possible dependencies if overridden methods are present:

PackageA defines method Object>>foo.
PackageB overrides method foo.
PackageC sends #foo.

Assume Object>>foo is the only implementor of #foo.

NewPrerequisitesEngine misses the dependency of PackageC on PackageA or
PackageB, since #foo is multiply-packaged.

Patching
PrerequisiteTracer>>addSinglyPackagedSentMessages
to consider only the topmost overriding package for each method seems to
fix this issue for us. (In the above example, a dependency on PackageB
would be flagged.) I've attached the patch in case anyone is interested.


- Wolfgang

<?xml version="1.0"?>

<st-source>
<time-stamp>From VisualWorks® NonCommercial, 7.4.1 of May 30, 2006 on April 17, 2007 at 2:51:29 am</time-stamp>


<methods>
<class-id>Refactory.Browser.PrerequisiteTracer</class-id> <category>tracing</category>

<body package="NewPrerequisiteEngine" selector="addSinglyPackagedSentMessages">addSinglyPackagedSentMessages
        | singlyPackaged doublyPackaged |
        doublyPackaged := Set new.
        singlyPackaged := Dictionary new.
        self enumerateImplementorsOfSentMessages:
                        [:eachMethod |
                        | selector |
                        selector := eachMethod selector.
                        (doublyPackaged includes: selector)
                                ifFalse:
                                        [| package |
                                        package := (self registry containingPackageForSelector: selector class: eachMethod mclass).
                                        package notNil ifTrue:
                                                                [| notedPackage |
                                                                notedPackage := singlyPackaged at: selector ifAbsent: [nil].
                                                                notedPackage == nil
                                                                        ifTrue: [singlyPackaged at: selector put: package]
                                                                        ifFalse:
                                                                                [notedPackage = package
                                                                                        ifFalse:
                                                                                                [doublyPackaged add: selector.
                                                                                                singlyPackaged removeKey: selector]]]]].
        singlyPackaged
                keysAndValuesDo: [:selector :itsPackage | self addPackage: itsPackage forSentMessage: selector]</body>
</methods>

</st-source>
Reply | Threaded
Open this post in threaded view
|

Re: NewPrerequisitesEngine and Overrides

Travis Griggs-3
On Apr 17, 2007, at 2:56, Wolfgang Mayer wrote:

We recently discovered that NewPrerequisitesEngine may not find all
possible dependencies if overridden methods are present:

PackageA defines method Object>>foo.
PackageB overrides method foo.
PackageC sends #foo.

Assume Object>>foo is the only implementor of #foo.

NewPrerequisitesEngine misses the dependency of PackageC on PackageA or
PackageB, since #foo is multiply-packaged.

Patching
PrerequisiteTracer>>addSinglyPackagedSentMessages
to consider only the topmost overriding package for each method seems to
fix this issue for us. (In the above example, a dependency on PackageB
would be flagged.) I've attached the patch in case anyone is interested.

Cool. I'm glad you've got something that works for your stuff. There is no correct way to do this as far as I can tell, since it is context dependent. Sounds like for your context, B turns out being the correct prereq? I can imagine scenarios both ways. One's where I would want it to remain A. And those where it should be B.

Of note. There are two kinds of prerequisite computation in there. The first is the "hard and fast" kind. This class needs this environment, etc. The second is the "probably" kind. This second catches many that wouldn't be caught otherwise, but can't ever be perfect. Looking for singly packaged message sends is in this category.

Of note, the override thing causes an even nastier problem for the "hard and fast" prereqs. Because if package B redefines a namespace of A, and C defines classes in that namespace, it will switch to finding B as the prereq, rather than A. IIRC.

--
Travis Griggs
Objologist
What's next, Intel Processors branded with "Apple Outside" stickers?