As software increases in complexity, the development of software is becoming more and more difficult. Development of software is increasingly evolving from a solitary occupation into a team effort, making it necessary for a developer to be familiar with and use source code he did not write. Thus it is more and more important to be able to browse information concerning symbols defined in source code (e.g. functions, classes, properties, namespaces, macros, attributes and type definitions, etc).
For example, perhaps a developer is reading a program that makes a function call. It may be helpful for the developer to know all the places where the function is called from, and where the function is defined. That is, if the developer calls the function “foo” in [one] place in the source code, it is helpful to know that “foo” is also called by [these other] places in the source code, and that function “foo” is defined in [this] place in the source code. If a developer is considering making a change to a function definition, it would be helpful to know where the function is used so that the developer can determine how the change will impact each situation in which the function is used. It might be helpful to know what symbols a given function uses or what classes are derived from a certain class, and so on. Particularly when looking at source code the developer has not written or when a program is large, such browse information is invaluable to obtain an understanding of and work with the program.
Typically, however, in order to generate this browse information, the program must be fully compilable. Compilers typically generate browse information during compilation. This information can be very helpful to further program development. For example, development tools may use the browse information generated by the compiler to display reference information. There are, however, a number of drawbacks associated with using browse information generated by a compiler.
One of the drawbacks with generating browse information with a compiler is that it is not always feasible to compile the program, making the browse information unavailable. The program may be uncompilable because the source code has errors in it that prevent it from being compiled. In addition, there are cases where it is very difficult to know all the settings and commands needed to compile the program.
Even if the program has been compiled, the browse information is only correct up to the most recent compile. As new source code is added, the browse information generated by the compiler becomes more and more outdated, detracting from its usefulness. For example, if the developer originally places calls to function “foo” in his source code, and compiles the program, browse information for function “foo” will exist in the browse information generated by the compiler. If subsequently the developer removes all the calls to function “foo”, the browse information will still erroneously contain the outdated browse information for function “foo” until the next compile. Because the compilation process itself can consume a non-trivial amount of time, explicit compilation may be infrequently initiated, compounding the problem.
Thus it would be helpful to be able to generate browse information dynamically so that changes to the source code are immediately reflected in the browse information, without having to recompile the program.
Dynamic parsers exist that attempt to address the shortcomings of compiler-generated browse information. One dynamic parser is described in U.S. Pat. No. 6,367,068 B1 issued Apr. 2, 2002, entitled “Dynamic Parsing”.
A dynamic parser typically dynamically parses the source code that has changed since the last time it parsed (e.g., the developer has modified the source code, or a new version of the source code has been installed). Such a parser typically checks for changes using a predetermined heuristic, such as at fixed intervals such as every second, when the developer completes writing a statement or when the developer is inactive or idle, without waiting for the developer to initiate compiling. The parser may identify errors and warnings in the source code, and display limited information such as the members belonging to a class. Typically, source code is parsed for declaration and definition information. However, this declaration and definition information on symbols such as functions is frequently limited to return types and parameters, while the body of the function typically is not parsed for symbol information. Hence, browse information concerning the source code contained within the function body is not available from the dynamic parser. Some development tools available today do provide information concerning the source code contained within the function body. Typically, however, these editors provide this functionality by doing a text search through source code to find all occurrences of the name of a symbol. For example, if a portion of the source code contained the lines:
000001namespace N1000002{000003void foo( )000004{000005// I'm N1::foo000006}000007}000008namespace N2000009{000010void foo( )000011{000012//I'm N2::foo000013}000014}000015using namespace N1;000016void bar( )000017{000018//...foo is here000019foo( );000020str = “Hello foo”;000021N2::foo( );. . .000026}                and a developer wanted to find every place that the function “N1::foo” was referenced, a development tool that does a text search would find the occurrences of “foo” on lines 000003, 000005, 00010, 00012, 00018, 00019, 00020, and 00021, which is incorrect. The only occurrences are on line 000003 which is the definition of N1::foo and line 00019, which is a call to “N1::foo”. Hence it would be helpful if a dynamic browse information parser existed that could dynamically generate browse information, including source code contained within a function body, and could distinguish calls made to a function, from calls made to a different function with the same name, and from comments and strings containing the function's name (i.e., that would be as smart as a compiler) without explicitly invoking a compiler.        