You've already forked linux-packaging-mono
Imported Upstream version 6.6.0.89
Former-commit-id: b39a328747c2f3414dc52e009fb6f0aa80ca2492
This commit is contained in:
parent
cf815e07e0
commit
95fdb59ea6
228
external/api-doc-tools/tools/DocStat/DocStat/CommandUtils.cs
vendored
Normal file
228
external/api-doc-tools/tools/DocStat/DocStat/CommandUtils.cs
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Mono.Options;
|
||||
|
||||
namespace DocStat
|
||||
{
|
||||
public static class CommandUtils
|
||||
{
|
||||
public static List<string> ProcessFileArgs(IEnumerable<string> args,
|
||||
ref string rootdir,
|
||||
ref string omitlist,
|
||||
ref string processlist,
|
||||
ref string pattern)
|
||||
{
|
||||
// Take that, compiler!
|
||||
string _rd = "";
|
||||
string _ol = "";
|
||||
string _pl = "";
|
||||
string _pa = "";
|
||||
|
||||
List<string> extras;
|
||||
|
||||
var opt = new OptionSet {
|
||||
|
||||
{ "d|dir|directory=",
|
||||
(string d) => _rd = d },
|
||||
// Provide a file that contains a list of files to omit. User may use more than one -o
|
||||
{ "e|exceptlist=",
|
||||
(m) => _ol = m },
|
||||
// List a file that contains a list of files to process
|
||||
{ "p|processlist=",
|
||||
(f) => _pl = f},
|
||||
{ "n|namematches=",
|
||||
(n) => _pa = n }
|
||||
};
|
||||
extras = opt.Parse(args);
|
||||
|
||||
// And that!
|
||||
rootdir = String.IsNullOrEmpty(_rd) ? rootdir : _rd;
|
||||
omitlist = String.IsNullOrEmpty(_ol) ? omitlist : _ol;
|
||||
processlist =String.IsNullOrEmpty(_pl) ? processlist : _pl;
|
||||
pattern = String.IsNullOrEmpty(_pa) ? pattern : _pa;
|
||||
|
||||
return extras;
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetFileList(string processListFileName,
|
||||
string omitListFileName,
|
||||
string rootDir,
|
||||
string pattern,
|
||||
bool recurse = true,
|
||||
bool skipNsAndIndex = true)
|
||||
{
|
||||
IEnumerable<string> toProcess = Enumerable.Empty<string>();
|
||||
|
||||
// Build search predicates
|
||||
Func<string, bool> fileMatches;
|
||||
Func<string, bool> omitFile;
|
||||
|
||||
if (!String.IsNullOrEmpty(pattern))
|
||||
{
|
||||
Regex fm = new Regex(pattern);
|
||||
fileMatches = fm.IsMatch;
|
||||
}
|
||||
else
|
||||
{
|
||||
fileMatches = (string s) => true;
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(omitListFileName))
|
||||
{
|
||||
omitFile = (string s) => false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (File.Exists(omitListFileName))
|
||||
{
|
||||
IEnumerable<string> toOmit = FileNamesIn(omitListFileName);
|
||||
omitFile = toOmit.Contains;
|
||||
}
|
||||
else
|
||||
throw new ArgumentException("Omission file does not exist: " + omitListFileName);
|
||||
}
|
||||
|
||||
// Process any user-supplied file lists
|
||||
if (!String.IsNullOrEmpty(processListFileName))
|
||||
{
|
||||
if (File.Exists(processListFileName))
|
||||
{
|
||||
toProcess = toProcess.Union(
|
||||
FileNamesIn(processListFileName)
|
||||
.Where((p) => fileMatches(Path.GetFileName(p)) && !omitFile(p)));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new FileNotFoundException("Process list file does not exist: " + processListFileName);
|
||||
}
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(rootDir) && !String.IsNullOrEmpty(processListFileName))
|
||||
return toProcess; // they gave us a list only, so they're happy
|
||||
|
||||
if (String.IsNullOrEmpty(rootDir))
|
||||
rootDir = Directory.GetCurrentDirectory(); // no list or rootdir, so they want the default
|
||||
|
||||
if (!Directory.Exists(rootDir)) //They gave us something, but it was a boo-boo
|
||||
throw new ArgumentException("The provided root directory was required and does not exist: " + rootDir);
|
||||
|
||||
// We have a good root directory, and we want to use it.
|
||||
|
||||
Func<string, bool> isNsOrIndex;
|
||||
|
||||
if (skipNsAndIndex)
|
||||
{
|
||||
isNsOrIndex = (string fName) => {
|
||||
string barename = Path.GetFileName(fName);
|
||||
return barename.StartsWith("ns-") || barename.StartsWith("index");
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
isNsOrIndex = (string arg) => false;
|
||||
}
|
||||
return toProcess.Union(Directory.GetFiles(rootDir,
|
||||
"*.xml",
|
||||
recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly))
|
||||
.Where(p => fileMatches(Path.GetFileName(p)) && !omitFile(p) && !isNsOrIndex(p));
|
||||
|
||||
}
|
||||
|
||||
public static void ThrowOnFiniteExtras(List<string> extras)
|
||||
{
|
||||
if (extras.Count > 1)
|
||||
{
|
||||
StringBuilder s = new StringBuilder("The following options were not recoginzed:\n");
|
||||
List<string> sl = new List<string>();
|
||||
for (int i = 1; i < extras.Count; i++)
|
||||
{
|
||||
sl.Add(extras[i]);
|
||||
}
|
||||
s.Append(String.Join("\n", sl));
|
||||
throw new Exception(s.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static XmlDocument ToXmlDocument(XDocument xDocument)
|
||||
{
|
||||
var xmlDocument = new XmlDocument();
|
||||
using (var reader = xDocument.CreateReader())
|
||||
{
|
||||
xmlDocument.Load(reader);
|
||||
}
|
||||
|
||||
var xDeclaration = xDocument.Declaration;
|
||||
if (xDeclaration != null)
|
||||
{
|
||||
var xmlDeclaration = xmlDocument.CreateXmlDeclaration(
|
||||
xDeclaration.Version,
|
||||
xDeclaration.Encoding,
|
||||
xDeclaration.Standalone);
|
||||
xmlDocument.InsertBefore(xmlDeclaration, xmlDocument.FirstChild);
|
||||
}
|
||||
|
||||
return xmlDocument;
|
||||
}
|
||||
|
||||
public static void WriteXDocument(XDocument xdoc, string file)
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
throw new FileNotFoundException("File not found: " + file);
|
||||
|
||||
XmlDocument xmldoc = CommandUtils.ToXmlDocument(xdoc);
|
||||
TextWriter xdout = new StreamWriter(file);
|
||||
// Write back
|
||||
XmlTextWriter writer = new XmlTextWriter(xdout)
|
||||
{
|
||||
Formatting = Formatting.Indented,
|
||||
IndentChar = ' ',
|
||||
Indentation = 2
|
||||
};
|
||||
xmldoc.WriteTo(writer);
|
||||
xdout.WriteLine();
|
||||
xdout.Flush();
|
||||
}
|
||||
|
||||
private static IEnumerable<string> FileNamesIn(string fileListPath)
|
||||
{
|
||||
return File.ReadLines(fileListPath)
|
||||
.Where(s =>
|
||||
!String.IsNullOrEmpty(s) &&
|
||||
Uri.IsWellFormedUriString(s, UriKind.Absolute) &&
|
||||
File.Exists(s)
|
||||
);
|
||||
}
|
||||
|
||||
public static string CSVFormatString(int numColumns, int[] order = null)
|
||||
{
|
||||
if (null != order && order.Length != numColumns)
|
||||
throw new ArgumentException(String.Format("Column order array had {0} entries, but {1} columns are needed.",
|
||||
order.Length.ToString(),
|
||||
numColumns.ToString()));
|
||||
Func<int, int> indexFor = null;
|
||||
|
||||
if (null != order)
|
||||
{
|
||||
indexFor = (int i) => order[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
indexFor = (int i) => i;
|
||||
}
|
||||
|
||||
string[] cols = new string[numColumns];
|
||||
|
||||
for (int i = 0; i < numColumns; i++)
|
||||
cols[i] = "\"{" + indexFor(i) + "}\"";
|
||||
|
||||
return String.Join(",", cols);
|
||||
}
|
||||
}
|
||||
}
|
||||
49
external/api-doc-tools/tools/DocStat/DocStat/DocStat.csproj
vendored
Normal file
49
external/api-doc-tools/tools/DocStat/DocStat/DocStat.csproj
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProjectGuid>{EF899D5E-28F7-4CEE-A47A-80C4B4995B81}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>DocStat</RootNamespace>
|
||||
<AssemblyName>DocStat</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug</OutputPath>
|
||||
<DefineConstants>DEBUG;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="apistat.cs" />
|
||||
<Compile Include="CommandUtils.cs" />
|
||||
<Compile Include="comparefix.cs" />
|
||||
<Compile Include="internalize.cs" />
|
||||
<Compile Include="obsolete.cs" />
|
||||
<Compile Include="EcmaXmlHelper.cs" />
|
||||
<Compile Include="remaining.cs" />
|
||||
<Compile Include="..\..\..\mdoc\Options.cs">
|
||||
<Link>Options.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="comparereport.cs" />
|
||||
<Compile Include="fixsummaries.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
220
external/api-doc-tools/tools/DocStat/DocStat/EcmaXmlHelper.cs
vendored
Normal file
220
external/api-doc-tools/tools/DocStat/DocStat/EcmaXmlHelper.cs
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace DocStat
|
||||
{
|
||||
public static class EcmaXmlHelper
|
||||
{
|
||||
public static void Fix(XElement toFix, XElement forReference)
|
||||
{
|
||||
if (null == forReference)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (XNode.DeepEquals(toFix, forReference))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
toFix.ReplaceWith(forReference);
|
||||
}
|
||||
|
||||
// Sometimes, the identifying attribute lives in a child. This means that
|
||||
// we need to return a predicate that finds the piece to match.
|
||||
// So:
|
||||
// Return a function that takes an XElement with a known unique identifier
|
||||
// and return a predicate that gets the XAttribute that identifies it
|
||||
public static Func<XElement, XAttribute> IdentifyingAttributePredicateFor(XElement el)
|
||||
{
|
||||
switch (el.Name.ToString())
|
||||
{
|
||||
case "typeparam":
|
||||
case "param":
|
||||
return (XElement e) => e.Attribute("name");
|
||||
case "Member":
|
||||
// The ILAsm signature is unique, and always present
|
||||
return (XElement e) => e.Elements("MemberSignature")
|
||||
.First((a) => a.Attribute("Language").Value == "ILAsm")
|
||||
.Attribute("Value");
|
||||
case "related":
|
||||
return (XElement e) => e.Attribute("href"); ;
|
||||
default:
|
||||
throw new Exception("Encountered plural node of type " + el.Name);
|
||||
}
|
||||
}
|
||||
|
||||
// Walk the hierarchy to get a selector that can be used to find the current element
|
||||
// This selector can then be used on the parallel XDocument to retrieve the equivalent
|
||||
// XElement. The selector returns null early if any selector returns null
|
||||
public static Func<XDocument, XElement> GetSelectorFor(XElement toSelect)
|
||||
{
|
||||
List<Func<XElement, XElement>> toRun = new List<Func<XElement, XElement>>();
|
||||
|
||||
XElement current = toSelect;
|
||||
Func<XElement, XElement> selector;
|
||||
|
||||
while (current.Parent != null)
|
||||
{
|
||||
XName currentName = current.Name;
|
||||
if (current.Parent.Elements(currentName).Count() > 1)
|
||||
{
|
||||
// Function that finds the element-specific unique attribute.
|
||||
Func<XElement, XAttribute> uniquePredicate
|
||||
= IdentifyingAttributePredicateFor(current);
|
||||
|
||||
// Get the unique attribute value in *this* xml tree.
|
||||
// (We know this exists.)
|
||||
string uniqueAttr = uniquePredicate(current).Value;
|
||||
|
||||
selector = (XElement arg) => arg.Elements(currentName)
|
||||
.FirstOrDefault((XElement a) =>
|
||||
uniquePredicate(a).Value == uniqueAttr);
|
||||
}
|
||||
else
|
||||
{
|
||||
selector = (XElement arg) => arg.Element(currentName);
|
||||
}
|
||||
|
||||
toRun.Add(selector);
|
||||
current = current.Parent;
|
||||
}
|
||||
|
||||
return (XDocument doc) =>
|
||||
{
|
||||
XElement _current = doc.Root;
|
||||
|
||||
foreach (var _selector in ((IEnumerable<Func<XElement, XElement>>)toRun).Reverse())
|
||||
{
|
||||
|
||||
_current = _selector(_current);
|
||||
|
||||
if (_current == null)
|
||||
return null;
|
||||
}
|
||||
return _current;
|
||||
};
|
||||
}
|
||||
|
||||
public static string GetParallelFilePathFor(string pathToTypeToFix,
|
||||
string rootOfReferenceFiles,
|
||||
string rootOfFilesToFix,
|
||||
Func<string, string> referenceRootTransform = null,
|
||||
Func<string, string> referencePathTransform = null)
|
||||
{
|
||||
|
||||
string fullFixPath = Path.GetFullPath(pathToTypeToFix);
|
||||
|
||||
string fullFixRoot = Path.GetFullPath(rootOfFilesToFix);
|
||||
|
||||
rootOfReferenceFiles =
|
||||
null == referenceRootTransform ? rootOfReferenceFiles : referenceRootTransform(rootOfReferenceFiles);
|
||||
string fullRefRoot = Path.GetFullPath(rootOfReferenceFiles);
|
||||
|
||||
string fullReferencePath = fullFixPath.Replace(fullFixRoot, fullRefRoot);
|
||||
|
||||
fullReferencePath =
|
||||
null == referencePathTransform ? fullReferencePath : referencePathTransform(fullReferencePath);
|
||||
return fullReferencePath;
|
||||
}
|
||||
|
||||
public static XDocument GetParallelXDocFor(string parallelFilePath,
|
||||
HashSet<string> refPaths = null)
|
||||
{
|
||||
|
||||
if (!File.Exists(parallelFilePath))
|
||||
return null;
|
||||
|
||||
if ((null != refPaths) && !refPaths.Contains(parallelFilePath))
|
||||
return null;
|
||||
|
||||
return XDocument.Load(parallelFilePath);
|
||||
}
|
||||
|
||||
public static IEnumerable<XElement> ElementsOfInterest(XDocument ecmaXmlDoc)
|
||||
{
|
||||
// (1) Yield type-level summary and remarks:
|
||||
yield return ecmaXmlDoc.Element("Type").Element("Docs").Element("summary");
|
||||
|
||||
yield return ecmaXmlDoc.Element("Type").Element("Docs").Element("remarks");
|
||||
|
||||
|
||||
var members = ecmaXmlDoc.Element("Type").Element("Members");
|
||||
|
||||
if (null != members)
|
||||
{
|
||||
|
||||
foreach (XElement m in members.Elements())
|
||||
{
|
||||
// (2) Yield summary, remarks, return values, parameters, and typeparams
|
||||
XElement docsElement = m.Element("Docs");
|
||||
|
||||
yield return docsElement.Element("summary");
|
||||
|
||||
|
||||
XElement remarks = docsElement.Element("remarks");
|
||||
if (null != remarks)
|
||||
yield return remarks;
|
||||
|
||||
XElement returns = docsElement.Element("returns");
|
||||
if (null != returns)
|
||||
yield return returns;
|
||||
|
||||
if (docsElement.Elements("param").Any())
|
||||
{
|
||||
IEnumerable<XElement> _params = docsElement.Elements("param");
|
||||
foreach (XElement p in _params)
|
||||
{
|
||||
yield return p;
|
||||
}
|
||||
}
|
||||
|
||||
if (docsElement.Elements("typeparam").Any())
|
||||
{
|
||||
IEnumerable<XElement> typeparams = docsElement.Elements("typeparam");
|
||||
foreach (XElement p in typeparams)
|
||||
{
|
||||
yield return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<XElement> Members(XDocument ecmaXmlDoc)
|
||||
{
|
||||
var members = ecmaXmlDoc.Element("Type").Element("Members");
|
||||
if (null != members)
|
||||
{
|
||||
foreach (var m in members.Elements("Member"))
|
||||
yield return m;
|
||||
}
|
||||
yield break;
|
||||
}
|
||||
|
||||
public static IEnumerable<XElement> NewMembers(XDocument newXml, XDocument oldXml)
|
||||
{
|
||||
|
||||
if (null == Members(newXml))
|
||||
{ yield break; }
|
||||
if (null == oldXml)
|
||||
{
|
||||
|
||||
foreach (var e in Members(newXml))
|
||||
yield return e;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var e in Members(newXml))
|
||||
{
|
||||
if (null == GetSelectorFor(e)(oldXml))
|
||||
yield return e;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
82
external/api-doc-tools/tools/DocStat/DocStat/apistat.cs
vendored
Normal file
82
external/api-doc-tools/tools/DocStat/DocStat/apistat.cs
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Mono.Options;
|
||||
|
||||
|
||||
namespace DocStat
|
||||
{
|
||||
public class apistat
|
||||
{
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
apistat a = new apistat();
|
||||
try
|
||||
{
|
||||
a.Run(args);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
Console.Error.WriteLine("apistat: {0}", e.Message);
|
||||
Environment.ExitCode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
internal Dictionary<string, ApiCommand> subcommands;
|
||||
|
||||
private void Run (string[] args) {
|
||||
subcommands = new Dictionary<string, ApiCommand>() {
|
||||
{"internalize", new InternalizeCommand() },
|
||||
{"remaining", new RemainingCommand() },
|
||||
{"obsolete", new ObsoleteCommand() },
|
||||
{"comparefix", new CompareFixCommand()},
|
||||
{"reportnew", new CompareReportCommand()},
|
||||
{"fixsummaries", new FixSummariesCommand()}
|
||||
};
|
||||
|
||||
GetCommand(args.First()).Run(args);
|
||||
}
|
||||
internal ApiCommand GetCommand(string command)
|
||||
{
|
||||
ApiCommand a;
|
||||
if (!subcommands.TryGetValue(command, out a))
|
||||
{
|
||||
throw new Exception(String.Format("Unknown command: {0}.", command));
|
||||
}
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class ApiCommand {
|
||||
|
||||
public abstract void Run(IEnumerable<string> args);
|
||||
|
||||
protected List<string> Parse(OptionSet p, IEnumerable<string> args,
|
||||
string command, string prototype, string description)
|
||||
{
|
||||
bool showHelp = false;
|
||||
p.Add("h|?|help",
|
||||
"Show this message and exit.",
|
||||
v => showHelp = v != null);
|
||||
|
||||
List<string> extra = null;
|
||||
if (args != null)
|
||||
{
|
||||
extra = p.Parse(args.Skip(1));
|
||||
}
|
||||
if (args == null || showHelp)
|
||||
{
|
||||
Console.WriteLine("usage: mdoc {0} {1}",
|
||||
args == null ? command : args.First(), prototype);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(description);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Available Options:");
|
||||
p.WriteOptionDescriptions(Console.Out);
|
||||
return null;
|
||||
}
|
||||
return extra;
|
||||
}
|
||||
}
|
||||
}
|
||||
96
external/api-doc-tools/tools/DocStat/DocStat/comparefix.cs
vendored
Normal file
96
external/api-doc-tools/tools/DocStat/DocStat/comparefix.cs
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Mono.Options;
|
||||
|
||||
namespace DocStat
|
||||
{
|
||||
public class CompareFixCommand : ApiCommand
|
||||
{
|
||||
|
||||
public override void Run(IEnumerable<string> args)
|
||||
{
|
||||
string filesToFixDir = "";
|
||||
string omitlist = "";
|
||||
string processlist = "";
|
||||
string pattern = "";
|
||||
|
||||
List<string> extras = CommandUtils.ProcessFileArgs(args,
|
||||
ref filesToFixDir,
|
||||
ref omitlist,
|
||||
ref processlist,
|
||||
ref pattern);
|
||||
// must have
|
||||
string filesToUseAsRefDir = "";
|
||||
// should have
|
||||
bool doSummaries = true;
|
||||
bool doParameters = true;
|
||||
bool doReturns = true;
|
||||
bool doRemarks = true;
|
||||
bool doTypes = true;
|
||||
// nice to have
|
||||
bool dryRun = false;
|
||||
bool reportChanges = false;
|
||||
|
||||
var opts = new OptionSet {
|
||||
{"f|fix=", (f) => filesToFixDir = f},
|
||||
{"u|using=", (u) => filesToUseAsRefDir = u},
|
||||
{"s|summaries", (s) => doSummaries = s != null},
|
||||
{"a|params", (p) => doParameters = p != null },
|
||||
{"r|retvals", (r) => doReturns = r != null },
|
||||
{"m|remarks", (r) => doRemarks = r != null },
|
||||
{"t|typesummaries", (t) => doTypes = t != null },
|
||||
{"y|dryrun", (d) => dryRun = d != null },
|
||||
{"c|reportchanges", (c) => reportChanges = c != null },
|
||||
};
|
||||
|
||||
extras = opts.Parse(extras);
|
||||
CommandUtils.ThrowOnFiniteExtras(extras);
|
||||
if (String.IsNullOrEmpty(filesToUseAsRefDir))
|
||||
throw new ArgumentException("You must supply a parallel directory from which to source new content with '[u|using]'=.");
|
||||
|
||||
|
||||
IEnumerable<string> filesToFix = CommandUtils.GetFileList(processlist, omitlist, filesToFixDir, pattern);
|
||||
HashSet<string> filesToUseAsReference = new HashSet<string>(CommandUtils.GetFileList("", "", filesToUseAsRefDir, ""));
|
||||
|
||||
filesToFix =
|
||||
filesToFix.Where((f) =>
|
||||
filesToUseAsReference.Contains(EcmaXmlHelper.GetParallelFilePathFor(f,
|
||||
filesToUseAsRefDir,
|
||||
filesToFixDir)));
|
||||
|
||||
|
||||
foreach (var f in filesToFix)
|
||||
{
|
||||
XDocument currentRefXDoc = EcmaXmlHelper.GetParallelXDocFor(
|
||||
EcmaXmlHelper.GetParallelFilePathFor(f, filesToUseAsRefDir, filesToFixDir),
|
||||
filesToUseAsReference
|
||||
);
|
||||
|
||||
if (null == currentRefXDoc)
|
||||
continue;
|
||||
|
||||
Action<XElement> fix =
|
||||
(XElement e) => EcmaXmlHelper.Fix(e, EcmaXmlHelper.GetSelectorFor(e)(currentRefXDoc));
|
||||
|
||||
bool changed = false;
|
||||
XDocument currentXDocToFix = XDocument.Load(f);
|
||||
|
||||
EventHandler<XObjectChangeEventArgs> SetTrueIfChanged = null;
|
||||
SetTrueIfChanged =
|
||||
new EventHandler<XObjectChangeEventArgs>((sender, e) => { currentXDocToFix.Changed -= SetTrueIfChanged; changed = true; });
|
||||
currentXDocToFix.Changed += SetTrueIfChanged;
|
||||
|
||||
foreach (XElement e in EcmaXmlHelper.ElementsOfInterest(currentXDocToFix))
|
||||
fix(e);
|
||||
|
||||
if (changed)
|
||||
{
|
||||
CommandUtils.WriteXDocument(currentXDocToFix, f);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
142
external/api-doc-tools/tools/DocStat/DocStat/comparereport.cs
vendored
Normal file
142
external/api-doc-tools/tools/DocStat/DocStat/comparereport.cs
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Mono.Options;
|
||||
|
||||
namespace DocStat
|
||||
{
|
||||
public class CompareReportCommand : ApiCommand
|
||||
{
|
||||
|
||||
public override void Run(IEnumerable<string> args)
|
||||
{
|
||||
// throw new NotImplementedException();
|
||||
|
||||
string updatedDir = "";
|
||||
string omitlist = "";
|
||||
string processlist = "";
|
||||
string pattern = "";
|
||||
|
||||
List<string> extras = CommandUtils.ProcessFileArgs(args,
|
||||
ref updatedDir,
|
||||
ref omitlist,
|
||||
ref processlist,
|
||||
ref pattern);
|
||||
|
||||
string oldFilesDir = "";
|
||||
bool typeOnly = false;
|
||||
string reportFile = "";
|
||||
bool nosigil = false;
|
||||
|
||||
var options = new OptionSet {
|
||||
{"previous=", (p) => oldFilesDir = p},
|
||||
{"typeonly", (t) => typeOnly = t != null},
|
||||
{"reportfile=", (r) => reportFile = r},
|
||||
{ "no-check-TBA", (t) => nosigil = t != null }
|
||||
};
|
||||
|
||||
extras = options.Parse(extras);
|
||||
|
||||
CommandUtils.ThrowOnFiniteExtras(extras);
|
||||
|
||||
if (String.IsNullOrEmpty(oldFilesDir))
|
||||
throw new ArgumentException("You must supply a parallel directory from which to source new content with 'previous='.");
|
||||
|
||||
if (String.IsNullOrEmpty(reportFile) || !reportFile.EndsWith(".csv"))
|
||||
throw new ArgumentException("'reportfile=' must be used, and its value must end with '.csv'.");
|
||||
|
||||
string bareReportDir = Path.GetDirectoryName(Path.GetFullPath(reportFile));
|
||||
|
||||
if (!Directory.Exists(bareReportDir))
|
||||
throw new ArgumentException(bareReportDir + " does not exist.");
|
||||
|
||||
IEnumerable<string> updated = CommandUtils.GetFileList(processlist, omitlist, updatedDir, pattern);
|
||||
|
||||
StreamWriter reportStream = new StreamWriter(reportFile);
|
||||
|
||||
reportStream.WriteLine(String.Format(CommandUtils.CSVFormatString(5), "File Name", "Type", "Member","Need file summary", "Need member summary"));
|
||||
|
||||
Func<XElement, bool> hasSigil = null;
|
||||
|
||||
if (nosigil)
|
||||
{
|
||||
hasSigil = (XElement e) => true;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasSigil = (XElement e) => e.Element("Docs").Element("summary").Value == "To be added.";
|
||||
}
|
||||
|
||||
//Func<XElement, bool> needSummary = (XElement e) => e.Element("Docs").Element("summary").Value == "To be added.";
|
||||
|
||||
Func<XElement, string> MemberLine = (XElement e) => {
|
||||
return string.Format(
|
||||
CommandUtils.CSVFormatString(5),
|
||||
"",
|
||||
"",
|
||||
e.Attribute("MemberName").Value,
|
||||
"",
|
||||
hasSigil(e) ? "y" : "n");
|
||||
};
|
||||
|
||||
|
||||
|
||||
List<string> toWrite = new List<string>();
|
||||
foreach (string updatedXMLFile in updated)
|
||||
{
|
||||
|
||||
bool fileLineAdded = false;
|
||||
|
||||
XDocument updatedXDoc = XDocument.Load(updatedXMLFile);
|
||||
|
||||
Func<string> FileLine = () =>
|
||||
{
|
||||
return string.Format(
|
||||
CommandUtils.CSVFormatString(5),
|
||||
updatedXMLFile,
|
||||
updatedXDoc.Element("Type").Attribute("FullName").Value,
|
||||
"",
|
||||
hasSigil(updatedXDoc.Element("Type")) ? "y" : "n",
|
||||
"");
|
||||
};
|
||||
|
||||
|
||||
string oldXMLFile = EcmaXmlHelper.GetParallelFilePathFor(updatedXMLFile, oldFilesDir, updatedDir);
|
||||
XDocument oldXDoc = File.Exists(oldXMLFile) ? XDocument.Load(oldXMLFile) : null;
|
||||
if (null == oldXDoc && hasSigil(updatedXDoc.Element("Type")))
|
||||
{
|
||||
toWrite.Add(FileLine());
|
||||
fileLineAdded = true;
|
||||
}
|
||||
|
||||
IEnumerable<XElement> newMembers = EcmaXmlHelper.NewMembers(updatedXDoc, oldXDoc);
|
||||
if (null != newMembers && newMembers.Where((f) => hasSigil(f)).Any())
|
||||
{
|
||||
if (!fileLineAdded)
|
||||
toWrite.Add(FileLine());
|
||||
|
||||
foreach (XElement e in newMembers.Where((f) => hasSigil(f)))
|
||||
{
|
||||
toWrite.Add(MemberLine(e));
|
||||
}
|
||||
}
|
||||
|
||||
// If toWrite isn't empty, write all lines
|
||||
if (toWrite.Any())
|
||||
{
|
||||
foreach (string s in toWrite)
|
||||
reportStream.WriteLine(s);
|
||||
}
|
||||
toWrite.Clear();
|
||||
}
|
||||
reportStream.Flush();
|
||||
reportStream.Close();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
80
external/api-doc-tools/tools/DocStat/DocStat/fixsummaries.cs
vendored
Normal file
80
external/api-doc-tools/tools/DocStat/DocStat/fixsummaries.cs
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Mono.Options;
|
||||
|
||||
namespace DocStat
|
||||
{
|
||||
public class FixSummariesCommand : ApiCommand
|
||||
{
|
||||
public FixSummariesCommand()
|
||||
{
|
||||
}
|
||||
|
||||
public override void Run(IEnumerable<string> args)
|
||||
{
|
||||
string rootdir = "";
|
||||
string omitlist = "";
|
||||
string processlist = "";
|
||||
string pattern = "";
|
||||
List<string> extras = CommandUtils.ProcessFileArgs(args,
|
||||
ref rootdir,
|
||||
ref omitlist,
|
||||
ref processlist,
|
||||
ref pattern
|
||||
);
|
||||
CommandUtils.ThrowOnFiniteExtras(extras);
|
||||
|
||||
foreach (string file in CommandUtils.GetFileList(processlist, omitlist, rootdir, pattern))
|
||||
{
|
||||
bool changed = false;
|
||||
XDocument xdoc = new XDocument(XElement.Load(file));
|
||||
|
||||
XElement memberRoot = xdoc.Element("Type").Element("Members");
|
||||
if (memberRoot == null || !memberRoot.Descendants().Any())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
foreach (XElement m in memberRoot.Elements("Member"))
|
||||
{
|
||||
XElement summary = m.Element("Docs").Element("summary");
|
||||
|
||||
if (null == summary)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (summary.IsEmpty || (summary.Value.Length == 0 && summary.Descendants().Count() == 0))
|
||||
{
|
||||
summary.Value = "To be added.";
|
||||
changed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
IEnumerable<XElement> mistakeParams = summary.Descendants("param");
|
||||
|
||||
if (mistakeParams.Count() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
mistakeParams.ToList().ForEach(e => e.Name = "paramref");
|
||||
|
||||
changed = true;
|
||||
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
CommandUtils.WriteXDocument(xdoc, file);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
97
external/api-doc-tools/tools/DocStat/DocStat/internalize.cs
vendored
Normal file
97
external/api-doc-tools/tools/DocStat/DocStat/internalize.cs
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Mono.Options;
|
||||
|
||||
namespace DocStat
|
||||
{
|
||||
public class InternalizeCommand : ApiCommand
|
||||
{
|
||||
|
||||
public override void Run(IEnumerable<string> args)
|
||||
{
|
||||
string rootdir = "";
|
||||
string omitlist = "";
|
||||
string processlist = "";
|
||||
string pattern = "";
|
||||
List<string> extras = CommandUtils.ProcessFileArgs(args,
|
||||
ref rootdir,
|
||||
ref omitlist,
|
||||
ref processlist,
|
||||
ref pattern
|
||||
);
|
||||
|
||||
string message = "For internal use only.";
|
||||
string sigil = "To be added.";
|
||||
bool nocheck = false;
|
||||
bool nosigil = false;
|
||||
|
||||
var opt = new OptionSet {
|
||||
{ "m|message=", (m) => message = m },
|
||||
{ "s|sigil=", (s) => sigil = s },
|
||||
{ "no-check-browsable", (n) => nocheck = n != null},
|
||||
{ "no-check-TBA", (t) => nosigil = t != null }
|
||||
};
|
||||
|
||||
extras = opt.Parse(extras);
|
||||
|
||||
CommandUtils.ThrowOnFiniteExtras(extras);
|
||||
|
||||
Func<XElement, bool> hassigil;
|
||||
Func<XDocument, bool> typehassigil;
|
||||
Func<XElement, bool> qualifies;
|
||||
|
||||
if (nosigil)
|
||||
{
|
||||
// Mark types and members internal, regardless of whether the summaries are filled out
|
||||
hassigil = (x) => true;
|
||||
typehassigil = (x) => true;
|
||||
}
|
||||
else
|
||||
{
|
||||
hassigil = (e) => e.Element("Docs").Element("summary").Value == sigil;
|
||||
typehassigil = (t) => t.Element("Type").Element("Docs").Element("summary").Value == sigil;
|
||||
}
|
||||
|
||||
if (!nocheck)
|
||||
{
|
||||
qualifies = (e) =>
|
||||
{
|
||||
return e.Elements("Attributes")
|
||||
.Any((XElement child) => child.Elements("Attribute")
|
||||
.Any((XElement name) => name.Value.Contains("EditorBrowsableState.Never")))
|
||||
&& hassigil(e);
|
||||
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
qualifies = hassigil;
|
||||
}
|
||||
|
||||
foreach (string file in CommandUtils.GetFileList(processlist, omitlist, rootdir, pattern))
|
||||
{
|
||||
XDocument xdoc = new XDocument(XElement.Load(file));
|
||||
// Find every member that has the internal marker and summary="To be added." (or the provided sigil)
|
||||
|
||||
XElement memberRoot = xdoc.Element("Type").Element("Members");
|
||||
if (memberRoot == null || !memberRoot.Descendants().Any())
|
||||
continue;
|
||||
|
||||
IEnumerable<XElement> hits = memberRoot.Elements("Member").Where(s => qualifies(s));
|
||||
|
||||
foreach (XElement x in hits)
|
||||
{
|
||||
x.Element("Docs").Element("summary").Value = message;
|
||||
}
|
||||
|
||||
if (typehassigil(xdoc))
|
||||
xdoc.Element("Type").Element("Docs").Element("summary").Value = message;
|
||||
|
||||
|
||||
CommandUtils.WriteXDocument(xdoc, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
73
external/api-doc-tools/tools/DocStat/DocStat/obsolete.cs
vendored
Normal file
73
external/api-doc-tools/tools/DocStat/DocStat/obsolete.cs
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Mono.Options;
|
||||
|
||||
namespace DocStat
|
||||
{
|
||||
public class ObsoleteCommand : ApiCommand
|
||||
{
|
||||
|
||||
public override void Run(IEnumerable<string> args)
|
||||
{
|
||||
string rootdir = "";
|
||||
string omitlist = "";
|
||||
string processlist = "";
|
||||
string pattern = "";
|
||||
|
||||
List<string> extras = CommandUtils.ProcessFileArgs(args,
|
||||
ref rootdir,
|
||||
ref omitlist,
|
||||
ref processlist,
|
||||
ref pattern);
|
||||
string obsoleteMarker = "System.Obsolete";
|
||||
string sigil = "To be added.";
|
||||
bool skipSigil = false;
|
||||
string message = "Deprecated. Do not use.";
|
||||
var opt = new OptionSet {
|
||||
{"a|attribute",
|
||||
(x) => obsoleteMarker = x },
|
||||
{ "s|sigil=", (s) => sigil = s },
|
||||
{ "no-check-TBA", (s) => skipSigil = s != null},
|
||||
{ "m|message=", (m) => message = m}
|
||||
};
|
||||
|
||||
extras = opt.Parse(extras);
|
||||
CommandUtils.ThrowOnFiniteExtras(extras);
|
||||
|
||||
Func<XElement, bool> sigilCheck;
|
||||
Func<XElement, bool> obsoleteCheck;
|
||||
|
||||
if (skipSigil)
|
||||
{
|
||||
sigilCheck = (e) => true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sigilCheck = (e) => e.Element("Docs").Element("summary").Value == sigil;
|
||||
}
|
||||
|
||||
obsoleteCheck = (e) => e.Elements("Attribute").Any((arg) =>
|
||||
arg.Elements("Attribute").Any((arg2) =>
|
||||
arg2.Value.StartsWith(obsoleteMarker))); ; ;
|
||||
|
||||
foreach (string file in CommandUtils.GetFileList(processlist, omitlist, rootdir, pattern))
|
||||
{
|
||||
// find all the ones that have attributes that start with the provided attribute
|
||||
XDocument xdoc = XDocument.Load(file);
|
||||
|
||||
XElement memberRoot = xdoc.Element("Type").Element("Members");
|
||||
if (memberRoot == null || !memberRoot.Descendants().Any())
|
||||
continue;
|
||||
|
||||
foreach (XElement toMark in memberRoot.Elements("Member")
|
||||
.Where((e) => obsoleteCheck(e) && sigilCheck(e)))
|
||||
{
|
||||
toMark.Element("Docs").Element("summary").Value = message;
|
||||
}
|
||||
CommandUtils.WriteXDocument(xdoc, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
133
external/api-doc-tools/tools/DocStat/DocStat/remaining.cs
vendored
Normal file
133
external/api-doc-tools/tools/DocStat/DocStat/remaining.cs
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Mono.Options;
|
||||
|
||||
namespace DocStat
|
||||
{
|
||||
public class RemainingCommand : ApiCommand
|
||||
{
|
||||
|
||||
public override void Run(IEnumerable<string> args)
|
||||
{
|
||||
|
||||
string rootdir = "";
|
||||
string omitlist = "";
|
||||
string processlist = "";
|
||||
string pattern = "";
|
||||
List<string> extras = CommandUtils.ProcessFileArgs(args,
|
||||
ref rootdir,
|
||||
ref omitlist,
|
||||
ref processlist,
|
||||
ref pattern);
|
||||
string sigil = "To be added.";
|
||||
string outputfile = "";
|
||||
|
||||
var opt = new OptionSet
|
||||
{
|
||||
{"s|sigil=", (s) => sigil = s},
|
||||
{"o|output|ofile=", (o) => outputfile = o.EndsWith(@"csv") ? o : outputfile}
|
||||
};
|
||||
|
||||
extras = opt.Parse(extras);
|
||||
|
||||
if (String.IsNullOrEmpty(outputfile))
|
||||
throw new ArgumentException("You must supply an output file, and it must end with '.csv'");
|
||||
|
||||
CommandUtils.ThrowOnFiniteExtras(extras);
|
||||
|
||||
List<XElement> results = new List<XElement>();
|
||||
|
||||
IEnumerable<string> files = CommandUtils.GetFileList(processlist, omitlist, rootdir, pattern);
|
||||
List<string> fileList = files.ToList();
|
||||
foreach (string file in fileList)
|
||||
{
|
||||
AddResults(file, results, sigil);
|
||||
}
|
||||
|
||||
WriteResults(results, outputfile);
|
||||
|
||||
}
|
||||
|
||||
internal void AddResults(string file, List<XElement> results, string sigil)
|
||||
{
|
||||
// Add results
|
||||
// <QueryResults>
|
||||
// <Type name="..." filename="....">
|
||||
// <Member name="...">
|
||||
// ....
|
||||
// </Type ... >
|
||||
// <Type>
|
||||
// ....
|
||||
// <QueryResults>
|
||||
|
||||
XElement top = XElement.Load(file);
|
||||
if (top.Name == "Type")
|
||||
{
|
||||
// We got a live one!
|
||||
IEnumerable<XElement> qres =
|
||||
from member in top.Descendants("Member")
|
||||
where (string)member.Element("Docs").Element("summary") == sigil
|
||||
select member;
|
||||
List<XElement> le = new List<XElement>(qres);
|
||||
if (le.Any())
|
||||
{
|
||||
string typeName = top.Attribute("FullName").Value;
|
||||
XElement t = new XElement("Type");
|
||||
t.Add(new XAttribute("name", typeName));
|
||||
t.Add(new XAttribute("filename", file));
|
||||
// add member name node for each node
|
||||
|
||||
foreach (XElement m in le)
|
||||
{
|
||||
XElement mres = new XElement("Member");
|
||||
mres.Add(new XAttribute("name", m.Attribute("MemberName").Value));
|
||||
t.Add(mres);
|
||||
}
|
||||
|
||||
results.Add(t);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal void WriteResults(List<XElement> results, string outputFileName)
|
||||
{
|
||||
if (null == results || results.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StreamWriter ofile = new StreamWriter(outputFileName);
|
||||
int typeCount = 0;
|
||||
int memberCount = 0;
|
||||
ofile.WriteLine("Type,Count,File Name,Member");
|
||||
|
||||
string typeFormat = "\"{0}\",\"{1}\",\"{2}\",";
|
||||
string memberFormat = ",,,\"{0}\"";
|
||||
string rollupFormat = "Types:,\"{0}\",Members:,\"{1}\"";
|
||||
foreach (XElement e in results)
|
||||
{
|
||||
//List<XElement> countable = new List<XElement>(e.Elements());
|
||||
ofile.WriteLine(typeFormat,
|
||||
e.Attribute("name").Value,
|
||||
e.Elements().Count(),
|
||||
e.Attribute("filename").Value.Replace("`", "\\`"));
|
||||
typeCount++;
|
||||
foreach (XElement x in e.Elements())
|
||||
{
|
||||
ofile.WriteLine(memberFormat, x.Attribute("name").Value);
|
||||
memberCount++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
ofile.WriteLine(rollupFormat, typeCount, memberCount);
|
||||
ofile.Flush();
|
||||
ofile.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user