Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Recommenders/CleanCodeMethodSorter"

(Added functionality of build 101++)
(Separate invocation ordering: Typo)
 
(23 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
== Plugin  ==
 
== Plugin  ==
''Currently BETA-stadium (Build 101, 08/22/2011). Features and description are subject to change.''  
+
''Currently BETA-stadium (Build 114, 08/30/2011). Features and description are subject to change.''  
  
 
==== Description ====
 
==== Description ====
Line 15: Line 15:
 
Please download and install the plugin using the [http://vandyk.st.informatik.tu-darmstadt.de/updates/students/ep/mateusz-method-sorter/org.eclipselabs.recommenders.cleancode.methodsorter.repository/target/site/ update-site].
 
Please download and install the plugin using the [http://vandyk.st.informatik.tu-darmstadt.de/updates/students/ep/mateusz-method-sorter/org.eclipselabs.recommenders.cleancode.methodsorter.repository/target/site/ update-site].
  
==== Bugs ====
+
==== Bugs and Planned Features ====
So far, no issues documented. Please report any encountered bugs [https://bugs.eclipse.org/bugs/show_bug.cgi?id=344394 here] (suggestions are also welcome).
+
Currently, no issues or bugs reported. Please report any encountered bugs [https://bugs.eclipse.org/bugs/show_bug.cgi?id=344394 here] or drop me a quick note per mail (suggestions are also welcome). Tested in Eclipse 3.6.2 and 3.7.
  
==== Maintainers ====
+
In future versions the following features are planned:
 +
* handling of invocations of initializers in fields
 +
* handling of invocations from anonymous classes
 +
* sorting of methods in nested classes
 +
* costumisable start-point heuristics
 +
* conceptual unification of clustering and separation in preferences-GUI (and the algorithm itself)
 +
 
 +
Caveats: The plugin sorts methods, but sometimes has to sort other elements as well, as nested types, enums and fields. Usually real-life classes have no fields scattered among methods, but types are more common to be found in the middle of the class. When the method sorter is executed, these will be sorted similar to the "Member sort..." operation: Types, enums and fields will be sorted ''before'' or ''after'' constructors and methods, so your carefully placed type will be moved somewhere else (sorry about that).
 +
The order of the this other element-types is "borrowed" from the "Members Sort Order"-preference pane. In future builds this behaviour might change, where types may be considered as parts of the invocation chain of a class.
 +
 
 +
==== Responsible Staff ====
 
This plugin is developed by Mateusz Parzonka as part of an university hands-on at the [http://www.stg.tu-darmstadt.de Technische Universität Darmstadt] (Germany), supervised by Marcel Bruch and Andreas Sewe.
 
This plugin is developed by Mateusz Parzonka as part of an university hands-on at the [http://www.stg.tu-darmstadt.de Technische Universität Darmstadt] (Germany), supervised by Marcel Bruch and Andreas Sewe.
  
Line 29: Line 39:
 
When a Java-class is opened in the Java Editor, the source menu should be visible in the main menu bar. The plugin augments the import-group in the source menu with a command labeled "Sort methods…". Triggering this command lets the Clean Code Method Sorter sort the methods in this class.  
 
When a Java-class is opened in the Java Editor, the source menu should be visible in the main menu bar. The plugin augments the import-group in the source menu with a command labeled "Sort methods…". Triggering this command lets the Clean Code Method Sorter sort the methods in this class.  
  
Per default, the command is bound to the keybinding "Option-S" (Mac) or "alt-S" (other platforms). User-defined keybindings are possible: Search for the command "Sort methods…" in the "Clean Code"-category in the keys-preferences-menu.  
+
Per default, the command is bound to the keybinding "Option-S" (Mac) or "Alt-S" (other platforms). User-defined keybindings are possible: Search for the command "Sort methods…" in the "Clean Code"-category in the keys-preferences-menu.  
  
[[Image:SourceMenu.jpg]]  
+
[[Image:SourceMenu.jpg]]
  
 
=== Processing of multiple Java-classes  ===
 
=== Processing of multiple Java-classes  ===
Line 52: Line 62:
 
== Preferences  ==
 
== Preferences  ==
  
===== Invocation start-point strategy  =====
+
This is the default setting. As explained more detailled in the setting descriptions, the plugin calculates a method ordering using multiple criteria. Try it to see if it suits your needs.
 +
 
 +
[[Image:CCMS_Preferences.jpg]]
 +
 
 +
==== Ordering priorities ====
 +
Users can priorize (using the up/down buttons)  the properties used to sort the methods. The priorities can be seen as ''layers''. When two methods are compared, the current highest layer is queried to resolve the ordering. If the methods appear to be in no ordering relation to each other, the next layer is queried until an absolute ordering is found. Since properties like original source position provide absolute orderings this criterium is always met. Bear in mind that these layers form a natural border for lower priorities, beyond that no other layer will be reached.
 +
 
 +
''The prefence-GUI does not fully reflect this 'border'-property. This will be adressed In a later revision of the plugin.''
 +
===== Respect before/after-relationship  =====
 +
When set to true, the sorting algorithm tries to find an ordering where methods are ordered before methods following in the invocation chain. What is the difference to pure invocation ordering, you may ask?
 +
To traverse call chains you have to select start points. As a result some start point ''p'' may be entered ''after'' a method ''m'' is called by ''p'' yielding an ordering of p-after-m, which may be not desired.
 +
This option corrects this behaviour.
 +
 
 +
A more technical description:  A method ''a'' is said to be ''before'' method ''b'', when ''b'' is after ''a'' in some point of the chain of invocations. The relationship can be expressed in terms of ''reachability'' in invocation graphs. Note that because of cyclicity in invocation graphs a method ''a'' can be before a method ''b'' and vice versa.
 +
When the relationship is respected, these properties hold:
 +
* ''a'' is before ''b'' and ''b'' is not before a : ''a'' will be sorted before ''b''
 +
* ''a'' is before ''b'' and ''b'' is before ''a'' : Cyclicity, ''a'' and ''b'' will be ordered by invocation order only
 +
* ''a'' is not before ''b'' and ''b'' is not before ''a'' : Non-reachability, ''a'' and ''b'' will be ordered by invocation order only
 +
 
 +
===== Apply invocation ordering  =====
 +
Using a working list of invocation start-points all invocation chains are executed. Methods are enumerated by their first execution or invocation. The enumeration is absolute, ties are not possible. Lower levels will be reached.
 +
 
 +
===== Keep original source position  =====
 +
When this layer is reached, all methods are sorted using the original (existing) position in the source code. Since ties are logically impossible lower layers will not be reached.
 +
 
 +
===== Separate by access level  =====
 +
Methods are separated according to their access level (aka "visibility"): public, protected, default, private.
 +
 
 +
===== Apply lexical ordering  =====
 +
Methods are sorted by lexical (alphabetic a->z) ordering. No ties in this layer, lower levels will not be reached.
 +
 
 +
==== Invocation start-point strategy  ====
 
Following the news-paper-metaphor the invocation-relation between methods is one of the strongest clues to derive a method ordering.
 
Following the news-paper-metaphor the invocation-relation between methods is one of the strongest clues to derive a method ordering.
 
Since classes usually offer some interface callable by clients, the invocation chain(s) can begin from several points.
 
Since classes usually offer some interface callable by clients, the invocation chain(s) can begin from several points.
Line 59: Line 100:
 
*Use existing order: Methods which are found at the beginning of the class are used as start points first. Useful, when beginning of the class (e.g. the public interface) is ordered acceptably.
 
*Use existing order: Methods which are found at the beginning of the class are used as start points first. Useful, when beginning of the class (e.g. the public interface) is ordered acceptably.
 
*Apply heuristic: A working list of start-points is calculated exploiting a multitude of clues:
 
*Apply heuristic: A working list of start-points is calculated exploiting a multitude of clues:
** Separation of "roots" and "leafs" in the invocation graph
+
** static initializer invocation
 +
** constructor method
 +
** separation of "roots" and "leafs" in the invocation graph
 
** access level
 
** access level
 
** number of callees
 
** number of callees
 
** method name (lexical ordering)
 
** method name (lexical ordering)
  
===== Invocation ordering strategy in method bodies =====
+
==== Invocation ordering strategy  ====
 
A method can have multiple invocations in its body. This leaves us two possibilities to traverse the invocation graph to derive a method ordering:
 
A method can have multiple invocations in its body. This leaves us two possibilities to traverse the invocation graph to derive a method ordering:
 
We can go "deep" by entering each method we encounter and processing the methods there, or we can go "broad" by processing all methods in the body before going to a lower level in the invocation tree.
 
We can go "deep" by entering each method we encounter and processing the methods there, or we can go "broad" by processing all methods in the body before going to a lower level in the invocation tree.
  
When deriving a method ordering from the order of invocations,
+
The traversal mimics the behaviour of a breadth- or depth-first-search algorithm. Thus, the options are named accordingly:
  
 
*Breadth-first: Ordering is following a breadth-first-search approach in the invocation graph.  
 
*Breadth-first: Ordering is following a breadth-first-search approach in the invocation graph.  
 
*Depth-first: Ordering is following a depth-first-search approach in the invocation graph.
 
*Depth-first: Ordering is following a depth-first-search approach in the invocation graph.
  
Which setting is better is a matter of taste. Depth-first is set as default, since it seemed be more consistent with the original description by Robert Martin and due to feedback of beta-testing users.
+
Which setting is better is a matter of taste. Depth-first is set as default, as it seems to be more consistent with the original description by Robert Martin and a non-representative set of beta-testers prefers it.
(Discussion about the ordering strategy is welcome).
+
  
===== Cluster getter and setters  =====
+
==== Cluster getter and setters  ====
 
The user can activate the clustering of getter and setters denoting pairs of methods where the methods:
 
The user can activate the clustering of getter and setters denoting pairs of methods where the methods:
 
*Start with "get" and "set"
 
*Start with "get" and "set"
Line 83: Line 125:
  
 
The clustered methods form a subgraph which is ordered using the same parameters like its supergraph (except applying clustering).
 
The clustered methods form a subgraph which is ordered using the same parameters like its supergraph (except applying clustering).
===== Cluster overloaded methods  =====
+
==== Cluster overloaded methods  ====
 
The user can cluster overloaded methods which are methods that have the same name but have different parameters.
 
The user can cluster overloaded methods which are methods that have the same name but have different parameters.
 
Overloaded method clusters are handled as subgraphs and sorted individually.
 
Overloaded method clusters are handled as subgraphs and sorted individually.
 
===== Cluster access levels  =====
 
When activated, methods are clustered according to their access. Note that each access level is ''not'' handled as a subgraph: The clustering is applied "post-hoc".
 
 
===== Respect before/after-relationship  =====
 
With this set to true, the sorting algorithm tries to find an ordering, where each caller is ordered before the callee it invokes (transitively).
 
A method ''a'' is before method ''b'' when ''b'' is after ''a'' in some point of the call chain. The relationship can be expressed in terms of reachability in invocation graphs.
 
Note that because of cyclicity in invocation graphs a method ''a'' can be before a method ''b'' and vice versa.
 
Therefor upon activation, these properties hold:
 
* ''a'' is before ''b'' and ''b'' is not before a : ''a'' will be sorted before ''b''
 
* ''a'' is before ''b'' and ''b'' is before a : Cyclicity, ''a'' and ''b'' will be will be ordered by invocation order only
 
* ''a'' is not before ''b'' and ''b'' is not before a : Non-reachability, ''a'' and ''b'' will be will be ordered by invocation order only
 
 
This setting defaults to true, because it seems to yield intuitively convincing results. Discussions are - of course- welcome.
 

Latest revision as of 09:41, 11 October 2011

Plugin

Currently BETA-stadium (Build 114, 08/30/2011). Features and description are subject to change.

Description

The Clean Code Method Sorter is a lightweight plugin for the Eclipse Platform. It provides techniques to sort methods in Java-classes, aiming to increase the readability of the source code.

Methods are reordered following the news-paper-metaphor conceived by Robert C. Martin in his book "Clean Code": A class should be readable like a newspaper, with the most important methods being at the beginning of the class, followed by methods which are invoked later in the execution flow.

Further organisation possibilities are provided by method clustering according to:

  • access level
  • method name (aka overloaded methods)
  • being accessors of the same field (aka getters and setters).

Installation Instructions

Please download and install the plugin using the update-site.

Bugs and Planned Features

Currently, no issues or bugs reported. Please report any encountered bugs here or drop me a quick note per mail (suggestions are also welcome). Tested in Eclipse 3.6.2 and 3.7.

In future versions the following features are planned:

  • handling of invocations of initializers in fields
  • handling of invocations from anonymous classes
  • sorting of methods in nested classes
  • costumisable start-point heuristics
  • conceptual unification of clustering and separation in preferences-GUI (and the algorithm itself)

Caveats: The plugin sorts methods, but sometimes has to sort other elements as well, as nested types, enums and fields. Usually real-life classes have no fields scattered among methods, but types are more common to be found in the middle of the class. When the method sorter is executed, these will be sorted similar to the "Member sort..." operation: Types, enums and fields will be sorted before or after constructors and methods, so your carefully placed type will be moved somewhere else (sorry about that). The order of the this other element-types is "borrowed" from the "Members Sort Order"-preference pane. In future builds this behaviour might change, where types may be considered as parts of the invocation chain of a class.

Responsible Staff

This plugin is developed by Mateusz Parzonka as part of an university hands-on at the Technische Universität Darmstadt (Germany), supervised by Marcel Bruch and Andreas Sewe.

User-Interface

The plugin mainly provides a "Sort Methods..."-Operation which can be triggered from different point in the GUI.

Processing of individual Java-classes

When a Java-class is opened in the Java Editor, the source menu should be visible in the main menu bar. The plugin augments the import-group in the source menu with a command labeled "Sort methods…". Triggering this command lets the Clean Code Method Sorter sort the methods in this class.

Per default, the command is bound to the keybinding "Option-S" (Mac) or "Alt-S" (other platforms). User-defined keybindings are possible: Search for the command "Sort methods…" in the "Clean Code"-category in the keys-preferences-menu.

SourceMenu.jpg

Processing of multiple Java-classes

When selecting Java-specific content in the Package Explorer a right mouse-click (context-click) activates the associated pop-up-menu. In the Java-context, a source-submenu is visible. The plugin augments the import-group in this menu with the command labeled "Sort methods…", which will sort all methods in selected objects and their child-objects upon triggering.

"Sort methods…" can be called on any selection of

  • Java-projects
  • source folders
  • packages
  • compilation units (Java-files).

After successful sorting, a message will appear showing the number of processed classes.

In the beta-phase an additional command "Shuffle methods randomly…" may be available which shuffles methods randomly to enable easier evaluation of the method sorter.

PulldownMenu.jpg 

Preferences

This is the default setting. As explained more detailled in the setting descriptions, the plugin calculates a method ordering using multiple criteria. Try it to see if it suits your needs.

CCMS Preferences.jpg

Ordering priorities

Users can priorize (using the up/down buttons) the properties used to sort the methods. The priorities can be seen as layers. When two methods are compared, the current highest layer is queried to resolve the ordering. If the methods appear to be in no ordering relation to each other, the next layer is queried until an absolute ordering is found. Since properties like original source position provide absolute orderings this criterium is always met. Bear in mind that these layers form a natural border for lower priorities, beyond that no other layer will be reached.

The prefence-GUI does not fully reflect this 'border'-property. This will be adressed In a later revision of the plugin.

Respect before/after-relationship

When set to true, the sorting algorithm tries to find an ordering where methods are ordered before methods following in the invocation chain. What is the difference to pure invocation ordering, you may ask? To traverse call chains you have to select start points. As a result some start point p may be entered after a method m is called by p yielding an ordering of p-after-m, which may be not desired. This option corrects this behaviour.

A more technical description: A method a is said to be before method b, when b is after a in some point of the chain of invocations. The relationship can be expressed in terms of reachability in invocation graphs. Note that because of cyclicity in invocation graphs a method a can be before a method b and vice versa. When the relationship is respected, these properties hold:

  • a is before b and b is not before a : a will be sorted before b
  • a is before b and b is before a : Cyclicity, a and b will be ordered by invocation order only
  • a is not before b and b is not before a : Non-reachability, a and b will be ordered by invocation order only
Apply invocation ordering

Using a working list of invocation start-points all invocation chains are executed. Methods are enumerated by their first execution or invocation. The enumeration is absolute, ties are not possible. Lower levels will be reached.

Keep original source position

When this layer is reached, all methods are sorted using the original (existing) position in the source code. Since ties are logically impossible lower layers will not be reached.

Separate by access level

Methods are separated according to their access level (aka "visibility"): public, protected, default, private.

Apply lexical ordering

Methods are sorted by lexical (alphabetic a->z) ordering. No ties in this layer, lower levels will not be reached.

Invocation start-point strategy

Following the news-paper-metaphor the invocation-relation between methods is one of the strongest clues to derive a method ordering. Since classes usually offer some interface callable by clients, the invocation chain(s) can begin from several points. The user can select two different strategies to priorize the invocation start points:

  • Use existing order: Methods which are found at the beginning of the class are used as start points first. Useful, when beginning of the class (e.g. the public interface) is ordered acceptably.
  • Apply heuristic: A working list of start-points is calculated exploiting a multitude of clues:
    • static initializer invocation
    • constructor method
    • separation of "roots" and "leafs" in the invocation graph
    • access level
    • number of callees
    • method name (lexical ordering)

Invocation ordering strategy

A method can have multiple invocations in its body. This leaves us two possibilities to traverse the invocation graph to derive a method ordering: We can go "deep" by entering each method we encounter and processing the methods there, or we can go "broad" by processing all methods in the body before going to a lower level in the invocation tree.

The traversal mimics the behaviour of a breadth- or depth-first-search algorithm. Thus, the options are named accordingly:

  • Breadth-first: Ordering is following a breadth-first-search approach in the invocation graph.
  • Depth-first: Ordering is following a depth-first-search approach in the invocation graph.

Which setting is better is a matter of taste. Depth-first is set as default, as it seems to be more consistent with the original description by Robert Martin and a non-representative set of beta-testers prefers it.

Cluster getter and setters

The user can activate the clustering of getter and setters denoting pairs of methods where the methods:

  • Start with "get" and "set"
  • Have the same suffix after "get" and "set"
  • The return type of the potential getter fits the parameter-type of the potential setter (which has an arity of 1)

The clustered methods form a subgraph which is ordered using the same parameters like its supergraph (except applying clustering).

Cluster overloaded methods

The user can cluster overloaded methods which are methods that have the same name but have different parameters. Overloaded method clusters are handled as subgraphs and sorted individually.

Back to the top