[prev] [up] [next]

Refactorings

A number of code rewrite operations (refactorings) are supported by the browser. This functionality is provided by the refactoryBrowser package.
For more detailed information, please refer to the refactoryBrowser documentation.

New Refactorings

The following refactorings were not present in the original refactoryBrowser package but added later:

Refactorings By Name

Refactorings By Problem To Solve

Abstract Variable
Creates getter/setters for a variable, and then changes all direct references to the variables to go through the getter/setter methods. If getter/setter methods already exist, it will use the existing methods. However, they must be pure getter/setter methods (i.e., no lazy initialization getters). If no getter/setter methods exist it will create them based on the variable's name (see Create Variable Accessors). If the class already defines a method with the variable name's then it will simply add an integer to the name.

The abstract instance variable refactoring is available from the "SourceCode" menu when you have selected an instance variable. It is also available from the "Variables" menu in the class definition when you have selected an instance variable. Finally, it is available from the "Class"->"Instance Variables" menu

Similarly, the abstract class variable refactoring is available from the "SourceCode" menu when you have selected a class variable. It is also available from the "Variables" menu in the class definition view when you have selected a class variable. Finally, it is available from the "Class"->"Class variables" menu.

Safety: The abstract variable refactorings are safe under normal circumstances.

Add Parameter to Method
Adds a parameter to all senders of a method and adds the argument to all implementors of the method. This makes it easy to quickly add a needed object to a method.

The add parameter refactoring is available from the "SourceCode"->"Other"->"Add Method Parameter..." menu item.

Safety: The add parameter is relatively safe assuming that the code that is added as a parameter is safe (i.e., the code doesn't have side-effects). One area where it would be unsafe is to add a parameter to a method that is #perform:ed since we can't determine where the method is performed from (and the refactoring changes the name of the method).

Children To Sibling
Converts a class to be a sibling of its subclasses. This is accomplished by adding a new class that is a superclass of the class and its subclasses. This new class will contain all the common methods between the class and its subclasses. Those methods that have been redefined in the subclasses will be defined as #subclassResponsibility methods in the new class.

This refactoring is available from "Class"->"Other"->"Convert to Sibling". It is enabled, if a single class is selected, which contains at least one subclass.

Safety: This refactoring could fail if you check the class hierarchy of the superclass, since the class hierarchy is changed for the new class.

Before conversion of A to a sibling:

     A
+----+----+
|    |    |
B    C    D

After:

	N
	|
+----+--+--+----+
|    |     |    |
A    B     C    D

Convert to ValueHolder
Creates an accessor for a valueHolder on a variable, and rewrites all accesses to the variable to fetch the value indirectly through the valueHolder. This includes existing accessor methods.

This code generator refactoring is available for individual variables (select one or more) from the "Variables"->"Convert to ValueHolder" menu.

Safety: This refactoring changes the behavior, if a corresponding message response is already inherited by a superclass.

Create Variable Accessors
Creates getter/setters for a variable. If corresponding methods already exist, they will not be overwritten.

This code generator refactoring is available for individual variables (select one or more) from the "Variables"->"Generate"->"Access Methods" menu. It is also available from the "Class"->"Generate"->"Access Methods" menu, here, accessors for all variables are generated.

Safety: This refactoring changes the behavior, if a corresponding message response is already inherited by a superclass.

Eliminate Constant
Replaces a literal constant by either an inst- or class variable or a getter message If corresponding variables/methods already exist, they will not be overwritten.

In the browser, select a literal constant and choose this refactoring from the code menu. Depending on the chosen replacement, class- or instance variables are added, and the corresponding initialize method is updated to properly set the variable. Then all references to that constant are reqritten to access the variable instead.
You can also choose to rewrite the literal into a getter-call to either the instance or the class side. In that case, a corresponding getter method is created.

Safety: This refactoring changes the behavior, if a corresponding message response is already inherited by a superclass or redefined in a subclass. Use this if the same constant occurs multiple times within a class, or when it needs to be visible in other classes via a getter (typically, on the class side).

Extract Method
Extract method is an easy refactoring to perform with the Refactoring Browser. When you are viewing a method, select the statements that you want to extract, and perform "Code"->"Extract Method" from the code editors pop-up menu.

The browser will determine if it is legal to extract the method by checking for return statements and temporary variable assignments. If everything is OK, it will prompt you for a method name.
In this dialog, you can enter the new selector with the appropriate number of arguments (listed in the list box below the selector). You can also reorder the parameters from this dialog. Select a parameter and use the arrow buttons to move the parameter up or down in the list.

Extract Method to Component
Extract method to component is a more complicated refactoring, which extracts the selected code in the editor, and converts it to a message send to another component via a variable (i.e, in contrast to the above, not a self-send).
The extracted code is converted to a new method (in one or more receiver classes), where all references to local variables are passed as argument, and references to instance variables are converted to accessor messages.
To perform the reafctoring, select the statements that you want to extract, and perform "Code"->"Extract Method to Component" from the code editors pop-up menu.

The browser will ask for any additional information, which is required to execute the refactoring.

Extract to Temporary
Extract the selected expression into a (new) temporary of the method (Intention revealing temporary variable).

This refactoring is available when you have selected the code of an expression (in the editor) that is used as part of another expression. After you have selected the expression, select the "Code"->"Extract to Temporary" menu choice.

Safety: Since this refactoring can change the evaluation order of the overall expression, it is not safe if there are side effects between those expression that are evaluated before the selected expression and the selected expression itself.
The refactoring fails, if the new temporary name hides an existing variables name (because this makes the code more error-prone)

Inline All Self-Sends
Inlines the selected method wherever it is used in a self-send.

This refactoring is available from the "Selector"->"Refactor"->"Inline All Self Sends" menu when you select a message in the method list.

Safety: This refactoring is fairly safe.

Inline Method
Inlines the selected message send into the method. If the method is defined on another class, it may need to create accessors for the variables referenced in the method to be inlined.

This refactoring is available from the "Code"->"Inline Method" menu when you select a message send in the code.

Safety: This refactoring is fairly safe. If the refactoring finds something that it considers unsafe, it will warn you before performing the refactoring. If you proceed through the warning it will still inline the method.

Inline Parameter
Moves a constant literal parameter of a message send into the method that is sent.

This refactoring is available both from the "Source"->"Inline Method Parameter" and the codeviews "Code"->"Inline Method Parameter" menu, after you have selected the text of a parameter of the method in the codeView.

Safety: This refactoring is safe except when performing methods, since we can't convert the symbols that are performed (the name of the method is changed by this refactoring).

Inline Temporary
Replaces all references to a temporary variable with its definition.

This refactoring is available from the "Selection"->"Inline Temporary" when you have an assignment statement selected.

Safety: This refactoring can be unsafe if the code you are inlining has side-effect or if any code between the assignment statement and the references have side effects on the inlined expression.

Insert Superclass (Add Class)
Asks for a (possibly new) common superclass for a number of child classes.

This refactoring is available from "Class"->"Move"->"Insert Common Superclass". It is enabled, if at least one class is selected, and all selected classes have a common superclass.

Safety: This refactoring could fail if you check the class hierarchy of the superclass, since the class hierarchy is changed for the new class.

Before insertion of N as a new superclass of A, B and C:

     S
+----+----+
|    |    |
A    C    D

After:

     S
     |
     N
     |
+----+----+
|    |    |
A    C    D

Move Method
Moves a method from one class to another. The original method will be replaced with a forwarder method. The method will be moved into an argument of the method or a variable of the original method's class.

This refactoring is available from "Selector"->"Move"->"To Component".

Safety: This refactoring is safe assuming you select the correct class(es) of the variable that should contain the new method.

Move To Inner Scope
Move a temporary variable's definition to the inner most block that completely defines its.

This refactoring is available from "Selection"->"Move to Inner Scope" when you have selected a temporary variable in a method.

Safety: This refactoring is safe unless someone is looking at the source code.

Rewrite Oldstyle Messages
Rewrites sends to "handle:do:", "valueOnUnwindDo:" and "valueNowOrOnUnwindDo:" to corresponding ANSI messages "on:do:", "ifCurtailed:" and "ensure:".

Safety: This refactoring is safe and improves portability of your program.

Protect (Concrete) Instance Variable
Removes indirect references through getter/setter methods to use direct variable referencing. If the getter/setter methods are no longer used, then they will be removed.

This refactoring is available from "Class"->"Instance Variables"->"Concrete".

Safety: This refactoring is essentially an Inline All Self Sends, so it contains all the safe restrictions as Inline All Self Sends has.

Pull Up Variable
Moves an instance/class variable up the hierarchy.

The pull up instance variable refactoring is available from the "Class"->"Instance Variables"->"Pull Up" menu. It is also available as "Push up" when you have selected the variable in either the class definition or a method under the "Variables" and "Selection" menus.

Similarly, the pull up class variable is available from the "Class"->"Class Variables"->"Pull Up" menu. It is also available as "Push up" when you have selected the variable in either the class definition or a method under the "Variables" and "Selection" menus.

Safety: This refactoring is not safe if you code that depends on the exact layout of the class. Such code normally uses the #instVarAt:{put:} methods.

Push Down Variable
Moves a variable into the subclasses that use the variable.

The push down instance/class variable refactoring is available from the "Class"->"Instance/Class variables"->"Push Down" menu, and also from the "Variables"->"Push Down" menu when the variable is selected in the class definition.

Safety: This refactoring is safe unless one is accessing the variable using the #instVarAt:{put:} methods.

Pull Up Method
Move a method into the superclass. If the superclass already defines the method, then the superclass must be abstract. In this case, the superclass' definition is copied down to the subclasses that do not define the method.

The push up method refactoring is available from the "Selector"->"Move"->"Pull Up" menu.

Safety: This refactoring is safe assuming that every class that sends #subclassResponsibility is abstract.

Push Down Method
Moves a method into the subclasss that do not define the method. The method can only be moved, if the class that defines the method is an abstract class.

The push down method refactoring is available from the "Selector"->"Move"->"Push Down" menu.

Safety: This refactoring is safe assuming that every class that sends #subclassResponsibility is abstract.

Remove Class
Removes a class if it is not referenced. If the class contains subclasses, then the subclasses will be moved under the removed class' superclass.

The remove class refactoring is available from the "Class"->"Safe Remove" menu.

Safety: This refactoring is safe if they are no indirect references to the class. Such references maybe from the #subclasses method or from performing "Smalltalk at: ...".

Before removal of A:

     S
     |
     A
+----+----+
|    |    |
B    C    D

After:

     S
+----+----+
|    |    |
B    C    D

Remove Method
Remove a method if there are no references to the selector.

This refactoring is available from the "Selector"->"Safe Remove" menu.

Safety: This refactoring is not safe if you have constructed selectors that perform the method (e.g., "self perform: 'foo' asSymbol). However, if you have code such as "self perform: #foo" then it will consider the #foo method referenced.

Remove Parameter from Method
Removes a parameter from a method if that parameter is not referenced in any implementation of that method.

This refactoring is available both from the "Source"->"Remove Method Parameter" and the codeviews "Code"->"Remove Method Parameter" menu, after you have selected the text of a parameter of the method in the codeView.

Safety: This refactoring is not safe when you are performing the method (the name of the method is changed by this refactoring). Also, it is not safe if the parameter that is removed, has side-effects at one of its call sites.

Remove Variable
Removes an instance/class variable from a class if it is not referenced.

The remove instance variable refactoring is available from the "Class"->"Instance variable"->"Remove..." menu as well as the "Variables" menu.

Similarly, the remove class variable refactoring is available from the "Class"->"Class variable"->"Remove..." menu as well as the "Variables" menu.

Safety: This refactoring is safe under normal circumstances. However, if you have code that depends on the layout of the classes, then it may not be safe.

Rename Class
Renames a class and all references to the class. Symbols are also renamed.

This refactoring is available from "Class"->"Rename".

Safety: This refactoring is safe except when you have indirect class references (e.g., "Smalltalk at: 'Foo' asSymbol").

Rename Method
Renames all implementors of the method and all references to the method. Symbols with the same name are also renamed.

This refactoring is available from "Selector"->"Rename".

Safety: This refactoring is not safe for constructed selectors that are perform:ed. Also, if you reorder the parameters, this refactoring will not be safe if the parameters have side-effects on each other.

Notice that this operation is also able to change the order of the methods arguments (and rewrite all senders).

Rename Local Variable (Rename Temporary)
Renames a temporary variable and all references to the temporary within the edited method.

This refactoring is available from the code editors "Code"->"Rename Local Variable" menu when you have a temporary variable or argument selected.

Safety: This refactoring is completely safe, unless someone is looking at the source code for the method.

Rename Variable
Renames an instance/class variable and all references to the variable. It does not rename the getter/setter methods.

The rename instance variable refactoring is available from the "Class"->"Instance Variables"->"Rename" menu, and also the "Variables" menu.

Similarly, the rename class variable refactoring is available from "Class"->"Class variables"->"Rename" or the "Variables" menu.

Safety: This refactoring is safe except for classes that depend on the class layout since the positions of the variables may change.

Temporary to Instance Variable
This refactoring converts a temporary variable into an instance variable.

This refactoring is available from the "Code"->"Convert to Instance Variable" menu, after you have selected the text of a temporary variable.

Safety: This refactoring is not safe if the method that defines the temporary is a recursive method.

Abstract class

The refactorings considers a class abstract if it defines a method as subclassResponsibility or the class does not have any references. Since Metaclasses contain a living instance in the system, they are only considered abstract if they contain a method defined as a subclassResponsibility.
Next: Code Generation

[stx logo] Copyright © 2000 eXept Software AG, all rights reserved

<info@exept.de>

Doc $Revision: 1.26 $ $Date: 2020/09/13 11:01:56 $