Refactorings

Rename Symbol
Rename Class
Rename Package


Description: Change the name of a program symbol

Example:

  Before refactoring:

           for(int a=0; a<args.length; a++) {
                   action(args[a]);
           }

  After refactoring:

           for(int i=0; i<args.length; i++) {
                   action(args[i]);
           }

Refactoring Context: Cursor has to be on the symbol.

Input parameters: New name of the symbol (for example: 'i')

Mechanics:  Replace  old  symbol name  by  the  new  name on  all  its
        occurences in the project. In case of public class stored in a
        file  of the  same  name, also  rename  the file.  In case  of
        package also store files in new directories.






Add Parameter


Description: Add parameter to a method, function or macro.

Example:

        Before refactoring:

            public int method(int x) {
                   if (x<=1) return(1);
                   return(method(x-1)+method(x-2));
            }

        After refactoring:

            public int method(int x, int y) {
                   if (x<=1) return(1);
                   return(method(x-1, 0)+method(x-2, 0));
            }


Refactoring Context: Cursor  has to be on the  method's (function's or
        macro's) name.

Input parameters:  Position of the new parameter,  its declaration and
        default value.  (for example: '2', 'int y' and '0').

Mechanics: Inspect  all references of  the method (function  or macro)
        and add  declaration of the  new parameter to  each definition
        and default value to each invocation of the method.







Delete Parameter


Description: Delete parameter of a method, function or macro.

Example:

        Before refactoring:

            public int method(int x, int y) {
                   if (x<=1) return(1);
                   return(method(x-1, 0)+method(x-2, 0));
            }

        After refactoring:

            public int method(int x) {
                   if (x<=1) return(1);
                   return(method(x-1)+method(x-2));
            }


Refactoring Context: Cursor  has to be on the  method's (function's or
        macro's) name.

Input parameters:  Position of the  parameter to delete  (for example:
      '2').

Mechanics: Inspect  all references of  the method (function  or macro)
        and remove the parameter.





Move Parameter


Description: Reorder parameter of a method, function or macro.

Example:

        Before refactoring:

            public int method(int x, int y) {
                   if (x<=1) return(1);
                   return(method(x-1, 0)+method(x-2, 0));
            }

        After refactoring:

            public int method(int y, int x) {
                   if (x<=1) return(1);
                   return(method(0, x-1)+method(0, x-2));
            }


Refactoring Context: Cursor  has to be on the  method's (function's or
        macro's) name.

Input parameters: Old and new positions of the parameter (for example:
      '1' and '2').

Mechanics: Inspect all references of  the mehod and move the parameter
        from its original to its new position.







Extract Method
Extract Function
Extract Macro


Description: Extract region into new method (function or macro).
Example:

        Before refactoring:

            public static void main(String[] args) {
                   int i,n,x,y,t;
                   n = Integer.parseInt(args[0]);
                   x=0; y=1;
                   for(i=0; i<n; i++) {
                            t=x+y; x=y; y=t;
                   }
                   System.out.println("" + n + "-th fib == " + x);
            }

        After refactoring:

            static int fib(int n) {
                   int i, x, y, t;
                   x=0; y=1;
                   for(i=0; i<n; i++) {
                            t=x+y; x=y; y=t;
                   }
                   return(x);
            }


            public static void main(String[] args) {
                   int i,n,x,y,t;
                   n = Integer.parseInt(args[0]);
                   x = fib(n);
                   System.out.println("" + n + "-th fib == " + x);
            }


Refactoring Context: The code for extraction has to be selected within
            the editor.


Input Parameters: Name fo the new method (function or macro).

Mechanics: Copy the region  before the method (function), generate new
           header  and footer  based on  static analysis  of  code and
           generate call to the new method at the original place.




Expand Names



Description: Expand types to fully qualified names
Example:

        Before refactoring:

            package com.xrefactory.refactorings;
            import javax.swing.*;
            class Hello {
                public static void main(String argv[]) {
                    JOptionPane.showMessageDialog(null, "Hello world");
                }
            }


        After refactoring:

            package com.xrefactory.refactorings;
            import javax.swing.*;
            class Hello {
                public static void main(java.lang.String argv[]) {
                    javax.swing.JOptionPane.showMessageDialog(null, "Hello world");
                }
            }


Refactoring Context: Cursor has to be on a definition of a class.

Input Parameters: None.

Mechanics: Replace short type names by fully qualified names.





Reduce Names


Description: Reduce fully qualified type names to short form.
Example:

        Before refactoring:

            package com.xrefactory.refactorings;
            class Hello {
                public static void main(java.lang.String argv[]) {
                    javax.swing.JOptionPane.showMessageDialog(null, "Hello world");
                }
            }

        After refactoring:

            package com.xrefactory.refactorings;
            import javax.swing.JOptionPane;
            class Hello {
                public static void main(String argv[]) {
                    JOptionPane.showMessageDialog(null, "Hello world");
                }
            }


Refactoring Context: Cursor has to be on a definition of a class.

Input Parameters: None.

Mechanics: Replace fully qualified names  by short names.  If the type
           is  not imported then add either import on demand or single 
           type import command.





Set Target for Next Moving Refactoring


Description: Set target positon for moving refactorings

Refactoring Context: Cursor has to be on the position where the field,
            method or class will be moved, pulled up or pushed down.

Input Parameters: None.





Move Static Field
Move Static Method


Description: Move static field or method to another place.
Example:

        Before refactoring:

        class Target {
            static int i=0;
        }               

        class Source {
            static int j=1;
            public static void method() {
                    System.out.println("i, j == " + Target.i + ", " + j);
            }
            public static void main(String[] args) {
                    method();
            }
        }


        After refactoring:

        class Target {
            static int i=0;
            public static void method() {
                 System.out.println("i, j == " + i + ", " + Source.j);
            }
        }

        class Source {
            static int j=1;
            public static void main(String[] args) {
                Target.method();
            }
        }


Refactoring  Context:  Target  place  has  to set  using  'Set  Target
            Position',  cursor has  to be  on the  name of  the method
            (field) to be moved (at its definition).

Input Parameters: None.

Mechanics: Move  the method (field), adjust all  references within its
           body  (initialisation)  and   all  its  references  in  the
           project.





Move Class


Description: Move class from one place to another.

Example:
        Before refactoring:

            class A {
                static int i;
                static class B {
                    static void method() {
                        System.out.println("i==" + i);
                    }
                }
            }

        After refactoring:

            class A {
                static int i;   
            }

            class B {
                static void method() {
                    System.out.println("i==" + A.i);
                }
            }

Refactoring  Context:  Target  place  has  to set  using  'Set  Target
            Position', cursor has to be on the name of the class to be
            moved (at its definition).

Input Parameters: None.

Mechanics: Move the class and adjust all its references.





Move Class to New File


Description: Move class into its own file.

Example:
        Before refactoring:

---- file A.java
            package pack;

            class A {
                static int i;
                static class B {
                    static void method() {
                        System.out.println("i==" + i);
                    }
                }
            }

        After refactoring:

---- file A.java
            package pack;

            class A {
                static int i;   
            }

---- file B.java
            package pack;

            public class B {
                static void method() {
                    System.out.println("i==" + A.i);
                }
            }

Refactoring Context: Cursor  has to be on the name of  the class to be
            moved (at its definition).

Input Parameters: Name of the file to create

Mechanics: Create new file, add package and imports and move the class
           and adjust all its references.





Move Field


Description: Move field from one class to another
Example:
        Before refactoring:

            class Target {
    
            }

            class Source {
                  Target link;
                  int field;
                  public int method() {
                         return(field);
                  }
            }

        After refactoring:

            class Target {
                  int field;
            }
    
            class Source {
                  Target link;
                  public int method() {
                         return(link.field);
                  }
            }

Refactoring  Context:  Target  place  has  to set  using  'Set  Target
            Position', cursor has to be on the name of the field to be
            moved (at its definition).

Input Parameters: the field pointing from source class to target class
      (in the example: 'link').

Mechanics: Move the  field, inspect all its references  add insert the
           field pointing from source to target.

Comment:  This  refactoring  relies  on  semantic  properties  of  the
         program,  it can not  be ensured  to be  100% safe  by static
         analysis of the program.






Pull Up Field
Pull Up Method
Push Down Field
Push Down Method


Description: Move method (field) up (down) in the class hierarchy.

