2009/12/21 Adrian Lienhard <adi@netstyle.ch>:
Hi Igor,
This looks complicated...
Hmm, i wonder, what Traits serve for, if requesting an original source code of method which being installed in specific behavior using specific selector becomes non-trivial task.
Note, in Pharo this does not work because there is no sharing of compiled methods from traits anymore.
and it is good that there is no sharing, because in fact, my new code won't work if traits/behaviors sharing same CompiledMethod instances, because this could lead to recursion when looking for method's source code. I'm also made my own 'fix' for that by overriding the addTraitSelector: aSymbol withMethod: aCompiledMethod which ALWAYS makes a copy of aCompiledMethod before installing it into receiver's method dict and replaces its trailer with one that tells class to use #getSourceCodeBySelector: for finding its source code. (I hope this is the only entry method, which used by all traits to install the non-local method in behavior's method dict, if not, please tell me what other places should be fixed). I found that because squeak not doing that, there is a funky methods, which a) originally belong to some trait b) responding a behavior (not trait), where it installed when sending #methodClass a regression test is: Trait allSubInstancesDo:[:t | t methodDict do: [:m | self assert(m methodClass == t) ]]
I attached a changeset that does the same as yours but for Pharo.
Thanks, i'll take a look.
The only thing that is needed are a few lines in sourceCodeAt:. The method #traitOrClassOfSelector: returns the origin of a method -- this should work just fine for aliased methods too.
HTH, Adrian
On Dec 21, 2009, at 01:09 , Igor Stasenko wrote:
I just created a small changeset
http://bugs.squeak.org/view.php?id=7432
which gives me a long awaited feature: to see in a browser, where the heck a given method comes from.
If method comes from trait, a method's source tells me , from which one exactly!
Open a browser on Behavior clas and select an #addExclusionOf:to: method. Usually you'll see:
addExclusionOf: aSymbol to: aTrait     self setTraitComposition: (         self traitComposition copyWithExclusionOf: aSymbol to: aTrait)
But with my changes you'll see:
" From: TAccessingTraitCompositionBehavior " addExclusionOf: aSymbol to: aTrait     self setTraitComposition: (         self traitComposition copyWithExclusionOf: aSymbol to: aTrait)
in code pane.
Same applies to traits themselves for instance, browse TPureBehavior>>isAliasSelector:
" From: TAccessingTraitCompositionBehavior " isAliasSelector: aSymbol     "Return true if the selector aSymbol is an alias defined     in my or in another composition somewhere deeper in     the tree of traits compositions."
    ^(self includesLocalSelector: aSymbol) not         and: [self hasTraitComposition]         and: [self traitComposition isAliasSelector: aSymbol]
There is one problem , which requires better expertise than mine and i need a help from Traits experts: an aliased methods. I tried to find out, how to dig out the aliased method from composition, and get its source to display in code pane .. but no luck. Please give me an advice, how a  #getSourceCodeBySelector: method should be implemented for proper handling of aliases. Currently, all aliased methods sources shown using decompiler:
Behavior>>methodDictAddSelectorSilently: t1 withMethod: t2 Â Â Â Â self basicAddSelector: t1 withMethod: t2
Aliased methods, obviously, will require an additional info in source header, like:
" From: SomeTrait , originalSelector: Â #blablba "
-- Best regards, Igor Stasenko AKA sig.
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig.