How to: Add Import Chasing
Most languages have some mechanism to import namespaces or include files. Include files are read before the parser is called, while imported modules are called by the parser to include their information in an IScope Interface object.
This topic is based on the Visual Studio Language Package solution, which provides a basic implementation of the Babel package. For more information about creating one of these solutions, see Walkthrough: Creating a Language Service Package.
Finding Files
It is not always possible to find the correct include file or module without interaction with the build system. In the C language, include files are specified with a user-defined search path. The Babel package allows users to specify search paths in Visual Studio projects that implement the IBabelProject Interface. The searchFile method queries the associated project to search for a file. If the project does not support the IBabelProject interface, the fileName parameter is returned unmodified.
Getting Scopes
If your language supports the separate compilation of modules, you should consider loading the IScope object for an imported module directly, instead of parsing the file recursively as if it were an include file. The loadScope method returns the IScope object for any file associated with a Babel language service.
If the fileName parameter of the loadScope method includes an extension that is registered for the language service, it is automatically expanded to a full path before the Babel package tries to load it. The Babel package provides a default service for returning an IScope interface on Common Language Runtime (CLR) metadata files (.dll, .tlb, .exe). The resulting scope object is delay-loaded, such that the service is called only if the parser calls a method on the IScope object.
The following code from a parser source file uses the searchFile and loadScope methods to process include files as external modules.
import_statement : KWIMPORT CHARACTER_STRING SEMICOLON
{ char fileName[1024];
const char * tokenstring;
//copy and remove the quotes
tokenstring = g_service->tokenText(&$2) + 1;
int i = 0;
while (*tokenstring != '\0')
fileName[i++] = *(tokenstring+);
fileName[i-1] = '\0';
//find & load source
IScope* scope = NULL;
//searchFile does ParseSink::GetProject & BabelProject::SearchFile
g_service->searchFile(fileName,1024);
g_service->loadScope( fileName, &scope );
if (scope) { g_service->addExtern( $1, $2, scope ); scope->Release(); }
}
;
Change History
Date |
History |
Reason |
---|---|---|
July 2008 |
Rewrote and refactored project. |
Content bug fix. |