Catalog of Refactorings

This section describes each of the refactorings available from ProRefactor's user interface.


Names Refactoring

This refactoring is intended to be used as part of a legacy code clean-up project. It is unlikely to be used on a day-to-day basis.

This refactoring allows you to automatically:

Usage

  1. In the Navigator view, select the files, directories, and/or projects to be refactored.
  2. From the Navigator view's context menu, choose ProRefactor > Names (table and field) Refactoring.
  3. The Names Refactoring wizard will be presented, where you are required to choose an empty output directory for the source code that gets changed.

This refactoring checks if an include file is changed multiple times for multiple compile units. If the changes are different for different compile units, then the include file is not written to the output directory, and warning messages are issued.

Example Output

Using "sports2000" schema, we automatically refactored this:

FIND FIRST CUST.
DISPLAY BAL.

into this:

FIND FIRST customer.
DISPLAY customer.balance.

NO-UNDO Refactoring

This refactoring is intended to be used as part of a legacy code modernization project. It is unlikely to be used on a day-to-day basis.

Although most Progress programmers recognize that NO-UNDO is important for application performance, it is not unusual to find legacy applications where NO-UNDO was not consistently added to DEFINE statements. This refactoring is intended to be run as a single pass through old code, in order to correct those statements.

Usage

  1. In the Navigator view, select the files, directories, and/or projects to be refactored.
  2. From the Navigator view's context menu, choose ProRefactor > NO-UNDO Refactoring.
  3. The NO-UNDO Refactoring wizard will be presented, where you are required to choose an empty output directory for the source code that gets changed.

Features

This NO-UNDO refactoring has a few features which are worthy of note.

These features work nicely with Prolint. If ProRefactor's NO-UNDO Refactoring does not add NO-UNDO to a DEFINE statement, for whatever reason, Prolint will continue to warn about that DEFINE statement until you explicitly tell Prolint that it is intentional with a prolint-nowarn directive. (Or else of course you might review the code and decide to add NO-UNDO by hand.) Here is a snippet of code which is the output from the unit test used for the NO-UNDO refactoring. All of the NO-UNDO options on DEFINE statements were added by the NO-UNDO refactoring, but more interesting is to note where the NO-UNDO refactoring did not add NO-UNDO.

/* n o - u n d o . p
 * This file contains tests for our  N O - U N D O  refactoring.
 * IMPORTANT!! Comments containing "u n d o" (without the spaces)
 * have an impact on the refactoring's behaviour!
 */


{&_proparse_ prolint-nowarn(noundo)}
DEFINE VARIABLE myInt AS INTEGER.

PROCEDURE myProc1:
  DEFINE INPUT PARAMETER p1 AS LOGICAL NO-UNDO.
END.

PROCEDURE myProc2 EXTERNAL "whatever.dll":
  DEFINE INPUT PARAMETER p2 AS LONG.
END.


/* Test for  U N D O  statement. */
DEFINE VARIABLE myChar AS CHARACTER.
DEFINE VARIABLE myChar2 AS CHARACTER NO-UNDO.
DEFINE VARIABLE myChar3 AS CHARACTER NO-UNDO.
DO:
  myChar3 = "".
  DO:
    myChar = "".
    UNDO, LEAVE.
    myChar2 = "".
  END.
END.


/* U N D O  statement tests for named block and OUTPUT val */
DEFINE VARIABLE myChar10 AS CHARACTER.
DEFINE VARIABLE myChar11 AS CHARACTER.
my-block:
DO:
  RUN changeVal(OUTPUT myChar10).
  DO:
    RUN changeVal(OUTPUT myChar11).
    UNDO my-block, LEAVE.
  END.
END.

PROCEDURE changeVal:
  DEFINE OUTPUT PARAMETER changed AS CHARACTER NO-UNDO.
END.


/* This should remain UNDO */
DEFINE VARIABLE c1 AS CHARACTER.

/* This var should be UNDO           */
/* with this two line comment.       */
DEFINE VARIABLE c2 AS CHARACTER.

