On Aug 14, 2012, at 2:01 PM, Mariano Martinez Peck <marianopeck@gmail.com> wrote:
Hi guys. Today, there is a part of the system coupled with Compiler. Issue is: http://code.google.com/p/pharo/issues/detail?id=6110
Now, if you see the method:
getSourceReplacingSelectorWith: newSelector | oldKeywords newKeywords args newSelectorWithArgs source oldSelector s | source := self sourceCode. oldSelector := self parserClass new parseSelector: source. oldSelector = newSelector ifTrue: [ ^ source ]. oldKeywords := oldSelector keywords. newKeywords := (newSelector ifNil: [self defaultSelector]) keywords. [oldKeywords size = newKeywords size] assert. args := (self methodClass parserClass new parseArgsAndTemps: source string notifying: nil) copyFrom: 1 to: self numArgs. newSelectorWithArgs := String streamContents: [:stream | newKeywords withIndexDo: [:keyword :index | stream nextPutAll: keyword. stream space. args size >= index ifTrue: [ stream nextPutAll: (args at: index); space]]]. s := source string readStream. oldKeywords do: [ :each | s match: each ]. args isEmpty ifFalse: [ s match: args last ]. ^newSelectorWithArgs trimBoth, s upToEnd
The 2 magic lines are:
oldSelector := self parserClass new parseSelector: source. oldSelector = newSelector ifTrue: [ ^ source ].
So, why we cannot just replace "self parserClass new parseSelector: source." with "self selector". Well, I think (talking with Guille) this ONLY because of Trait transformation/aliases that associates a selector with a method of a different selector.
If this is the case, it means that 99% of the cases,"oldSelector = newSelector ifTrue: [ ^ source ]. " is true. Because those aliases are only used in one trait in all the image ().
So...if that is the case, can't we get the oldSelector from elsewhere rather than needing to use the Compiler to get the selector from the source code ?
As we now encode the selector in the CompiledMethod itself, this can be relaced with oldSelector := self selector. But what you have left is the arguments... args := (self methodClass parserClass new parseArgsAndTemps: source string notifying: nil) copyFrom: 1 to: self numArgs. The only way to get the the argument names (temps) of a method is to compile the source... no way around it. (I personally think this is another example why bytecode as the model for reflection is just wrong) Marcus -- Marcus Denker -- http://marcusdenker.de