# HG changeset patch # User Aziz K?ksal # Date 1205358105 -3600 # Node ID 35d238d502cb241a16d76236525e870a00cb5d37 # Parent 615c1386b18d534ac15952f720461355931d5663 The ModuleManager handles packages as well now. Added options -ps and -pm to command compile. diff -r 615c1386b18d -r 35d238d502cb src/cmd/Compile.d --- a/src/cmd/Compile.d Wed Mar 12 19:11:30 2008 +0100 +++ b/src/cmd/Compile.d Wed Mar 12 22:41:45 2008 +0100 @@ -5,6 +5,7 @@ module cmd.Compile; import dil.semantic.Module; +import dil.semantic.Package; import dil.semantic.Pass1; import dil.semantic.Pass2; import dil.semantic.Symbols; @@ -18,6 +19,8 @@ struct CompileCommand { string[] filePaths; /// Explicitly specified modules (on the command line.) + bool printSymbolTree; /// Whether to print the symbol tree. + bool printModuleTree; /// Whether to print the module tree. ModuleManager moduleMan; SemanticPass1[] passes1; @@ -32,7 +35,8 @@ { auto modul = moduleMan.loadModuleFile(filePath); runPass1(modul); - printSymbolTable(modul, ""); + if (printSymbolTree) + printSymbolTable(modul, ""); } // foreach (modul; moduleMan.loadedModules) @@ -40,6 +44,18 @@ // auto pass2 = new SemanticPass2(modul); // pass2.run(); // } + + if (printModuleTree) + printMTree(moduleMan.rootPackage, ""); + } + + void printMTree(Package pckg, string indent) + { + Stdout(indent)(pckg.pckgName)("/").newline; + foreach (p; pckg.packages) + printMTree(p, indent ~ " "); + foreach (m; pckg.modules) + Stdout(indent ~ " ")(m.moduleName)(".d").newline; } /// Runs the first pass on modul. diff -r 615c1386b18d -r 35d238d502cb src/dil/ModuleManager.d --- a/src/dil/ModuleManager.d Wed Mar 12 19:11:30 2008 +0100 +++ b/src/dil/ModuleManager.d Wed Mar 12 22:41:45 2008 +0100 @@ -20,6 +20,10 @@ /// Manages loaded modules in a table. class ModuleManager { + /// The root package. Contains all other modules and packages. + Package rootPackage; + /// Maps full package names to packages. E.g.: dil.ast + Package[string] packageTable; /// Maps FQN paths to modules. E.g.: dil/ast/Node Module[string] moduleFQNPathTable; /// Maps absolute file paths to modules. E.g.: /home/user/dil/src/main.d @@ -31,6 +35,8 @@ /// Constructs a ModuleManager object. this(string[] importPaths, InfoManager infoMan) { + this.rootPackage = new Package(null); + packageTable[""] = this.rootPackage; this.importPaths = importPaths; this.infoMan = infoMan; } @@ -58,16 +64,58 @@ moduleFQNPathTable[moduleFQNPath] = newModule; absFilePathTable[absFilePath] = newModule; loadedModules ~= newModule; + // Add the module to its package. + auto pckg = getPackage(newModule.packageName); + pckg.add(newModule); return newModule; } + /// Returns the package given a fully package name. + /// Returns the root package for an empty string. + Package getPackage(string pckgFQN) + { + auto pPckg = pckgFQN in packageTable; + if (pPckg) + return *pPckg; + + string prevFQN, lastPckgName; + // E.g.: pckgFQN = 'dil.ast', prevFQN = 'dil', lastPckgName = 'ast' + splitPackageFQN(pckgFQN, prevFQN, lastPckgName); + // Recursively build package hierarchy. + auto parentPckg = getPackage(prevFQN); // E.g.: 'dil' + // Create a new package. + auto pckg = new Package(lastPckgName); // E.g.: 'ast' + parentPckg.add(pckg); // 'dil'.add('ast') + // Insert the package into the table. + packageTable[pckgFQN] = pckg; + return pckg; + } + + /// Splits e.g. 'dil.ast.xyz' into 'dil.ast' and 'xyz'. + /// Params: + /// pckgFQN = the full package name to be split. + /// prevFQN = set to 'dil.ast' in the example. + /// lastName = the last package name; set to 'xyz' in the example. + void splitPackageFQN(string pckgFQN, ref string prevFQN, ref string lastName) + { + uint lastDotIndex; + foreach_reverse (i, c; pckgFQN) + if (c == '.') + { lastDotIndex = i; break; } // Found last dot. + prevFQN = pckgFQN[0..lastDotIndex]; + if (lastDotIndex == 0) + lastName = pckgFQN; // Special case - no dot found. + else + lastName = pckgFQN[lastDotIndex+1..$]; + } + /// Loads a module given an FQN path. Module loadModule(string moduleFQNPath) { // Look up in table if the module is already loaded. - Module* pmodul = moduleFQNPath in moduleFQNPathTable; - if (pmodul) - return *pmodul; + Module* pModul = moduleFQNPath in moduleFQNPathTable; + if (pModul) + return *pModul; // Locate the module in the file system. auto moduleFilePath = findModuleFilePath(moduleFQNPath, importPaths); if (moduleFilePath.length) @@ -76,7 +124,7 @@ if (modul.getFQNPath() != moduleFQNPath) { // Error: the requested module is not in the correct package. auto location = modul.moduleDecl.begin.getErrorLocation(); - auto msg = Format(MSG.ModuleNotInPackage, getPackage(moduleFQNPath)); + auto msg = Format(MSG.ModuleNotInPackage, getPackageFQN(moduleFQNPath)); infoMan ~= new SemanticError(location, msg); } return modul; @@ -85,7 +133,7 @@ } /// Returns e.g. 'dil.ast' for 'dil/ast/Node'. - string getPackage(string moduleFQNPath) + string getPackageFQN(string moduleFQNPath) { string pckg = moduleFQNPath.dup; uint lastDirSep; diff -r 615c1386b18d -r 35d238d502cb src/dil/semantic/Package.d --- a/src/dil/semantic/Package.d Wed Mar 12 19:11:30 2008 +0100 +++ b/src/dil/semantic/Package.d Wed Mar 12 22:41:45 2008 +0100 @@ -20,7 +20,7 @@ /// Constructs a Package object. this(string pckgName) { - auto ident = IdTable.inStatic(pckgName); + auto ident = IdTable.lookup(pckgName); super(SYM.Package, ident, null); this.pckgName = pckgName; } @@ -43,6 +43,7 @@ /// Adds a module to this package. void add(Module modul) { + modul.parent = this; modules ~= modul; insert(modul, modul.name); } @@ -50,6 +51,7 @@ /// Adds a package to this package. void add(Package pckg) { + pckg.parent = this; packages ~= pckg; insert(pckg, pckg.name); } diff -r 615c1386b18d -r 35d238d502cb src/main.d --- a/src/main.d Wed Mar 12 19:11:30 2008 +0100 +++ b/src/main.d Wed Mar 12 22:41:45 2008 +0100 @@ -74,6 +74,10 @@ cmd.context.releaseBuild = true; else if (arg == "-unittest") cmd.context.unittestBuild = true; + else if (arg == "-ps") + cmd.printSymbolTree = true; + else if (arg == "-pm") + cmd.printModuleTree = true; else cmd.filePaths ~= arg; } @@ -412,6 +416,9 @@ -release : compile a release build -unittest : compile a unittest build + -ps : print the symbol tree of the modules + -pm : print the package/module tree + Example: dil c src/main.d -Isrc/`; break;