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. */