SystemOrganization addCategory: #'OB-Regex-Tools'! SystemOrganization addCategory: #'OB-Regex-Commands'! OBDefinition subclass: #ORRegexDefinition instanceVariableNames: 'environment text' classVariableNames: '' poolDictionaries: '' category: 'OB-Regex-Commands'! ORRegexDefinition subclass: #ORClassRegexDefinition instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'OB-Regex-Commands'! !ORClassRegexDefinition methodsFor: 'configuration' stamp: 'lr 5/30/2008 13:53'! template ^ 'ORClassRegexRefactoring new "Example 1: Change class prefixes" renameClasses; replace: ''AB(.*)'' with: ''CD$1''; "Example 2: Generate empty test classes" createClasses; rootClass: TestCase; replace: ''^.*$'' with: ''$0Test''; "Example 3: Copy classes" copyClasses; replace: ''^.*$'' with: ''$0Plus''; yourself'! ! !ORRegexDefinition class methodsFor: 'instance-creation' stamp: 'lr 5/30/2008 10:35'! on: anEnvironment ^ self new initializeOn: anEnvironment! ! !ORRegexDefinition methodsFor: 'accessing' stamp: 'lr 5/30/2008 10:40'! accept: aText notifying: aController | refactoring command | text := aText asString. refactoring := self class evaluatorClass evaluate: text for: self notifying: aController logged: false. refactoring model environment: environment. ORCommand new performRefactoring: refactoring. ^ true! ! !ORRegexDefinition methodsFor: 'initialization' stamp: 'lr 5/30/2008 10:36'! initializeOn: anEnvironment environment := anEnvironment! ! !ORRegexDefinition methodsFor: 'accessing' stamp: 'lr 5/30/2008 10:36'! template self subclassResponsibility! ! !ORRegexDefinition methodsFor: 'accessing' stamp: 'lr 5/30/2008 10:36'! text ^ text ifNil: [ text := self template ]! ! ORRegexDefinition subclass: #ORSourceRegexDefinition instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'OB-Regex-Commands'! !ORSourceRegexDefinition methodsFor: 'configuration' stamp: 'lr 5/30/2008 13:58'! template ^ 'ORSourceRegexRefactoring new "Example 1: Replace symbols with strings" replace: ''#(\w+)'' with: ''''''$1''''''; "Example 2: Replace 4 spaces with tabs" replace: '' '' with: '' ''; yourself'! ! !OBCodeBrowser methodsFor: '*ob-regex-commands' stamp: 'lr 2/3/2008 21:20'! cmdRegexEnvironment ^ ORCmdRegexEnvironment allSubclasses! ! ORCmdOpen subclass: #ORCmdOpenRegexClass instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'OB-Regex-Commands'! !ORCmdOpenRegexClass methodsFor: 'execution' stamp: 'lr 5/30/2008 10:35'! execute self definition: (ORClassRegexDefinition on: self environment)! ! !ORCmdOpenRegexClass methodsFor: 'accessing' stamp: 'lr 5/30/2008 10:22'! group ^ #regex! ! !ORCmdOpenRegexClass methodsFor: 'accessing' stamp: 'lr 5/30/2008 10:21'! label ^ 'rewrite class'! ! ORCmdOpen subclass: #ORCmdOpenRegexSource instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'OB-Regex-Commands'! !ORCmdOpenRegexSource methodsFor: 'execution' stamp: 'lr 5/30/2008 10:35'! execute self definition: (ORSourceRegexDefinition on: self environment)! ! !ORCmdOpenRegexSource methodsFor: 'accessing' stamp: 'lr 5/30/2008 10:22'! group ^ #regex! ! !ORCmdOpenRegexSource methodsFor: 'accessing' stamp: 'lr 5/30/2008 10:21'! label ^ 'rewrite source'! ! Refactoring subclass: #ORRegexRefactoring instanceVariableNames: 'find replace refactorings mode' classVariableNames: '' poolDictionaries: '' category: 'OB-Regex-Tools'! ORRegexRefactoring subclass: #ORClassRegexRefactoring instanceVariableNames: 'rootClass' classVariableNames: '' poolDictionaries: '' category: 'OB-Regex-Tools'! !ORClassRegexRefactoring methodsFor: 'transforming' stamp: 'lr 5/30/2008 13:14'! copy: aClass name: aSymbol ^ self duplicate: aClass name: aSymbol deep: true! ! !ORClassRegexRefactoring methodsFor: 'actions' stamp: 'lr 5/30/2008 13:15'! copyClasses mode := #copy:name:! ! !ORClassRegexRefactoring methodsFor: 'private' stamp: 'lr 5/30/2008 13:23'! copyFrom: aSourceClass to: aTargetClass aSourceClass instanceVariableNames do: [ :each | aTargetClass addInstanceVariable: each ]. aSourceClass isMeta ifFalse: [ aSourceClass allClassVariableNames do: [ :each | aTargetClass addClassVariable: each ]. aSourceClass poolDictionaryNames do: [ :each | aTargetClass addPoolDictionary: each ] ]. aSourceClass selectors do: [ :each | aTargetClass compile: (aSourceClass sourceCodeFor: each) classified: (aSourceClass protocolsFor: each) ]! ! !ORClassRegexRefactoring methodsFor: 'transforming' stamp: 'lr 5/30/2008 13:15'! create: aClass name: aSymbol ^ self duplicate: aClass name: aSymbol deep: false! ! !ORClassRegexRefactoring methodsFor: 'actions' stamp: 'lr 5/30/2008 13:15'! createClasses mode := #create:name:! ! !ORClassRegexRefactoring methodsFor: 'private' stamp: 'lr 5/30/2008 13:51'! duplicate: aClass name: aSymbol deep: aBoolean | superclass superclassName name class | (self model includesClassNamed: aSymbol) ifTrue: [ ^ nil ]. superclass := aClass superclass ifNil: [ self rootClass ]. superclassName := (self model includesClassNamed: superclass name) ifFalse: [ superclass name ] ifTrue: [ (name := self replace: superclass name) = superclass name ifFalse: [ self duplicate: superclass name: name deep: aBoolean ]. name ]. self model defineClass: ('<1s> subclass: #<2s> instanceVariableNames: '''' classVariableNames: '''' poolDictionaries: '''' category: <3p>' expandMacrosWith: superclassName with: aSymbol with: aClass category asString). aBoolean ifTrue: [ (class := self model classNamed: aSymbol) ifNil: [ ^ self ]. self copyFrom: aClass to: class. self copyFrom: aClass metaclass to: class metaclass ]. ^ nil! ! !ORClassRegexRefactoring methodsFor: 'initialization' stamp: 'lr 5/30/2008 11:46'! initialize super initialize. self createClasses! ! !ORClassRegexRefactoring methodsFor: 'transforming' stamp: 'lr 5/30/2008 13:15'! rename: aClass name: aSymbol ^ RenameClassRefactoring model: self model rename: aClass to: aSymbol! ! !ORClassRegexRefactoring methodsFor: 'actions' stamp: 'lr 5/30/2008 13:15'! renameClasses mode := #rename:name:! ! !ORClassRegexRefactoring methodsFor: 'accessing' stamp: 'lr 5/30/2008 13:51'! rootClass ^ rootClass ifNil: [ Object ]! ! !ORClassRegexRefactoring methodsFor: 'initialization' stamp: 'lr 5/30/2008 13:50'! rootClass: aClass rootClass := aClass! ! !ORClassRegexRefactoring methodsFor: 'transforming' stamp: 'lr 5/30/2008 11:21'! transform | replacement refactoring | self model allClassesDo: [ :class | (class isNil or: [ class isMeta ]) ifFalse: [ replacement := self replace: class name asString. replacement = class name asString ifFalse: [ refactoring := self perform: mode with: class with: replacement asSymbol. (refactoring notNil and: [ refactoring preconditions check ]) ifTrue: [ refactoring transform ] ] ] ]! ! !ORRegexRefactoring class methodsFor: 'instance-creation' stamp: 'lr 2/7/2008 13:51'! find: aFindString replace: aReplaceString "Answer a refactoring that searches for the regular-expression aFindString. Depending on the subclass implementation it replaces matches with aReplaceString, where $0 references the whole match, and $1..$9 the matched groups." ^ self new find: aFindString replace: aReplaceString! ! !ORRegexRefactoring methodsFor: 'preconditions' stamp: 'lr 2/3/2008 22:02'! preconditions ^ RBCondition empty! ! !ORRegexRefactoring methodsFor: 'private' stamp: 'lr 2/7/2008 13:42'! replace: aString ^ find copy: aString translatingMatchesUsing: [ :match | String streamContents: [ :stream | [ replace atEnd ] whileFalse: [ stream nextPutAll: (replace upTo: $$). replace atEnd ifFalse: [ replace peek isDigit ifFalse: [ stream nextPut: replace next ] ifTrue: [ stream nextPutAll: (find subexpression: replace next asInteger - $0 asInteger + 1) ] ] ]. replace reset ] ]! ! !ORRegexRefactoring methodsFor: 'initialization' stamp: 'lr 5/30/2008 10:28'! replace: aFindString with: aReplaceString find := aFindString asRegex. replace := aReplaceString readStream! ! ORRegexRefactoring subclass: #ORSourceRegexRefactoring instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'OB-Regex-Tools'! !ORSourceRegexRefactoring methodsFor: 'private' stamp: 'lr 2/4/2008 09:28'! parseMethod: aString ^ [ RBParser parseMethod: aString ] on: Error do: [ :err | nil ]! ! !ORSourceRegexRefactoring methodsFor: 'private' stamp: 'lr 2/4/2008 09:29'! parseSelector: aString ^ RBParser parseMethodPattern: aString! ! !ORSourceRegexRefactoring methodsFor: 'transforming' stamp: 'lr 5/30/2008 13:56'! transform | original replacement protocols | self model allClassesDo: [ :class | class selectors do: [ :selector | original := class sourceCodeFor: selector. replacement := self replace: original. replacement = original ifFalse: [ (self parseMethod: replacement) isNil ifFalse: [ protocols := class protocolsFor: selector. (self parseSelector: replacement) = selector ifFalse: [ class removeMethod: selector ]. class compile: replacement classified: protocols ] ] ] ]! ! ORCommand subclass: #ORCmdRegexEnvironment instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'OB-Regex-Commands'! ORCmdRegexEnvironment subclass: #ORCmdCategoryRegexEnvironment instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'OB-Regex-Commands'! !ORCmdCategoryRegexEnvironment methodsFor: 'accessing' stamp: 'lr 2/9/2008 15:16'! name ^ 'categories'! ! !ORCmdCategoryRegexEnvironment methodsFor: 'execution' stamp: 'lr 2/9/2008 15:34'! search: aMatcher | categories parent | categories := Set new. parent := self environment. parent categories do: [ :category | (aMatcher matches: category) ifTrue: [ categories add: category ] ]. ^ CategoryEnvironment onEnvironment: parent categories: categories! ! ORCmdRegexEnvironment subclass: #ORCmdClassRegexEnvironment instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'OB-Regex-Commands'! !ORCmdClassRegexEnvironment methodsFor: 'accessing' stamp: 'lr 2/9/2008 15:22'! name ^ 'classes'! ! !ORCmdClassRegexEnvironment methodsFor: 'execution' stamp: 'lr 1/28/2008 23:13'! search: aMatcher | parent environment | parent := self environment. environment := ClassEnvironment onEnvironment: parent. parent classesDo: [ :class | aMatcher matchesIn: class name do: [ :each | environment addClass: class; addSearchString: each ] ]. ^ environment! ! ORCmdRegexEnvironment subclass: #ORCmdProtocolRegexEnvironment instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'OB-Regex-Commands'! !ORCmdProtocolRegexEnvironment methodsFor: 'accessing' stamp: 'lr 2/9/2008 15:16'! name ^ 'protocols'! ! !ORCmdProtocolRegexEnvironment methodsFor: 'execution' stamp: 'lr 1/28/2008 23:14'! search: aMatcher | parent environment | parent := self environment. environment := SelectorEnvironment onEnvironment: parent. parent classesDo: [ :class | (parent protocolsFor: class) do: [ :protocol | (aMatcher matches: protocol) ifTrue: [ (parent selectorsFor: protocol in: class) do: [ :selector | environment addClass: class selector: selector ] ] ] ]. ^ environment! ! !ORCmdRegexEnvironment methodsFor: 'accessing' stamp: 'lr 1/28/2008 22:47'! cluster ^ #'open environment'! ! !ORCmdRegexEnvironment methodsFor: 'execution' stamp: 'lr 2/10/2008 22:45'! execute | expression matcher environment | expression := [ self request: 'Search in ' , self name , ':' ] on: ORUICancellationError do: [ :err | ^ self ]. matcher := [ expression asRegex ] on: RegexError do: [ :err | ^ self inform: err messageText ]. environment := self search: matcher. environment label: (String with: self name first asUppercase) , self name allButFirst , ' matching ' , expression. self openEnvironment: environment! ! !ORCmdRegexEnvironment methodsFor: 'accessing' stamp: 'lr 1/28/2008 22:25'! group ^ #regex! ! !ORCmdRegexEnvironment methodsFor: 'accessing' stamp: 'lr 2/9/2008 15:15'! label ^ 'find ' , self name , '...'! ! !ORCmdRegexEnvironment methodsFor: 'accessing' stamp: 'lr 2/9/2008 15:15'! name ^ self subclassResponsibility! ! !ORCmdRegexEnvironment methodsFor: 'execution' stamp: 'lr 1/28/2008 22:52'! search: aMatcher self subclassResponsibility! ! ORCmdRegexEnvironment subclass: #ORCmdSelectorRegexEnvironment instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'OB-Regex-Commands'! !ORCmdSelectorRegexEnvironment methodsFor: 'accessing' stamp: 'lr 2/9/2008 15:16'! name ^ 'selectors'! ! !ORCmdSelectorRegexEnvironment methodsFor: 'execution' stamp: 'lr 1/28/2008 23:16'! search: aMatcher | parent environment | parent := self environment. environment := SelectorEnvironment onEnvironment: parent. parent classesAndSelectorsDo: [ :class :selector | aMatcher matchesIn: selector do: [ :each | environment addClass: class selector: selector; addSearchString: each ] ]. ^ environment! ! ORCmdRegexEnvironment subclass: #ORCmdSourceRegexEnvironment instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'OB-Regex-Commands'! !ORCmdSourceRegexEnvironment methodsFor: 'accessing' stamp: 'lr 2/9/2008 15:24'! name ^ 'sources'! ! !ORCmdSourceRegexEnvironment methodsFor: 'execution' stamp: 'lr 1/28/2008 23:16'! search: aMatcher | parent environment | parent := self environment. environment := SelectorEnvironment onEnvironment: parent. parent classesAndSelectorsDo: [ :class :selector | aMatcher matchesIn: (class sourceCodeAt: selector) do: [ :each | environment addClass: class selector: selector; addSearchString: each ] ]. ^ environment! !