Mercurial > projects > dil
view src/docgen/misc/parser.d @ 806:bcb74c9b895c
Moved out files in the trunk folder to the root.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Sun, 09 Mar 2008 00:12:19 +0100 |
parents | trunk/src/docgen/misc/parser.d@2eee29aaa357 |
children |
line wrap: on
line source
/** * Author: Aziz Köksal & Jari-Matti Mäkelä * License: GPL3 */ module docgen.misc.parser; import dil.parser.Parser; import dil.parser.ImportParser; import dil.File; import dil.Settings; public import dil.semantic.Module; import tango.text.Regex : RegExp = Regex; import tango.io.FilePath; import tango.io.FileSystem; import tango.core.Array : remove; import tango.text.Util; import docgen.misc.meta; debug import tango.io.Stdout; alias void delegate (char[] fqn, char[] path, Module module_) modDg; alias void delegate (Module imported, Module importer, bool isPublic, bool isStatic) importDg; class Parser { protected: // ParserOptions m_options; static char[] findModuleFilePath(char[] moduleFQNPath, char[][] importPaths) { auto filePath = new FilePath(); foreach (importPath; importPaths) { filePath.set(importPath); filePath.append(moduleFQNPath); foreach (moduleSuffix; [".d", ".di"/*interface file*/]) { filePath.suffix(moduleSuffix); debug Stdout("Trying ")(filePath.toString()).newline; if (filePath.exists()) return filePath.toString(); } } debug Stdout(" * ")(moduleFQNPath)(" does not exist in imports\n")(); return null; } public: /** * Imports the transitive closure of imports starting from "filePath", * limited by recursionDepth. * * The search can be filtered by providing a list of regexps that match the * FQNs of modules to be ignored. * * Params: * filePath = Path of the file to parse * importPaths = Directories to look for imports * strRegexps = Filter regexps * IncludeUnlocatableModules = Call the delegate also for unlocatable files * recursionDepth = How many levels of imports to follow (-1 = no limit) * mdg = Delegate that gets called for every module found * idg = Delegate that gets called for every import found * modules = List of parsed modules */ static void loadModules(char[] filePath, char[][] importPaths, char[][] strRegexps, bool IncludeUnlocatableModules, int recursionDepth, modDg mdg, importDg idg, out Module[] modules) { loadModules([filePath], importPaths, strRegexps, IncludeUnlocatableModules, recursionDepth, mdg, idg, modules); } /** * Imports the transitive closure of imports starting from "filePath", * limited by recursionDepth. * * The search can be filtered by providing a list of regexps that match the * FQNs of modules to be ignored. * * Params: * filePaths = Paths of the files to parse * importPaths = Directories to look for imports * strRegexps = Filter regexps * IncludeUnlocatableModules = Call the delegate also for unlocatable files * recursionDepth = How many levels of imports to follow (-1 = no limit) * mdg = Delegate that gets called for every module found * idg = Delegate that gets called for every import found * modules = List of parsed modules */ static void loadModules(char[][] filePaths, char[][] importPaths, char[][] strRegexps, bool IncludeUnlocatableModules, int recursionDepth, modDg mdg, importDg idg, out Module[] modules) { // Initialize regular expressions. RegExp[] regexps; foreach (strRegexp; strRegexps) regexps ~= new RegExp(strRegexp); importPaths ~= "."; // Add directory of file and global directories to import paths. foreach(filePath; filePaths) { auto fileDir = (new FilePath(filePath)).folder(); if (fileDir.length) importPaths ~= fileDir; } // importPaths ~= GlobalSettings.importPaths; debug foreach(path; importPaths) { Stdout("Import path: ")(path).newline; } Module[char[]] loadedModules; Module loadModule(char[] moduleFQNPath, int depth) { if (depth == 0) return null; debug Stdout("Loading ")(moduleFQNPath).newline; // Return already loaded module. auto mod_ = moduleFQNPath in loadedModules; if (mod_ !is null) { debug Stdout(" Already loaded.")(moduleFQNPath).newline; return *mod_; } auto FQN = replace(moduleFQNPath.dup, dirSep, '.'); // Ignore module names matching regular expressions. foreach (rx; regexps) if (rx.test(FQN)) return null; auto moduleFilePath = findModuleFilePath(moduleFQNPath, importPaths); debug Stdout(" FQN ")(FQN).newline; debug Stdout(" Module path ")(moduleFilePath).newline; Module mod = null; if (moduleFilePath is null) { if (IncludeUnlocatableModules) mdg(FQN, moduleFQNPath, null); } else { mod = new Module(moduleFilePath); // Use lightweight ImportParser. // mod.parser = new ImportParser(loadFile(moduleFilePath), moduleFilePath); mod.parse(); debug Stdout(" Parsed FQN ")(mod.getFQN()).newline; // autoinclude dirs (similar to Java) // running docgen in foo/bar/abc/ also finds foo/xyz/zzz.d if module names are right { // foo.bar.mod -> [ "foo", "bar" ] auto modPackage = split(mod.getFQN, ".")[0..$-1]; auto modDir = split(FileSystem.toAbsolute(new FilePath(moduleFilePath)).standard().folder(), "/"); auto modLocation = modDir[0..modDir.remove(".")]; bool matches = false; int i; for(i = 1; i <= min(modPackage.length, modLocation.length); i++) { matches = true; debug Stdout(" Decl: ")(modPackage[$-i]).newline; debug Stdout(" Path: ")(modLocation[$-i]).newline; if (modPackage[$-i] != modLocation[$-i]) { matches = false; break; } } if (matches) { auto loc = modLocation[0..$-i+1].join("/"); debug Stdout(" Autoadding import: ")(loc).newline; importPaths ~= loc; } } mdg(FQN, moduleFQNPath, mod); loadedModules[moduleFQNPath] = mod; foreach (importDecl; mod.imports) foreach(moduleFQN_; importDecl.getModuleFQNs(dirSep)) { auto loaded_mod = loadModule(moduleFQN_, depth == -1 ? depth : depth-1); if (loaded_mod !is null) { idg(loaded_mod, mod, importDecl.isPublic(), importDecl.isStatic()); } else if (IncludeUnlocatableModules) { auto tmp = new Module(null); tmp.setFQN(replace(moduleFQN_.dup, dirSep, '.')); idg(tmp, mod, importDecl.isPublic(), importDecl.isStatic()); } } } return mod; } // loadModule foreach(filePath; filePaths) loadModule(filePath, recursionDepth); // Finished loading modules. // Ordered list of loaded modules. modules = loadedModules.values; } }