[svn] r7319: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel: SourceGenerator.n XmlDo...

pbludov svnadmin at nemerle.org
Mon Jan 22 14:37:03 CET 2007


Log:
Cache for xml documentation.

Author: pbludov
Date: Mon Jan 22 14:37:00 2007
New Revision: 7319

Modified:
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/SourceGenerator.n
   vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/XmlDocReader.n

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/SourceGenerator.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/SourceGenerator.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/SourceGenerator.n	Mon Jan 22 14:37:00 2007
@@ -189,78 +189,20 @@
 
     private WriteDocumentation(member : IMember) : void
     {
-      def info = XmlDocReader.GetInfo(member, member.Location);
+      def content = XmlDocReader.GetContent(member, member.Location);
 
-      def writeText(text)
+      unless (content == null)
       {
-          using (r = StringReader(text))
+        using (r = StringReader(content))
           {
             while (r.Peek() > 0)
             {
               Write("/// ");
-              Write(r.ReadLine());
+            Write(r.ReadLine().TrimStart(null));
               WriteLine();
             }
           }
       }
-
-      def writeComment(name, text)
-      {
-        unless (string.IsNullOrEmpty(text))
-        {
-          Write("/// <");
-          Write(name);
-          Write(">");
-          WriteLine();
-
-          writeText(text);
-
-          Write("/// </");
-          Write(name);
-          Write(">");
-          WriteLine();
-        }
-      }
-
-      def writeParamComment(name, text)
-      {
-        unless (string.IsNullOrEmpty(text))
-        {
-          Write("/// <param name=\"");
-          Write(name);
-          Write("\">");
-          WriteLine();
-
-          writeText(text);
-
-          Write("/// </param>");
-          WriteLine();
-        }
-      }
-
-      def writeExceptionComment(name, text)
-      {
-        unless (string.IsNullOrEmpty(text))
-        {
-          Write("/// <exception cref=\"");
-          Write(name);
-          Write("\">");
-          WriteLine();
-
-          writeText(text);
-
-          Write("/// </exception>");
-          WriteLine();
-        }
-      }
-
-      unless (info == null)
-      {
-        writeComment("summary", info.Summary);
-        info.Params.Iter(writeParamComment);
-        writeComment("returns", info.Returns);
-        info.Exceptions.Iter(writeExceptionComment);
-      }
     }
 
     private WriteAttributes(member : IMember) : void

Modified: vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/XmlDocReader.n
==============================================================================
--- vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/XmlDocReader.n	(original)
+++ vs-plugin/trunk/Nemerle.Compiler.Utils/Nemerle.Completion2/CodeModel/XmlDocReader.n	Mon Jan 22 14:37:00 2007
@@ -2,6 +2,7 @@
 using System.IO;
 using System.Xml;
 
+using Nemerle.Collections;
 using Nemerle.Compiler;
 using Nemerle.Compiler.Utils;
 using Nemerle.Imperative;
