During the recent field test for RAD Studio 2010, I had a discussion with some field testers about the different mechanisms that the IDE provides for navigating through your source code. In particular, they were wondering why sometimes one method of code navigation fails, but other methods still work. I thought that this would be of interest to some of you as well, so I figured that I’d post about it here.
The IDE provides four common ways of navigating through your code within the code editor:
- Code Browsing (also known as Ctrl-Click or Go To Declaration)
- Toggling between interface and implementation sections
- Open File At Cursor
- Help Insight navigation links
The mechanism behind each is completely different and some are more tolerant of incomplete or broken code than others.
Code Browsing/Go To Declaration (Ctrl-Click)
Code Browsing is supported in both Delphi and C++Builder. It is invoked when you hold down the Ctrl key and move the mouse over a symbol. This underlines the symbol, like a web page link that you can click on. You can also right-click on a symbol and choose “Go to declaration” from the context menu. This method of navigation works by invoking the compiler in a special browsing mode that we call “kibitzing.”
The IDE asks the compiler to find the declaration of the symbol. The compiler goes off and partially compiles enough source code to be able to find the declaration. It reports back to the IDE with either the filename and line number of the declaration or with an indication it couldn’t find the declaration.
In this browsing mode, the compiler works a little differently than when it actually builds your project. When browsing, the compiler’s back end is turned off so that no binary code is produced. The compiler is also more relaxed about syntax errors. It has several error recovery mechanisms that allow it to keep parsing through some incomplete or incorrect code, too. Still, if the code is too incomplete or too incorrect, the compiler may not be able to recover and code browsing may fail.
For Delphi projects, the compiler’s browsing mode also differs from the regular compile operation in that it uses a different path for resolving units listed in the uses clauses. In browsing mode, the compiler does not use the program (.dpr) or package (.dpk) file. Instead, it just compiles the particular unit that you are working with and it tries to find the units in the uses clauses by looking on the project’s search path and the global browsing path. Before starting a browsing operation, the IDE adds the paths for all of the units listed in the project manager to the browsing path and passes this extended browsing path to the compiler. If you hand-edit the program or package source to include units that are not listed in the project manager, then the compiler may not be able to find them and this can make code browsing fail. If you hand-edit the program or project source, it is very important that your global browsing path include the directories for all of the source code that may be pulled into your build.
For C++Builder, the program or package source does not list the used units like Delphi does. When the C++ compiler is in browsing mode, it always tries to find the source along the project’s include path or the global browsing path.
Toggle Between Declaration and Definition (Ctrl-Shift Up/Down)
Toggling between the interface declaration and implementation definition of a method is supported only for Delphi projects. Pressing Ctrl-Shift-Up Arrow will show the method’s declaration and pressing Ctrl-Shift-Down Arrow will show the method’s implementation.
This method of code navigation does not invoke the compiler at all. It is an entirely IDE-based mechanism that uses the same per-unit parser that provides the editor’s code folding regions and the structure pane information. This parser is even more resilient to code errors because it looks only for structure elements and it completely skips procedure bodies. As long as the parser is able to locate the procedure header for both the declaration and implementation then this method of code navigation will work, even on code that would not yet compile.
Open File At Cursor (Ctrl-Enter)
“Open file at cursor” is another mechanism of navigation that is available in both Delphi and C++Builder. This method of code navigation takes a very simple approach:
The IDE simply looks at the token underneath the cursor. For Delphi, if the token does not have an extension, the IDE appends “.pas” to the token then looks along the project’s search path for a matching filename. For C++Builder, the IDE just takes the editor token and tries to find it as a filename along the include path.
For both personalities, if the IDE is unable to find a matching filename it will show the standard File Open dialog.
Help Insight Links
Help Insight is available only in Delphi projects. When your mouse hovers over a symbol in the code editor, a pop-up window will appear with additional information about the symbol, including a hotlink to the symbol’s declaration.
Information for Help Insight is produced by yet another IDE-based parser. This parser also provides the information for Error Insight and powers the refactoring and modeling features. It is a more complete parser than the structure parser, but it was designed to be very resilient when it encounters incomplete or incorrect code. For units within the project, this parser looks at all the source code. For used units that are not listed in the project manager, the parser invokes the compiler to find the exported symbols.
I hope this helps to explain the different navigation mechanisms that are available in the RAD Studio IDE and gives some insight into how they work.