[mdoc] Fixes an issue with member and type deletion.
authorJoel Martinez <joelmartinez@gmail.com>
Tue, 25 Aug 2015 19:52:13 +0000 (15:52 -0400)
committerJoel Martinez <joelmartinez@gmail.com>
Tue, 1 Sep 2015 18:52:54 +0000 (14:52 -0400)
Specifically, when updating classic and unified assemblies, members
that were completely removed from one or both assemblies were not
being removed from the XML. This patch updates mdoc's `DeleteMember`
method to properly handle deletion in all scenarios (normal, classic, unified).

Of course, deletion will still not happen if one of two things is true:

- `--delete` is *not* passed into the `mdoc update` call and the member node
  contains existing documentation.
- `--preserve` *is* passed into the `mdoc update` invocation.

In both of those cases, the member will not be deleted, and a message stating
as such will be written as a warning to the output.

mcs/tools/mdoc/Makefile
mcs/tools/mdoc/Mono.Documentation/monodocer.cs
mcs/tools/mdoc/Test/DocTest-DropNS-classic.cs
mcs/tools/mdoc/Test/DocTest-DropNS-unified.cs
mcs/tools/mdoc/Test/en.expected-dropns-delete/MyFramework.MyNamespace/MyClass.xml [new file with mode: 0644]
mcs/tools/mdoc/Test/en.expected-dropns-delete/MyFramework.MyNamespace/WillDelete.xml.remove [new file with mode: 0644]
mcs/tools/mdoc/Test/en.expected-dropns-delete/MyFramework.MyNamespace/nint.xml [new file with mode: 0644]
mcs/tools/mdoc/Test/en.expected-dropns-delete/index.xml [new file with mode: 0644]
mcs/tools/mdoc/Test/en.expected-dropns-delete/ns-MyFramework.MyNamespace.xml [new file with mode: 0644]

index a5bced66881cd52641c18ff1b705b88477814ec6..4675d4a833a49c6a3c4679785b8b1b4831e99b71 100644 (file)
@@ -108,6 +108,22 @@ Test/DocTest-DropNS-classic.dll:
 Test/DocTest-DropNS-unified.dll:
        $(CSCOMPILE) $(TEST_CSCFLAGS) -debug -unsafe -target:library -out:$@ Test/DocTest-DropNS-unified.cs
 
+Test/DocTest-DropNS-unified-deletetest.dll:
+       rm -f Test/DocTest-DropNS-unified-deletetest.dll
+       $(CSCOMPILE) $(TEST_CSCFLAGS) -debug -unsafe -target:library -out:$@ Test/DocTest-DropNS-unified.cs /define:DELETETEST
+
+Test/DocTest-DropNS-unified-deletetest-V2.dll:
+       rm -f Test/DocTest-DropNS-unified-deletetest.dll
+       $(CSCOMPILE) $(TEST_CSCFLAGS) -debug -unsafe -target:library -out:Test/DocTest-DropNS-unified-deletetest.dll Test/DocTest-DropNS-unified.cs /define:DELETETEST,V2
+
+Test/DocTest-DropNS-classic-deletetest.dll:
+       rm -f Test/DocTest-DropNS-classic-deletetest.dll
+       $(CSCOMPILE) $(TEST_CSCFLAGS) -debug -unsafe -target:library -out:$@ Test/DocTest-DropNS-classic.cs /define:DELETETEST
+
+Test/DocTest-DropNS-classic-deletetest-V2.dll:
+       rm -f Test/DocTest-DropNS-classic-deletetest.dll
+       $(CSCOMPILE) $(TEST_CSCFLAGS) -debug -unsafe -target:library -out:Test/DocTest-DropNS-classic-deletetest.dll Test/DocTest-DropNS-classic.cs /define:DELETETEST,V2
+
 Test/DocTest.dll: 
        $(CSCOMPILE) $(TEST_CSCFLAGS) -debug -unsafe -target:library -out:$@ Test/DocTest.cs
 
@@ -151,6 +167,18 @@ check-monodocer-dropns-classic: $(PROGRAM)
        $(MAKE) update-monodocer-dropns-unified
        diff --exclude=.svn -rup Test/en.expected-dropns-classic-v1 Test/en.actual
 
