Try OpenEdge Now
skip to main content
Online Help
Introducing the ABL Editor : Concepts : ABL Editor Features : Finding references
 
Finding references
Progress Developer Studio for OpenEdge helps you find all occurrences of a specific ABL construct in an ABL file, project, or workspace. It enables you find declarations, references, and occurrences of procedural and object-oriented ABL constructs such as procedures, functions, methods, fields, and variables through editors, menu items, and views.
The references to the following are not found:
*System level members for example, Integer function
*Files that reside on network file paths
*Constructs in r-code
*Constructs in file types other than .i, .w, .cls, or .p file, for example, spring.xml or JSON file
*Constructs in speedscript files
*Dynamic instances such as dynamic casts that use expression values, expressions used as parameters, statements that include pre-processors, and handles.
PDSOE lets you find references to the following ABL constructs:
*Include file
You can find references to Include file (.i), Procedure file (.p), or class in an Include file in a project or a workspace. The search depends on PROPATH; any path specified in procedure or function is relative to the order of entries of the relevant resource in the PROPATH project. If the path in an Include statement resolves to two resources in PROPATH, the reference to the entry that is listed first in the order is displayed. However, the references are not found if the Include statement has a pre-processor value instead of an include file name in text format, for example, as follows:
&SCOPED-DEFINE INCLUDE_FILE_NAME custom.i

/* Include statement with file name */
{custom.i}

/* Include statement with pre-processor value */
{{&INCLUDE_FILE_NAME}}
*Internal procedure or user defined function
You can find references to an internal procedure or a user-defined function (UDF) defined in a Procedure (.p) file or an Include (.i) file. All the references to the internal procedures in the RUN statement and the function calls in the same file are found. However, the references in the other files that invoke the internal procedure using handle variables and references to a UDF that is invoked as a dynamic function using the DYNAMIC-FUNCTION statement are not found. The reference to Procedure (.p) file included as a pre-processor directive is also not found.
The following example displays the RUN statement with a procedure name and expression:
DEFINE VARIABLE procName AS CHARACTER.

procName = "myProcedure".

/* Run with direct internal procedure name */
RUN myProcedure.

/* Run with expression */
RUN value(procName).

/* ********************** Internal Procedures *********************** */

PROCEDURE myProcedure:

MESSAGE "Inside Custom.myProcedure"
VIEW-AS ALERT-BOX.

END PROCEDURE.
The following example shows you how to create a handle:
/* HandleTest.p: Invoking an internal procedure using handle*/
DEFINE VARIABLE h AS HANDLE NO-UNDO.

RUN zsource.p PERSISTENT SET h.

RUN intProc in h.
The following example shows you how to create Source.p for the above handle:
/* Source.p : Procedure file with an internal procedure */
PROCEDURE intProc:

message "in zSource.p>intProc" VIEW-AS ALERT-BOX.

END PROCEDURE.
The following example displays the DYNAMIC-FUNCTION statement:
/* h-FuncProc.p -- contains CtoF and other possible useful functions. */
FUNCTION CtoF RETURNS DECIMAL (INPUT dCelsius AS DECIMAL):
RETURN (dCelsius * 1.8) + 32.
END FUNCTION.


/* Custom.p */
DEFINE VARIABLE dTemp AS DECIMAL NO-UNDO.
DEFINE VARIABLE hFuncProc AS HANDLE NO-UNDO.
DEFINE VARIABLE func-name AS CHARACTER NO-UNDO INIT "CtoF".

RUN h-FuncProc.p PERSISTENT SET hFuncProc.

REPEAT dTemp = 0 TO 5:
DISPLAY dTemp LABEL "Celsius"
/* Invoking function defined in other procedure dynamically */
DYNAMIC-FUNCTION (func-name IN hFuncProc, dTemp) LABEL "Fahrenheit"
WITH FRAME f 10 DOWN.
END.

DELETE PROCEDURE hFuncProc.
*External procedure
You can find references to an external procedure in a project or a workspace, the functionality evaluates all the ABL resources and invokes the RUN statement. However, if the RUN statement uses an expression to evaluate the external procedure name dynamically, the references are not found.
The following is an example of the RUN statement with an external procedure name, and path and expression:
DEFINE VARIABLE procName AS CHARACTER.
procName = "custom".

/* Run using external procedure name */
RUN custom.p.

/* Run with expression value */
RUN value(procName + ".p")
*Variable
You can find references to a variable defined in a procedure or class in the working file. Finding references to SHARED and GLOBAL variables are limited. A SHARED variable is created in a source procedure and accessed by all other procedures. There can be multiple source procedure files for a single consumer procedure, so the value of the variable depends on the source being executed and hence the SHARED variable is found only in the source procedure.
The following example displays two source procedures, Source1.p and Source2.p that run the consume.p procedure. The value of the SHARED variable sharedVar in consumer.p depends on the source procedure that is being executed.
The following code shows how to create Source1.p:
/* Source1.p : Creating new shared variable */
DEFINE NEW SHARED VARIABLE sharedVar AS CHARACTER.

/* Initialize shared variable */
sharedVar = "This is source1".


/* Statically invoked */
RUN consume.p.

The following code shows how to create Source2.p:
/* Source2.p : Creating new shared variable */
DEFINE NEW SHARED VARIABLE sharedVar AS CHARACTER.

/* Initialize shared variable */
sharedVar = "This is source 2".

/* Statically invoked */
RUN consume.p.
The following code shows how the shared variable is used:
/* consume.p : Defining shared variable */
DEFINE SHARED VARIABLE sharedVar AS CHARACTER.

/* Accessing shared variable value set in source procedure */
MESSAGE sharedVar
VIEW-AS ALERT-BOX.

sharedVar = "02".

*Temp table or DataSet
You can find references to a temp table or a DataSet defined in the current Procedure (.p) file, Class (.cls) file, AppBuilder (.w) file, or in an Include (.i) file. If the temp table or DataSet is defined in the Include, Class, or Procedure file then the functionality searches for the reference in all the files including the temp tables and DataSets. However, the references to a shared temp table or DataSet are not found as they are available to other procedures only till the procedure that defined it, runs.
The following example displays temp-item temp table including two fields and two indexes. You can find references to the temp table, fields, or index. For example, if you find references to temp-item, PDSOE displays all the references to temp-item including the fields that qualify with the specified temp table.
DEFINE TEMP-TABLE temp-item
FIELD cat-page LIKE Item.CatPage
FIELD inventory LIKE Item.Price LABEL "Inventory Value"
INDEX cat-page IS PRIMARY cat-page ASCENDING
INDEX inventory-value inventory DESCENDING.

DEFINE VARIABLE cutoff NO-UNDO LIKE item.price.
DEFINE VARIABLE inv-value NO-UNDO LIKE item.price.
DEFINE VARIABLE report-type AS INTEGER NO-UNDO INITIAL 1.
DEFINE BUTTON ok-butt LABEL "OK" AUTO-GO.
DEFINE BUTTON cancel-butt LABEL "CANCEL" AUTO-ENDKEY.
FORM cutoff LABEL "Inventory Lower Cutoff for each Catalog Page"
AT ROW 1.25 COLUMN 2 report-type LABEL "Report Sorted ..."
AT ROW 2.25 COLUMN 2
VIEW-AS RADIO-SET RADIO-BUTTONS "By Catalog Page", 1,
"By Inventory Value",
2 SKIP ok-butt cancel-butt WITH FRAME select-frame SIDE-LABELS WIDTH 70
TITLE "Specify

