Call Graph Reports


The call graph related reports provided by FWD Analytics can be used both in the call graph building process (by i.e. disambiguating the call sites and/or removing dead code) and also in normal application development/maintenance.

For call graph generation, see the Ambiguous Call Sites, Dead Code and Missing Call Targets reports.

For application development/maintenance, the External Dependencies, Schema Triggers and Call_Graph_Reports reports will be of value in analysis of code.

This chapter will explain what each report contains, how to interpret it and the benefits associated with it.

Ambiguous Call Sites

Ambiguous call sites represent any call-like statement (i.e. RUN, DYNAMIC-FUNCTION, etc) for which its target is computed via a dynamic expression. Here is a common example:

DEF VAR prog-name AS CHAR.

UPDATE prog-name LABEL "Program Name" FORMAT "x(50)".

RUN VALUE(prog-name).

Any program invocation that uses a runtime-calculated expression will be ambiguous in the call graph. This could be due to user input, reading some or all of the value from the database, taking input from a file (or socket or any other resource) and/or any combination of these with some calculation algorithm.

In these cases, the call graph can not be populated correctly without some developer help. A 4GL developer that understands the application will need to define hints (as documented in the Resolving Ambiguous Call sites chapter, to disambiguate each call site. Keep in mind, if there are ambiguous call sites, the dead code report might be incorrect, as programs reachable via dynamic expressions will not be linked by their RUN statement (or other invocation mechanism) which is assumed to invoke them via a dynamic expression.

In the left-side of the report is a list of all programs which have ambiguous call-sites, with the number of ambiguities in each file. Once once of these programs is selected, the list of all ambiguous call sites will be displayed on the right-side, where:

  1. Hint ID column specifies the hint name to be used in the program's UAST .hints file.
  2. the Call Site column contains the call site's name (this is a prefix for Hint ID).
  3. Line and Column will identify the location of a call site in the programs preprocessed .cache file.

This information can be used to create the hint(s) to disambiguate the related call site.

For certain cases, the hint's value is allowed to be suffixed with a i.e. internal procedure name or user defined function name. See the Possible Ambiguous Call Sites section for more details.

Below is an example of this report:

Dead Code

By performing a Depth First Search using all the configured root entry programs, this report can determine which parts of code are never reached. The categories of dead code which can be reported are:
  • External programs - this includes all the unreachable external procedures and classes.
  • Include files - this includes all the unused include files
  • Internal procedures - this includes all unreachable internal procedures, even if they are part from an unreachable external program.
  • User defined functions - this includes all unreachable user-defined functions, even if they are part from an unreachable external program.
  • UI triggers - this includes all unreachable UI triggers (experimental)
  • OO class definitions - this includes all unreachable class definitions
  • OO interface definitions - this includes all unreachable interface definitions
  • OO method definitions - this includes all unreachable method definitions, even if they are part from an unreachable class or interface.
  • OO property definitions - this includes all unreachable property definitions, even if they are part from an unreachable class or interface.
The report is split in two sections:
  • left-side will have all determined dead code, grouped by category
  • right-side will provide an insight of the selected entry, which will be:
    • for external programs, all defined internal entries and the call sites which are contained in this external program.
    • for include files, all its references. An include file may be part of a connected sub-graph, which is by itself fully dead.
    • for internal procedures, user-defined functions or UI triggers, all contained call sites.
    • for class or interface definitions, its defined methods and properties
    • for method definitions, the contained call sites.
    • for property getter and/or setter definitions, the contained call sites.

See below for an example:

The correctness of this report depends on the:

  • The defined root entry points - if an entry point was missed, it may lead to incorrect reporting of a dead code. In this case, carefully analyze all the reported dead external programs and remove them after you are sure they can never be reached. Confirm that the application behaviour is not changed without them.
  • The resolved ambiguous call sites - the complexity of the call sites depends on the complexity of your application. Some call sites may be resolved from a database, user input or other dynamic expression. Regardless how it gets resolved, if an external program which is called by a RUN statement is not included in the hints to disambiguate that statement, it may lead to inconsistencies in this report.

Assuming the call graph was generated correctly, use this report to cut-down your code to a minimum set of files, while keeping the application behaviour unchanged.

Missing Call Targets

The report will show you all the external programs, internal procedures or user-defined functions which are attempted to be invoked, but they do not exist in the code-set. The report will provide these categories:
  • External Program - with the list of programs targeted by RUN statements, which can not be found.
  • Function - with the list of user-defined functions targeted by DYNAMIC-FUNCTION, which can not be found.
  • Internal Procedure - with the list of internal procedures targeted by RUN statements or RUN ... ASYNC EVENT-PROCEDURE event-internal-procedure, which can not be found.

The report is split in two sections:

  • left-side provides an overview of all missing targets, grouped by each category
  • once you select a row in the left-side table, the right-side will be populated with all the external programs (and their call-sites) which use the selected missing target.

See below for an example:

During graph generation, this report provides an overview of which program files may be missing from the code set. As an internal procedure or user-defined function can't be ran without having the associated external program already executed (persistent or not), you can focus only the External Program category - analyze all programs which appear here, and their call-sites, and determine if:

  • The program is really missing and needs to be added to the project; OR
  • The call-site should not be invoking this program - fix the code or the hints; OR
  • The call-site is dead-code and this specific code (or the entire program) can be removed from the project.

After the graph is completed (all ambiguities and missing targets are resolved), anything else included by this report means that your application may attempt to invoke these missing programs at some point. These are logic problems which should be resolved.

External Dependencies

The external dependencies represent any kind of call outside of the 4GL code; this includes the following categories:
  • Procedure Library Member - the RUN statements which target compiled R-CODE legacy code
  • Web Service - the target of a RUN port-type SET hport ON SERVER h statement, which represents the name of the WSDL port type.
  • Shared Library - the OS shared library name to which the target of a PROCEDURE nativeApi EXTERNAL sharedLibName procedure belongs.
  • Native API - the API targeted by a PROCEDURE ... EXTERNAL procedure.
  • Child Process - the command for an OS process launching statement, like UNIX, BTOS, INPUT THROUGH.
  • Socket - the configuration for a connection to/from a socket, AppServer or Web Service.
  • COM Automation - the target of an automation object being created via a CREATE automation-object statement; it specifies the details about the created automation object.
  • DDE Server - the target of a DDE INITIATE statement; it specifies details about the DDE server.
  • OCX Control - the target of a loadControls method call; it specifies the name of the control file.
The report will list all the external dependencies, for each category, in two sections:
  • left side will contain the dependencies, grouped by their category
  • right side will contain all references to this external target (i.e. all call sites which link to it)

See below for an example:

The report will allow you to determine all the external requirements to install your application. Analyze each dependency and determine which program/module requires it; if is linked to dead code, you can conclude that this dependency is no longer needed and remove it from your installation process/documentation.

When migrating your application to run using the FWD Application Server, this will help you understand the constraints under which you will be able to deploy your clients, making decisions such as:

  • if a user which requires access to native libraries will be deployed to the web or not
  • which network resources the clients need access to
  • which OS libraries require to be installed on client machines

Schema Triggers

This report will analyze your schema triggers and programs defined as schema triggers: it will show you any inconsistencies between the trigger type, schema and more. The possible found problems are split into these categories:

  • External program is not a table trigger - this section includes all external programs which are specified at the table definition as a trigger, but are missing the TRIGGER PROCEDURE FOR statement, which marks them as a schema trigger.
  • Trigger type mismatch - in this case, the trigger type at the table definition and the trigger type specified at the external program via the TRIGGER PROCEDURE FOR <trigger-type> statement are not identical.
  • Different table - the table at which the external program is registered is different from the table specified via the TRIGGER PROCEDURE FOR <trigger-type> OF <table> statement.
  • Missing external program - the external program associated with the trigger configured at the table definition does not exist.
  • Dead table trigger - the external program with a TRIGGER PROCEDURE FOR is not registered at the schema definition, or is registered incorrectly.

The report is split into two sections:

  • left-side section will have all the problematic external programs, grouped by category
  • right-side will provide details about the call sites (i.e. where this trigger is referenced from). The references can only be from schema files, so you will find a reference to a table's trigger definition, with KW_TAB_TRG call sites.

See below for an example:

Using this report, you can fix any inconsistencies between the triggers specified at the table definition and their target program, for example:

  • During graph generation, you can determine which programs need to be added to the code set.
  • Fix any typos, for the program name specified at the table definition or even the external program name.
  • Determine which external program triggers should be removed, as they are dead code.


The report allows you to identify all dependencies for a certain file; a file can be:

  • An external program, OO class or trigger definition. For such a file, you will be able to determine all dependencies originating from this file:
    • Call sites which invoke other code; this will not include internal calls, inside the same program, or the defined procedures or functions - only dependencies to other programs.
    • Include files which are used by this program.
    • References to other internal procedures or user-defined functions .
  • An include file, which will allow you to see which programs include it and the location where it is included.
  • A schema file, which will provide all triggers referenced by this schema.

See below for an example:

© 2004-2018 Golden Code Development Corporation. ALL RIGHTS RESERVED.

verify_schema_triggers.png (453 KB) Constantin Asofiei, 03/20/2018 03:47 PM

missing_external_targets.png (489 KB) Constantin Asofiei, 03/20/2018 04:09 PM

external_dependencies.png (420 KB) Constantin Asofiei, 03/20/2018 06:41 PM

dead_code.png (439 KB) Constantin Asofiei, 03/20/2018 06:57 PM

ambiguous_call_sites.png (438 KB) Constantin Asofiei, 03/21/2018 02:56 PM

dependencies.png (455 KB) Constantin Asofiei, 03/21/2018 03:14 PM