+check-monodocer-dropns-delete: $(PROGRAM)
+       -rm -Rf Test/en.actual
+       $(MAKE) Test/DocTest-DropNS-classic-deletetest.dll
+       $(MONO) $(PROGRAM) update --delete --exceptions=all -o Test/en.actual Test/DocTest-DropNS-classic-deletetest.dll
+       $(MAKE) Test/DocTest-DropNS-unified-deletetest.dll
+       $(MONO) $(PROGRAM) update --delete --exceptions=all -o Test/en.actual Test/DocTest-DropNS-unified-deletetest.dll --dropns Test/DocTest-DropNS-unified-deletetest.dll=MyFramework
+       $(MAKE) Test/DocTest-DropNS-classic-deletetest-V2.dll
+       $(MONO) $(PROGRAM) update --delete --exceptions=all -o Test/en.actual Test/DocTest-DropNS-classic-deletetest.dll
+       $(MAKE) Test/DocTest-DropNS-unified-deletetest-V2.dll
+       $(MONO) $(PROGRAM) update --delete --exceptions=all -o Test/en.actual Test/DocTest-DropNS-unified-deletetest.dll --dropns Test/DocTest-DropNS-unified-deletetest.dll=MyFramework
+       diff --exclude=.dvn -rup Test/en.expected-dropns-delete Test/en.actual
+
 check-monodocer-dropns-classic-withsecondary: $(PROGRAM)
        # tests case where a secondary assembly is included with a --dropns parameter
        -rm -Rf Test/en.actual
@@ -343,6 +371,7 @@ check-doc-tools-update: check-monodocer-since-update \
        check-monodocer-update \
        check-monodocer-dropns-classic \
        check-monodocer-dropns-classic-withsecondary \
+       check-monodocer-dropns-delete \
        check-monodocer-internal-interface \
        check-monodocer-enumerations \
        check-monodocer-delete-update \
index 81bcc850c5671d9a038c7d1f6677fdb1d41952e7..50e7d3e287cc9da3e18734eb6ea9a980bd59a529 100644 (file)
@@ -187,6 +187,11 @@ class MDocUpdater : MDocCommand
                return !string.IsNullOrWhiteSpace (droppedNamespace) && droppedAssemblies.Any(da => da == forModule.Name);
        }
 
+       public static bool HasDroppedAnyNamespace ()
+       {
+               return !string.IsNullOrWhiteSpace (droppedNamespace);
+       }
+
        
        static List<string> droppedAssemblies = new List<string>();
 
@@ -1012,11 +1017,40 @@ class MDocUpdater : MDocCommand
                                                continue;
                                        }
 
-                                       if (string.IsNullOrWhiteSpace (PreserveTag)) { // only do this if there was no -preserve
+                                       Action actuallyDelete = () => {
                                                string newname = typefile.FullName + ".remove";
-                                               try { System.IO.File.Delete(newname); } catch (Exception) { }
-                                               try { typefile.MoveTo(newname); } catch (Exception) { }
-                                               Console.WriteLine("Class no longer present; file renamed: " + Path.Combine(nsdir.Name, typefile.Name));
+                                               try { System.IO.File.Delete (newname); } catch (Exception ex) { Warning ("Unable to delete existing file: {0}", newname); }
+                                               try { typefile.MoveTo (newname); } catch (Exception ex) { Warning ("Unable to rename to: {0}", newname); }
+                                               Console.WriteLine ("Class no longer present; file renamed: " + Path.Combine (nsdir.Name, typefile.Name));
+                                       };
+
+                                       if (string.IsNullOrWhiteSpace (PreserveTag)) { // only do this if there was not a -preserve
+                                               using (TextWriter writer = OpenWrite (typefile.FullName, FileMode.Truncate))
+                                                       WriteXml (doc.DocumentElement, writer);
+                                               
+                                               var unifiedAssemblyNode = doc.SelectSingleNode ("/Type/AssemblyInfo[@apistyle='unified']");
+                                               var classicAssemblyNode = doc.SelectSingleNode ("/Type/AssemblyInfo[@apistyle='classic']");
+                                               bool isUnifiedRun = HasDroppedAnyNamespace ();
+                                               bool isClassicOrNormalRun = !isUnifiedRun;
+                                               if (isClassicOrNormalRun) {
+                                                       if (unifiedAssemblyNode != null) {
+                                                               Warning ("*** this type is marked as unified, not deleting during this run: {0}", typefile.FullName);
+                                                               // if truly removed from both assemblies, it will be removed fully during the unified run
+                                                               continue;
+                                                       } else {
+                                                               // we should be safe to delete here because it was not marked as a unified assembly
+                                                               actuallyDelete ();
+                                                       }
+                                               }
+                                               if (isUnifiedRun) {
+                                                       if (classicAssemblyNode != null) {
+                                                               Warning ("*** this type is marked as classic, not deleting {0}", typefile.FullName);
+                                                               continue; 
+                                                       } else {
+                                                               // safe to delete because it wasn't marked as a classic assembly, so the type is gone in both.
+                                                               actuallyDelete ();
+                                                       }
+                                               }
                                        }
                                }
                        }