Report ..." VIEW-AS DIALOG-BOX.
FOR EACH Item BREAK BY Item.CatPage:
ACCUMULATE Item.Price * Item.OnHand (SUB-TOTAL BY Item.CatPage).
IF LAST-OF(Item.CatPage) THEN
DO:
inv-value = ACCUM SUB-TOTAL BY Item.CatPage
(Item.Price * Item.OnHand).
CREATE temp-item.
temp-item.cat-page = Item.CatPage.
inventory = inv-value.
END.
END. /* FOR EACH item */
ON CHOOSE OF ok-butt
DO:
HIDE FRAME select-frame.
IF report-type = 1 THEN
FOR EACH temp-item USE-INDEX cat-page WITH FRAME rpt1-frame:
IF inventory >= cutoff THEN
DISPLAY temp-item.cat-page inventory.
END.
ELSE
FOR EACH temp-item USE-INDEX inventory-value WITH FRAME rpt2-frame:
IF inventory >= cutoff THEN
DISPLAY temp-item.cat-page inventory.
END.
VIEW FRAME select-frame.

END.
ENABLE ALL WITH FRAME select-frame.
WAIT-FOR CHOOSE OF cancel-butt OR WINDOW-CLOSE OF CURRENT-WINDOW.
The following example displays the dsStudent DataSet. When you find references to this DataSet, PDSOE displays all the references to the dsStudent DataSet.
p/*Temp-table definition*/
DEFINE TEMP-TABLE ttCourse NO-UNDO
FIELD CourseID AS CHARACTER
FIELD CourseName AS CHARACTER
FIELD Duration AS INTEGER
FIELD ClgID AS CHARACTER
FIELD prereqId AS CHARACTER
INDEX test IS UNIQUE ClgID CourseID.

/*Temp-table definition*/
DEFINE DATASET dsStudent FOR ttCourse
DATA-RELATION relation FOR ttCourse, ttCourse RELATION-FIELDS
(CourseID, prereqId) RECURSIVE.

DATASET dsStudent:HANDLE.
DEF VAR i AS INT.
DEF VAR h AS HANDLE.

DO i = 1 TO DATASET dsStudent:num-buffers:
h = DATASET dsStudent:get-buffer-handle(i).
MESSAGE
h:NAME SKIP
h:PARENT-RELATION SKIP
h:NUM-CHILD-RELATIONS SKIP
VIEW-AS ALERT-BOX.
END.
*Buffer
You can find references to a buffer in the current Procedure (.p) file, Class (.cls) file, AppBuilder (.w) file, or in an Include (.i) file. If the buffer is defined in the Include, Class, or Procedure file then the functionality searches for the reference in all the files. However, the reference to a shared buffer is not found.
The following example displays how cust buffer is used in proc1 internal procedure. When you find references to this buffer, PDSOE displays all the references to the cust buffer.
PROCEDURE proc1:
/*Buffer declaration for Customer table*/
DEFINE BUFFER cust FOR Customer.
FOR EACH cust NO-LOCK BY cust.CreditLimit DESCENDING:
DISPLAY "Highest:" cust.CustNum cust.Name cust.CreditLimit
WITH 1 DOWN.
LEAVE.
END.
FOR EACH cust NO-LOCK WHERE cust.State = "NH"
BY cust.CreditLimit DESCENDING:
DISPLAY cust.CustNum cust.Name cust.CreditLimit.
END.

END PROCEDURE.
*ABL class level members
You can find references to method and variable and class members of a class depending on the access mode and way the members are defined.
*Class method
You can find references to an instance method depending on the access mode. The functionality finds all the references in the same class file (if the class is declared as private), class hierarchy (if the hierarchy is declared as protected), and other publicly accessed classes or procedure files for a particular class method. However, references to the DYNAMIC-INVOKE function, the Progress.Lang.Class.Invoke method, method calls with expression as parameters, or other library files are not found.
The following example displays a sample class including the sayHello instance method and sayHi class method.
METHOD PUBLIC VOID sayHello( ):

RETURN.

END METHOD.

METHOD PUBLIC STATIC VOID sayHi( ):

RETURN.

END METHOD.

END CLASS.
The following class uses the Sample class:
CLASS TestClass:

/*defining variable for Sample class*/
DEFINE VARIABLE var1 AS Sample NO-UNDO.

