-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #54 from jecisc/17-Cleaner-notNil--isNotNil-and-no…
…tEmpty--isNotEmpty 17-Cleaner-notNil--isNotNil-and-notEmpty--isNotEmpty
- Loading branch information
Showing
8 changed files
with
284 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
167 changes: 167 additions & 0 deletions
167
src/Chanel-Tests/ChanelMethodAliasesCleanerTest.class.st
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
Class { | ||
#name : #ChanelMethodAliasesCleanerTest, | ||
#superclass : #ChanelAbstractCleanerTest, | ||
#category : #'Chanel-Tests' | ||
} | ||
|
||
{ #category : #running } | ||
ChanelMethodAliasesCleanerTest >> setUp [ | ||
super setUp. | ||
class := self createDefaultClass | ||
] | ||
|
||
{ #category : #tests } | ||
ChanelMethodAliasesCleanerTest >> testDoesNotReplaceIfItIntroduceAnInfinitLoop [ | ||
| oldMethod | | ||
class | ||
compile: | ||
'isNotEmpty | ||
^self notEmpty'. | ||
|
||
oldMethod := class >> #isNotEmpty. | ||
|
||
self runCleaner. | ||
|
||
self | ||
assert: (class >> #isNotEmpty) sourceCode | ||
equals: | ||
'isNotEmpty | ||
^self notEmpty'. | ||
|
||
self assert: class >> #isNotEmpty identicalTo: oldMethod | ||
] | ||
|
||
{ #category : #tests } | ||
ChanelMethodAliasesCleanerTest >> testDoesNotReplaceIfItIntroduceAnInfinitLoop2 [ | ||
| oldMethod | | ||
class | ||
compile: | ||
'isNotEmpty | ||
self notEmpty'. | ||
|
||
oldMethod := class >> #isNotEmpty. | ||
|
||
self runCleaner. | ||
|
||
self | ||
assert: (class >> #isNotEmpty) sourceCode | ||
equals: | ||
'isNotEmpty | ||
self notEmpty'. | ||
|
||
self assert: class >> #isNotEmpty identicalTo: oldMethod | ||
] | ||
|
||
{ #category : #tests } | ||
ChanelMethodAliasesCleanerTest >> testIfNilIfNotNilDo [ | ||
self assert: 'nil ifNil: [ false ] ifNotNilDo: [ true ]' isRewrittenAs: 'nil ifNil: [ false ] ifNotNil: [ true ]' | ||
] | ||
|
||
{ #category : #tests } | ||
ChanelMethodAliasesCleanerTest >> testIfNotNilDo [ | ||
self assert: 'nil ifNotNilDo: [ true ]' isRewrittenAs: 'nil ifNotNil: [ true ]' | ||
] | ||
|
||
{ #category : #tests } | ||
ChanelMethodAliasesCleanerTest >> testIfNotNilDoIfNil [ | ||
self assert: 'nil ifNotNilDo: [ true ] ifNil: [ false ]' isRewrittenAs: 'nil ifNotNil: [ true ] ifNil: [ false ]' | ||
] | ||
|
||
{ #category : #tests } | ||
ChanelMethodAliasesCleanerTest >> testNotEmpty [ | ||
self assert: '#() notEmpty' isRewrittenAs: '#() isNotEmpty' | ||
] | ||
|
||
{ #category : #tests } | ||
ChanelMethodAliasesCleanerTest >> testNotNil [ | ||
self assert: 'nil notNil' isRewrittenAs: 'nil isNotNil' | ||
] | ||
|
||
{ #category : #tests } | ||
ChanelMethodAliasesCleanerTest >> testReplacementDoesNotRemoveExtensions [ | ||
class | ||
compile: | ||
('{1} | ||
{2}' format: {self selector . '#() notEmpty'}) | ||
classified: self extensionProtocol. | ||
|
||
self runCleaner. | ||
|
||
self | ||
assert: (class >> self selector) sourceCode | ||
equals: | ||
('{1} | ||
{2}' format: {self selector . '#() isNotEmpty'}). | ||
|
||
self assert: (class >> self selector) protocol equals: self extensionProtocol | ||
] | ||
|
||
{ #category : #tests } | ||
ChanelMethodAliasesCleanerTest >> testReplacementInTraits [ | ||
| trait | | ||
trait := self createDefaultTrait. | ||
|
||
class setTraitComposition: trait. | ||
|
||
trait | ||
compile: | ||
('{1} | ||
{2}' format: {self selector . '#() notEmpty'}). | ||
|
||
self runCleaner. | ||
|
||
self | ||
assert: (trait >> self selector) sourceCode | ||
equals: | ||
('{1} | ||
{2}' format: {self selector . '#() isNotEmpty'}). | ||
|
||
self assert: (trait localSelectors includes: self selector). | ||
self deny: (class localSelectors includes: self selector) | ||
] | ||
|
||
{ #category : #tests } | ||
ChanelMethodAliasesCleanerTest >> testReplacementOnClassSide [ | ||
class class | ||
compile: | ||
('{1} | ||
{2}' format: {self selector . '#() notEmpty'}). | ||
|
||
self runCleaner. | ||
|
||
self | ||
assert: (class class >> self selector) sourceCode | ||
equals: | ||
('{1} | ||
{2}' format: {self selector . '#() isNotEmpty'}) | ||
] | ||
|
||
{ #category : #tests } | ||
ChanelMethodAliasesCleanerTest >> testWithNothingToReplace [ | ||
| oldMethod | | ||
class | ||
compile: | ||
('{1} | ||
{2}' format: {self selector . '#() isNotEmpty'}). | ||
|
||
oldMethod := class >> self selector. | ||
self runCleaner. | ||
|
||
self | ||
assert: (class >> self selector) sourceCode | ||
equals: | ||
('{1} | ||
{2}' format: {self selector . '#() isNotEmpty'}). | ||
|
||
self assert: class >> self selector identicalTo: oldMethod | ||
] | ||
|
||
{ #category : #tests } | ||
ChanelMethodAliasesCleanerTest >> testincludesAllOf [ | ||
self assert: '#() includesAllOf: #()' isRewrittenAs: '#() includesAll: #()' | ||
] | ||
|
||
{ #category : #tests } | ||
ChanelMethodAliasesCleanerTest >> testincludesAnyOf [ | ||
self assert: '#() includesAnyOf: #()' isRewrittenAs: '#() includesAny: #()' | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
" | ||
Description | ||
-------------------- | ||
I am a cleaner that will replace aliases with only one of the form. | ||
For example I'll replace `notEmpty` by `isNotEmpty` and `notNil` by `isNotNil`. The reason is that it is more coherent with `isNil` that cannot be written `nil`. | ||
I'll also replace `ifNotNilDo:` because it is not an iteration and the name is missleading. | ||
" | ||
Class { | ||
#name : #ChanelMethodAliasesCleaner, | ||
#superclass : #ChanelMethodRewriterCleaner, | ||
#category : #Chanel | ||
} | ||
|
||
{ #category : #accessing } | ||
ChanelMethodAliasesCleaner class >> priority [ | ||
"I need to be high in the priority since I'll simplify next cleaners." | ||
|
||
^ 500 | ||
] | ||
|
||
{ #category : #cleaning } | ||
ChanelMethodAliasesCleaner >> rewriter [ | ||
^ RBParseTreeRewriter new | ||
replace: '`@receiver notEmpty' with: '`@receiver isNotEmpty'; | ||
replace: '`@receiver notNil' with: '`@receiver isNotNil'; | ||
replace: '`@receiver includesAnyOf: `@arg' with: '`@receiver includesAny: `@arg'; | ||
replace: '`@receiver includesAllOf: `@arg' with: '`@receiver includesAll: `@arg'; | ||
replace: '`@receiver ifNotNilDo: `@arg' with: '`@receiver ifNotNil: `@arg'; | ||
replace: '`@receiver ifNil: `@arg ifNotNilDo: `@arg2' with: '`@receiver ifNil: `@arg ifNotNil: `@arg2'; | ||
replace: '`@receiver ifNotNilDo: `@arg ifNil: `@arg2' with: '`@receiver ifNotNil: `@arg ifNil: `@arg2'; | ||
yourself | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
" | ||
Description | ||
-------------------- | ||
I am an abstract cleaner for cleanings using Pharo's parse tree rewriter to update the contents of some methods. | ||
" | ||
Class { | ||
#name : #ChanelMethodRewriterCleaner, | ||
#superclass : #ChanelAbstractCleaner, | ||
#category : #Chanel | ||
} | ||
|
||
{ #category : #testing } | ||
ChanelMethodRewriterCleaner class >> isAbstract [ | ||
^ self = ChanelMethodRewriterCleaner | ||
] | ||
|
||
{ #category : #cleaning } | ||
ChanelMethodRewriterCleaner >> clean [ | ||
| rewriter | | ||
rewriter := self rewriter. | ||
(self scope flatCollect: [ :class | class localMethods , class class localMethods ]) | ||
do: [ :method | (rewriter executeTree: method ast) ifTrue: [ method installAST ] ] | ||
] | ||
|
||
{ #category : #cleaning } | ||
ChanelMethodRewriterCleaner >> rewriter [ | ||
"Return the rewriter to use to clean the methods." | ||
|
||
^ self subclassResponsibility | ||
] | ||
|
||
{ #category : #cleaning } | ||
ChanelMethodRewriterCleaner >> scope [ | ||
"Return all the classes whose methods needs to be cleaned. By default, all of them." | ||
|
||
^ self configuration definedClasses | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters