I've been engaged (in my spare time) for about a year in refactoring associations so that they and their subclasses work a bit more rationally. And I almost have a change set that works!
The tricky bit was to get a change set that files in. This I now have, but it took a lot of hand work, because there are various checks to make sure that Association is NOT recompiled.
OK, so it files in. And most things seem to work. But the WeakIdentityKeyDictionary "ObsoleteSubclasses" (a class variable of Behavior) is messed up after the file in. It should, I think, hold a mapping between "Association" (that is, the class) and an array of its now obsolete subclasses #(WeakKeyAssocation). It actually holds a mapping between a weak "#(Association)" and that array. Very strange.
I think that it's my fault. WeakKeyAssociations used to be implemented by putting a weak one-element array in the key slot of an association. With my refactoring, they are now implemented by using the weak slot of a new subclass, HalfWeakAssociation, for the key and the strong slot for the value, which means that the relative positions of the slots have been switched.
Now, here is my question. Does something in the VM or the GC know about WeakKeyAssociations? That is, does something (think) that it knows about this hidden one-element array. Is that how the one element array is appearing in ObsoleteSubclasses?
I've done the obvious stuff: the only value that Behavior uses as a key in ObsoleteSubclasses is "self". If it is not something in the VM or GC magic, I can't see where this broken key is coming from.
I'm attaching my changeset, and my tests for Association. (This requires the dictionary = fix that I just mailed out.) Inspect ObsoleteSubclasses before and after you file AssociationRefact.Hand in.
Andrew