/*-------------------------------------------------------------------------
Purpose: Test method which calls instance method and class method.
Notes:
-------------------------------------------------------------------------*/
METHOD PUBLIC VOID test( ):
/*Instance method call*/
var1:sayHello().
/*Class level method call*/
Sample:sayHi().
RETURN.
END METHOD.

END CLASS.
*Class and interface types
You can find all occurrences of object-oriented ABL (class and interface) types that are used in a procedure file, include file, class, and interface. You can search for user-defined types and types from libraries. The search for object-oriented ABL types depends on the project’s PROPATH information. Types are resolved based on the PROPATH entries. Types with same names are resolved by their package name. If the package names are the same, then the types are resolved based on the order of the PROPATH entries.
*Queries
You can find references to all instances of a query definition in a procedure file, include file, class, and interface. If the query definition is in an include file, then you can find references to it in all the files that use it. In case of a procedure, you can find its references in the currently open file. If the query definition is in a class or interface and if the query is declared as a private class, then you can find its references in the currently open file; if it is declared as a protected class, then you can find its references in the hierarchy of that class.
Limitation: In a procedure file, you can declare a query as a shared query, which can be shared by one or more procedures that are directly or indirectly called by the current procedure. The shared query remains available to the other procedures until the procedure that defines it ends. The procedures that are called by the current procedure must define the query with the same name using the DEFINE SHARED TEMP-TABLE statement. When you try to find references of such shared queries, the ABL editor displays only those references that are in the file where the query is defined; the other procedures directly or indirectly accessing the query are not displayed.
The following example illustrates the limitation for finding references to queries. In the example, Source.p and Consumer.p share the query (sharedQry). When the code is executed to find references to sharedQry from Source.p, only references from the current file (Source.p) are displayed; the references from Consumer.p are not displayed.
/* Source.p : Creating new shared QUERY */

DEFINE NEW SHARED BUFFER sharedBuf FOR Customer.
DEFINE NEW SHARED QUERY sharedQry FOR sharedBuf.

OPEN QUERY sharedQry FOR EACH sharedBuf NO-LOCK.

/* Statically invoked */
RUN shared_query/Consumer.p.

DEFINE SHARED BUFFER sharedBuf FOR Customer.
DEFINE SHARED QUERY sharedQry FOR sharedBuf.

/*Accessing the QUERY shared by Source.p*/

GET FIRST sharedQry.

/*Displaying the Customer details*/

DO WHILE AVAILABLE sharedBuf:
DISPLAY sharedBuf.CustNum sharedBuf.Name SKIP
sharedBuf.Phone SKIP sharedBuf.Address
VIEW-AS EDITOR SIZE 50 BY 2 SCROLLBAR-VERTICAL
WITH FRAME ord-info CENTERED SIDE-LABELS TITLE "Order Information".

PAUSE.
GET NEXT sharedQry.
END.

/* DO WHILE AVAILABLE records */
*Class and interface types
You can find all occurrences of object-oriented ABL (class and interface) types that are used in a procedure file, include file, class, and interface. You can search for user-defined types and types from libraries. The search for object-oriented ABL types depends on the project’s PROPATH information. Types are resolved based on the PROPATH entries. Types with same names are resolved by their package name. If the package names are the same, then the types are resolved based on the order of the PROPATH entries.
*Properties
You can find references to the ABL properties in a project or a workspace. You can search for the references to the properties that are defined in the current file or in the hierarchy of the current file. You can also find references to properties accessed statically or through class instances.
*ABL events
You can find references to ABL events in a project or a workspace. You can search for the references to events that are defined in the current file or in the hierarchy of the current file. You can also find references to the events accessed statically or through class instances.
*Data-sources
You can find references to ABL data-sources in a project or a workspace depending on where you defined the data-source. If the data-source is defined in an Include (.i) file, all the references to the files including that Include file are found. If it is defined in a Procedure (.p) or an AppBuilder (.w) file, only the reference to the current file is found. If it is defined in a Class (.cls) file, the references to the current class file (if the data-source is declared as private) or class hierarchy (if the data-source is declared as protected) are found.