Recently I wanted to replace all method sends of oldMessage to
newMessage in a specific method category in a class, then I wrote this little script I want to share with you: | className realClass replacer category | className := #MyClass. realClass := Smalltalk at: className. category := #accessing. replacer := RBParseTreeRewriter new replace: '`receiver oldMessage' with: '`receiver newMessage'; yourself. (realClass organization listAtCategoryNamed: category) collect: [:sel | | parseTree | parseTree := ( realClass >> sel) parseTree. (replacer executeTree: parseTree) ifTrue: [ realClass compile: replacer tree newSource " [1] " ] ] Now some questions: 1) In [1] "( RBClass existingNamed: className ) compileTree: replacer tree" would be more appropiate? I get a MNU when evaluated with latest AST/Refactoring. 2) The above script have some problems, if you want to get replaced 'this is a string' asString. to 'this is a string' asText it won't match. The same happens with: " self model asString " and other patterns. How to modify the rewriter to match oldMessage/newMessage at any point? i.e. [: tmp | anObject1 blabla1 blabla2 oldMessage blabla3 ] Thanks in advance, -- Hernán Morales Information Technology Manager, Institute of Veterinary Genetics. National Scientific and Technical Research Council (CONICET). La Plata (1900), Buenos Aires, Argentina. Telephone: +54 (0221) 421-1799. Internal: 422 Fax: 425-7980 or 421-1799. |
> 1) In [1] "( RBClass existingNamed: className ) compileTree: replacer
> tree" would be more appropiate? I get a MNU when evaluated with latest > AST/Refactoring. What kind of MNU? > 2) The above script have some problems, if you want to get replaced > > 'this is a string' asString. > > to > > 'this is a string' asText > > it won't match. The same happens with: " self model asString " and > other patterns. `#literal asString > i.e. [: tmp | anObject1 blabla1 blabla2 oldMessage blabla3 ] > How to modify the rewriter to match > oldMessage/newMessage at any point? ``@obj oldMessage Lukas -- Lukas Renggli www.lukas-renggli.ch |
2011/1/12 Lukas Renggli <[hidden email]>:
>> 1) In [1] "( RBClass existingNamed: className ) compileTree: replacer >> tree" would be more appropiate? I get a MNU when evaluated with latest >> AST/Refactoring. > > What kind of MNU? > Debug log attached >> 2) The above script have some problems, if you want to get replaced >> >> 'this is a string' asString. >> >> to >> >> 'this is a string' asText >> >> it won't match. The same happens with: " self model asString " and >> other patterns. > > `#literal asString > >> i.e. [: tmp | anObject1 blabla1 blabla2 oldMessage blabla3 ] >> How to modify the rewriter to match >> oldMessage/newMessage at any point? > > ``@obj oldMessage > > Lukas > RBClassMNU.log (43K) Download Attachment |
The stack-trace and your code snippet does not match. There are no
references (and should be no references) to #compileTree: or RBClass in the code you pasted into the mail. The easiest is probably if you use the refactoring tools as integrated into OB. This does all automatically. Lukas On 12 January 2011 08:47, Hernán Morales Durand <[hidden email]> wrote: > 2011/1/12 Lukas Renggli <[hidden email]>: >>> 1) In [1] "( RBClass existingNamed: className ) compileTree: replacer >>> tree" would be more appropiate? I get a MNU when evaluated with latest >>> AST/Refactoring. >> >> What kind of MNU? >> > > Debug log attached > >>> 2) The above script have some problems, if you want to get replaced >>> >>> 'this is a string' asString. >>> >>> to >>> >>> 'this is a string' asText >>> >>> it won't match. The same happens with: " self model asString " and >>> other patterns. >> >> `#literal asString >> >>> i.e. [: tmp | anObject1 blabla1 blabla2 oldMessage blabla3 ] >>> How to modify the rewriter to match >>> oldMessage/newMessage at any point? >> >> ``@obj oldMessage >> >> Lukas >> > > Cool, thanks! > -- Lukas Renggli www.lukas-renggli.ch |
2011/1/12 Lukas Renggli <[hidden email]>:
> The stack-trace and your code snippet does not match. There are no > references (and should be no references) to #compileTree: or RBClass > in the code you pasted into the mail. > The thing was to replace the line marked with [1] as I've commented above. If you file in the attached dummy class and evaluate the following script should be reproduceable: | className realClass replacer category | className := #MyClass. realClass := Smalltalk at: className. category := #accessing. replacer := RBParseTreeRewriter new replace: '`receiver asString' with: '`receiver asText'; yourself. (realClass organization listAtCategoryNamed: category) collect: [:sel | | parseTree | parseTree := ( realClass >> sel) parseTree. (replacer executeTree: parseTree) ifTrue: [ ( RBClass existingNamed: className ) compileTree: replacer tree ] ] > The easiest is probably if you use the refactoring tools as integrated > into OB. This does all automatically. It should be too obvious but I didn't find how. May you comment how to perform the task in the script with OB? Thanks, Hernán > Lukas > > On 12 January 2011 08:47, Hernán Morales Durand > <[hidden email]> wrote: >> 2011/1/12 Lukas Renggli <[hidden email]>: >>>> 1) In [1] "( RBClass existingNamed: className ) compileTree: replacer >>>> tree" would be more appropiate? I get a MNU when evaluated with latest >>>> AST/Refactoring. >>> >>> What kind of MNU? >>> >> >> Debug log attached >> >>>> 2) The above script have some problems, if you want to get replaced >>>> >>>> 'this is a string' asString. >>>> >>>> to >>>> >>>> 'this is a string' asText >>>> >>>> it won't match. The same happens with: " self model asString " and >>>> other patterns. >>> >>> `#literal asString >>> >>>> i.e. [: tmp | anObject1 blabla1 blabla2 oldMessage blabla3 ] >>>> How to modify the rewriter to match >>>> oldMessage/newMessage at any point? >>> >>> ``@obj oldMessage >>> >>> Lukas >>> >> >> Cool, thanks! >> > > > > -- > Lukas Renggli > www.lukas-renggli.ch > > MyCategory.st (528 bytes) Download Attachment |
>> The stack-trace and your code snippet does not match. There are no
>> references (and should be no references) to #compileTree: or RBClass >> in the code you pasted into the mail. > > The thing was to replace the line marked with [1] as I've commented > above. I don't get it, the code you posted looks ok. RBClass is a class private to the framework, you should never need to instantiate it directly. And if you do, only through an instance of RBNamespace that provides a delta to the current system state. In your example you don't need to do that. >> The easiest is probably if you use the refactoring tools as integrated >> into OB. This does all automatically. > > It should be too obvious but I didn't find how. May you comment how to > perform the task in the script with OB? 1. Select "MyClass" 2. Menu "Refactoring Scope" -> "Class" 3. Menu "Rewrite Code" and fill the template 4. Accept the rewrite expression 5. Review and accept the proposed changes This is also show here in a slightly older version of OB: http://www.lukas-renggli.ch/blog/ob-rb-3 Lukas -- Lukas Renggli www.lukas-renggli.ch |
2011/1/12 Lukas Renggli <[hidden email]>:
>>> The stack-trace and your code snippet does not match. There are no >>> references (and should be no references) to #compileTree: or RBClass >>> in the code you pasted into the mail. >> >> The thing was to replace the line marked with [1] as I've commented >> above. > > I don't get it, the code you posted looks ok. > > RBClass is a class private to the framework, you should never need to > instantiate it directly. And if you do, only through an instance of > RBNamespace that provides a delta to the current system state. In your > example you don't need to do that. That's exactly what I wanted to know :) >>> The easiest is probably if you use the refactoring tools as integrated >>> into OB. This does all automatically. >> >> It should be too obvious but I didn't find how. May you comment how to >> perform the task in the script with OB? > > 1. Select "MyClass" > 2. Menu "Refactoring Scope" -> "Class" > 3. Menu "Rewrite Code" and fill the template > 4. Accept the rewrite expression > 5. Review and accept the proposed changes > > This is also show here in a slightly older version of OB: > http://www.lukas-renggli.ch/blog/ob-rb-3 > Thanks, just an *idea* you may like: It would be cool to select a method category, then a menu item for having a rewrite to be applied only to that category. > Lukas > > -- > Lukas Renggli > www.lukas-renggli.ch > > |
> Thanks, just an *idea* you may like: It would be cool to select a
> method category, then a menu item for having a rewrite to be applied > only to that category. Refactoring Scope -> Selection Lukas -- Lukas Renggli www.lukas-renggli.ch |
In reply to this post by Lukas Renggli
lukas
it would be great if you could write some blog entries on RBWriter and that we turn that into a book chapter. We have powerful tools but only two guys knowing how to use them and this is a pity. Stef On Jan 12, 2011, at 7:08 AM, Lukas Renggli wrote: >> 1) In [1] "( RBClass existingNamed: className ) compileTree: replacer >> tree" would be more appropiate? I get a MNU when evaluated with latest >> AST/Refactoring. > > What kind of MNU? > >> 2) The above script have some problems, if you want to get replaced >> >> 'this is a string' asString. >> >> to >> >> 'this is a string' asText >> >> it won't match. The same happens with: " self model asString " and >> other patterns. > > `#literal asString > >> i.e. [: tmp | anObject1 blabla1 blabla2 oldMessage blabla3 ] >> How to modify the rewriter to match >> oldMessage/newMessage at any point? > > ``@obj oldMessage > > Lukas > > -- > Lukas Renggli > www.lukas-renggli.ch > |
Free forum by Nabble | Edit this page |