@@ -1291,34 +1325,51 @@ class MDocUpdater : MDocCommand
                string format = output != null
                        ? "{0}: File='{1}'; Signature='{4}'"
                        : "{0}: XPath='/Type[@FullName=\"{2}\"]/Members/Member[@MemberName=\"{3}\"]'; Signature='{4}'";
+               string signature = member.SelectSingleNode ("MemberSignature[@Language='C#']/@Value").Value;
                Warning (format,
                                reason, 
                                output,
                                member.OwnerDocument.DocumentElement.GetAttribute ("FullName"),
                                member.Attributes ["MemberName"].Value, 
-                               member.SelectSingleNode ("MemberSignature[@Language='C#']/@Value").Value);
-                       if (!delete && MemberDocsHaveUserContent (member)) {
-                               Warning ("Member deletions must be enabled with the --delete option.");
-                       } else if (HasDroppedNamespace (type)) {
-                               // if we're dropping the namespace, add the "classic style"
-                               var existingAttribute = member.Attributes ["apistyle"];
-                               if (existingAttribute != null) {
-                                       existingAttribute.Value = "classic";
-                               } else {
-                                       // add the attribute and do not remove
-                                       XmlAttribute apistyleAttr = member.OwnerDocument.CreateAttribute ("apistyle");
+                               signature);
 
-                                       apistyleAttr.Value = "classic";
+               // Identify all of the different states that could affect our decision to delete the member
+               bool shouldPreserve = !string.IsNullOrWhiteSpace (PreserveTag);
+               bool hasContent = MemberDocsHaveUserContent (member);
+               bool shouldDelete = !shouldPreserve && (delete || !hasContent);
 
-                                       member.Attributes.Append (apistyleAttr);
-                               }
-                       } else if (!HasDroppedNamespace (type) && member.Attributes ["apistyle"] != null && member.Attributes ["apistyle"].Value == "unified") {
-                               // do nothing if there's an apistyle=new attribute and we haven't dropped the namespace
-                       } else if (!string.IsNullOrWhiteSpace (PreserveTag)) {
-                               // do nothing
-                       } else {
+               bool unifiedRun = HasDroppedNamespace (type);
+
+               var classicAssemblyInfo = member.SelectSingleNode ("AssemblyInfo[@apistyle='classic']");
+               bool nodeIsClassic = classicAssemblyInfo != null;
+
+               Action actuallyDelete = () => {
                        todelete.Add (member);
                        deletions++;
+               };
+
+               if (!shouldDelete) {
+                       // explicitly not deleting
+                       string message = shouldPreserve ? 
+                                       "Not deleting '{0}' due to --preserve." :
+                                       "Not deleting '{0}'; must be enabled with the --delete option";
+                       Warning (message, signature);
+               } else if (unifiedRun && nodeIsClassic) {
+                       // this is a unified run, and the member doesn't exist, but is marked as being in the classic assembly.
+                               Warning ("Not removing '{0}' since it's still in the classic assembly.", signature);
+               } else if (unifiedRun && !nodeIsClassic) {
+                       // unified run, and the node is not classic, which means it doesn't exist anywhere.
+                       actuallyDelete ();
+               } else {
+                       if (!nodeIsClassic) {
+                               actuallyDelete ();
+                       } else {
+                               Warning ("Removing classic from '{0}' ... will be removed in the unified run if not present there.", signature);
+                               member.RemoveApiStyle (ApiStyle.Classic);
+                               if (classicAssemblyInfo != null) {
+                                       member.RemoveChild (classicAssemblyInfo);
+                               }
+                       }
                }
        }
 
