95fdb59ea6
Former-commit-id: b39a328747c2f3414dc52e009fb6f0aa80ca2492
156 lines
6.5 KiB
C#
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;
|
|
}
|
|
}
|
|
} |