\section{Introduction}

Contributing a new refactoring to Photran is best done by following a working
example.

This paragraph describes the general approach: First, an action must be added to
both the editor popup menu \textbf{and} the Refactor menu in the menu bar by
modifying the plugin.xml file. Then, the action delegate and its accompanying
refactoring wizard have to be coded; these two classes are responsible for
populating the user interface of the refactoring wizard dialog. Finally, the
actual Fortran refactoring itself has to be coded.

The remaining sections go into the details of each of those steps based on a
simple (but not useful) refactoring example: obfuscating Fortran by removing the
comments and adding redundant comments to the header. The source code is
available from
\url{http://subversion.cs.uiuc.edu/pub/svn/FruitFly/edu.uiuc.nchen.obfuscator/trunk/}

\section{Modifying the plugin.xml}

There are \textbf{four} extensions points (from the Eclipse core) that our plug-in needs to extend:

\begin{description}

 \item [\texttt{org.eclipse.ui.commands}] Creates a new command \emph{category}
to represent our refactoring. This category will be referenced by the other
extensions in the plugin.xml file.

 \item [\texttt{org.eclipse.ui.actionSets}] This extension point is used to add
menus and menu items to the Fortran perspective.

 \item [\texttt{org.eclipse.ui.actionSetPartAssociations}] Allows our
refactoring to be visible/enabled in the context of the Fortran editor.

 \item [\texttt{org.eclipse.ui.popupMenus}] Displays our refactoring in the
pop-up menu that appears during a right-click.

 \item [\texttt{org.eclipse.ui.bindings}] (Optional) Allows our refactoring to
be invoked via keyboard shortcuts. For instance the Fortran Rename Refactoring
is bound to the Alt + Shift + R keyboard shortcut, which is the same as the one
for the Java Rename Refactoring.

\end{description}

Please refer to the documentation and schema description for each extension point; the documentation is available from Help $>$ Help Contents in Eclipse.

Fortran currently does \textbf{not} use the newer \texttt{org.eclipse.ui.menus}
extension points (introduced in Eclipse 3.3) for adding menus, menu items and
pop-up menus.

It is possible to use the newer \texttt{org.eclipse.ui.menus} extension point if
desired, but this chapter uses the older extension points to remain consistent
with how Photran is doing it.

For more information, see the plugin.xml file of our refactoring example.

\section{Creating an Action Delegate and a Refactoring Wizard}

The \texttt{org.eclipse.ui.actionSets} and \texttt{org.eclipse.ui.popupMenus}
extension points that were extended in our plugin.xml file require a reference
to action delegate class that we need to provide.

For a Fortran refactoring, our action delegate should extend the
\\\texttt{AbstractFortranRefactoringActionDelegate} class \textbf{and} implement
the \\\texttt{IWorkbenchWindowActionDelegate} and \texttt{IEditorActionDelegate}
interfaces.

The most important method in our action delegate class is the
\textbf{constructor}. The constructor has to be done in a particular way so that
everything is setup correctly. Listing~\ref{lst:obfuscateaction} shows how the constructor needs to be setup.

\begin{code}
\begin{lstlisting}
public class ObfuscateAction extends AbstractFortranRefactoringActionDelegate
	implements IWorkbenchWindowActionDelegate, IEditorActionDelegate {

    public ObfuscateAction() {
			super(ObfuscateRefactoring.class, ObfuscateRefactoringWizard.class);
    }
		
		...
}
\end{lstlisting}
\caption{\texttt{ObfuscateAction} for our simple refactoring example}
\label{lst:obfuscateaction}
\end{code}

Inside our constructor, we need to call the parent constructor that takes
\textbf{two} parameters: the class of the actual refactoring object (e.g.
ObfuscateRefactoring) and the class of the actual refactoring wizard (e.g.
ObfuscateRefactoringWizard). The parent class will dynamically create the
refactoring object and refactoring wizard using Java reflection.

Our refactoring wizard needs to be a subclass of
\texttt{AbstractFortranRefactoringWizard}. The only method that we are required
to implement is the \texttt{doAddUserInputPages} method. This page is
responsible for creating a page for the wizard. For instance, a refactoring such
as rename refactoring requires the user to provide a new name. So the
\texttt{doAddUserInputPages} is responsible for creating the interface for that.

Ideally, if our refactoring does not require the user to provide any input, it
should just have an empty \texttt{doAddUserInputPages} method. However, because
of a bug in the Mac OS X version of Eclipse, it is necessary to add a
\emph{dummy} page. Without this dummy page the refactoring will cause the entire
Eclipse UI to lock up on Mac OS X. Listing~\ref{lst:dummy_wizard_page} shows how
to add a dummy input page. \\

\begin{code}
\begin{lstlisting}
protected void doAddUserInputPages() {
    addPage(new UserInputWizardPage(refactoring.getName()) {

	public void createControl(Composite parent) {
	    Composite top = new Composite(parent, SWT.NONE);
	    initializeDialogUnits(top);
	    setControl(top);

	    top.setLayout(new GridLayout(1, false));

	    Label lbl = new Label(top, SWT.NONE);
	    lbl.setText("Click OK to obfuscate the current Fortran file. 
			To see what changes will be made, click Preview.");

	}
    });
}
\end{lstlisting}
\caption{Adding a \texttt{dummy} wizard input page}
\label{lst:dummy_wizard_page}
\end{code}

\section{Creating the Actual Refactoring}

Section~\ref{sec:structure_of_a_fortran_refactoring} gives a good overview of
the \textbf{four} methods that a Fortran refactoring needs to implement. And
Section~\ref{sec:refactoring_caveats} gives an overview of things to avoid while
performing a refactoring. Our example refactoring conforms to the lessons in
both those sections.

Here we briefly describe the four methods in our example:

\begin{description}

 \item [getName] This just returns the text ``Obfuscate Fortran Code''
describing our refactoring. This text will be used as the title of the
refactoring wizard dialog.

 \item [doCheckInitialConditions] Our simple refactoring does not have any
\emph{real} initial conditions. Our refactoring can proceed as long as the
current file can be parsed as valid Fortran source code. This is automatically
checked by the \texttt{FortranRefactoring} parent class.

 Instead we use this method as a hook to perform some simple program analysis --
acquiring the names of all the functions and subroutines in the current file. We
will print these names later as part of the header comment. 

	\item [doCheckFinalConditions] Since we do not require the user to provide any
additional input, there are no final conditions to check.

	\item [doCreateChange] The actual refactoring changes are constructed in this
method. 

We iterate through every token in the current file to check if it has a comment
string. Comment strings are acquired by calling \texttt{Token\#getWhiteBefore()}
and \texttt{Token\#getWhiteAfter()}. Following the advice of
Section~\ref{sec:refactoring_caveats}, we store a list of all the tokens (call
this list TokensWithComments) that contain comment strings. Once we have
iterated through all the tokens, we proceed to remove the comments for tokens in
our TokensWithComments list. Removing comments is done by calling
\texttt{Token\#setWhiteBefore()} and \texttt{Token\#setWhiteAfter()} with blank
strings as parameters.

Finally, we create a header comment that just lists all the functions and
subroutines in the current source file and add that to the preamble of the main
program.

\end{description}

For more information, please consult the source code for our example.
