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> |
On Apr 17, 2007, at 2:56, Wolfgang Mayer wrote:
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? |
Free forum by Nabble | Edit this page |