5. Browsing and Navigation

5.1. Crucial Setup Requirement

Unlike Ada-aware editing, which will work for any properly-named Ada source file, browsing and navigating require some processing prior to use. Specifically, these facilities require the Ada source code to be in a GNATbench project and to have been analyzed by the GNAT Pro compiler. Failure to meet these requirements will result in either unsuccessful invocations or missing menu entries in some menus.

Being “in” a GNATbench project means that the source code is in a file residing within one of the directories specified by the Source_Dirs attribute of a GNATbench project file (the project “gpr file”). Implicit inclusion by residence within the same directory as the project file will also suffice.

Analysis by the GNAT Pro compiler happens either automatically, as a result of normal compilation, or explicitly, by manual invocation of the compiler in a special mode to perform the analysis.

Therefore, building the entire project will make all the sources navigable. Of course, those Ada files not in a GNATbench project are not compiled when building the project so they are not analyzed. That means they will not support navigation and browsing, even though the Ada editor will open them.

You can compile individual files via the Ada editor’s contextual menu. Manually compiling some of the files will make some of the files navigable.

Analysis results are stored in a cross-reference database. By default this database is named ‘gnatinspect.db’ and is located in the project’s object directory.

For your convenience, GNATbench attempts to support navigation prior to the corresponding files’ analysis, but to ensure full functionality you must use the compiler to analyze the sources. When the functionality is not possible a dialog box will notify you of that fact, suggesting the cause of the problem.

Also for your convenience, GNATbench attempts to support navigation even in the face of changes to the source code. Such changes can invalidate any previous analysis, however, so ensuring accurate navigation functionality requires that you re-analyze the code.

5.1.1. The cross-reference database

GNATbench parses the cross-reference information generated by the compiler (the .ali and .gli) files into an sqlite database. This database can become quite large and should preferably be on a fast local disk.

By default, GNATbench places this database in the object directory of the currently-loaded root project. Override this choice by adding an attribute Xref_Database in the IDE package of your project file, either as an absolute path or a path relative to the location of the project file. We recommend this path be specific to each use, and to each project this user might be working on, as in the following examples:

--  assume this is in /home/user1/work/default.gpr
project Default is
   for Object_Dir use "obj";

   package IDE is
      for Xref_Database use "xref_database.db";
      --  This would be /home/user1/work/xref_database.db

      for Xref_Database use Project'Object_Dir & "/xref_database.db";
      --  This would be /home/user1/work/obj/xref_database.db
      --  This is the default when this attribute is not specified

      for Xref_Database use external("HOME") & "/prj1/database.db";
      --  This would be /home/user1/prj1/database.db
   end IDE;
end Default;

One drawback in altering the default location is that gprclean will not remove this database when you clean your project. But it might speed up GNATbench if your project is not on a fast local disk and you can put the database there.

WARNING: You should not store this file in a directory that is accessed via a network filesystem, like NFS, or Clearcase’s MVFS. If your obj directory is on such a filesystem, be sure to specify a custom Xref_Database directory in your project file.

5.1.2. Cross-references and partially compiled projects

The cross-reference engine works best when the cross-reference information generated by the compiler (the .ali files) is fully up to date.

If you start from such a state and then modify the spec or body of an Ada package and recompile only that file, any reference to entities declared in that spec in other packages might no longer be found (until you recompile those other packages, as gprbuild would).

This is because GNATbench has no way to know for sure whether an entity Foo in the spec is the same entity as before or is a new one with the same name. It uses an approximate algorithm where the references are only preserved if an entity with the same name remains at precisely the same location in the new version of the source. But if a blank line in the file will change the declaration line for all entities declared further in the file, so those will lose their references from other source files.

5.3. Editor Tooltips

Hovering the mouse cursor over an entity in the Ada editor causes the profile and documentation to appear in a tooltip. For example, in the following image, the mouse is hovering over the name “Activate”, resulting in the tooltip shown:

editor tooltip

Note the green dot symbol indicating that this is a visible procedure, as is employed elsewhere such as the Outline view. Note also the text describing the purpose of the procedure, taken from a comment next to the procedure declaration. The formal parameters, if any, are also indicated.

These tooltips can be disabled via the Ada Editor preferences page.

5.4. Visiting Declarations and Bodies

