SystemOrganization addCategory: #'Refactoring-Experimental'! RBBlockLintRule subclass: #RBDuplicatedCodeRule instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Refactoring-Experimental'! RBDuplicatedCodeRule subclass: #RBDuplicatedAstRule instanceVariableNames: 'index' classVariableNames: '' poolDictionaries: '' category: 'Refactoring-Experimental'! RBDuplicatedCodeRule subclass: #RBDuplicatedBytesRule instanceVariableNames: 'index' classVariableNames: '' poolDictionaries: '' category: 'Refactoring-Experimental'! !RBDuplicatedBytesRule methodsFor: 'running' stamp: 'lr 7/12/2009 13:15'! checkMethod: aContext | bytes substring | bytes := aContext compiledMethod. bytes initialPC to: bytes size - self minimalSize do: [ :i | i + self minimalSize to: bytes size do: [ :j | substring := ByteArray new: j - i + 1. substring replaceFrom: 1 to: substring size with: bytes startingAt: i. index do: [ :other | (other indexOfSubCollection: substring startingAt: 1) = 0 ifFalse: [ self addDuplication: bytes with: other in: result ] ] ] ]. index addLast: aContext compiledMethod! ! !RBDuplicatedBytesRule methodsFor: 'initialization' stamp: 'lr 7/12/2009 12:57'! initialize super initialize. index := OrderedCollection new! ! !RBDuplicatedBytesRule methodsFor: 'private' stamp: 'lr 7/12/2009 13:41'! minimalSize ^ 8! ! !RBDuplicatedBytesRule methodsFor: 'accessing' stamp: 'lr 7/12/2009 12:57'! name ^ super name , ' (bytecode)'! ! !RBDuplicatedCodeRule class methodsFor: 'testing' stamp: 'lr 7/12/2009 13:48'! isVisible ^ self name ~= #RBDuplicatedCodeRule! ! !RBDuplicatedCodeRule methodsFor: 'private' stamp: 'lr 7/12/2009 12:48'! addDuplication: aFirstMethod with: aSecondMethod in: anEnvironment anEnvironment addClass: aFirstMethod methodClass selector: aFirstMethod selector into: aFirstMethod methodClass name , '>>' , aFirstMethod selector; addClass: aFirstMethod methodClass selector: aFirstMethod selector into: aSecondMethod methodClass name , '>>' , aSecondMethod selector; addClass: aSecondMethod methodClass selector: aSecondMethod selector into: aFirstMethod methodClass name , '>>' , aFirstMethod selector; addClass: aSecondMethod methodClass selector: aSecondMethod selector into: aSecondMethod methodClass name , '>>' , aSecondMethod selector! ! !RBDuplicatedCodeRule methodsFor: 'accessing' stamp: 'lr 7/12/2009 12:56'! name ^ 'Duplicated code'! ! !RBDuplicatedCodeRule methodsFor: 'accessing' stamp: 'lr 6/15/2009 20:44'! rationale ^ 'Code duplication is considered bad practice as it hinders maintenance and evolution of software.'! ! !RBDuplicatedCodeRule methodsFor: 'accessing' stamp: 'lr 6/19/2009 17:40'! resultClass ^ MultiEnvironment! ! RBDuplicatedCodeRule subclass: #RBDuplicatedTokenRule instanceVariableNames: 'index' classVariableNames: '' poolDictionaries: '' category: 'Refactoring-Experimental'! !RBDuplicatedTokenRule methodsFor: 'running' stamp: 'lr 7/12/2009 13:49'! checkMethod: aContext | tokens substring | tokens := self scanTokens: aContext. 1 to: tokens size - self minimalSize do: [ :i | i + self minimalSize to: tokens size do: [ :j | substring := tokens copyFrom: i to: j. index do: [ :assoc | | method source | method := assoc key. source := assoc value. (source indexOfSubCollection: substring startingAt: 1) = 0 ifFalse: [ self addDuplication: aContext compiledMethod with: method in: result ] ] ] ]. index addLast: aContext compiledMethod -> tokens! ! !RBDuplicatedTokenRule methodsFor: 'initialization' stamp: 'lr 7/12/2009 12:55'! initialize super initialize. index := OrderedCollection new! ! !RBDuplicatedTokenRule methodsFor: 'private' stamp: 'lr 7/12/2009 12:55'! minimalSize ^ 10! ! !RBDuplicatedTokenRule methodsFor: 'accessing' stamp: 'lr 7/12/2009 12:56'! name ^ super name , ' (token)'! ! !RBDuplicatedTokenRule methodsFor: 'private' stamp: 'lr 7/12/2009 12:55'! scanTokens: aContext | tokens scanner | tokens := OrderedCollection new. scanner := RBScanner on: aContext sourceCode asString readStream errorBlock: [ :s :p | ^ tokens ]. [ scanner atEnd ] whileFalse: [ tokens addLast: scanner next value ]. ^ tokens asArray! !