Xamarin Public Jenkins (auto-signing) 95fdb59ea6 Imported Upstream version 6.6.0.89
Former-commit-id: b39a328747c2f3414dc52e009fb6f0aa80ca2492
2019-09-24 08:53:40 +00:00

156 lines
6.5 KiB
C#

using System;
using System.IO;
using System.Linq;
using System.Xml;
using Mono.Cecil;
namespace Mono.Documentation.Updater
{
class MsxdocDocumentationImporter : DocumentationImporter
{
XmlDocument slashdocs;
public MsxdocDocumentationImporter (string file)
{
try
{
char oppositeSlash = Path.DirectorySeparatorChar == '/' ? '\\' : '/';
if (file.Contains (oppositeSlash))
file = file.Replace (oppositeSlash, Path.DirectorySeparatorChar);
var xml = File.ReadAllText (file);
// Ensure Unix line endings
xml = xml.Replace ("\r", "");
slashdocs = new XmlDocument ();
slashdocs.LoadXml (xml);
}
catch (IOException ex)
{
Console.WriteLine ($"Importer Error: {ex.Message}");
}
}
public override void ImportDocumentation (DocsNodeInfo info)
{
//first try C# compiler docIds, next other languages
XmlNode elem = GetDocs(info.Member ?? info.Type, MDocUpdater.csharpSlashdocFormatter) ??
GetDocs(info.Member ?? info.Type, MDocUpdater.msxdocxSlashdocFormatter);
if (elem == null)
return;
XmlElement e = info.Node;
if (elem.SelectSingleNode("summary") != null && DocUtils.NeedsOverwrite(e["summary"]))
MDocUpdater.ClearElement(e, "summary");
if (elem.SelectSingleNode("remarks") != null && DocUtils.NeedsOverwrite(e["remarks"]))
MDocUpdater.ClearElement(e, "remarks");
if (elem.SelectSingleNode("value") != null || elem.SelectSingleNode("returns") != null)
{
if (DocUtils.NeedsOverwrite(e["value"]))
MDocUpdater.ClearElement(e, "value");
if (DocUtils.NeedsOverwrite(e["returns"]))
MDocUpdater.ClearElement(e, "returns");
}
foreach (XmlNode child in elem.ChildNodes)
{
switch (child.Name)
{
case "param":
case "typeparam":
{
XmlAttribute name = child.Attributes["name"];
if (name == null)
break;
XmlElement p2 = (XmlElement)e.SelectSingleNode (child.Name + "[@name='" + name.Value + "']");
if (DocUtils.NeedsOverwrite(p2))
{
p2.RemoveAttribute("overwrite");
p2.InnerXml = child.InnerXml;
}
break;
}
// Occasionally XML documentation will use <returns/> on
// properties, so let's try to normalize things.
case "value":
case "returns":
{
XmlElement v = e.OwnerDocument.CreateElement (info.ReturnIsReturn ? "returns" : "value");
XmlElement p2 = (XmlElement)e.SelectSingleNode(child.Name);
if (p2 == null)
{
v.InnerXml = child.InnerXml;
e.AppendChild(v);
}
break;
}
case "altmember":
case "exception":
case "permission":
{
XmlAttribute cref = child.Attributes["cref"] ?? child.Attributes["name"];
if (cref == null)
break;
XmlElement a = (XmlElement)e.SelectSingleNode (child.Name + "[@cref='" + cref.Value + "']");
if (a == null)
{
a = e.OwnerDocument.CreateElement (child.Name);
a.SetAttribute ("cref", cref.Value);
e.AppendChild (a);
}
if(DocUtils.NeedsOverwrite(a))
a.InnerXml = child.InnerXml;
break;
}
case "seealso":
{
XmlAttribute cref = child.Attributes["cref"];
if (cref == null)
break;
XmlElement a = (XmlElement)e.SelectSingleNode ("altmember[@cref='" + cref.Value + "']");
if (a == null)
{
a = e.OwnerDocument.CreateElement ("altmember");
a.SetAttribute ("cref", cref.Value);
e.AppendChild (a);
}
break;
}
default:
{
var targetNodes = e.ChildNodes.Cast<XmlNode> ()
.Where (n => n.Name == child.Name)
.Select (n => new
{
Xml = n.OuterXml,
Overwrite = n.Attributes != null ? n.Attributes["overwrite"] : null
});
string sourceXml = child.OuterXml;
if (!targetNodes.Any (n => sourceXml.Equals (n.Xml) || n.Overwrite?.Value == "false"))
{
MDocUpdater.CopyNode(child, e);
}
break;
}
}
}
}
private XmlNode GetDocs (MemberReference member, MemberFormatter formatter)
{
string slashdocsig = formatter?.GetDeclaration (member);
if (slashdocsig != null && slashdocs != null)
return slashdocs.SelectSingleNode ("doc/members/member[@name='" + slashdocsig + "']");
return null;
}
}
}