Skip to content

Commit

Permalink
Log every updates via TinyLogger.
Browse files Browse the repository at this point in the history
Fixes #5
  • Loading branch information
jecisc committed Apr 21, 2020
1 parent f12483b commit ffc048d
Show file tree
Hide file tree
Showing 14 changed files with 117 additions and 49 deletions.
42 changes: 33 additions & 9 deletions resources/doc/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,31 @@ It is advised to keep the cleaner in the given order of this snippet since some

> You can open playgrounds containing those snippets via the world menu once the project is installed.
## Tests equality
## Logging changes

By default, *Chanel* uses [TinyLogger](https://github.com/jecisc/TinyLogger) to record every changes.

The default logger output the logs on the Transcript, STDio and in a file named `Chanel.log`.

It is possible to update the logger to use:

```Smalltalk
Chanel logger: (TinyLogger new ensureTranscriptLogger; yourself)
```

It is also possible to disable the logging:

```Smalltalk
Chanel logger: TinyLogger new
```

For more info on the logger customization, read the documentation of `TinyLogger`.

## Cleaners descriptions

This section will go over every cleaners and explain their behavior.

### Tests equality

Chanel iterates on all the tests of the packages and clean equality assertions.
Here is the list of rewrites it will apply:
Expand All @@ -47,7 +71,7 @@ Here is the list of rewrites it will apply:

> The danger of this cleaning happens on projects working in Pharo < 7. Some of this new assertions were introduced in Pharo 7.
## Clean protocols
### Clean protocols

Channel do multiple cleanings in protocols.

Expand All @@ -56,7 +80,7 @@ Channel do multiple cleanings in protocols.

> This cleaning should not have any counter indication.
## Conditional simplifications
### Conditional simplifications

Chanel simplifies conditionals. For example it will rewrite:

Expand All @@ -73,36 +97,36 @@ Chanel simplifies conditionals. For example it will rewrite:

> The only danger of this cleaning happens for projects working on multiple Smalltalks
## Test case names
### Test case names

Chanel rename each test case ending with `Tests` te end with `Test` since this is `a XXTestCase`.

> This might cause trouble if you have a test case end with `Test` and another class with the same name ending with `Tests`.
## Ensure right super are call
### Ensure right super are call

- Ensure `#setUp` in TestCases always begins by `super setUp` (move it if not the first messand sent)
- Ensure `#tearDown` in TestCases always ends by `super tearDown` (move it if not the last messand sent)
- Ensure `#initialize` on instance side always has `super initialize`

> A problem might happen if a super was deliberatly ignored.
## Remove nil assignments in initialization
### Remove nil assignments in initialization

Chanel removes all nil assignations in `initialize` methods because most of the time they are not needed.

> This might be a problem in some rare case where #initialize methods are called by teh user to reset an instance. In that case it is recommended to create a `#reset` method.
## Remove methods only calling super
### Remove methods only calling super

Remove each methods only doing a super call. This does not remove methods with pragmas.

> This might remove methods added just to add comments in a subclass.
## Remove unread temporaries
### Remove unread temporaries

Remove all temporaries that are defined but not read.

## Remove duplicated methods from traits
### Remove duplicated methods from traits

If methods present on traits are duplicated in a classe using the trait, Chanel removes the duplicated version.
15 changes: 13 additions & 2 deletions src/BaselineOfChanel/BaselineOfChanel.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ BaselineOfChanel >> baseline: spec [
<baseline>
spec
for: #common
do: [ self iterators: spec.
do: [ self
iterators: spec;
tinyLogger: spec.

spec
package: 'Chanel' with: [ spec requires: #('Iterators') ];
package: 'Chanel' with: [ spec requires: #('Iterators' 'TinyLogger') ];
package: 'Chanel-Tests' with: [ spec requires: #('Chanel') ].

spec
Expand Down Expand Up @@ -47,3 +49,12 @@ BaselineOfChanel >> pharoBackwardCompatibility: spec [
BaselineOfChanel >> projectClass [
^ MetacelloCypressBaselineProject
]

{ #category : #dependencies }
BaselineOfChanel >> tinyLogger: spec [
spec
baseline: 'TinyLogger'
with: [ spec
loads: 'Core';
repository: 'github://jecisc/TinyLogger:v1.x.x/src' ]
]
2 changes: 1 addition & 1 deletion src/Chanel-Tests/ChanelAbstractCleanerTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ ChanelAbstractCleanerTest >> extensionProtocol [

{ #category : #running }
ChanelAbstractCleanerTest >> runCleaner [
(self actualClass configuration: (Chanel new packages: {package})) clean
Chanel perfume: {package} using: {self actualClass}
]

{ #category : #running }
Expand Down
44 changes: 33 additions & 11 deletions src/Chanel/Chanel.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,27 @@ Class {
#instVars : [
'packages'
],
#classVars : [
'Logger'
],
#category : #Chanel
}

{ #category : #accessing }
Chanel class >> logger [
^ Logger
ifNil: [ Logger := TinyLogger new
ensureTranscriptLogger;
ensureStdoutLogger;
ensureFileLoggerNamed: 'Chanel.log';
yourself ]
]

{ #category : #accessing }
Chanel class >> logger: anObject [
Logger := anObject
]

{ #category : #'world menu' }
Chanel class >> openWorkspaceToCleanProject [
GTPlayground
Expand Down Expand Up @@ -104,17 +122,21 @@ Chanel class >> worldMenuOn: aBuilder [

{ #category : #cleaning }
Chanel >> cleanUsing: cleaners [
UIManager default
displayProgress: 'Running Chanel'
from: 1
to: cleaners size
during: [ :bar |
cleaners
doWithIndex: [ :cleaner :index |
bar
value: index;
title: '(' , index asString , '/' , cleaners size asString , ') Running ' , cleaner printString.
(cleaner configuration: self) clean ] ]
TinyCurrentLogger
value: self class logger
during: [ self
execute: [ UIManager default
displayProgress: 'Running Chanel'
from: 1
to: cleaners size
during: [ :bar |
cleaners
doWithIndex: [ :cleaner :index |
bar
value: index;
title: '(' , index asString , '/' , cleaners size asString , ') Running ' , cleaner printString.
self execute: [ (cleaner configuration: self) clean ] recordedAs: 'Running ' , cleaner printString ] ] ]
recordedAs: 'Running Chanel on: ' , (', ' join: (packages collect: #name)) ]
]

{ #category : #accessing }
Expand Down
2 changes: 1 addition & 1 deletion src/Chanel/ChanelAbstractCleaner.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,5 @@ ChanelAbstractCleaner >> configuration: anObject [
{ #category : #rewriting }
ChanelAbstractCleaner >> rewriteMethodsOf: classes with: rewriter [
(classes flatCollect: [ :class | class localMethods , class class localMethods ])
do: [ :method | (rewriter executeTree: method ast) ifTrue: [ method ast install ] ]
do: [ :method | (rewriter executeTree: method ast) ifTrue: [ method installAST ] ]
]
28 changes: 11 additions & 17 deletions src/Chanel/ChanelEnsureSuperIsCalledCleaner.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@ ChanelEnsureSuperIsCalledCleaner >> ensureSuperInitializeForMethods: methods [
| [ :method | method selector = #initialize ] selectIt
| #hasMessages selectIt
| [ :method | method sendNodes noneSatisfy: [ :node | node isSuperSendTo: #initialize ] ] selectIt
> [ :method |
| ast |
ast := method ast.
ast body addNodeFirst: (RBMessageNode superSendTo: #initialize).
ast install ] doIt

| [ :method | method ast body addNodeFirst: (RBMessageNode superSendTo: #initialize) ] doIt
> #installAST doIt
]

{ #category : #cleaning }
Expand All @@ -50,12 +48,10 @@ ChanelEnsureSuperIsCalledCleaner >> ensureSuperSetUpForMethods: methods [
| [ :method | method selector = #setUp ] selectIt
| #hasMessages selectIt
| [ :method | method sendNodes first isSuperSendTo: #setUp ] rejectIt
> [ :method |
| ast |
ast := method ast.
ast sendNodes select: [ :each | each isSuperSendTo: #setUp ] thenDo: #removeFromTree.
ast body addNodeFirst: (RBMessageNode superSendTo: #setUp).
ast install ] doIt

| [ :method | method ast sendNodes select: [ :each | each isSuperSendTo: #setUp ] thenDo: #removeFromTree ] doIt
| [ :method | method ast body addNodeFirst: (RBMessageNode superSendTo: #setUp) ] doIt
> #installAST doIt
]

{ #category : #cleaning }
Expand All @@ -65,10 +61,8 @@ ChanelEnsureSuperIsCalledCleaner >> ensureSuperTearDownForMethods: methods [
| [ :method | method selector = #tearDown ] selectIt
| #hasMessages selectIt
| [ :method | method sendNodes last isSuperSendTo: #tearDown ] rejectIt
> [ :method |
| ast |
ast := method ast.
ast sendNodes select: [ :each | each isSuperSendTo: #tearDown ] thenDo: #removeFromTree.
ast body addNodeLast: (RBMessageNode superSendTo: #tearDown).
ast install ] doIt

| [ :method | method ast sendNodes select: [ :each | each isSuperSendTo: #tearDown ] thenDo: #removeFromTree ] doIt
| [ :method | method ast body addNodeLast: (RBMessageNode superSendTo: #tearDown) ] doIt
> #installAST doIt
]
2 changes: 1 addition & 1 deletion src/Chanel/ChanelMethodsOnlyCallingSuperCleaner.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ ChanelMethodsOnlyCallingSuperCleaner >> clean [
self configuration localMethods iterator
| #hasPragma rejectIt
| [ :method | matcher executeMethod: method ast initialAnswer: false ] selectIt
> #removeFromSystem doIt
> #removeMethod doIt
]
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ ChanelNilAssignationInInitializeCleaner >> clean [
| [ :method | method selector = #initialize ] selectIt
| [ :method | method ast nilAssignmentNodes isNotEmpty ] selectIt
| [ :method | method ast nilAssignmentNodes do: #removeFromTree ] doIt
> [ :method | method ast install ] doIt
> #installAST doIt
]
2 changes: 1 addition & 1 deletion src/Chanel/ChanelProtocolsCleaner.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ ChanelProtocolsCleaner >> cleanCloseProtocolsOf: methods [
keysAndValuesDo: [ :olds :new |
methods
select: [ :meth | olds includes: meth protocol ]
thenDo: [ :meth | meth protocol: new ] ]
thenDo: [ :meth | meth ensureProtocol: new ] ]
]

{ #category : #cleaning }
Expand Down
4 changes: 3 additions & 1 deletion src/Chanel/ChanelTestCaseNameCleaner.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,7 @@ ChanelTestCaseNameCleaner class >> priority [
ChanelTestCaseNameCleaner >> clean [
self configuration definedTestCases
select: [ :class | class name endsWith: 'Tests' ]
thenDo: [ :class | (RBRenameClassRefactoring rename: class to: (class name withoutSuffix: 'Tests') , 'Test') execute ]
thenDo: [ :class |
('Renaming ' , class name , ' to ' , class name allButLast) record.
(RBRenameClassRefactoring rename: class to: class name allButLast) execute ]
]
2 changes: 1 addition & 1 deletion src/Chanel/ChanelUnreadTemporaryCleaner.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ ChanelUnreadTemporaryCleaner >> clean [
(method ast allTemporaries select: #isNotReadOnce)
ifNotEmpty: [ :temporariesToRemove |
temporariesToRemove do: #inlineTemporary.
method ast install ] ]
method installAST ] ]
]
4 changes: 2 additions & 2 deletions src/Chanel/ClassDescription.extension.st
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ Extension { #name : #ClassDescription }
{ #category : #'*Chanel' }
ClassDescription >> removeDuplicatedMethodsFromTrait [
self localMethods
do: [ :method | self traitComposition compiledMethodAt: method selector ifPresent: [ :m | m ast = method ast ifTrue: [ method removeFromSystem ] ] ].
do: [ :method | self traitComposition compiledMethodAt: method selector ifPresent: [ :m | m ast = method ast ifTrue: [ method removeMethod ] ] ].

self class localMethods
do: [ :method | self traitComposition classComposition compiledMethodAt: method selector ifPresent: [ :m | m ast = method ast ifTrue: [ method removeFromSystem ] ] ].
do: [ :method | self traitComposition classComposition compiledMethodAt: method selector ifPresent: [ :m | m ast = method ast ifTrue: [ method removeMethod ] ] ].
]
16 changes: 15 additions & 1 deletion src/Chanel/CompiledMethod.extension.st
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ Extension { #name : #CompiledMethod }
{ #category : #'*Chanel' }
CompiledMethod >> ensureProtocol: aSymbol [
self protocol = aSymbol ifTrue: [ ^ self ].


('Updating protocol of: ' , self printString , ' from ' , self protocol , ' to ' , aSymbol) record.
self protocol: aSymbol
]

Expand All @@ -17,7 +18,20 @@ CompiledMethod >> hasPragma [
^ self pragmas isNotEmpty
]

{ #category : #'*Chanel' }
CompiledMethod >> installAST [
"In Chanel we update some ASTs. This method install the updated AST."

self ast install
]

{ #category : #'*Chanel' }
CompiledMethod >> isInstanceSide [
^ self methodClass isInstanceSide
]

{ #category : #'*Chanel' }
CompiledMethod >> removeMethod [
('Removing: ' , self printString) record.
self removeFromSystem
]
1 change: 1 addition & 0 deletions src/Chanel/RBMethodNode.extension.st
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ RBMethodNode >> allTemporaries [

{ #category : #'*Chanel' }
RBMethodNode >> install [
('Updating: ' , self method printString) record.
^ self methodClass compile: self formattedCode
]

0 comments on commit ffc048d

Please sign in to comment.