Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/api-doc-tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/mdoc
diff options
context:
space:
mode:
authorJoel Martinez <joelmartinez@gmail.com>2018-06-06 00:32:58 +0300
committerGitHub <noreply@github.com>2018-06-06 00:32:58 +0300
commitc756eefaea192143452b9033e6fed8fdfb0440b3 (patch)
treecfe686883e36c3e04b23a3b38745d1944797d22b /mdoc
parent111914edcbdf705aa44cfaeadabf343e3e3ea052 (diff)
Adding "FrameworkAlternate" and "Index" to XSD
Updated to add attributes to MemberSignature, TypeSignature, Parameter, TypeParameter. Additionally, added validation unit tests, and reformatted the mdoc validator subcommand for future-proof maintainability. Closes #262
Diffstat (limited to 'mdoc')
-rw-r--r--mdoc/Consts.cs2
-rw-r--r--mdoc/Mono.Documentation/MDocUpdater.cs68
-rw-r--r--mdoc/Mono.Documentation/MDocValidator.cs156
-rw-r--r--mdoc/Mono.Documentation/Updater/Frameworks/FrameworkIndex.cs2
-rw-r--r--mdoc/Mono.Documentation/Updater/XmlSyncer.cs10
-rw-r--r--mdoc/Mono.Documentation/validate.cs123
-rw-r--r--mdoc/Resources/monodoc-ecma.xsd9
-rw-r--r--mdoc/mdoc.Test/ValidationTests.cs154
-rw-r--r--mdoc/mdoc.Test/XmlUpdateTests.cs40
-rw-r--r--mdoc/mdoc.Test/mdoc.Test.csproj1
-rw-r--r--mdoc/mdoc.csproj2
11 files changed, 383 insertions, 184 deletions
diff --git a/mdoc/Consts.cs b/mdoc/Consts.cs
index d435c1d0..e049b679 100644
--- a/mdoc/Consts.cs
+++ b/mdoc/Consts.cs
@@ -26,5 +26,7 @@ namespace Mono.Documentation
public const string RefTypeObsoleteString = "Types with embedded references are not supported in this version of your compiler.";
public const string CompilerGeneratedAttribute = "System.Runtime.CompilerServices.CompilerGeneratedAttribute";
public const string CompilationMappingAttribute = "Microsoft.FSharp.Core.CompilationMappingAttribute";
+ public const string FrameworksIndex = "FrameworksIndex";
+ public const string FrameworkAlternate = "FrameworkAlternate";
}
}
diff --git a/mdoc/Mono.Documentation/MDocUpdater.cs b/mdoc/Mono.Documentation/MDocUpdater.cs
index 46b0d895..1345b859 100644
--- a/mdoc/Mono.Documentation/MDocUpdater.cs
+++ b/mdoc/Mono.Documentation/MDocUpdater.cs
@@ -285,7 +285,7 @@ namespace Mono.Documentation
{
Name = f.Attribute("Name").Value,
Source = f.Attribute("Source").Value,
- XmlPath = Path.Combine(srcPath, "FrameworksIndex", f.Attribute("Source").Value + ".xml"),
+ XmlPath = Path.Combine(srcPath, Consts.FrameworksIndex, f.Attribute("Source").Value + ".xml"),
})
.Where(f => File.Exists(f.XmlPath))
.Select(f => XDocument.Load(f.XmlPath));
@@ -1238,7 +1238,7 @@ namespace Mono.Documentation
private void CleanupFiles (string dest, HashSet<string> goodfiles)
{
// Look for files that no longer correspond to types
- foreach (System.IO.DirectoryInfo nsdir in new System.IO.DirectoryInfo (dest).GetDirectories ("*").Where (d => Path.GetFileName (d.FullName) != "FrameworksIndex"))
+ foreach (System.IO.DirectoryInfo nsdir in new System.IO.DirectoryInfo (dest).GetDirectories ("*").Where (d => Path.GetFileName (d.FullName) != Consts.FrameworksIndex))
{
foreach (System.IO.FileInfo typefile in nsdir.GetFiles ("*.xml"))
{
@@ -1997,7 +1997,7 @@ namespace Mono.Documentation
if (!existing.Any ())
{
var newNode = WriteElementText (basenode, "BaseTypeName", basetypename, forceNewElement: true);
- WriteElementAttribute (basenode, newNode, "FrameworkAlternate", typeEntry.Framework.Name);
+ WriteElementAttribute (basenode, newNode, Consts.FrameworkAlternate, typeEntry.Framework.Name);
}
}
}
@@ -2240,33 +2240,33 @@ namespace Mono.Documentation
if (existingNodes.Count () > 1) {
// find the right one to update based on `currentFX`
- if (existingNodes.Any (e => e.HasAttribute ("FrameworkAlternate"))) {
- var nodesWithFX = existingNodes.Where (e => e.HasAttribute ("FrameworkAlternate"));
+ if (existingNodes.Any (e => e.HasAttribute (Consts.FrameworkAlternate))) {
+ var nodesWithFX = existingNodes.Where (e => e.HasAttribute (Consts.FrameworkAlternate));
if (nodesWithFX.Any ()) {
// one exists, we can continue
if (!fxAlternateTriggered)
{
- var matchingSignature = nodesWithFX.FirstOrDefault (nfx => nfx.GetAttribute ("Value") == valueToUse && !nfx.GetAttribute ("FrameworkAlternate").Contains (currentFX));
+ var matchingSignature = nodesWithFX.FirstOrDefault (nfx => nfx.GetAttribute ("Value") == valueToUse && !nfx.GetAttribute (Consts.FrameworkAlternate).Contains (currentFX));
if (matchingSignature!= null) {
// The current implementation has changed
- matchingSignature.SetAttribute ("FrameworkAlternate", FXUtils.AddFXToList (matchingSignature.GetAttribute ("FrameworkAlternate"), currentFX));
+ matchingSignature.SetAttribute (Consts.FrameworkAlternate, FXUtils.AddFXToList (matchingSignature.GetAttribute (Consts.FrameworkAlternate), currentFX));
foreach (var n in nodesWithFX.Where (nfx => nfx != matchingSignature))
{
- string nfx = n.GetAttribute ("FrameworkAlternate");
+ string nfx = n.GetAttribute (Consts.FrameworkAlternate);
string nfixed = FXUtils.RemoveFXFromList (nfx, currentFX);
if (string.IsNullOrEmpty (nfixed))
{
n.ParentNode.RemoveChild (n);
var nodesWithoutFX = existingNodes
- .Where (e => e.HasAttribute ("FrameworkAlternate") && !e.GetAttribute ("FrameworkAlternate").Contains (currentFX))
- .Select (e => new { Element = e, FX = e.GetAttribute ("FrameworkAlternate") });
+ .Where (e => e.HasAttribute (Consts.FrameworkAlternate) && !e.GetAttribute (Consts.FrameworkAlternate).Contains (currentFX))
+ .Select (e => new { Element = e, FX = e.GetAttribute (Consts.FrameworkAlternate) });
foreach (var nwofx in nodesWithoutFX)
{
- nwofx.Element.SetAttribute ("FrameworkAlternate", FXUtils.AddFXToList (nwofx.FX, currentFX));
+ nwofx.Element.SetAttribute (Consts.FrameworkAlternate, FXUtils.AddFXToList (nwofx.FX, currentFX));
}
}
else
- n.SetAttribute ("FrameworkAlternate", nfixed);
+ n.SetAttribute (Consts.FrameworkAlternate, nfixed);
}
}
@@ -2290,7 +2290,7 @@ namespace Mono.Documentation
if (!string.IsNullOrWhiteSpace (previousFX))
{
var node = existingNodes.First ();
- node.SetAttribute ("FrameworkAlternate", previousFX);
+ node.SetAttribute (Consts.FrameworkAlternate, previousFX);
}
else
{
@@ -2300,13 +2300,13 @@ namespace Mono.Documentation
}
var newelement = makeNewNode ();
- newelement.SetAttribute ("FrameworkAlternate", currentFX);
+ newelement.SetAttribute (Consts.FrameworkAlternate, currentFX);
return;
}
- else if (!fxAlternateTriggered && existingNodes.Count () == 1 && typeEntry.Framework.Frameworks.Count () > 1 && existingNodes.First ().HasAttribute ("FrameworkAlternate")) {
+ else if (!fxAlternateTriggered && existingNodes.Count () == 1 && typeEntry.Framework.Frameworks.Count () > 1 && existingNodes.First ().HasAttribute (Consts.FrameworkAlternate)) {
var node = existingNodes.First ();
- string newfxvalue = FXUtils.AddFXToList (node.GetAttribute ("FrameworkAlternate"), typeEntry.Framework.Name);
- node.SetAttribute ("FrameworkAlternate", newfxvalue);
+ string newfxvalue = FXUtils.AddFXToList (node.GetAttribute (Consts.FrameworkAlternate), typeEntry.Framework.Name);
+ node.SetAttribute (Consts.FrameworkAlternate, newfxvalue);
return;
}
@@ -3293,10 +3293,10 @@ namespace Mono.Documentation
if (alreadyExists != null)
{
// if FXA, add fx.name
- if (fx.Frameworks.Count() > 1 && alreadyExists.XElement.HasAttribute("FrameworkAlternate"))
+ if (fx.Frameworks.Count() > 1 && alreadyExists.XElement.HasAttribute(Consts.FrameworkAlternate))
{
- var newfxlist = FXUtils.AddFXToList (alreadyExists.XElement.GetAttribute ("FrameworkAlternate"), fx.Name);
- alreadyExists.XElement.SetAttribute ("FrameworkAlternate", newfxlist);
+ var newfxlist = FXUtils.AddFXToList (alreadyExists.XElement.GetAttribute (Consts.FrameworkAlternate), fx.Name);
+ alreadyExists.XElement.SetAttribute (Consts.FrameworkAlternate, newfxlist);
}
continue;
}
@@ -3313,7 +3313,7 @@ namespace Mono.Documentation
if (fx.Frameworks.Count() > 1 && !fx.IsFirstFramework && (!typeNotExisted && !assemblyNotExisted))
{
- ae.SetAttribute ("FrameworkAlternate", fx.Name);
+ ae.SetAttribute (Consts.FrameworkAlternate, fx.Name);
}
}
}
@@ -3331,17 +3331,17 @@ namespace Mono.Documentation
if (fx.Frameworks.Count() > 1) {
- if (stateAttribute.XElement.HasAttribute ("FrameworkAlternate"))
+ if (stateAttribute.XElement.HasAttribute (Consts.FrameworkAlternate))
{
// if has FXA, remove from list
- var newfxlist = FXUtils.RemoveFXFromList (stateAttribute.XElement.GetAttribute ("FrameworkAlternate"), fx.Name);
- stateAttribute.XElement.SetAttribute ("FrameworkAlternate", newfxlist);
+ var newfxlist = FXUtils.RemoveFXFromList (stateAttribute.XElement.GetAttribute (Consts.FrameworkAlternate), fx.Name);
+ stateAttribute.XElement.SetAttribute (Consts.FrameworkAlternate, newfxlist);
}
else if (!fx.IsFirstFramework) // doesn't have FXA, and isn't the first framework
{
// if not, we need to make sure
var priorfxList = fx.PreviousFrameworks.Select (f => f.Name).ToArray ();
- stateAttribute.XElement.SetAttribute ("FrameworkAlternate", string.Join (";", priorfxList));
+ stateAttribute.XElement.SetAttribute (Consts.FrameworkAlternate, string.Join (";", priorfxList));
}
else if (fx.IsFirstFramework)
{
@@ -3356,7 +3356,7 @@ namespace Mono.Documentation
// clean up
if (fx.IsLastFramework) {
foreach(var attr in e.ChildNodes.Cast<XmlElement> ().ToArray()) {
- if (attr.HasAttribute ("FrameworkAlternate") && string.IsNullOrWhiteSpace (attr.GetAttribute ("FrameworkAlternate")))
+ if (attr.HasAttribute (Consts.FrameworkAlternate) && string.IsNullOrWhiteSpace (attr.GetAttribute (Consts.FrameworkAlternate)))
attr.ParentNode.RemoveChild (attr);
}
}
@@ -3448,7 +3448,7 @@ namespace Mono.Documentation
if (addIndex)
pe.SetAttribute ("Index", index.ToString ());
if (addfx)
- pe.SetAttribute ("FrameworkAlternate", fx);
+ pe.SetAttribute (Consts.FrameworkAlternate, fx);
MakeAttributes (pe, GetCustomAttributes (param.CustomAttributes, ""), typeEntry.Framework, typeEntry: typeEntry);
};
@@ -3496,7 +3496,7 @@ namespace Mono.Documentation
Type = n.GetAttribute ("Type"),
ChildIndex = i,
ActualIndex = actualIndex,
- FrameworkAlternates = n.GetAttribute ("FrameworkAlternate")
+ FrameworkAlternates = n.GetAttribute (Consts.FrameworkAlternate)
};
})
.ToArray ();
@@ -3510,8 +3510,8 @@ namespace Mono.Documentation
if (xitem != null)
{
var xelement = xitem.Element;
- if (xelement.HasAttribute ("FrameworkAlternate") && !xelement.GetAttribute ("FrameworkAlternate").Contains (typeEntry.Framework.Name))
- xelement.SetAttribute ("FrameworkAlternate", FXUtils.AddFXToList (xelement.GetAttribute ("FrameworkAlternate"), typeEntry.Framework.Name));
+ if (xelement.HasAttribute (Consts.FrameworkAlternate) && !xelement.GetAttribute (Consts.FrameworkAlternate).Contains (typeEntry.Framework.Name))
+ xelement.SetAttribute (Consts.FrameworkAlternate, FXUtils.AddFXToList (xelement.GetAttribute (Consts.FrameworkAlternate), typeEntry.Framework.Name));
continue;
@@ -3528,7 +3528,7 @@ namespace Mono.Documentation
//-find < parameter where index = currentIndex >
var currentNode = xdata[i].Element;
- currentNode.SetAttribute ("FrameworkAlternate", fxList);
+ currentNode.SetAttribute (Consts.FrameworkAlternate, fxList);
addParameter (p.Definition, currentNode, p.Type, i, true, typeEntry.Framework.Name, true);
@@ -3556,8 +3556,8 @@ namespace Mono.Documentation
{
Element = p,
Name = p.GetAttribute ("Name"),
- HasFrameworkAlternate = p.HasAttribute ("FrameworkAlternate"),
- FrameworkAlternate = p.GetAttribute ("FrameworkAlternate")
+ HasFrameworkAlternate = p.HasAttribute (Consts.FrameworkAlternate),
+ FrameworkAlternate = p.GetAttribute (Consts.FrameworkAlternate)
})
.Where (p =>
p.HasFrameworkAlternate &&
@@ -3577,7 +3577,7 @@ namespace Mono.Documentation
}
else
{
- a.Element.SetAttribute ("FrameworkAlternate", newValue);
+ a.Element.SetAttribute (Consts.FrameworkAlternate, newValue);
}
}
}
diff --git a/mdoc/Mono.Documentation/MDocValidator.cs b/mdoc/Mono.Documentation/MDocValidator.cs
new file mode 100644
index 00000000..1716313b
--- /dev/null
+++ b/mdoc/Mono.Documentation/MDocValidator.cs
@@ -0,0 +1,156 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using System.Xml;
+using System.Xml.Schema;
+
+using Mono.Options;
+
+namespace Mono.Documentation
+{
+ public class MDocValidator : MDocCommand
+ {
+ XmlReaderSettings settings;
+ long errors = 0;
+
+ public override void Run (IEnumerable<string> args)
+ {
+ string[] validFormats = {
+ "ecma",
+ };
+ string format = "ecma";
+ var p = new OptionSet () {
+ { "f|format=",
+ "The documentation {0:FORMAT} used within PATHS. " +
+ "Valid formats include:\n " +
+ string.Join ("\n ", validFormats) + "\n" +
+ "If no format provided, `ecma' is used.",
+ v => format = v },
+ };
+ List<string> files = Parse (p, args, "validate",
+ "[OPTIONS]+ PATHS",
+ "Validate PATHS against the specified format schema.");
+ if (files == null)
+ return;
+ if (Array.IndexOf (validFormats, format) < 0)
+ Error ("Invalid documentation format: {0}.", format);
+ Run (format, files);
+ }
+
+ public void Run (string format, IEnumerable<string> files)
+ {
+ InitializeSchema (format);
+
+ // skip args[0] because it is the provider name
+ foreach (string arg in files)
+ {
+ if (IsMonodocFile (arg))
+ ValidateFile (arg);
+
+ if (Directory.Exists (arg))
+ {
+ RecurseDirectory (arg);
+ }
+ }
+
+ Message (errors == 0 ? TraceLevel.Info : TraceLevel.Error,
+ "Total validation errors: {0}", errors);
+ }
+
+ public void InitializeSchema (string format, ValidationEventHandler extraHandler = null)
+ {
+ Stream s = null;
+
+ switch (format)
+ {
+ case "ecma":
+ s = Assembly.GetExecutingAssembly ().GetManifestResourceStream ("monodoc-ecma.xsd");
+ break;
+
+ default:
+ throw new NotSupportedException (string.Format ("The format `{0}' is not suppoted.", format));
+ }
+
+ if (s == null)
+ throw new NotSupportedException (string.Format ("The schema for `{0}' was not found.", format));
+
+ settings = new XmlReaderSettings ();
+ settings.Schemas.Add (XmlSchema.Read (s, null));
+ settings.Schemas.Compile ();
+ settings.ValidationType = ValidationType.Schema;
+ settings.ValidationEventHandler += OnValidationEvent;
+ if (extraHandler != null)
+ settings.ValidationEventHandler += extraHandler;
+ }
+
+ public void ValidateFile (string file)
+ {
+ if (settings == null) InitializeSchema ("ecma");
+
+ try
+ {
+ using (var reader = XmlReader.Create (new XmlTextReader (file), settings))
+ {
+ while (reader.Read ())
+ {
+ // do nothing
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ Message (TraceLevel.Error, "mdoc: {0}", e.ToString ());
+ }
+ }
+
+ public void ValidateFile (TextReader textReader)
+ {
+ if (settings == null) InitializeSchema ("ecma");
+
+ try
+ {
+ using (var xmlReader = XmlReader.Create (textReader, settings))
+ while (xmlReader.Read ()) {}
+ }
+ catch (Exception e)
+ {
+ Message (TraceLevel.Error, "mdoc: {0}", e.ToString ());
+ }
+ }
+
+ void RecurseDirectory (string dir)
+ {
+ string[] files = Directory.GetFiles (dir, "*.xml");
+ foreach (string f in files)
+ {
+ if (IsMonodocFile (f))
+ ValidateFile (f);
+ }
+
+ string[] dirs = Directory.GetDirectories (dir);
+ foreach (string d in dirs)
+ RecurseDirectory (d);
+ }
+
+ void OnValidationEvent (object sender, ValidationEventArgs a)
+ {
+ errors++;
+ Message (TraceLevel.Error, "mdoc: {0}", a.Message);
+ }
+
+ static bool IsMonodocFile (string file)
+ {
+ var dpath = Path.GetDirectoryName (file);
+ var dname = Path.GetFileName (dpath);
+
+ if (File.Exists (file) && Path.GetExtension (file).ToLower () == ".xml" && !dname.Equals(Consts.FrameworksIndex))
+ return true;
+ else
+ return false;
+
+ }
+ }
+}
+
diff --git a/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkIndex.cs b/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkIndex.cs
index 9d0ae887..e9e19600 100644
--- a/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkIndex.cs
+++ b/mdoc/Mono.Documentation/Updater/Frameworks/FrameworkIndex.cs
@@ -60,7 +60,7 @@ namespace Mono.Documentation.Updater.Frameworks
if (string.IsNullOrWhiteSpace (this.path))
return;
- string outputPath = Path.Combine (path, "FrameworksIndex");
+ string outputPath = Path.Combine (path, Consts.FrameworksIndex);
if (!Directory.Exists (outputPath))
Directory.CreateDirectory (outputPath);
diff --git a/mdoc/Mono.Documentation/Updater/XmlSyncer.cs b/mdoc/Mono.Documentation/Updater/XmlSyncer.cs
index 4bc3a40c..dda4cd0e 100644
--- a/mdoc/Mono.Documentation/Updater/XmlSyncer.cs
+++ b/mdoc/Mono.Documentation/Updater/XmlSyncer.cs
@@ -35,7 +35,7 @@ namespace Mono.Documentation.Updater
if (addIndex)
pe.SetAttribute ("Index", index.ToString ());
if (addfx)
- pe.SetAttribute ("FrameworkAlternate", fx);
+ pe.SetAttribute (Consts.FrameworkAlternate, fx);
MakeAttributes (pe, GetCustomAttributes (param.CustomAttributes, ""));
};
@@ -104,7 +104,7 @@ namespace Mono.Documentation.Updater
//-find < parameter where index = currentIndex >
var currentNode = paramNodes[parameterIndex] as XmlElement;
- currentNode.SetAttribute ("FrameworkAlternate", fxList);
+ currentNode.SetAttribute (Consts.FrameworkAlternate, fxList);
addParameter (p, parameterNode, ptype, parameterIndex - parameterIndexOffset, true, typeEntry.Framework.Name, true);
parameterIndexOffset++;
@@ -149,7 +149,7 @@ namespace Mono.Documentation.Updater
{
Element = p,
Name = p.GetAttribute ("Name"),
- FrameworkAlternate = p.GetAttribute ("FrameworkAlternate")
+ FrameworkAlternate = p.GetAttribute (Consts.FrameworkAlternate)
})
.Where (p =>
!string.IsNullOrWhiteSpace (p.FrameworkAlternate) &&
@@ -163,11 +163,11 @@ namespace Mono.Documentation.Updater
string newValue = FXUtils.RemoveFXFromList (a.FrameworkAlternate, typeEntry.Framework.Name);
if (string.IsNullOrWhiteSpace (newValue))
{
- a.Element.RemoveAttribute ("FrameworkAlternate");
+ a.Element.RemoveAttribute (Consts.FrameworkAlternate);
}
else
{
- a.Element.SetAttribute ("FrameworkAlternate", newValue);
+ a.Element.SetAttribute (Consts.FrameworkAlternate, newValue);
}
}
}
diff --git a/mdoc/Mono.Documentation/validate.cs b/mdoc/Mono.Documentation/validate.cs
deleted file mode 100644
index afaba40f..00000000
--- a/mdoc/Mono.Documentation/validate.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Reflection;
-using System.Xml;
-using System.Xml.Schema;
-
-using Mono.Options;
-
-namespace Mono.Documentation
-{
- public class MDocValidator : MDocCommand
- {
- XmlReaderSettings settings;
- long errors = 0;
-
- public override void Run (IEnumerable<string> args)
- {
- string[] validFormats = {
- "ecma",
- };
- string format = "ecma";
- var p = new OptionSet () {
- { "f|format=",
- "The documentation {0:FORMAT} used within PATHS. " +
- "Valid formats include:\n " +
- string.Join ("\n ", validFormats) + "\n" +
- "If no format provided, `ecma' is used.",
- v => format = v },
- };
- List<string> files = Parse (p, args, "validate",
- "[OPTIONS]+ PATHS",
- "Validate PATHS against the specified format schema.");
- if (files == null)
- return;
- if (Array.IndexOf (validFormats, format) < 0)
- Error ("Invalid documentation format: {0}.", format);
- Run (format, files);
- }
-
- public void Run (string format, IEnumerable<string> files)
- {
- Stream s = null;
-
- switch (format) {
- case "ecma":
- s = Assembly.GetExecutingAssembly ().GetManifestResourceStream ("monodoc-ecma.xsd");
- break;
-
- default:
- throw new NotSupportedException (string.Format ("The format `{0}' is not suppoted.", format));
- }
-
- if (s == null)
- throw new NotSupportedException (string.Format ("The schema for `{0}' was not found.", format));
-
- settings = new XmlReaderSettings ();
- settings.Schemas.Add (XmlSchema.Read (s, null));
- settings.Schemas.Compile ();
- settings.ValidationType = ValidationType.Schema;
- settings.ValidationEventHandler += OnValidationEvent;
-
- // skip args[0] because it is the provider name
- foreach (string arg in files) {
- if (IsMonodocFile (arg))
- ValidateFile (arg);
-
- if (Directory.Exists (arg))
- {
- RecurseDirectory (arg);
- }
- }
-
- Message (errors == 0 ? TraceLevel.Info : TraceLevel.Error,
- "Total validation errors: {0}", errors);
- }
-
- void ValidateFile (string file)
- {
- try {
- using (var reader = XmlReader.Create (new XmlTextReader (file), settings)) {
- while (reader.Read ()) {
- // do nothing
- }
- }
- }
- catch (Exception e) {
- Message (TraceLevel.Error, "mdoc: {0}", e.ToString ());
- }
- }
-
- void RecurseDirectory (string dir)
- {
- string[] files = Directory.GetFiles (dir, "*.xml");
- foreach (string f in files)
- {
- if (IsMonodocFile (f))
- ValidateFile (f);
- }
-
- string[] dirs = Directory.GetDirectories (dir);
- foreach (string d in dirs)
- RecurseDirectory (d);
- }
-
- void OnValidationEvent (object sender, ValidationEventArgs a)
- {
- errors ++;
- Message (TraceLevel.Error, "mdoc: {0}", a.Message);
- }
-
- static bool IsMonodocFile (string file)
- {
- if (File.Exists (file) && Path.GetExtension (file).ToLower () == ".xml")
- return true;
- else
- return false;
-
- }
- }
-}
-
diff --git a/mdoc/Resources/monodoc-ecma.xsd b/mdoc/Resources/monodoc-ecma.xsd
index 3ae49b62..3a777492 100644
--- a/mdoc/Resources/monodoc-ecma.xsd
+++ b/mdoc/Resources/monodoc-ecma.xsd
@@ -51,6 +51,8 @@ add masterdoc support?
<xs:attribute name="TypeParamName" type="xs:string" />
<xs:attribute name="overwrite" type="xs:boolean" />
<xs:attribute name="supported" type="xs:boolean"/>
+ <xs:attribute name="FrameworkAlternate" type="xs:string"/>
+ <xs:attribute name="Index" type="xs:integer"/>
<!-- define simple elements -->
<xs:element name="AssemblyName" type="xs:string" />
@@ -116,6 +118,7 @@ add masterdoc support?
<xs:element ref="ExcludedTypeName" minOccurs="0" />
<xs:element ref="ExcludedLibraryName" minOccurs="0" />
</xs:sequence>
+ <xs:attribute name="FrameworkAlternate" use="optional" />
</xs:complexType>
</xs:element>
@@ -467,6 +470,7 @@ add masterdoc support?
<xs:attribute ref="Language" />
<xs:attribute ref="Value" />
<xs:attribute ref="Usage" />
+ <xs:attribute name="FrameworkAlternate" use="optional" />
</xs:complexType>
</xs:element>
@@ -622,6 +626,8 @@ add masterdoc support?
<xs:attribute ref="Name" />
<xs:attribute ref="Type" />
<xs:attribute ref="RefType" />
+ <xs:attribute name="Index" use="optional" />
+ <xs:attribute name="FrameworkAlternate" use="optional" />
</xs:complexType>
</xs:element>
@@ -948,6 +954,8 @@ add masterdoc support?
<xs:element ref="Constraints" />
</xs:choice>
<xs:attribute ref="Name" use="required" />
+ <xs:attribute name="Index" use="optional" />
+ <xs:attribute name="FrameworkAlternate" use="optional" />
</xs:complexType>
</xs:element>
@@ -967,6 +975,7 @@ add masterdoc support?
<xs:attribute ref="Value"/>
<xs:attribute ref="Usage"/>
<xs:attribute ref="Maintainer" />
+ <xs:attribute name="FrameworkAlternate" use="optional" />
</xs:complexType>
</xs:element>
diff --git a/mdoc/mdoc.Test/ValidationTests.cs b/mdoc/mdoc.Test/ValidationTests.cs
new file mode 100644
index 00000000..54827d71
--- /dev/null
+++ b/mdoc/mdoc.Test/ValidationTests.cs
@@ -0,0 +1,154 @@
+using Mono.Documentation;
+using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.IO;
+using System.Text;
+using System.Xml;
+
+namespace mdoc.Test
+{
+ [TestFixture ()]
+ public class ValidationTests
+ {
+
+ [Test ()]
+ public void ValidationFailure ()
+ {
+ var context = InitializeTestContext ();
+
+ context.Validator.ValidateFile (new StringReader ("<random></random>"));
+
+ Assert.AreEqual (1, context.Errors.Count);
+ Assert.IsTrue (context.Errors.Any (e => e.Message.Contains ("random")));
+ }
+
+ [Test ()]
+ public void ValidationSuccess ()
+ {
+ var context = InitializeTestContext ();
+
+ context.Validator.ValidateFile (new StringReader ("<Type Name=\"AVKitError\" FullName=\"AVKit.AVKitError\"></Type>"));
+
+ Assert.AreEqual (0, context.Errors.Count);
+ }
+
+ [Test]
+ public void FrameworkAlternate_Attributes_Type ()
+ {
+ string xmlString = @"<Type Name=""AVKitError"" FullName=""AVKit.AVKitError"">
+ <Attributes>
+ <Attribute>
+ <AttributeName>ObjCRuntime.Introduced(ObjCRuntime.PlatformName.iOS, 9, 0, ObjCRuntime.PlatformArchitecture.None, null)</AttributeName>
+ </Attribute>
+ <Attribute FrameworkAlternate=""One;Two"">
+ <AttributeName>ObjCRuntime.Native</AttributeName>
+ </Attribute>
+ </Attributes>
+</Type>";
+
+
+ var context = InitializeTestContext ();
+
+ context.Validator.ValidateFile (new StringReader (xmlString));
+
+
+ Assert.AreEqual (0, context.Errors.Count, context.ErrorText);
+ }
+
+ [Test]
+ public void FrameworkAlternate_MemberSignature ()
+ {
+ string xmlString = @"<Type Name=""blah"" FullName=""blah.blah"">
+ <Members><Member MemberName=""Meth"">
+ <MemberSignature Language=""C#"" Value=""public void Meth (int a, string d, int c);"" FrameworkAlternate=""One;Three"" />
+ <MemberSignature Language=""C#"" Value=""public void Meth (int a, string b, int c);"" FrameworkAlternate=""Two"" />
+ <MemberType>b</MemberType>
+ <Docs></Docs>
+ </Member></Members></Type>";
+
+
+ var context = InitializeTestContext ();
+
+ context.Validator.ValidateFile (new StringReader (xmlString));
+
+
+ Assert.AreEqual (0, context.Errors.Count, context.ErrorText);
+ }
+
+ [Test]
+ public void FrameworkAlternate_TypeSignature ()
+ {
+ string xmlString = @"<Type Name=""blah"" FullName=""blah.blah"">
+ <TypeSignature Language=""C#"" Value=""blah"" FrameworkAlternate=""One;Three"" />
+ <TypeSignature Language=""C#"" Value=""blah2"" FrameworkAlternate=""Two"" />
+</Type>";
+
+
+ var context = InitializeTestContext ();
+
+ context.Validator.ValidateFile (new StringReader (xmlString));
+
+
+ Assert.AreEqual (0, context.Errors.Count, context.ErrorText);
+ }
+
+ [Test]
+ public void FrameworkAlternate_Parameter ()
+ {
+ string xmlString = @"<Member MemberName=""Meth"">
+ <MemberSignature Language=""C#"" Value=""blah"" />
+ <MemberType>Method</MemberType>
+ <Parameters>
+ <Parameter Name = ""a"" Type=""System.Int32"" Index=""0"" FrameworkAlternate=""One"" />
+ <Parameter Name = ""d"" Type=""System.Int32"" Index=""0"" FrameworkAlternate=""Three"" />
+ </Parameters>
+ <Docs></Docs>
+ </Member>";
+
+
+ var context = InitializeTestContext ();
+
+ context.Validator.ValidateFile (new StringReader (xmlString));
+
+
+ Assert.AreEqual (0, context.Errors.Count, context.ErrorText);
+ }
+
+ #region Test Context Stuff
+ struct ValidationContext
+ {
+ public MDocValidator Validator;
+ public List<Exception> Errors;
+ public string ErrorText{
+ get => Errors.Aggregate (
+ new StringBuilder (),
+ (sb, e) =>
+ {
+ sb.Append (e.Message + ";");
+ return sb;
+ }
+ ).ToString ();
+ }
+ }
+
+ private static ValidationContext InitializeTestContext ()
+ {
+ List<Exception> errors = new List<Exception> ();
+
+ MDocValidator validator = new MDocValidator ();
+ validator.InitializeSchema (
+ "ecma",
+ (a, b) => errors.Add (b.Exception)
+ );
+ ValidationContext context = new ValidationContext
+ {
+ Validator = validator,
+ Errors = errors
+ };
+ return context;
+ }
+ #endregion
+ }
+}
diff --git a/mdoc/mdoc.Test/XmlUpdateTests.cs b/mdoc/mdoc.Test/XmlUpdateTests.cs
index 2ced1283..39f58663 100644
--- a/mdoc/mdoc.Test/XmlUpdateTests.cs
+++ b/mdoc/mdoc.Test/XmlUpdateTests.cs
@@ -443,7 +443,7 @@ namespace mdoc.Test
Assert.IsTrue (attributes.Count () == 1);
Assert.AreEqual ("One", attributes[0].FirstChild.InnerText);
- Assert.AreEqual ("Three", attributes[0].GetAttribute ("FrameworkAlternate"));
+ Assert.AreEqual ("Three", attributes[0].GetAttribute (Consts.FrameworkAlternate));
}
[Test]
@@ -466,7 +466,7 @@ namespace mdoc.Test
Assert.IsTrue (attributes.Count () == 1);
Assert.AreEqual ("One", attributes[0].FirstChild.InnerText);
- Assert.IsFalse (attributes[0].HasAttribute ("FrameworkAlternate"));
+ Assert.IsFalse (attributes[0].HasAttribute (Consts.FrameworkAlternate));
}
[Test]
@@ -492,8 +492,8 @@ namespace mdoc.Test
Assert.IsTrue (attributes.Count () == 1);
Assert.AreEqual ("One", attributes[0].FirstChild.InnerText);
- Assert.IsTrue (attributes[0].HasAttribute ("FrameworkAlternate"));
- Assert.AreEqual ("Three;Two", attributes[0].GetAttribute ("FrameworkAlternate"));
+ Assert.IsTrue (attributes[0].HasAttribute (Consts.FrameworkAlternate));
+ Assert.AreEqual ("Three;Two", attributes[0].GetAttribute (Consts.FrameworkAlternate));
}
[Test]
@@ -519,8 +519,8 @@ namespace mdoc.Test
Assert.IsTrue (attributes.Count () == 1);
Assert.AreEqual ("One", attributes[0].FirstChild.InnerText);
- Assert.IsTrue (attributes[0].HasAttribute ("FrameworkAlternate"));
- Assert.AreEqual ("One;Three", attributes[0].GetAttribute ("FrameworkAlternate"));
+ Assert.IsTrue (attributes[0].HasAttribute (Consts.FrameworkAlternate));
+ Assert.AreEqual ("One;Three", attributes[0].GetAttribute (Consts.FrameworkAlternate));
}
[Test]
@@ -558,10 +558,10 @@ namespace mdoc.Test
Assert.IsTrue (attributes.Count () == 2);
Assert.AreEqual ("One", attributes[0].FirstChild.InnerText);
- Assert.IsFalse (attributes[0].HasAttribute ("FrameworkAlternate"));
+ Assert.IsFalse (attributes[0].HasAttribute (Consts.FrameworkAlternate));
Assert.AreEqual ("Two", attributes[1].FirstChild.InnerText);
- Assert.IsTrue (attributes[1].HasAttribute ("FrameworkAlternate"));
- Assert.AreEqual ("Three", attributes[1].GetAttribute ("FrameworkAlternate"));
+ Assert.IsTrue (attributes[1].HasAttribute (Consts.FrameworkAlternate));
+ Assert.AreEqual ("Three", attributes[1].GetAttribute (Consts.FrameworkAlternate));
}
[Test]
@@ -600,10 +600,10 @@ namespace mdoc.Test
Assert.IsTrue (attributes.Count () == 2);
Assert.AreEqual ("One", attributes[0].FirstChild.InnerText);
- Assert.IsFalse (attributes[0].HasAttribute ("FrameworkAlternate"));
+ Assert.IsFalse (attributes[0].HasAttribute (Consts.FrameworkAlternate));
Assert.AreEqual ("Two", attributes[1].FirstChild.InnerText);
- Assert.IsTrue (attributes[1].HasAttribute ("FrameworkAlternate"));
- Assert.AreEqual ("One", attributes[1].GetAttribute ("FrameworkAlternate"));
+ Assert.IsTrue (attributes[1].HasAttribute (Consts.FrameworkAlternate));
+ Assert.AreEqual ("One", attributes[1].GetAttribute (Consts.FrameworkAlternate));
}
[Test]
@@ -642,10 +642,10 @@ namespace mdoc.Test
Assert.IsTrue (attributes.Count () == 2);
Assert.AreEqual ("One", attributes[1].FirstChild.InnerText);
- Assert.IsTrue (attributes[1].HasAttribute ("FrameworkAlternate"));
- Assert.AreEqual ("Two", attributes[1].GetAttribute ("FrameworkAlternate"));
+ Assert.IsTrue (attributes[1].HasAttribute (Consts.FrameworkAlternate));
+ Assert.AreEqual ("Two", attributes[1].GetAttribute (Consts.FrameworkAlternate));
Assert.AreEqual ("Two", attributes[0].FirstChild.InnerText);
- Assert.IsFalse (attributes[0].HasAttribute ("FrameworkAlternate"));
+ Assert.IsFalse (attributes[0].HasAttribute (Consts.FrameworkAlternate));
}
@@ -672,8 +672,8 @@ namespace mdoc.Test
Assert.IsTrue (attributes.Count () == 1);
Assert.AreEqual ("One", attributes[0].FirstChild.InnerText);
- Assert.IsTrue (attributes[0].HasAttribute ("FrameworkAlternate"));
- Assert.AreEqual ("One;Two", attributes[0].GetAttribute ("FrameworkAlternate"));
+ Assert.IsTrue (attributes[0].HasAttribute (Consts.FrameworkAlternate));
+ Assert.AreEqual ("One;Two", attributes[0].GetAttribute (Consts.FrameworkAlternate));
}
@@ -705,8 +705,8 @@ namespace mdoc.Test
Assert.IsTrue (attributes.Count () == 1);
Assert.AreEqual ("One", attributes[0].FirstChild.InnerText);
- Assert.IsTrue (attributes[0].HasAttribute ("FrameworkAlternate"));
- Assert.AreEqual ("One;Two", attributes[0].GetAttribute ("FrameworkAlternate"));
+ Assert.IsTrue (attributes[0].HasAttribute (Consts.FrameworkAlternate));
+ Assert.AreEqual ("One;Two", attributes[0].GetAttribute (Consts.FrameworkAlternate));
}
[Test]
@@ -732,7 +732,7 @@ namespace mdoc.Test
Assert.IsTrue (attributes.Count () == 1);
Assert.AreEqual ("One", attributes[0].FirstChild.InnerText);
- Assert.IsFalse (attributes[0].HasAttribute ("FrameworkAlternate"));
+ Assert.IsFalse (attributes[0].HasAttribute (Consts.FrameworkAlternate));
}
string Normalize(string xml) {
diff --git a/mdoc/mdoc.Test/mdoc.Test.csproj b/mdoc/mdoc.Test/mdoc.Test.csproj
index 9cf223d0..01a8b803 100644
--- a/mdoc/mdoc.Test/mdoc.Test.csproj
+++ b/mdoc/mdoc.Test/mdoc.Test.csproj
@@ -100,6 +100,7 @@
<Compile Include="VBFormatterTests.cs" />
<Compile Include="FrameworkAlternateTests.cs" />
<Compile Include="XmlUpdateTests.cs" />
+ <Compile Include="ValidationTests.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config">
diff --git a/mdoc/mdoc.csproj b/mdoc/mdoc.csproj
index 718bbc07..6c6d229e 100644
--- a/mdoc/mdoc.csproj
+++ b/mdoc/mdoc.csproj
@@ -120,7 +120,7 @@
<Compile Include="Mono.Documentation\monodocs2slashdoc.cs" />
<Compile Include="Mono.Documentation\msitomsx.cs" />
<Compile Include="Mono.Documentation\normalize.cs" />
- <Compile Include="Mono.Documentation\validate.cs" />
+ <Compile Include="Mono.Documentation\MDocValidator.cs" />
<Compile Include="Mono.Documentation\webdoc.cs" />
<Compile Include="Mono.Documentation\XhtmlWriter.cs" />
<Compile Include="Mono.Documentation\exceptions.cs" />