Example:
        Before refactoring:

            class SuperClass {
                int x = 0;
                int y = 0;
            
            }
            
            class InferClass extends SuperClass {
                int y = 1;
            
                void method() {
                    System.out.println("x == " + x);
                    System.out.println("this.x == " + this.x);
                    System.out.println("this.y == " + this.y);
                    System.out.println("super.y == " + super.y);
                }
            
                public static void main(String args[]) {
                    (new InferClass()).method();
                }
            }

        After refactoring:

            class SuperClass {
                int x = 0;
                int y = 0;
            
                public void method() {
                    System.out.println("x == " + x);
                    System.out.println("this.x == " + this.x);
                    System.out.println("this.y == " + ((InferClass)this).y);
                    System.out.println("super.y == " + this.y);
                }            
            }

            class InferClass extends SuperClass {
                int y = 1;
            
                public static void main(String args[]) {
                    (new InferClass()).method();
                }
            }

Refactoring  Context:  Target  place  has  to set  using  'Set  Target
            Position',  cursor has  to be  on the  name of  the method
            (field) to be moved (at its definition).

Input Parameters: None.

Mechanics:  Move the  method  and adjust  references  inside its  body
           (initialisation).





Encapsulate Field
Self Encapsulate Field


Description: Generate field accessors and their invocations.

Example:
        Before refactoring:

            class EncapsulateField {
                public int field;
            
                void incrementField() {
                    field = field + 1;
                }
            }

            class AnotherClass extends EncapsulateField {
                void printField() {
                    System.out.println("field == " + field);
                }
            }

        After refactoring:

            class EncapsulateField {
                private int field;
                public int getField() {return field;}
                public int setField(int field) { this.field=field; return field;}
            
                void incrementField() {
                    setField(getField() + 1);
                }
            }
            
            class AnotherClass extends EncapsulateField {
                void printField() {
                    System.out.println("field == " + getField());
                }
            }

Refactoring  Context:  Cursor has  to  on the  name  of  the field  to
             encapsulate (on its definition).

Input Parameters: None.

Mechanics: Generate getter and  setter methods. Inspect all references
           of the field and  replace them by appropriate accessor. The
           Self Encapsulate field (in difference to Encapsulate field)
           processes  also references  within the  class  defining the
           field (see example). The  Encapsulate Field will left those
           references untouched.




Turn Virtual Method to Static


Description: Turn method into static.

Example:
        Before refactoring:

            class Project {
                Person[] participants;
            }

            class Person {
                int id;
                public boolean participate(Project proj) {
                    for(int i=0; i<proj.participants.length; i++) {
                        if (proj.participants[i].id == id) return(true);
                    }
                    return(false);
                }   
            }


        After refactoring:

            class Project {
                Person[] participants;
                static public boolean participate(Person person, Project proj) {
                    for(int i=0; i<proj.participants.length; i++) {
                        if (proj.participants[i].id == person.id) return(true);
                    }
                    return(false);
                }   
            }
            
            class Person {
                int id;
            }

Refactoring Context:  Cursor has to  on the name  of the method  to be
             turned static (on its name).

Input  Parameters: The  name of  the  new parameter  (in the  example:
       'person').

Mechanics:  Add new  parameter to  the method  passing  its invocation
           object.  Make  all accesses to method's object  via the new
           parameter.  Declare  the method static and  make all method
           invocations static.

Comment: This refactoring  is usualy used to move  virtual method from
         one  class to another  in the  sequence 'Turn  Virtual Method
         into Static',  'Move Static  Method' and 'Turn  Static Method
         into Virtual'.




Turn Static Method to Virtual


Description: Make the method virtual.
Example:

        Before refactoring:

            class Target {
                int field;
                static int method(Source ss) {
                    System.out.println("field==" + ss.link.field);
                }
            }

            class Source {
                Target link;
                static void main(String[] args) {
                    Target.method(new Source());
                }
            }

        After refactoring:

            class Target {
                int field;
                int method() {
                    System.out.println("field==" + field);
                }
            }

            class Source {
                Target link;
                static void main(String[] args) {
                    new Source().link.method();
                }
            }


Refactoring Context:  Cursor has to  on the name  of the method  to be
             turned virtual (on its name).

Input Parameters: The parameter containing method's object. Optionally
      a  field getting  method's  object from  the  parameter. In  the
      example: '1' and "link".

Mechanics:  Remove the  'static' keyword,  inspect all  references and
           apply  method on  the method's  object (method's  object is
           determine from the combination of parameter and field).

Comment: This refactoring  is usualy used to move  virtual method from
         one  class to another  in the  sequence 'Turn  Virtual Method
         into Static',  'Move Static  Method' and 'Turn  Static Method
         into Virtual'.