diff options
author | Joel Martinez <joelmartinez@gmail.com> | 2014-08-03 03:44:16 +0400 |
---|---|---|
committer | Joel Martinez <joelmartinez@gmail.com> | 2014-08-03 03:48:11 +0400 |
commit | be7502c908819d3bc205c01ef65af2232676c964 (patch) | |
tree | ac590297e6bb8558acd0cc076f02056f1e71bfc9 /mcs/class/monodoc | |
parent | 59258ea3f09a563a39a2fbc06842471c78a819b7 (diff) |
[monodoc] Changes to support new-style iOS documentation:
- Fixed bug in creating CREF strings.
- Refactored XML file processing for customization during new style iOS assembly. This was done through the new file source interface, which lets you use dependency injection to customize the process.
- Added the ability to rewrite CREF references when assembling docs that use native types. Also, the ability to handle dropped namespaces.
Diffstat (limited to 'mcs/class/monodoc')
-rw-r--r-- | mcs/class/monodoc/Monodoc.Ecma/EcmaDesc.cs | 47 | ||||
-rw-r--r-- | mcs/class/monodoc/Monodoc/cache.cs | 4 | ||||
-rw-r--r-- | mcs/class/monodoc/Monodoc/providers/EcmaDoc.cs | 72 | ||||
-rw-r--r-- | mcs/class/monodoc/Monodoc/providers/ecma-provider.cs | 78 |
4 files changed, 151 insertions, 50 deletions
diff --git a/mcs/class/monodoc/Monodoc.Ecma/EcmaDesc.cs b/mcs/class/monodoc/Monodoc.Ecma/EcmaDesc.cs index c16645971de..3d1e8c92c3f 100644 --- a/mcs/class/monodoc/Monodoc.Ecma/EcmaDesc.cs +++ b/mcs/class/monodoc/Monodoc.Ecma/EcmaDesc.cs @@ -86,6 +86,13 @@ namespace Monodoc.Ecma set; } + /* The GenericTypeArguments list may be null, in which case, this + * is an easier/safer way to check the count. + */ + public int GenericTypeArgumentsCount { + get { return GenericTypeArguments != null ? GenericTypeArguments.Count : 0; } + } + /* This property tells if the above collections only correct value * is the number of item in it to represent generic arguments */ @@ -100,6 +107,13 @@ namespace Monodoc.Ecma set; } + /* The GenericMemberArguments list may be null, in which case, this + * is an easier/safer way to check the count. + */ + public int GenericMemberArgumentsCount { + get { return GenericMemberArguments != null ? GenericMemberArguments.Count : 0; } + } + public bool GenericMemberArgumentsIsNumeric { get { return GenericMemberArguments != null && GenericMemberArguments.FirstOrDefault () == null; @@ -111,6 +125,13 @@ namespace Monodoc.Ecma set; } + /* The GenericTypeArguments list may be null, in which case, this + * is an easier/safer way to check the count. + */ + public int MemberArgumentsCount { + get { return MemberArguments != null ? MemberArguments.Count : 0; } + } + /* This indicates that we actually want an inner part of the ecmadesc * i.e. in case of T: we could want the members (*), ctor (C), methods (M), ... */ @@ -198,6 +219,7 @@ namespace Monodoc.Ecma var sb = new StringBuilder (); // Cref type sb.Append (DescKind.ToString ()[0]); + sb.Append (":"); // Create the rest ConstructCRef (sb); @@ -214,8 +236,15 @@ namespace Monodoc.Ecma sb.Append (TypeName); if (GenericTypeArguments != null) { sb.Append ('<'); - foreach (var t in GenericTypeArguments) + int i=0; + foreach (var t in GenericTypeArguments) { + if (i > 0) { + sb.Append (","); + } t.ConstructCRef (sb); + + i++; + } sb.Append ('>'); } if (NestedType != null) { @@ -232,8 +261,20 @@ namespace Monodoc.Ecma if (DescKind == Kind.Type) return; - if (MemberArguments != null) { - + sb.Append ("."); + sb.Append (MemberName); + + if (MemberArguments != null && MemberArgumentsCount > 0) { + sb.Append ("("); + int i=0; + foreach (var a in MemberArguments) { + if (i > 0) { + sb.Append(","); + } + a.ConstructCRef (sb); + i++; + } + sb.Append (")"); } } diff --git a/mcs/class/monodoc/Monodoc/cache.cs b/mcs/class/monodoc/Monodoc/cache.cs index 98291a4c031..f10320230db 100644 --- a/mcs/class/monodoc/Monodoc/cache.cs +++ b/mcs/class/monodoc/Monodoc/cache.cs @@ -35,7 +35,9 @@ namespace Monodoc static DocCacheHelper () { try { - var cacheValues = Config.Get ("cache").Split (','); + var cacheConfig = Config.Get ("cache"); + if (cacheConfig == null) return; + var cacheValues = cacheConfig.Split (','); if (cacheValues.Length == 2 && cacheValues[0].Equals ("file", StringComparison.Ordinal)) cacheBaseDirectory = cacheValues[1].Replace ("~", Environment.GetFolderPath (Environment.SpecialFolder.Personal)); } catch {} diff --git a/mcs/class/monodoc/Monodoc/providers/EcmaDoc.cs b/mcs/class/monodoc/Monodoc/providers/EcmaDoc.cs index efdeedf63a6..08ef203ed97 100644 --- a/mcs/class/monodoc/Monodoc/providers/EcmaDoc.cs +++ b/mcs/class/monodoc/Monodoc/providers/EcmaDoc.cs @@ -18,6 +18,8 @@ namespace Monodoc.Providers Meta, // A node that's here to serve as a header for other node } + + // Common functionality between ecma-provider and ecmauncompiled-provider internal class EcmaDoc { @@ -28,8 +30,10 @@ namespace Monodoc.Providers Tree tree, IDocStorage storage, Dictionary<string, XElement> nsSummaries, - Func<XElement, string> indexGenerator = null) + Func<XElement, string> indexGenerator = null, + IEcmaProviderFileSource fileSource = null) { + fileSource = fileSource ?? DefaultEcmaProviderFileSource.Default; var root = tree.RootNode; int resID = 0; var asm = Path.GetDirectoryName (indexFilePath); @@ -40,7 +44,7 @@ namespace Monodoc.Providers // default index generator uses a counter indexGenerator = indexGenerator ?? (_ => resID++.ToString ()); - using (var reader = XmlReader.Create (File.OpenRead (indexFilePath))) { + using (var reader = fileSource.GetIndexReader (indexFilePath)) { reader.ReadToFollowing ("Types"); var types = XElement.Load (reader.ReadSubtree ()); @@ -55,26 +59,34 @@ namespace Monodoc.Providers new XElement ("summary"), new XElement ("remarks")); //Add namespace summary and remarks data from file, if available - var nsFileName = Path.Combine(asm, String.Format("ns-{0}.xml", nsName)); + var nsFileName = fileSource.GetNamespaceXmlPath(asm, nsName); + if(File.Exists(nsFileName)){ - var nsEl = XElement.Load (nsFileName); + var nsEl = fileSource.GetNamespaceElement (nsFileName); nsElements.Element ("summary").ReplaceWith (nsEl.Descendants ("summary").First ()); nsElements.Element ("remarks").ReplaceWith (nsEl.Descendants ("remarks").First ()); }else{ - Console.WriteLine ("Error reading namespace XML for " + nsName); + Console.WriteLine ("Error reading namespace XML for {0} at {1}", nsName, nsFileName); } foreach (var type in ns.Elements ("Type")) { // Add the XML file corresponding to the type to our storage var id = indexGenerator (type); string typeFilePath; - var typeDocument = EcmaDoc.LoadTypeDocument (asm, nsName, type.Attribute ("Name").Value, out typeFilePath); + var typeDocument = EcmaDoc.LoadTypeDocument (asm, nsName, type.Attribute ("Name").Value, out typeFilePath, fileSource); if (typeDocument == null) continue; - using (var file = File.OpenRead (typeFilePath)) - storage.Store (id, file); - nsElements.Add (ExtractClassSummary (typeFilePath)); + + // write the document (which may have been modified by the fileSource) to the storage + MemoryStream io = new MemoryStream (); + using (var writer = XmlWriter.Create (io)) { + typeDocument.WriteTo (writer); + } + io.Seek (0, SeekOrigin.Begin); + storage.Store (id, io); + + nsElements.Add (ExtractClassSummary (typeDocument)); var typeCaption = EcmaDoc.GetTypeCaptionFromIndex (type); var url = idPrefix + id + '#' + typeCaption + '/'; @@ -123,15 +135,17 @@ namespace Monodoc.Providers // Utility methods - public static XDocument LoadTypeDocument (string basePath, string nsName, string typeName) + public static XDocument LoadTypeDocument (string basePath, string nsName, string typeName, IEcmaProviderFileSource fileSource = null) { string dummy; - return LoadTypeDocument (basePath, nsName, typeName, out dummy); + return LoadTypeDocument (basePath, nsName, typeName, out dummy, fileSource ?? DefaultEcmaProviderFileSource.Default); } - public static XDocument LoadTypeDocument (string basePath, string nsName, string typeName, out string finalPath) + public static XDocument LoadTypeDocument (string basePath, string nsName, string typeName, out string finalPath, IEcmaProviderFileSource fileSource = null) { - finalPath = Path.Combine (basePath, nsName, Path.ChangeExtension (typeName, ".xml")); + fileSource = fileSource ?? DefaultEcmaProviderFileSource.Default; + + finalPath = fileSource.GetTypeXmlPath (basePath, nsName, typeName); if (!File.Exists (finalPath)) { Console.Error.WriteLine ("Warning: couldn't process type file `{0}' as it doesn't exist", finalPath); return null; @@ -139,7 +153,7 @@ namespace Monodoc.Providers XDocument doc = null; try { - doc = XDocument.Load (finalPath); + doc = fileSource.GetTypeDocument(finalPath); } catch (Exception e) { Console.WriteLine ("Document `{0}' is unparsable, {1}", finalPath, e.ToString ()); } @@ -562,24 +576,20 @@ namespace Monodoc.Providers return nicename; } - static XElement ExtractClassSummary (string typeFilePath) + static XElement ExtractClassSummary (XDocument typeDoc) { - using (var reader = XmlReader.Create (typeFilePath)) { - reader.ReadToFollowing ("Type"); - var name = reader.GetAttribute ("Name"); - var fullName = reader.GetAttribute ("FullName"); - reader.ReadToFollowing ("AssemblyName"); - var assemblyName = reader.ReadElementString (); - var summary = reader.ReadToFollowing ("summary") ? XElement.Load (reader.ReadSubtree ()) : new XElement ("summary"); - var remarks = reader.ReadToFollowing ("remarks") ? XElement.Load (reader.ReadSubtree ()) : new XElement ("remarks"); - - return new XElement ("class", - new XAttribute ("name", name ?? string.Empty), - new XAttribute ("fullname", fullName ?? string.Empty), - new XAttribute ("assembly", assemblyName ?? string.Empty), - summary, - remarks); - } + string name = typeDoc.Root.Attribute("Name").Value; + string fullName = typeDoc.Root.Attribute("FullName").Value; + string assemblyName = typeDoc.Root.Element("AssemblyInfo") != null ? typeDoc.Root.Element("AssemblyInfo").Element("AssemblyName").Value : string.Empty; + var docs = typeDoc.Root.Element("Docs"); + var summary = docs.Element("summary") ?? new XElement("summary"); + var remarks = docs.Element("remarks") ?? new XElement("remarks"); + return new XElement ("class", + new XAttribute ("name", name ?? string.Empty), + new XAttribute ("fullname", fullName ?? string.Empty), + new XAttribute ("assembly", assemblyName ?? string.Empty), + summary, + remarks); } } } diff --git a/mcs/class/monodoc/Monodoc/providers/ecma-provider.cs b/mcs/class/monodoc/Monodoc/providers/ecma-provider.cs index 53e54c4310b..4e82c2c7668 100644 --- a/mcs/class/monodoc/Monodoc/providers/ecma-provider.cs +++ b/mcs/class/monodoc/Monodoc/providers/ecma-provider.cs @@ -25,9 +25,60 @@ using Mono.Utilities; namespace Monodoc.Providers { + public interface IEcmaProviderFileSource { + XmlReader GetIndexReader(string path); + XDocument GetTypeDocument(string path); + XElement GetNamespaceElement(string path); + string GetTypeXmlPath(string basePath, string nsName, string typeName); + string GetNamespaceXmlPath(string basePath, string ns); + XElement ExtractNamespaceSummary (string path); + } + + internal class DefaultEcmaProviderFileSource : IEcmaProviderFileSource { + public static readonly IEcmaProviderFileSource Default = new DefaultEcmaProviderFileSource(); + + public XmlReader GetIndexReader(string path) { + return XmlReader.Create (File.OpenRead (path)); + } + + public XElement GetNamespaceElement(string path) { + return XElement.Load (path); + } + + public string GetTypeXmlPath(string basePath, string nsName, string typeName) { + string finalPath = Path.Combine (basePath, nsName, Path.ChangeExtension (typeName, ".xml")); + return finalPath; + } + + public XDocument GetTypeDocument(string path) { + return XDocument.Load (path); + } + + public string GetNamespaceXmlPath(string basePath, string ns) { + string finalPath = Path.Combine(basePath, String.Format("ns-{0}.xml", ns)); + return finalPath; + } + + public XElement ExtractNamespaceSummary (string path) + { + using (var reader = XmlReader.Create (path)) { + reader.ReadToFollowing ("Namespace"); + var name = reader.GetAttribute ("Name"); + var summary = reader.ReadToFollowing ("summary") ? XElement.Load (reader.ReadSubtree ()) : new XElement ("summary"); + var remarks = reader.ReadToFollowing ("remarks") ? XElement.Load (reader.ReadSubtree ()) : new XElement ("remarks"); + + return new XElement ("namespace", + new XAttribute ("ns", name ?? string.Empty), + summary, + remarks); + } + } + } + public class EcmaProvider : Provider { HashSet<string> directories = new HashSet<string> (); + IEcmaProviderFileSource fileSource; public EcmaProvider () { @@ -38,6 +89,16 @@ namespace Monodoc.Providers AddDirectory (baseDir); } + public IEcmaProviderFileSource FileSource { + get { + if (fileSource == null) { + fileSource = new DefaultEcmaProviderFileSource(); + } + return fileSource; + } + set { fileSource = value; } + } + public void AddDirectory (string directory) { if (string.IsNullOrEmpty (directory)) @@ -59,7 +120,7 @@ namespace Monodoc.Providers continue; } - EcmaDoc.PopulateTreeFromIndexFile (indexFilePath, EcmaHelpSource.EcmaPrefix, tree, storage, nsSummaries, _ => resID++.ToString ()); + EcmaDoc.PopulateTreeFromIndexFile (indexFilePath, EcmaHelpSource.EcmaPrefix, tree, storage, nsSummaries, _ => resID++.ToString (), FileSource); } foreach (var summary in nsSummaries) @@ -68,24 +129,11 @@ namespace Monodoc.Providers var masterSummary = new XElement ("elements", directories .SelectMany (d => Directory.EnumerateFiles (d, "ns-*.xml")) - .Select (ExtractNamespaceSummary)); + .Select (FileSource.ExtractNamespaceSummary)); storage.Store ("mastersummary.xml", masterSummary.ToString ()); } - XElement ExtractNamespaceSummary (string nsFile) - { - using (var reader = XmlReader.Create (nsFile)) { - reader.ReadToFollowing ("Namespace"); - var name = reader.GetAttribute ("Name"); - var summary = reader.ReadToFollowing ("summary") ? XElement.Load (reader.ReadSubtree ()) : new XElement ("summary"); - var remarks = reader.ReadToFollowing ("remarks") ? XElement.Load (reader.ReadSubtree ()) : new XElement ("remarks"); - return new XElement ("namespace", - new XAttribute ("ns", name ?? string.Empty), - summary, - remarks); - } - } public override void CloseTree (HelpSource hs, Tree tree) { |