### Install Chanel Project Source: https://github.com/jecisc/chanel/blob/master/README.md Installs the Chanel project from GitHub into your Pharo image using Metacello. It specifies the user, repository, commitish, and path for the source code. ```Smalltalk Metacello new githubUser: 'jecisc' project: 'Chanel' commitish: 'v1.x.x' path: 'src'; baseline: 'Chanel'; load ``` -------------------------------- ### Protocol Cleaning Rules Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md Chanel cleans method protocols to ensure adherence to conventions. This includes moving methods like '#initialize' to '#initialization' and test case methods like '#setUp' to '#running'. It also ensures test methods are in protocols starting with 'test' and updates protocol names like '#initialize-release' to '#initialize'. ```Smalltalk Ensures '#initialize' is in '#initialization'. Ensures '#setUp' is in '#running' for TestCase subclasses. Ensures test methods (no args, starting with 'test' or 'should') are in protocols starting with 'test'. Updates '#initialize-release' to '#initialize'. ``` -------------------------------- ### Ensure Correct Super Calls in TestCases Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md Ensures that `#setUp` methods in TestCases always begin with `super setUp` and `#tearDown` methods always end with `super tearDown`. It also ensures that `#initialize` methods on the instance side have `super initialize`. These checks are applied if the method sends at least one message and the super call is not already in the correct position or is missing. ```Smalltalk TestCase>>setUp "Ensure super setUp is the first message sent." TestCase>>tearDown "Ensure super tearDown is the last message sent." Class>>initialize "Ensure super initialize is sent." ``` -------------------------------- ### Remove unnecessary assignments Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md This tool simplifies code by removing assignments that assign a variable to itself. For example, `toto := toto.` is removed. ```Smalltalk Chanels removes assigments to itself. For example it will rewrite: ```Smalltalk test o toto | toto := 2. toto := toto. ^ toto ``` To ```Smalltalk test o toto | toto := 2. ^ toto ``` *Conditions for the cleanings to by applied:* - Can be applied on any classes and traits. - A pattern from the list above match. ``` -------------------------------- ### List Available Cleaners Source: https://github.com/jecisc/chanel/blob/master/README.md Retrieves and lists all available cleaner classes that can be used with the Chanel project. This command helps users discover the different cleaning strategies they can apply. ```Smalltalk ChanelAbstractCleaner cleaners asArray ``` -------------------------------- ### Simplify empty assertions Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md This tool rewrites assertions related to emptiness for better readability and failure reporting. It transforms `isEmpty` and `isNotEmpty` checks into dedicated `assertEmpty:` and `denyEmpty:` methods, which were introduced in Pharo 8. ```Smalltalk Chanel iterates on all the tests of the packages and clean empty assertions. Here is the list of rewrites it will apply: | Original | Transformation | | ------------- | ------------- | | `x assert: y isEmpty` | `x assertEmpty: y` | | `x deny: y isEmpty` | `x denyEmpty: y` | | `x assert: y isNotEmpty` | `x denyEmpty: y` | | `x deny: y isNotEmpty` | `x assertEmpty: y` | `#assertEmpty:` and `denyEmpty:` were added in Pharo 8 and gives better descriptions in case of failure than simple asserts. *Conditions for the cleanings to by applied:* - Only subclasses of TestCase are cleaned. - Does not clean the traits in the packages. - A pattern from the list above match. - The minimal pharo version provided is supperior to 8. ``` -------------------------------- ### Add Chanel to Baseline Source: https://github.com/jecisc/chanel/blob/master/README.md Adds the Chanel project as a baseline dependency for your project. This allows for easier management of the Chanel library within your project's baseline configuration. ```Smalltalk spec baseline: 'Chanel' with: [ spec repository: 'github://jecisc/Chanel:v1.x.x/src' ] ``` -------------------------------- ### Clean Packages with Chanel Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md Applies cleaning operations to a collection of packages using the Chanel perfume method. It can also be used to specify a subset of cleaners and a minimum Pharo version. ```Smalltalk packages := ((IceRepository registry select: [ :e | e name includesSubstring: 'Moose' ]) flatCollect: [ :e | e workingCopy packageNames collect: [ :s | s asPackageIfAbsent: [ nil ] ] ]) reject: #isNil. Chanel perfume: packages ``` ```Smalltalk Chanel perfume: packages using: { ChanelTestEqualityCleaner . ChanelProtocolsCleaner }. ``` ```Smalltalk Chanel perfume: packages forPharo: 6. ``` ```Smalltalk Chanel perfume: packages using: { ChanelTestEqualityCleaner . ChanelProtocolsCleaner } forPharo: 6. ``` -------------------------------- ### Specify Minimal Pharo Version for Cleaning Source: https://github.com/jecisc/chanel/blob/master/README.md Applies cleaning operations to packages while specifying a minimal Pharo version compatibility. This ensures that cleaners compatible with older Pharo versions are used, preventing potential issues. ```Smalltalk Chanel perfume: packages forPharo: 6. ``` ```Smalltalk Chanel perfume: packages using: { ChanelTestEqualityCleaner . ChanelProtocolsCleaner } forPharo: 6. ``` -------------------------------- ### Configure Chanel Logger Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md Demonstrates how to configure the logger for Chanel. It shows how to set a custom logger, ensuring transcript logging, and how to disable logging. ```Smalltalk Chanel logger: (TinyLogger new ensureTranscriptLogger; yourself) ``` ```Smalltalk Chanel logger: TinyLogger new ``` -------------------------------- ### Clean Packages with Chanel Source: https://github.com/jecisc/chanel/blob/master/README.md Cleans a collection of Pharo packages using the #perfume: method provided by Chanel. It first collects packages containing 'Moose' in their names and then applies the cleaning process. ```Smalltalk packages := ((IceRepository registry select: [ :e | e name includesSubstring: 'Moose' ]) flatCollect: [ :e | e workingCopy packageNames collect: [ :s | s asPackageIfAbsent: [ nil ] ] ]) reject: #isNil. Chanel perfume: packages ``` -------------------------------- ### Clean Packages with Specific Cleaners Source: https://github.com/jecisc/chanel/blob/master/README.md Cleans a collection of packages using a specific set of cleaners defined in an array. This allows for targeted cleaning operations by selecting only the desired cleaner classes. ```Smalltalk Chanel perfume: packages using: { ChanelTestEqualityCleaner . ChanelProtocolsCleaner }. ``` -------------------------------- ### Unify Method Aliases Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md This section details the unification of method aliases to ensure consistency across classes and traits. It provides a list of original method names and their transformed counterparts, along with the reasons for the transformation. The cleaning applies to any class or trait, provided a pattern matches and does not create an infinite loop. ```Smalltalk x notEmpty -> x isNotEmpty x notNil -> x isNotNil x includesAnyOf: y -> x includesAny: y x includesAllOf: y -> x includesAll: y x ifNotNilDo: y -> x ifNotNil: y x ifNil: y ifNotNilDo: z -> x ifNil: y ifNotNil: z x ifNotNilDo: y ifNil: z -> x ifNotNil: y ifNil: z ``` -------------------------------- ### Simplify Empty Conditionals in Smalltalk Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md Chanel rewrites various forms of empty conditional checks to more concise equivalents. This includes transformations for `isEmpty`, `isNotEmpty`, `ifEmpty:`, and `ifNotEmpty:`. ```Smalltalk Original: `x isEmpty ifTrue: y` Transformation: `x ifEmpty: y` Original: `x isEmpty ifFalse: y` Transformation: `x ifNotEmpty: y` Original: `x isEmpty ifTrue: y ifFalse: z` Transformation: `x ifEmpty: y ifNotEmpty: z` Original: `x isEmpty ifFalse: y ifTrue: z` Transformation: `x ifEmpty: z ifNotEmpty: y` Original: `x isNotEmpty ifTrue: y` Transformation: `x ifNotEmpty: y` Original: `x isNotEmpty ifFalse: y` Transformation: `x ifEmpty: y` Original: `x isNotEmpty ifTrue: y ifFalse: z` Transformation: `x ifEmpty: z ifNotEmpty: y` Original: `x isNotEmpty ifFalse: y ifTrue: z` Transformation: `x ifEmpty: y ifNotEmpty: z` Original: `x ifEmpty: [ true ] ifNotEmpty: [ false ]` Transformation: `x isEmpty` Original: `x ifEmpty: [ false ] ifNotEmpty: [ true ]` Transformation: `x isNotEmpty` Original: `x ifNotEmpty: [ false ] ifEmpty: [ true ]` Transformation: `x isEmpty` Original: `x ifNotEmpty: [ true ] ifEmpty: [ false ]` Transformation: `x isNotEmpty` Original: `x isEmpty ifTrue: [ true ] ifFalse: [ false ]` Transformation: `x isEmpty` Original: `x isEmpty ifTrue: [ false ] ifFalse: [ true ]` Transformation: `x isNotEmpty` Original: `x isEmpty ifFalse: [ false ] ifTrue: [ true ]` Transformation: `x isEmpty` Original: `x isEmpty ifFalse: [ true ] ifTrue: [ false ]` Transformation: `x isNotEmpty` Original: `x isNotEmpty ifTrue: [ true ] ifFalse: [ false ]` Transformation: `x isNotEmpty` Original: `x isNotEmpty ifTrue: [ false ] ifFalse: [ true ]` Transformation: `x isEmpty` Original: `x isNotEmpty ifFalse: [ false ] ifTrue: [ true ]` Transformation: `x isNotEmpty` Original: `x isNotEmpty ifFalse: [ true ] ifTrue: [ false ]` Transformation: `x isEmpty` ``` -------------------------------- ### Equality Assertion Transformations Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md This section details the transformations applied to equality assertions in Smalltalk code. It covers changes from basic equality checks to more specific methods like 'equals:' and 'identicalTo:'. Conditions for application include subclassing TestCase and matching specific patterns. ```Smalltalk x assert: y = z -> x assert: y equals: z x deny: y = z -> x deny: y equals: z x assert: y == z -> x assert: y identicalTo: z x deny: y == z -> x deny: y identicalTo: z x assert: y = true -> x assert: y x deny: y = true -> x deny: y x assert: y = false -> x deny: y x deny: y = false -> x assert: y x assert: y equals: true -> x assert: y x deny: y equals: true -> x deny: y x assert: y equals: false -> x deny: y x deny: y equals: false -> x assert: y x assert: y identicalTo: true -> x assert: y x deny: y identicalTo: true -> x deny: y x assert: y identicalTo: false -> x deny: y x deny: y identicalTo: false -> x assert: y x assert: y == true -> x assert: y x deny: y == true -> x deny: y x assert: y == false -> x deny: y x deny: y == false -> x assert: y x assert: (y closeTo: z) -> x assert: y closeTo: z x deny: (y closeTo: z) -> x deny: y closeTo: z ``` -------------------------------- ### Nil Conditional Simplifications Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md This section outlines how Chanel simplifies conditional expressions involving nil checks. It transforms patterns like 'x isNil ifTrue: y' into 'x ifNil: y' and similar variations for 'isNotNil', 'ifFalse', and nested conditionals. ```Smalltalk x isNil ifTrue: y -> x ifNil: y x isNil ifFalse: y -> x ifNotNil: y x isNotNil ifTrue: y -> x ifNotNil: y x isNotNil ifFalse: y -> x ifNil: y x isNil ifTrue: y ifFalse: z -> x ifNil: y ifNotNil: z x isNil ifFalse: y ifTrue: z -> x ifNil: z ifNotNil: y x isNotNil ifTrue: y ifFalse: z -> x ifNil: z ifNotNil: y x isNotNil ifFalse: y ifTrue: z -> x ifNil: y ifNotNil: z ``` -------------------------------- ### Condense Sources Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md This cleaner removes trailing whitespace from lines and final periods from methods. It ensures a more consistent and clean source code format. ```Smalltalk Conditions: - There exists a useless space at the end of a line or a final dot at the end of the method. Warnings: - This can remove final spaces at the end of a line in a String. ``` -------------------------------- ### Remove Nil Assignments in Initialization Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md Chanel removes nil assignments within `#initialize` methods, as they are often unnecessary. This cleaning is applied to methods named `#initialize` that contain nil assignments, with a warning that it might affect cases where `#initialize` is used for resetting instances. ```Smalltalk Object>>initialize "Example: remove nil assignments" field1 := nil. field2 := nil. ``` -------------------------------- ### Categorize unclassified methods Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md Chanel utilizes the system method categorizer to classify methods marked as 'as yet unclassified'. This process works on instances, class sides of classes, and traits. ```Smalltalk Chanel try to use the system method categorizer to classify unclassified methods. *Conditions for the cleanings to by applied:* - Work on instances and class side of classes and traits. - The protocol of the method needs to by `as yet unclassified`. ``` -------------------------------- ### Replace nil equality checks with isNil/isNotNil Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md Chanel standardizes nil equality comparisons by replacing expressions like `x = nil` or `x ~= nil` with the more idiomatic `x isNil` or `x isNotNil`, respectively. This avoids potential infinite loops in specific override scenarios. ```Smalltalk Chanel replace of nil equality by #isNil or #isNotNil. Here is the list of rewrites: | Original | Transformation | Reason | | ------------- | ------------- | ------------- | | `x = nil` | `x isNil` | | `x == nil` | `x isNil` | | `x ~= nil` | `x isNotNil` | | `x ~~ nil` | `x isNotNil` | *Conditions for the cleanings to by applied:* - Can be applied on any classes and traits. - A pattern from the list above match. - Does not apply if the application of the pattern would cause an infinit loop. For example it will **not** rewrite: ```Smalltalk isNil ^ self = nil ``` into: ```Smalltalk isNil ^ self isNil ``` ``` -------------------------------- ### Cut Conditional Branches in Smalltalk Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md Chanel simplifies conditional statements by removing redundant branches, such as those involving `nil`, `true`, `false`, or self-referential blocks. ```Smalltalk Original: `x ifNil: [ nil ]` Transformation: `x` Original: `x ifNil: [ nil ] ifNotNil: y` Transformation: `x ifNotNil: y` Original: `x ifNotNil: y ifNil: [ nil ]` Transformation: `x ifNotNil: y` Original: `x ifNil: nil` Transformation: `x` Original: `x ifNil: nil ifNotNil: y` Transformation: `x ifNotNil: y` Original: `x ifNotNil: y ifNil: nil` Transformation: `x ifNotNil: y` Original: `x ifTrue: [ true ] ifFalse: [ false ]` Transformation: `x` Original: `x ifTrue: [ false ] ifFalse: [ true ]` Transformation: `x not` Original: `x ifFalse: [ false ] ifTrue: [ true ]` Transformation: `x` Original: `x ifFalse: [ true ] ifTrue: [ false ]` Transformation: `x not` Original: `x ifNotNil: [ x ]` Transformation: `x` Original: `x ifNotNil: [ x ] ifNil: y` Transformation: `x ifNil: y` Original: `x ifNil: y ifNotNil: [ x ]` Transformation: `x ifNil: y` Original: `x ifEmpty: [ y ] ifNotEmpty: [ x ]` Transformation: `x ifEmpty: [ y ]` Original: `x ifNotNil: [ :e | e ] ifNil: y` Transformation: `x ifNil: y` Original: `x ifNil: y ifNotNil: [ :e | e ]` Transformation: `x ifNil: y` Original: `x ifNotEmpty: [ x ] ifEmpty: y` Transformation: `x ifEmpty: y` Original: `x ifEmpty: [ y ] ifNotEmpty: [ :e | e ]` Transformation: `x ifEmpty: y` Original: `x ifNotEmpty: [ :e | e ] ifEmpty: y` Transformation: `x ifEmpty: y` Original: `x detect: y ifFound: [ :e | e ] ifNone: z ` Transformation: `x detect: y ifNone: z` Original: `x at: y ifPresent: [ :e | e ] ifAbsent: z ` Transformation: `x at: y ifAbsent: z` Original: `x at: y ifPresent: [ x at: y ] ifAbsent: z ` Transformation: `x at: y ifAbsent: z` Original: `x at: y ifPresent: [ :e | x at: y ] ifAbsent: z ` Transformation: `x at: y ifAbsent: z` ``` -------------------------------- ### Remove Unnecessary 'not' Transformations Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md This section details the transformations applied by Chanel to remove redundant 'not' expressions, simplifying boolean logic and conditional statements. It covers various patterns from simple boolean inversions to more complex conditional rewrites. ```Smalltalk | original | transformation | original := 'true not'. transformation := 'false'. original := 'false not'. transformation := 'true'. original := 'x not not'. transformation := 'x'. original := 'x not ifTrue: y'. transformation := 'x ifFalse: y'. original := 'x not ifFalse: y'. transformation := 'x ifTrue: y'. original := 'x not ifTrue: y1 ifFalse: z'. transformation := 'x ifTrue: z ifFalse: y1'. original := 'x not ifFalse: y1 ifTrue: z'. transformation := 'x ifTrue: y1 ifFalse: z'. original := 'x isEmpty not'. transformation := 'x isNotEmpty'. original := 'x isNotEmpty not'. transformation := 'x isEmpty'. original := 'x isNil not'. transformation := 'x isNotNil'. original := 'x isNotNil not'. transformation := 'x isNil'. original := 'x select: [:temp | a not]'. transformation := 'x reject: [:temp | a]'. original := 'x reject: [:temp | a not]'. transformation := 'x select: [:temp | a]'. original := '(x <= y) not'. transformation := 'x > y'. original := '(x < y) not'. transformation := 'x >= y'. original := '(x = y) not'. transformation := 'x ~= y'. original := '(x == y) not'. transformation := 'x ~~ y'. original := '(x ~= y) not'. transformation := 'x = y'. original := '(x ~~ y) not'. transformation := 'x == y'. original := '(x >= y) not'. transformation := 'x < y'. original := '(x > y) not'. transformation := 'x <= y'. original := '[ a not] whileTrue: y'. transformation := '[ a] whileFalse: y'. original := '[ a not] whileFalse: y'. transformation := '[ a] whileTrue: y'. original := '[ a not] whileTrue'. transformation := '[ a] whileFalse'. original := '[ a not] whileFalse'. transformation := '[ a] whileTrue'. original := 'self assert: x not'. transformation := 'self deny: x'. original := 'self deny: x not'. transformation := 'self assert: x'. original := 'self assert: x equals: y not'. transformation := 'self deny: x equals: y'. original := 'self assert: x not equals: y'. transformation := 'self deny: x equals: y'. original := 'self deny: x equals: y not'. transformation := 'self assert: x equals: y'. original := 'self deny: x not equals: y'. transformation := 'self assert: x equals: y'. ``` -------------------------------- ### Extract Return from Conditionals Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md Chanel attempts to extract a common return statement from all branches of a conditional message. This applies to various conditional selectors like #ifTrue:ifFalse:, #ifNil:ifNotNil:, etc., provided specific AST and block conditions are met. ```Smalltalk Conditional selectors supported: #ifTrue:ifFalse: #ifFalse:ifTrue: #ifNil:ifNotNil: #ifNotNil:ifNil: #ifEmpty:ifNotEmpty: #ifNotEmpty:ifEmpty: #ifExists:ifAbsent: Conditions: - AST node is a message. - Node is not in a cascade. - Node is the last node of the parent. - Selector matches one of the supported selectors. - All arguments are blocks. - All block arguments have a return as the last statement. ``` -------------------------------- ### Remove useless nodes from AST Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md This cleaner removes nodes from the Abstract Syntax Tree (AST) that are deemed useless, such as literals, blocks, globals, or variable usages, provided they are not part of essential structures like returns, messages, pragmas, or arrays. ```Smalltalk Chanel goes over all the methods in the system to remove some useless nodes. *Conditions for the cleanings to by applied:* A node can be useless if they are: - A literal - A block - A global - A temporary usage - An instance variable usage - An argument usage - A literal array - A dynamic array And if none of its ancestor in the ast are: - A return - A message - A pragma - A dynamic array - A literal array - An assigment ``` -------------------------------- ### Extract Assignments from Conditionals Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md This refactoring extracts a common assignment to the same variable from all branches of a conditional message. It supports the same conditional selectors as the 'Extract Return' refactoring, with the condition that each block's last statement is an assignment to the same variable. ```Smalltalk Conditional selectors supported: #ifTrue:ifFalse: #ifFalse:ifTrue: #ifNil:ifNotNil: #ifNotNil:ifNil: #ifEmpty:ifNotEmpty: #ifNotEmpty:ifEmpty: #ifExists:ifAbsent: Conditions: - AST node is a message. - Node is not in a cascade. - Selector matches one of the supported selectors. - All arguments are blocks. - All block arguments have an assignment of the same name as the last statement. ``` -------------------------------- ### Remove Unread Temporaries Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md Removes temporary variables that are defined but never read within their scope. This improves code clarity and reduces potential confusion. ```Smalltalk MyClass>>aMethod | temp1 temp2 | temp1 := 1. temp2 := 2. ^ temp1 ``` -------------------------------- ### Remove methods with equivalent in super classes Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md This cleaning tool removes methods that have an equivalent method of the same name in a superclass. It applies to instances and class sides of classes, provided the superclass is not nil and the method overrides another method with the same AST. ```Smalltalk If a methods has an equivalent method of the same name in a super class, Chanel remove the method. *Conditions for the cleanings to by applied:* - Work only on instances and class side of classes. Does not work on traits. - The superclass of the method should not be nil. - The method should override another method in the hierarchy. - The overriden method as the same AST than the overriding method. ``` -------------------------------- ### Remove Methods Only Calling Super Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md Removes methods that consist solely of a call to the superclass method with the same selector, provided they have no pragmas. This helps in cleaning up redundant method definitions. ```Smalltalk MyClass>>someMethod ^ super someMethod ``` -------------------------------- ### Rename Test Cases Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md Chanel renames test cases ending with 'Tests' to 'Test' to align with the convention 'a XXTestCase'. This applies to classes that are subclasses of TestCase and whose names end with 'Tests', provided no class with the same name without the 's' already exists. ```Smalltalk ClassNameTests -> ClassNameTest ``` -------------------------------- ### Remove Duplicated Methods from Traits Source: https://github.com/jecisc/chanel/blob/master/resources/doc/documentation.md Removes duplicate methods found in a class or trait that are also present in a trait it uses. This ensures that only the definitive version of a method is considered, preventing redundancy. ```Smalltalk TraitComposition uses: MyTrait. MyTrait>>duplicatedMethod "This method is also defined in MyTrait." MyClass>>duplicatedMethod "This is a duplicate of the method in MyTrait." ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.