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
diff options
context:
space:
mode:
authorJoel Martinez <joelmartinez@gmail.com>2017-09-15 00:01:50 +0300
committerJoel Martinez <joelmartinez@gmail.com>2017-09-15 00:01:50 +0300
commit1b452b9185083e7255d58a04a60fb5ddec398445 (patch)
tree7fe185dee5baf81e4e2871a8b4d3e5ad0e814415
parent2c1edaf8a0396c0f6f4f8bf9d54526d6be8d6f4d (diff)
mdoc: Improves member/xml node matching on members with modopt/modreq.preview-5.0.0.23
Additionally, duplicate members that differ very slightly (as in the case of members with modopt/modreq made with older versions of mdoc) will now be deleted instead of simply raisining a warning. Closes #107
-rw-r--r--mdoc/Consts.cs2
-rw-r--r--mdoc/Mono.Documentation/monodocer.cs77
-rw-r--r--mdoc/mdoc.Test/AssemblyGenerator.workbook86
3 files changed, 141 insertions, 24 deletions
diff --git a/mdoc/Consts.cs b/mdoc/Consts.cs
index 2a014973..eebed4e0 100644
--- a/mdoc/Consts.cs
+++ b/mdoc/Consts.cs
@@ -3,6 +3,6 @@ namespace Mono.Documentation
{
public static class Consts
{
- public static string MonoVersion = "5.0.0.22";
+ public static string MonoVersion = "5.0.0.23";
}
}
diff --git a/mdoc/Mono.Documentation/monodocer.cs b/mdoc/Mono.Documentation/monodocer.cs
index a7842815..859e2833 100644
--- a/mdoc/Mono.Documentation/monodocer.cs
+++ b/mdoc/Mono.Documentation/monodocer.cs
@@ -1309,10 +1309,9 @@ class MDocUpdater : MDocCommand
if (object.ReferenceEquals (oldmember, seenmembers [sig])) {
// ignore, already seen
}
- else if (DefaultMemberComparer.Compare (oldmember, seenmembers [sig]) == 0)
+ else
DeleteMember ("Duplicate Member Found", output, oldmember, todelete, type);
- else
- Warning ("TODO: found a duplicate member '{0}', but it's not identical to the prior member found!", sig);
+
continue;
}
@@ -4227,6 +4226,24 @@ class DocumentationMember {
public string MemberName;
public string MemberType;
+ /// <summary>Removes modreq and modopt from ReturnType, Parameters, and TypeParameters</summary>
+ private void CleanTypes() {
+ ReturnType = MemberFormatter.RemoveMod (ReturnType);
+ MemberType = MemberFormatter.RemoveMod (MemberType);
+
+ if (Parameters != null)
+ {
+ for (var i = 0; i < Parameters.Count; i++)
+ Parameters[i] = MemberFormatter.RemoveMod (Parameters[i]);
+ }
+
+ if (TypeParameters != null)
+ {
+ for (var i = 0; i < TypeParameters.Count; i++)
+ TypeParameters[i] = MemberFormatter.RemoveMod (TypeParameters[i]);
+ }
+ }
+
public DocumentationMember (XmlReader reader)
{
MemberName = reader.GetAttribute ("MemberName");
@@ -4279,6 +4296,8 @@ class DocumentationMember {
} else {
DiscernTypeParameters ();
}
+
+ CleanTypes ();
}
public DocumentationMember (XmlNode node)
@@ -4311,6 +4330,8 @@ class DocumentationMember {
else {
DiscernTypeParameters ();
}
+
+ CleanTypes ();
}
void DiscernTypeParameters ()
@@ -4390,32 +4411,42 @@ public abstract class MemberFormatter {
}
protected virtual string GetTypeName (TypeReference type, DynamicParserContext context)
- {
- if (type == null)
- throw new ArgumentNullException (nameof (type));
+ {
+ if (type == null)
+ throw new ArgumentNullException (nameof (type));
- var typeName = _AppendTypeName (new StringBuilder (type.Name.Length), type, context).ToString ();
+ var typeName = _AppendTypeName (new StringBuilder (type.Name.Length), type, context).ToString ();
+ typeName = RemoveMod (typeName);
- // For custom modifiers (modopt/modreq), we are just excising them
- // via string manipulation for simplicity; since these cannot be
- // expressed in C#. If finer control is needed in the future, you can
- // use IModifierType, PointerType, ByReferenceType, etc.
+ return typeName;
+ }
- int modIndex = Math.Max (typeName.LastIndexOf ("modopt(", StringComparison.Ordinal), typeName.LastIndexOf ("modreq(", StringComparison.Ordinal));
- if (modIndex > 0) {
- var tname = typeName.Substring (0, modIndex-1);
- var parenIndex = typeName.LastIndexOf (')');
- if (parenIndex == typeName.Length - 2) { // see if there's metadata like a pointer
- tname += typeName.Last ();
- }
- typeName = tname;
- }
+ public static string RemoveMod (string typeName)
+ {
+ if (string.IsNullOrWhiteSpace (typeName)) return typeName;
- return typeName;
- }
+ // For custom modifiers (modopt/modreq), we are just excising them
+ // via string manipulation for simplicity; since these cannot be
+ // expressed in C#. If finer control is needed in the future, you can
+ // use IModifierType, PointerType, ByReferenceType, etc.
+
+ int modIndex = Math.Max (typeName.LastIndexOf ("modopt(", StringComparison.Ordinal), typeName.LastIndexOf ("modreq(", StringComparison.Ordinal));
+ if (modIndex > 0)
+ {
+ var tname = typeName.Substring (0, modIndex - 1);
+ var parenIndex = typeName.LastIndexOf (')');
+ if (parenIndex == typeName.Length - 2)
+ { // see if there's metadata like a pointer
+ tname += typeName.Last ();
+ }
+ typeName = tname;
+ }
+
+ return typeName;
+ }
- protected virtual char[] ArrayDelimeters {
+ protected virtual char[] ArrayDelimeters {
get {return new char[]{'[', ']'};}
}
diff --git a/mdoc/mdoc.Test/AssemblyGenerator.workbook b/mdoc/mdoc.Test/AssemblyGenerator.workbook
new file mode 100644
index 00000000..9a65e07b
--- /dev/null
+++ b/mdoc/mdoc.Test/AssemblyGenerator.workbook
@@ -0,0 +1,86 @@
+---
+id: c70709d1-d0a6-4dec-9ce5-de04540e5de6
+title: AssemblyGenerator
+uti: com.xamarin.workbook
+platforms:
+- Console
+---
+
+From [this article](https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.isudtreturn\(v=vs.110\).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1)
+
+```csharp
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.CompilerServices;
+using System.Threading;
+```
+
+```csharp
+class CodeEmitter {
+ AssemblyBuilder asmBuilder;
+ string asmName;
+ ModuleBuilder modBuilder;
+ public CodeEmitter(string name) {
+ asmName = name;
+ AssemblyName aname = new AssemblyName { Name = name };
+ AppDomain currentDomain = Thread.GetDomain();
+ asmBuilder = currentDomain.DefineDynamicAssembly(aname, AssemblyBuilderAccess.RunAndSave);
+ modBuilder = asmBuilder.DefineDynamicModule(asmName);
+ }
+
+ public TypeBuilder CreateType(string name) {
+ return modBuilder.DefineType(name, TypeAttributes.Public);
+ }
+
+ public void WriteAssembly(MethodBuilder entryPoint) {
+ asmBuilder.SetEntryPoint(entryPoint);
+ asmBuilder.Save(asmName);
+ }
+}
+```
+
+```csharp
+void main() {
+ CodeEmitter e = new CodeEmitter("test-mod.exe");
+ TypeBuilder mainClass = e.CreateType("MainClass");
+
+ // main method
+ MethodBuilder mBuilder = mainClass.DefineMethod("mainMethod", MethodAttributes.Static);
+ ILGenerator ilGen = mBuilder.GetILGenerator();
+ ilGen.Emit(OpCodes.Ldstr, "Hello World");
+ Type[] type = new [] {typeof(string)};
+ MethodInfo writeMI = typeof(Console).GetMethod("WriteLine", type);
+ ilGen.EmitCall(OpCodes.Call, writeMI, null);
+ ilGen.Emit(OpCodes.Ret);
+
+ Type[] fType = new [] { typeof(IsUdtReturn)};
+
+ // operator overload
+ MethodBuilder sBuilder = mainClass.DefineMethod(
+ "op_Decrement",
+ MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.Public,
+ CallingConventions.Any,
+ Type.GetType("System.Void"),
+ fType, // rtype required mods
+ null, // rtype optional mods
+ null, // parameters
+ null, // parameter modreq
+ null); // parameters modopt
+
+ var silGen = sBuilder.GetILGenerator();
+ silGen.Emit(OpCodes.Ret);
+
+ // field
+ //Type[] fType = new [] { typeof(IsUdtReturn)};
+ mainClass.DefineField("modifiedInteger", Type.GetType("System.Type"), fType, null, FieldAttributes.Public);
+
+ // write
+ mainClass.CreateType();
+ e.WriteAssembly(mBuilder);
+ Console.WriteLine("Assembly created");
+}
+```
+
+```csharp
+main();
+``` \ No newline at end of file