@@ -2882,21 +2933,32 @@ enum ApiStyle {
 static class DocUtils {
 
        public static bool DoesNotHaveApiStyle(this XmlElement element, ApiStyle style) {
-               string styleString = style.ToString ().ToLower ();
+               string styleString = style.ToString ().ToLowerInvariant ();
                        string apistylevalue = element.GetAttribute ("apistyle");
                        return apistylevalue != styleString || string.IsNullOrWhiteSpace(apistylevalue);
        }
        public static bool HasApiStyle(this XmlElement element, ApiStyle style) {
-               string styleString = style.ToString ().ToLower ();
+               string styleString = style.ToString ().ToLowerInvariant ();
                return element.GetAttribute ("apistyle") == styleString;
        }
        public static void AddApiStyle(this XmlElement element, ApiStyle style) {
-               string styleString = style.ToString ().ToLower ();
+               string styleString = style.ToString ().ToLowerInvariant ();
                var existingValue = element.GetAttribute ("apistyle");
                if (string.IsNullOrWhiteSpace (existingValue) || existingValue != styleString) {
                        element.SetAttribute ("apistyle", styleString);
                }
        }
+       public static void RemoveApiStyle (this XmlElement element, ApiStyle style) 
+       {
+               element.RemoveAttribute (style.ToString ().ToLowerInvariant ());
+       }
+       public static void RemoveApiStyle (this XmlNode node, ApiStyle style) 
+       {
+               var styleAttribute = node.Attributes ["apistyle"];
+               if (styleAttribute != null) {
+                       node.Attributes.Remove (styleAttribute);
+               }
+       }
 
        public static bool IsExplicitlyImplemented (MethodDefinition method)
        {
index a279b0e85a75619279e7193cfef543bdbd875b83..8346834b778364e1413d16713c509c446398b228 100644 (file)
@@ -4,5 +4,25 @@ namespace MyFramework.MyNamespace {
                public float Hello(int value) {
                        return 0.0f;
                }
+               #if DELETETEST
+               public string InBoth {get;set;}
+               public string InBothClassic {get;set;}
+               public int InBothMagicType {get;set;}
+               #endif
+
+               #if DELETETEST && V2
+               public string AddedInV2 {get;set;}
+               public string AddedInV2Classic {get;set;}
+               #endif
+               #if DELETETEST && !V2
+               public string WillDeleteInV2 {get;set;}
+               public string WillDeleteInV2Classic {get;set;}
+               #endif
        }
+
+       #if DELETETEST && !V2
+       public class WillDelete {
+               public string Name {get;set;}
+       }
+       #endif
 }
index 8ee5e8a6ffd0875e9cc3d6b2064cf33147e23db3..9b0c364aef3eb084e5079fe50527f893cda0ddf7 100644 (file)
@@ -4,5 +4,30 @@ namespace MyNamespace {
                public float Hello(int value) {
                        return 0.0f;
                }
+               #if DELETETEST
+               public string InBoth {get;set;}
+               public string InBothUnified {get;set;}
+               public nint InBothMagicType {get;set;}
+               #endif
+
+               #if DELETETEST && V2
+               public string AddedInV2 {get;set;}
+               public string AddedInV2Unified {get;set;}
+               #endif
+               #if DELETETEST && !V2
+               public string WillDeleteInV2 {get;set;}
+               public string WillDeleteInV2Unified {get;set;}
+               #endif
        }
+
+       #if DELETETEST
+       public struct nint {
+
+       }
+       #endif
+       #if DELETETEST && !V2
+       public class WillDelete {
+               public string Name {get;set;}
+       }
+       #endif
 }
diff --git a/mcs/tools/mdoc/Test/en.expected-dropns-delete/MyFramework.MyNamespace/MyClass.xml b/mcs/tools/mdoc/Test/en.expected-dropns-delete/MyFramework.MyNamespace/MyClass.xml
new file mode 100644 (file)
index 0000000..cb620b8
--- /dev/null
@@ -0,0 +1,204 @@
+<Type Name="MyClass" FullName="MyFramework.MyNamespace.MyClass">
+  <TypeSignature Language="C#" Value="public class MyClass" />
+  <TypeSignature Language="ILAsm" Value=".class public auto ansi beforefieldinit MyClass extends System.Object" />
+  <AssemblyInfo apistyle="classic">
+    <AssemblyName>DocTest-DropNS-classic-deletetest</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <AssemblyInfo apistyle="unified">
+    <AssemblyName>DocTest-DropNS-unified-deletetest</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.Object</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>To be added.</summary>
+    <remarks>To be added.</remarks>
+  </Docs>
+  <Members>
+    <Member MemberName=".ctor">
+      <MemberSignature Language="C#" Value="public MyClass ();" />
+      <MemberSignature Language="ILAsm" Value=".method public hidebysig specialname rtspecialname instance void .ctor() cil managed" />
+      <MemberType>Constructor</MemberType>
+      <AssemblyInfo apistyle="classic">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <AssemblyInfo apistyle="unified">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="AddedInV2">
+      <MemberSignature Language="C#" Value="public string AddedInV2 { get; set; }" />
+      <MemberSignature Language="ILAsm" Value=".property instance string AddedInV2" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo apistyle="classic">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <AssemblyInfo apistyle="unified">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="AddedInV2Classic">
+      <MemberSignature Language="C#" Value="public string AddedInV2Classic { get; set; }" />
+      <MemberSignature Language="ILAsm" Value=".property instance string AddedInV2Classic" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo apistyle="classic">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="AddedInV2Unified">
+      <MemberSignature Language="C#" Value="public string AddedInV2Unified { get; set; }" />
+      <MemberSignature Language="ILAsm" Value=".property instance string AddedInV2Unified" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo apistyle="unified">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Hello">
+      <MemberSignature Language="C#" Value="public float Hello (int value);" />
+      <MemberSignature Language="ILAsm" Value=".method public hidebysig instance float32 Hello(int32 value) cil managed" />
+      <MemberType>Method</MemberType>
+      <AssemblyInfo apistyle="classic">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <AssemblyInfo apistyle="unified">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.Single</ReturnType>
+      </ReturnValue>
+      <Parameters>
+        <Parameter Name="value" Type="System.Int32" />
+      </Parameters>
+      <Docs>
+        <param name="value">To be added.</param>
+        <summary>To be added.</summary>
+        <returns>To be added.</returns>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="InBoth">
+      <MemberSignature Language="C#" Value="public string InBoth { get; set; }" />
+      <MemberSignature Language="ILAsm" Value=".property instance string InBoth" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo apistyle="classic">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <AssemblyInfo apistyle="unified">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="InBothClassic">
+      <MemberSignature Language="C#" Value="public string InBothClassic { get; set; }" />
+      <MemberSignature Language="ILAsm" Value=".property instance string InBothClassic" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo apistyle="classic">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="InBothMagicType">
+      <MemberSignature Language="C#" Value="public int InBothMagicType { get; set; }" apistyle="classic" />
+      <MemberSignature Language="ILAsm" Value=".property instance int32 InBothMagicType" apistyle="classic" />
+      <MemberSignature Language="C#" Value="public MyFramework.MyNamespace.nint InBothMagicType { get; set; }" apistyle="unified" />
+      <MemberSignature Language="ILAsm" Value=".property instance valuetype MyFramework.MyNamespace.nint InBothMagicType" apistyle="unified" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo apistyle="classic">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <AssemblyInfo apistyle="unified">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType apistyle="classic">System.Int32</ReturnType>
+        <ReturnType apistyle="unified">MyFramework.MyNamespace.nint</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="InBothUnified">
+      <MemberSignature Language="C#" Value="public string InBothUnified { get; set; }" />
+      <MemberSignature Language="ILAsm" Value=".property instance string InBothUnified" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo apistyle="unified">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="MyProperty">
+      <MemberSignature Language="C#" Value="public string MyProperty { get; set; }" />
+      <MemberSignature Language="ILAsm" Value=".property instance string MyProperty" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo apistyle="classic">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <AssemblyInfo apistyle="unified">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/tools/mdoc/Test/en.expected-dropns-delete/MyFramework.MyNamespace/WillDelete.xml.remove b/mcs/tools/mdoc/Test/en.expected-dropns-delete/MyFramework.MyNamespace/WillDelete.xml.remove
new file mode 100644 (file)
index 0000000..775b8af
--- /dev/null
@@ -0,0 +1,49 @@
+<Type Name="WillDelete" FullName="MyFramework.MyNamespace.WillDelete">
+  <TypeSignature Language="C#" Value="public class WillDelete" />
+  <TypeSignature Language="ILAsm" Value=".class public auto ansi beforefieldinit WillDelete extends System.Object" />
+  <Base>
+    <BaseTypeName>System.Object</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>To be added.</summary>
+    <remarks>To be added.</remarks>
+  </Docs>
+  <Members>
+    <Member MemberName=".ctor">
+      <MemberSignature Language="C#" Value="public WillDelete ();" />
+      <MemberSignature Language="ILAsm" Value=".method public hidebysig specialname rtspecialname instance void .ctor() cil managed" />
+      <MemberType>Constructor</MemberType>
+      <AssemblyInfo apistyle="classic">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <AssemblyInfo apistyle="unified">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <Parameters />
+      <Docs>
+        <summary>To be added.</summary>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+    <Member MemberName="Name">
+      <MemberSignature Language="C#" Value="public string Name { get; set; }" />
+      <MemberSignature Language="ILAsm" Value=".property instance string Name" />
+      <MemberType>Property</MemberType>
+      <AssemblyInfo apistyle="classic">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <AssemblyInfo apistyle="unified">
+        <AssemblyVersion>0.0.0.0</AssemblyVersion>
+      </AssemblyInfo>
+      <ReturnValue>
+        <ReturnType>System.String</ReturnType>
+      </ReturnValue>
+      <Docs>
+        <summary>To be added.</summary>
+        <value>To be added.</value>
+        <remarks>To be added.</remarks>
+      </Docs>
+    </Member>
+  </Members>
+</Type>
diff --git a/mcs/tools/mdoc/Test/en.expected-dropns-delete/MyFramework.MyNamespace/nint.xml b/mcs/tools/mdoc/Test/en.expected-dropns-delete/MyFramework.MyNamespace/nint.xml
new file mode 100644 (file)
index 0000000..2a8b2e2
--- /dev/null
@@ -0,0 +1,17 @@
+<Type Name="nint" FullName="MyFramework.MyNamespace.nint">
+  <TypeSignature Language="C#" Value="public struct nint" />
+  <TypeSignature Language="ILAsm" Value=".class public sequential ansi sealed beforefieldinit nint extends System.ValueType" />
+  <AssemblyInfo apistyle="unified">
+    <AssemblyName>DocTest-DropNS-unified-deletetest</AssemblyName>
+    <AssemblyVersion>0.0.0.0</AssemblyVersion>
+  </AssemblyInfo>
+  <Base>
+    <BaseTypeName>System.ValueType</BaseTypeName>
+  </Base>
+  <Interfaces />
+  <Docs>
+    <summary>To be added.</summary>
+    <remarks>To be added.</remarks>
+  </Docs>
+  <Members />
+</Type>
diff --git a/mcs/tools/mdoc/Test/en.expected-dropns-delete/index.xml b/mcs/tools/mdoc/Test/en.expected-dropns-delete/index.xml
new file mode 100644 (file)
index 0000000..0988450
--- /dev/null
@@ -0,0 +1,23 @@
+<Overview>
+  <Assemblies>
+    <Assembly Name="DocTest-DropNS-unified-deletetest" Version="0.0.0.0">
+      <Attributes>
+        <Attribute>
+          <AttributeName>System.Diagnostics.Debuggable(System.Diagnostics.DebuggableAttribute+DebuggingModes.IgnoreSymbolStoreSequencePoints)</AttributeName>
+        </Attribute>
+        <Attribute>
+          <AttributeName>System.Runtime.CompilerServices.RuntimeCompatibility(WrapNonExceptionThrows=true)</AttributeName>
+        </Attribute>
+      </Attributes>
+    </Assembly>
+  </Assemblies>
+  <Remarks>To be added.</Remarks>
+  <Copyright>To be added.</Copyright>
+  <Types>
+    <Namespace Name="MyFramework.MyNamespace">
+      <Type Name="MyClass" Kind="Class" />
+      <Type Name="nint" Kind="Structure" />
+    </Namespace>
+  </Types>
+  <Title>DocTest-DropNS-classic-deletetest</Title>
+</Overview>
diff --git a/mcs/tools/mdoc/Test/en.expected-dropns-delete/ns-MyFramework.MyNamespace.xml b/mcs/tools/mdoc/Test/en.expected-dropns-delete/ns-MyFramework.MyNamespace.xml
new file mode 100644 (file)
index 0000000..74df75a
--- /dev/null
@@ -0,0 +1,6 @@
+<Namespace Name="MyFramework.MyNamespace">
+  <Docs>
+    <summary>To be added.</summary>
+    <remarks>To be added.</remarks>
+  </Docs>
+</Namespace>