@@ -12,18 +13,91 @@
 {
   public module XmlDocReader
   {
-    public GetInfo(mtype : MType, location : Location) : XmlDocInfo
+    private class XmlDocFile
     {
-      GetInfo("T:" + mtype.TypeInfo.FullName, location);
+      private         _filePath  : string;
+      private mutable _timeStamp : DateTime;
+      private mutable _members   : Map[string, string];
+
+      public this(filePath : string)
+      {
+        _filePath  = filePath;
+        _members   = Map();
+        Load();
     }
 
-    public GetInfo(member : IMember, location : Location) : XmlDocInfo
+      public GetMemberDoc(member : string) : string
+      {
+        when (File.GetLastWriteTime(_filePath) > _timeStamp)
+          Load();
+
+        match (_members.Find(member))
+        {
+        | Some(doc) => doc;
+        | None      => null;
+        }
+      }
+
+      private Load() : void
+      {
+        _timeStamp = File.GetLastWriteTime(_filePath);
+        _members   = _members.Clear();
+
+        using (rdr = XmlTextReader(_filePath))
+        {
+          do
+          {
+              when (rdr.NodeType == XmlNodeType.Element && rdr.LocalName == "member")
+                _members = _members.Add(rdr.GetAttribute("name"), rdr.ReadInnerXml());
+          }
+          while (rdr.Read());
+        }
+      }
+    }
+
+    private mutable _xmlDocCache : Map[string, XmlDocFile];
+
+    public this()
+    {
+      _xmlDocCache = Map();
+    }
+
+    private GetDocFile(asmFilePath : string) : XmlDocFile
+    {
+      match (_xmlDocCache.Find(asmFilePath))
+      {
+      | Some(docFile) => docFile;
+      | None          =>
+        def xmlFile = Environment.ExpandEnvironmentVariables(Path.ChangeExtension(asmFilePath, ".xml"));
+        def docFile = 
+          if (File.Exists(xmlFile))
+            XmlDocFile(xmlFile);
+          else
+          {
+            // Hack for .Net framework assemblies.
+            // Some of them are loaded from the GAC, while their xml documentation stored in
+            // the %SystemRoot%/Microsoft.Net/<version>/ folder.
+            //
+            def altPath = Path.Combine(System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(), Path.GetFileName(xmlFile));
+
+            if (File.Exists(altPath))
+              XmlDocFile(altPath);
+            else
+              null;
+          }
+        _xmlDocCache = _xmlDocCache.Add(asmFilePath, docFile);
+
+        docFile;
+      }
+    }
+
+    private GetKey(member : IMember) : string
     {
       def name = member.GetFullName();
-      def key  = match (member)
+      match (member)
       {
-      | _  is IProperty  => "P:" + name
-      | _  is IField     => "F:" + name
+      | _  is IProperty  => "P:" + name;
+      | _  is IField     => "F:" + name;
       | mi is IMethod    => 
 
         def memType = mi.GetMemType();
@@ -41,91 +115,81 @@
 
         | Fun(MType.Array(MType.Class(ti, _), _), _) => "M:" + name + "(" + ti.FullName + "[])"
         | Fun(MType.Class(ti, _), _)                 => "M:" + name + "(" + ti.FullName + ")"
-        | Fun(MType.Void, _) => "M:" + name
-        | _                  => null
+        | Fun(MType.Void, _) => "M:" + name;
+        | _                  => null;
         }
 
-      | _ => null
+      | _ => null;
       }
-
-      if (key != null) GetInfo(key, location) else null
     }
 
-    public GetInfo(key : string, location : Location) : XmlDocInfo
-    {
-      ret :
+    public GetContent(key : string, location : Location) : string
       {
-        when (string.IsNullOrEmpty(location.File) || location.EndLine > 0)
-          ret(null);
-
-        def file = if (location.File.IndexOf("GAC") > 0)
+      if (string.IsNullOrEmpty(location.File) || location.EndLine > 0)
+        null;
+      else
         {
-          def fn  = location.File;
+        def docFile = GetDocFile(location.File);
 
-          /*
-          def low = Path.GetFullPath(fn).ToLower();
+        if (docFile == null)
+          null;
+        else
+          docFile.GetMemberDoc(key);
+      }
+    }
 
-          foreach (assembly in AppDomain.CurrentDomain.GetAssemblies())
+    public GetContent(member : IMember, location : Location) : string
           {
-            def cb = Path.GetFullPath(assembly.CodeBase.Replace("file:///", "")).ToLower();
-
-            def aName = assembly.GetName();
-
-            when (cb == low)
+      match (GetKey(member))
             {
-              aName.ToString();
-              break;
+      | null => null;
+      | key  => GetContent(key, location);
             }
           }
-          */
 
-          fn
-        }
-        else
+    public GetInfo(mtype : MType, location : Location) : XmlDocInfo
         {
-          location.File
+      GetInfo("T:" + mtype.TypeInfo.FullName, location);
         }
 
-        def name = Path.ChangeExtension(file, ".xml");
-
-        unless (File.Exists(name))
-          ret(null);
-
-        using (xml = XmlReader.Create(name))
+    public GetInfo(member : IMember, location : Location) : XmlDocInfo
         {
-          def reader = xml;
-          _ = reader.ToString();
-
-          _ = xml.MoveToContent();
-
-          while (xml.Read())
+      match (GetKey(member))
           {
-            match (xml.NodeType)
+      | null => null;
+      | key  => GetInfo(key, location);
+      }
+    }
+
+    public GetInfo(key : string, location : Location) : XmlDocInfo
             {
-            | XmlNodeType.Element =>
+      def content = GetContent(key, location);
 
-              when (xml.Name == "member"
-                && xml.MoveToAttribute("name")
-                && xml.Value == key)
+      if (content == null)
+        null
+      else
               {
+        def info = XmlDocInfo();
 
+        using (reader = XmlReader.Create(StringReader("<root>" + content + "</root>")))
+        {
                 def getText() 
                 {
-                  if (xml.Read())
+            if (reader.Read())
                   {
-                    match (xml.NodeType)
+              match (reader.NodeType)
                     {
-                    | XmlNodeType.Text       => xml.Value + getText()
+              | XmlNodeType.Text       => reader.Value + getText()
                     | XmlNodeType.EndElement => ""
                     | XmlNodeType.Element    =>
 
-                      def val = match (xml.Name)
+                def val = match (reader.Name)
                       {
                       | "see" =>
 
-                        if (xml.MoveToAttribute("cref"))
+                  if (reader.MoveToAttribute("cref"))
                         {
-                          def attr = xml.Value;
+                    def attr = reader.Value;
                           def text = getText();
 
                           if (string.IsNullOrEmpty(text)) attr.Substring(2) else text
@@ -133,7 +197,7 @@
                         else
                           getText()
 
-                      | _ => ""
+                | _ => string.Empty;
                       }
 
                       val + getText()
@@ -142,49 +206,38 @@
                     }
                   }
                   else
-                    ""
+              string.Empty;
                 }
 
-                def info = XmlDocInfo();
-
-                while (xml.Read())
+          while (reader.Read())
                 {
-                  match (xml.NodeType)
+            match (reader.NodeType)
                   {
-                  | XmlNodeType.Element    when xml.Name == "summary"   => info.Summary = getText()
-                  | XmlNodeType.Element    when xml.Name == "returns"   => info.Returns = getText()
-                  | XmlNodeType.Element    when xml.Name == "param"     => 
+            | XmlNodeType.Element    when reader.Name == "summary"   => info.Summary = getText()
+            | XmlNodeType.Element    when reader.Name == "returns"   => info.Returns = getText()
+            | XmlNodeType.Element    when reader.Name == "param"     => 
 
-                    if (xml.MoveToAttribute("name"))
-                      info.Params ::= (xml.Value, getText());
+              if (reader.MoveToAttribute("name"))
+                info.Params ::= (reader.Value, getText());
                     else
                       _ = getText()
 
-                  | XmlNodeType.Element    when xml.Name == "exception" => 
+            | XmlNodeType.Element    when reader.Name == "exception" => 
 
-                    if (xml.MoveToAttribute("cref"))
-                      info.Exceptions ::= (xml.Value.Substring(2), getText());
+              if (reader.MoveToAttribute("cref"))
+                info.Exceptions ::= (reader.Value.Substring(2), getText());
                     else
                       _ = getText()
 
-                  | XmlNodeType.EndElement when xml.Name == "member"    => 
-
-                    info.Params     = info.Params.    Rev();
-                    info.Exceptions = info.Exceptions.Rev();
-                    ret(info);
-
-                  | _ => ()
-                  }
-                }
-
-                ret(null);
-              }
             | _ => ()
             }
           }
         }
         
-        null
+        info.Params     = info.Params.    Rev();
+        info.Exceptions = info.Exceptions.Rev();
+
+        info;
       }
     }
   }



More information about the svn mailing list