The Ada language-sensitive editor supports navigation and browsing via menu entries in the contextual menu. Given an existing identifier, you may visit the corresponding declaration or body.

You may either left-click on the target and press F3, or right-click and select Open Declaration (or Open Body) from the editor’s contextual menu. If the cursor is not on an entity when visitation is requested, GNATbench will attempt to determine the enclosing program unit and visit the corresponding declaration or body.

contextual editor menu addition

The declarations and bodies of packages, protected types, tasks, procedures, and functions can be visited. In addition, you can navigate from an Ada declaration directly to its C or C++ implementation if the Ada declaration is completed by a pragma Import specifying convention C or CPP.

The declarations of types and objects may also be visited, in addition to the program units listed above. For example, given the use of a type in an object declaration, you may go to the declaration of that type using this interface.

Note that language-defined types declared in package Standard are not supported because there is no actual package Standard. However, language-defined types in other language-defined packages, such as System and Interfaces, are physically represented and are, therefore, supported.

Eclipse maintains a list of files visited in the editor and allows you revisit them using the yellow “Forward” and “Back” navigation arrows on the toolbar. (The left-arrow with an asterisk next to it, to the left of the Forward and Back buttons, visits the last location at which an actual editing change was made.) GNATbench is fully integrated with these navigation controls. Clicking one of these buttons visits the next or previous location visited, linearly. You may jump directly to any specific location in the list by clicking on the black down-arrow controls next to the buttons and selecting a file from the resulting list. The following figure shows a sample list:

forward and back buttons in toolbar

5.5. Visiting Declaration and Body Files

In addition to navigating and browsing by selecting individual entities in a source file, you can also navigate back and forth in terms of the files themselves, without first selecting the entity name. To do so, simply place the cursor anywhere within the file containing the declaration or body and invoke “Goto File Spec / Body”, in either the Ada menubar entry or the Ada menu in the editor contextual menu. The file containing the corresponding declaration or body will open.

In the following figure the cursor is in the file but is past the end of the package when the contextual menu is invoked. The corresponding body file will be opened as a result of the invocation.

goto file spec / body example

5.6. Traversing Within Source Files

You may visit the next or previous unit within an Ada source file using the “Goto Next Unit” and “Goto Previous Unit” commands. These commands will skip to the next/previous procedure, function, or entry in the file. Both declarations and bodies for these units in a given file will be visited.

By default these editor actions are bound to the Ctrl+Up_arrow and Ctrl+Down_arrow keys (for visiting the previous and next units, respectively). You may change these bindings if desired, as usual.

The commands are also available via the Ada menu on the menubar and the editor’s contextual menu.

If there is no next or previous unit, these actions have no effect.

5.7. Browsing via Reference Searching

In addition to browsing by navigating along the hyperlinks of individual Ada entities, you can also browse the code in a more “global” manner by searching for all references to a selected entity.

When the editor cursor (not the mouse cursor) is over a given entity in the Ada editor, or when the entity is selected, right-clicking with the mouse invokes a contextual menu that allows you to request a display of all references to that entity. (The menu entry is named “References”.)

references submenu

You control the scope of the search by selecting either “Project” or “Workspace” (or “Project Hierarchy”). Typically you will want to search within a single project but you can search all open projects by selecting “Workspace”.

The search results appear in the Search view. Clicking on one of these entries will traverse to the reference in the corresponding file, opening the file in the Ada editor if necessary. Within the editor, links to these references are added to the overview ruler and arrows are added to the annotation ruler.

The following figure illustrates the result of searching for the entity “Standard_Integer” in an Ada file. The Search view shows that the entity is declared in package “MS1553.Message_Element.Predefined” because of the icon appearing as a green circle with a ‘T’ in the middle. It further shows that “Standard_Integer” is referenced in a subprogram named “Pack” in that package. We have clicked on that Search entry so the editor has opened that file and highlighted the occurrences. Other references to “Standard_Integer” occur in three other packages and we could visit those occurrences in the same manner.

browsing references example

5.7.1. Advanced Options

You can refine the parameters of the references search in terms of Ada language features.

To do so, select “Advanced…” under the “References” submenu. Doing so will bring up the following dialog box, allowing you to select additional criteria for the search. You can also specify the same options as you would have without choosing the advanced options entry, namely the extent of the search itself (project, workspace, or project hierarchy).

advanced references options