DEFINE /* UNDOable */ VARIABLE c3 AS CHARACTER.

DEFINE VARIABLE c4 AS CHARACTER. /* not no-undo */

/* This comment does not change UNDO for the next define,
   because of the blank line between the comment and the statement.
*/

DEFINE VARIABLE c5 AS CHARACTER NO-UNDO.

DEFINE VARIABLE c6 AS CHARACTER NO-UNDO.
/* Comment on line after does not change UNDO for previous statement. */

Qualify Fields Refactoring

Generally, using unqualified field names is not viewed as "best practice" for 4gl developers. There are a number of pitfalls in using unqualified field names, one of the most significant is that when moving code around you can accidentally change which buffers are being implicitly used for the unqualified fields. This can lead to bugs that are rather difficult to track down.

ProRefactor has the semantic and contextual knowledge necessary to determine which buffer name is being implicitly used for unqualified field names. This refactoring finds unqualified field names in the current file (must be a compilable file) and adds the appropriate table or buffer names.

Usage

  1. This refactoring operates on the currently selected file or the file that is currently open in an editor. The file must be compilable.
  2. From the main menu, choose ProRefactor > Qualify Field Names. The preview dialog appears, allowing you to accept or reject the changes.

Features

This refactoring recognizes FIELDS, EXCEPT, and USING phrases, and does not qualify field names within those.


Rename Schema Refactoring

This refactoring finds and changes all hard-coded references to database table and fields that you want to rename. You select the projects or directories that you want to change, input a list of old and new names, and the refactoring writes the modified files to an output directory which you can review before merging the changes into your source.

Usage

  1. In the Navigator view, select the files, directories, and/or projects to be refactored.
  2. From the Navigator view's context menu, choose ProRefactor > Rename Schema.
  3. The Rename Schema Refactoring wizard is presented. Input a list of old and new name pairs into the editor, or else enter the name of a file which contains old and new name pairs.
  4. This refactoring writes the modified files out to a temporary directory of your choice.

Features

Caveats

Example

Here is an example renaming list:

sports2000.customer client
sports2000.customer.name legalName
sports2000.invoice.amount totalAmount

Here is the code before refactoring:

find first customer.
display customer.name.
display cust.na.
display customer except name.
display customer.creditLimit.

find first invoice.
display invoice.amount.
display invoice except amount.

def buffer bCustomer for customer.
find first bCustomer.
display bCustomer.name.
display bCustomer except name.
display bCustomer.creditLimit.

def buffer bInvoice for invoice.
find first bInvoice.
display bInvoice.amount.
display bInvoice except amount.

Here is the code after Rename Schema refactoring has been run:

find first Client.
display Client.legalName.
display Client.legalName.
display Client except legalName.
display Client.creditLimit.

find first invoice.
display invoice.totalAmount.
display invoice except totalAmount.

def buffer bCustomer for Client.
find first bCustomer.
display bCustomer.legalName.
display bCustomer except legalName.
display bCustomer.creditLimit.

def buffer bInvoice for invoice.
find first bInvoice.
display bInvoice.totalAmount.
display bInvoice except totalAmount.

SUBSTITUTE Refactoring

This refactoring is intended to be used as part of a legacy code modernization project. It is unlikely to be used on a day-to-day basis.

This feature assists in the transformation from string concatenation to the use of a single string with SUBSTITUTE. This is done because the full sentence in a single string is easier to translate (for internationalization) than the sentence fragmented into two strings.

Usage

  1. In the Navigator view, select the files, directories, and/or projects to be refactored.
  2. From the Navigator view's context menu, choose ProRefactor > SUBSTITUTE Refactoring.
  3. ProRefactor will parse the selected resources, and find any string concatenations which might require refactoring. It will present the suspect code in the Review Changes dialog.
  4. Review, and then accept or reject the code change. You may make manual changes to the source code before accepting the changes.

In some cases, ProRefactor may be unable to automatically suggest changes to the source code. You will be informed of this by a message, and you will be able to make the code change by hand if desired.

In the Review Changes dialog, the Cancel button will reject the current changes and stop any further processing.