changeset 816:35d238d502cb

The ModuleManager handles packages as well now. Added options -ps and -pm to command compile.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Wed, 12 Mar 2008 22:41:45 +0100
parents 615c1386b18d
children e6fb7ed87d3a
files src/cmd/Compile.d src/dil/ModuleManager.d src/dil/semantic/Package.d src/main.d
diffstat 4 files changed, 80 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- 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.
--- 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;
--- 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);
   }
--- 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;