Merge pull request #495 from nicolas-raoul/fix-for-issue2907-with-no-formatting-changes
[mono.git] / mcs / tools / mdoc / Mono.Documentation / monodocer.cs
index cd878db91b8cbee71a9011f2797808920549fda0..dcb23d2f17c9890b7477423b5c0f73e9717f0598 100644 (file)
@@ -5,6 +5,7 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Diagnostics;
 using System.Globalization;
 using System.IO;
@@ -59,10 +60,11 @@ class MDocUpdater : MDocCommand
 
        MyXmlNodeList extensionMethods = new MyXmlNodeList ();
 
+       HashSet<string> forwardedTypes = new HashSet<string> ();
+
        public override void Run (IEnumerable<string> args)
        {
                show_exceptions = DebugOutput;
-               string import = null;
                var types = new List<string> ();
                var p = new OptionSet () {
                        { "delete",
@@ -142,6 +144,9 @@ class MDocUpdater : MDocCommand
                
                this.assemblies = assemblies.Select (a => LoadAssembly (a)).ToList ();
 
+               // Store types that have been forwarded to avoid duplicate generation
+               GatherForwardedTypes ();
+
                docEnum = docEnum ?? new DocumentationEnumerator ();
                
                // PERFORM THE UPDATES
@@ -188,6 +193,13 @@ class MDocUpdater : MDocCommand
                }
        }
 
+       void GatherForwardedTypes ()
+       {
+               foreach (var asm in assemblies)
+                       foreach (var type in asm.MainModule.ExportedTypes.Where (t => t.IsForwarder).Select (t => t.FullName))
+                               forwardedTypes.Add (type);
+       }
+
        static ExceptionLocations ParseExceptionLocations (string s)
        {
                ExceptionLocations loc = ExceptionLocations.Member;
@@ -618,7 +630,7 @@ class MDocUpdater : MDocCommand
                index_assemblies.RemoveAll ();
 
 
-               HashSet<string> goodfiles = new HashSet<string> ();
+               HashSet<string> goodfiles = new HashSet<string> (StringComparer.OrdinalIgnoreCase);
 
                foreach (AssemblyDefinition assm in assemblies) {
                        AddIndexAssembly (assm, index_assemblies);
@@ -641,7 +653,7 @@ class MDocUpdater : MDocCommand
        {
                foreach (TypeDefinition type in docEnum.GetDocumentationTypes (assembly, null)) {
                        string typename = GetTypeFileName(type);
-                       if (!IsPublic (type) || typename.IndexOfAny (InvalidFilenameChars) >= 0)
+                       if (!IsPublic (type) || typename.IndexOfAny (InvalidFilenameChars) >= 0 || forwardedTypes.Contains (type.FullName))
                                continue;
 
                        string reltypepath = DoUpdateType (type, source, dest);
@@ -754,7 +766,8 @@ class MDocUpdater : MDocCommand
        {
                TypeDefinition decl = type;
                while (decl != null) {
-                       if (!(decl.IsPublic || decl.IsNestedPublic)) {
+                       if (!(decl.IsPublic || decl.IsNestedPublic ||
+                                               decl.IsNestedFamily || decl.IsNestedFamily || decl.IsNestedFamilyOrAssembly)) {
                                return false;
                        }
                        decl = (TypeDefinition) decl.DeclaringType;
@@ -772,7 +785,7 @@ class MDocUpdater : MDocCommand
                                        XmlDocument doc = new XmlDocument ();
                                        doc.Load (typefile.FullName);
                                        XmlElement e = doc.SelectSingleNode("/Type") as XmlElement;
-                                       if (UpdateAssemblyVersions(e, GetAssemblyVersions(), false)) {
+                                       if (!no_assembly_versions && UpdateAssemblyVersions(e, GetAssemblyVersions(), false)) {
                                                using (TextWriter writer = OpenWrite (typefile.FullName, FileMode.Truncate))
                                                        WriteXml(doc.DocumentElement, writer);
                                                goodfiles.Add (relTypeFile);
@@ -882,7 +895,7 @@ class MDocUpdater : MDocCommand
                                
                                // Deleted (or signature changed)
                                if (oldmember2 == null) {
-                                       if (UpdateAssemblyVersions (oldmember, new string[]{ GetAssemblyVersion (type.Module.Assembly) }, false))
+                                       if (!no_assembly_versions && UpdateAssemblyVersions (oldmember, new string[]{ GetAssemblyVersion (type.Module.Assembly) }, false))
                                                continue;
                                        DeleteMember ("Member Removed", output, oldmember, todelete);
                                        continue;
@@ -1247,9 +1260,32 @@ class MDocUpdater : MDocCommand
                if (!DocUtils.IsDelegate (type))
                        WriteElement (root, "Members");
 
+               OrderTypeNodes (root, root.ChildNodes);
                NormalizeWhitespace(root);
        }
 
+       static readonly string[] TypeNodeOrder = {
+               "TypeSignature",
+               "MemberOfLibrary",
+               "AssemblyInfo",
+               "ThreadingSafetyStatement",
+               "ThreadSafetyStatement",
+               "TypeParameters",
+               "Base",
+               "Interfaces",
+               "Attributes",
+               "Parameters",
+               "ReturnValue",
+               "Docs",
+               "Members",
+               "TypeExcluded",
+       };
+
+       static void OrderTypeNodes (XmlNode member, XmlNodeList children)
+       {
+               ReorderNodes (member, children, TypeNodeOrder);
+       }
+
        internal static IEnumerable<T> Sort<T> (IEnumerable<T> list)
        {
                List<T> l = new List<T> (list);
@@ -1293,9 +1329,51 @@ class MDocUpdater : MDocCommand
                
                info.Node = WriteElement (me, "Docs");
                MakeDocNode (info);
+               OrderMemberNodes (me, me.ChildNodes);
                UpdateExtensionMethods (me, info);
        }
 
+       static readonly string[] MemberNodeOrder = {
+               "MemberSignature",
+               "MemberType",
+               "AssemblyInfo",
+               "Attributes",
+               "ReturnValue",
+               "TypeParameters",
+               "Parameters",
+               "MemberValue",
+               "Docs",
+               "Excluded",
+               "ExcludedLibrary",
+               "Link",
+       };
+
+       static void OrderMemberNodes (XmlNode member, XmlNodeList children)
+       {
+               ReorderNodes (member, children, MemberNodeOrder);
+       }
+
+       static void ReorderNodes (XmlNode node, XmlNodeList children, string[] ordering)
+       {
+               MyXmlNodeList newChildren = new MyXmlNodeList (children.Count);
+               for (int i = 0; i < ordering.Length; ++i) {
+                       for (int j = 0; j < children.Count; ++j) {
+                               XmlNode c = children [j];
+                               if (c.Name == ordering [i]) {
+                                       newChildren.Add (c);
+                               }
+                       }
+               }
+               if (newChildren.Count >= 0)
+                       node.PrependChild ((XmlNode) newChildren [0]);
+               for (int i = 1; i < newChildren.Count; ++i) {
+                       XmlNode prev = (XmlNode) newChildren [i-1];
+                       XmlNode cur  = (XmlNode) newChildren [i];
+                       node.RemoveChild (cur);
+                       node.InsertAfter (cur, prev);
+               }
+       }
+
        IEnumerable<string> GetCustomAttributes (MemberReference mi)
        {
                IEnumerable<string> attrs = Enumerable.Empty<string>();
@@ -1358,7 +1436,7 @@ class MDocUpdater : MDocCommand
                        string a2 = String.Join(", ", fields.ToArray ());
                        if (a2 != "") a2 = "(" + a2 + ")";
 
-                       string name = attribute.Constructor.DeclaringType.FullName;
+                       string name = attribute.GetDeclaringType();
                        if (name.EndsWith("Attribute")) name = name.Substring(0, name.Length-"Attribute".Length);
                        yield return prefix + name + a2;
                }
@@ -1601,23 +1679,7 @@ class MDocUpdater : MDocCommand
 
        private static void OrderDocsNodes (XmlNode docs, XmlNodeList children)
        {
-               MyXmlNodeList newChildren = new MyXmlNodeList (children.Count);
-               for (int i = 0; i < DocsNodeOrder.Length; ++i) {
-                       for (int j = 0; j < children.Count; ++j) {
-                               XmlNode c = children [j];
-                               if (c.Name == DocsNodeOrder [i]) {
-                                       newChildren.Add (c);
-                               }
-                       }
-               }
-               if (newChildren.Count >= 0)
-                       docs.PrependChild ((XmlNode) newChildren [0]);
-               for (int i = 1; i < newChildren.Count; ++i) {
-                       XmlNode prev = (XmlNode) newChildren [i-1];
-                       XmlNode cur  = (XmlNode) newChildren [i];
-                       docs.RemoveChild (cur);
-                       docs.InsertAfter (cur, prev);
-               }
+               ReorderNodes (docs, children, DocsNodeOrder);
        }
        
 
@@ -1842,6 +1904,8 @@ class MDocUpdater : MDocCommand
                "System.Runtime.CompilerServices.UnsafeValueTypeAttribute",
                // extension methods
                "System.Runtime.CompilerServices.ExtensionAttribute",
+               // Used to differentiate 'object' from C#4 'dynamic'
+               "System.Runtime.CompilerServices.DynamicAttribute",
        };
 
        private void MakeAttributes (XmlElement root, IEnumerable<string> attributes)
@@ -1870,7 +1934,7 @@ class MDocUpdater : MDocCommand
                NormalizeWhitespace(e);
        }
 
-       private static string MakeAttributesValueString (object v, TypeReference valueType)
+       public static string MakeAttributesValueString (object v, TypeReference valueType)
        {
                if (v == null)
                        return "null";
@@ -1878,6 +1942,8 @@ class MDocUpdater : MDocCommand
                        return "typeof(" + v.ToString () + ")";
                if (valueType.FullName == "System.String")
                        return "\"" + v.ToString () + "\"";
+               if (valueType.FullName == "System.Char")
+                       return "'" + v.ToString () + "'";
                if (v is Boolean)
                        return (bool)v ? "true" : "false";
                TypeDefinition valueDef = valueType.Resolve ();
@@ -1893,7 +1959,7 @@ class MDocUpdater : MDocCommand
                                        (from i in values.Keys
                                         where (c & i) != 0
                                         select typename + "." + values [i])
-                                       .ToArray ());
+                                       .DefaultIfEmpty (v.ToString ()).ToArray ());
                }
                return "(" + GetDocTypeFullName (valueType) + ") " + v.ToString ();
        }
@@ -2208,6 +2274,11 @@ class MDocUpdater : MDocCommand
 }
 
 static class CecilExtensions {
+       public static string GetDeclaringType(this CustomAttribute attribute)
+       {
+               return attribute.Constructor.DeclaringType.FullName;
+       }
+
        public static IEnumerable<MemberReference> GetMembers (this TypeDefinition type)
        {
                foreach (var c in type.Methods.Where (m => m.IsConstructor))
@@ -2814,7 +2885,7 @@ class EcmaDocumentationEnumerator : DocumentationEnumerator {
                        .Concat (base.GetDocumentationTypes (assembly, forTypes, seen));
        }
 
-       IEnumerable<TypeDefinition> GetDocumentationTypes (AssemblyDefinition assembly, List<string> forTypes, HashSet<string> seen)
+       new IEnumerable<TypeDefinition> GetDocumentationTypes (AssemblyDefinition assembly, List<string> forTypes, HashSet<string> seen)
        {
                int typeDepth = -1;
                while (ecmadocs.Read ()) {
@@ -3204,9 +3275,27 @@ class DocumentationMember {
        }
 }
 
+public class DynamicParserContext {
+       public ReadOnlyCollection<bool> TransformFlags;
+       public int TransformIndex;
+
+       public DynamicParserContext (ICustomAttributeProvider provider)
+       {
+               CustomAttribute da;
+               if (provider.HasCustomAttributes &&
+                               (da = (provider.CustomAttributes.Cast<CustomAttribute>()
+                                       .SingleOrDefault (ca => ca.GetDeclaringType() == "System.Runtime.CompilerServices.DynamicAttribute"))) != null) {
+                       CustomAttributeArgument[] values = da.ConstructorArguments.Count == 0
+                               ? new CustomAttributeArgument [0]
+                               : (CustomAttributeArgument[]) da.ConstructorArguments [0].Value;
+
+                       TransformFlags = new ReadOnlyCollection<bool> (values.Select (t => (bool) t.Value).ToArray());
+               }
+       }
+}
+
 public enum MemberFormatterState {
        None,
-       WithinArray,
        WithinGenericTypeParameters,
 }
 
@@ -3216,11 +3305,16 @@ public abstract class MemberFormatter {
                get {return "";}
        }
 
-       public virtual string GetName (MemberReference member)
+       public string GetName (MemberReference member)
+       {
+               return GetName (member, null);
+       }
+
+       public virtual string GetName (MemberReference member, DynamicParserContext context)
        {
                TypeReference type = member as TypeReference;
                if (type != null)
-                       return GetTypeName (type);
+                       return GetTypeName (type, context);
                MethodReference method  = member as MethodReference;
                if (method != null && method.Name == ".ctor") // method.IsConstructor
                        return GetConstructorName (method);
@@ -3240,10 +3334,15 @@ public abstract class MemberFormatter {
        }
 
        protected virtual string GetTypeName (TypeReference type)
+       {
+               return GetTypeName (type, null);
+       }
+
+       protected virtual string GetTypeName (TypeReference type, DynamicParserContext context)
        {
                if (type == null)
                        throw new ArgumentNullException ("type");
-               return _AppendTypeName (new StringBuilder (type.Name.Length), type).ToString ();
+               return _AppendTypeName (new StringBuilder (type.Name.Length), type, context).ToString ();
        }
 
        protected virtual char[] ArrayDelimeters {
@@ -3252,37 +3351,29 @@ public abstract class MemberFormatter {
 
        protected virtual MemberFormatterState MemberFormatterState { get; set; }
 
-       protected StringBuilder _AppendTypeName (StringBuilder buf, TypeReference type)
+       protected StringBuilder _AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
                if (type is ArrayType) {
                        TypeSpecification spec = type as TypeSpecification;
-                       _AppendTypeName (buf, spec != null ? spec.ElementType : type.GetElementType ())
-                                       .Append (ArrayDelimeters [0]);
-                       var origState = MemberFormatterState;
-                       MemberFormatterState = MemberFormatterState.WithinArray;
-                       ArrayType array = (ArrayType) type;
-                       int rank = array.Rank;
-                       if (rank > 1)
-                               buf.Append (new string (',', rank-1));
-                       MemberFormatterState = origState;
-                       return buf.Append (ArrayDelimeters [1]);
+                       _AppendTypeName (buf, spec != null ? spec.ElementType : type.GetElementType (), context);
+                       return AppendArrayModifiers (buf, (ArrayType) type);
                }
                if (type is ByReferenceType) {
-                       return AppendRefTypeName (buf, type);
+                       return AppendRefTypeName (buf, type, context);
                }
                if (type is PointerType) {
-                       return AppendPointerTypeName (buf, type);
+                       return AppendPointerTypeName (buf, type, context);
                }
                AppendNamespace (buf, type);
                if (type is GenericParameter) {
-                       return AppendTypeName (buf, type);
+                       return AppendTypeName (buf, type, context);
                }
                GenericInstanceType genInst = type as GenericInstanceType;
                if (type.GenericParameters.Count == 0 &&
                                (genInst == null ? true : genInst.GenericArguments.Count == 0)) {
-                       return AppendFullTypeName (buf, type);
+                       return AppendFullTypeName (buf, type, context);
                }
-               return AppendGenericType (buf, type);
+               return AppendGenericType (buf, type, context);
        }
 
        protected virtual StringBuilder AppendNamespace (StringBuilder buf, TypeReference type)
@@ -3293,15 +3384,17 @@ public abstract class MemberFormatter {
                return buf;
        }
 
-       protected virtual StringBuilder AppendFullTypeName (StringBuilder buf, TypeReference type)
+       protected virtual StringBuilder AppendFullTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
                if (type.DeclaringType != null)
-                       AppendFullTypeName (buf, type.DeclaringType).Append (NestedTypeSeparator);
-               return AppendTypeName (buf, type);
+                       AppendFullTypeName (buf, type.DeclaringType, context).Append (NestedTypeSeparator);
+               return AppendTypeName (buf, type, context);
        }
 
-       protected virtual StringBuilder AppendTypeName (StringBuilder buf, TypeReference type)
+       protected virtual StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
+               if (context != null)
+                       context.TransformIndex++;
                return AppendTypeName (buf, type.Name);
        }
 
@@ -3313,14 +3406,23 @@ public abstract class MemberFormatter {
                return buf.Append (typename);
        }
 
+       protected virtual StringBuilder AppendArrayModifiers (StringBuilder buf, ArrayType array)
+       {
+               buf.Append (ArrayDelimeters [0]);
+               int rank = array.Rank;
+               if (rank > 1)
+                       buf.Append (new string (',', rank-1));
+               return buf.Append (ArrayDelimeters [1]);
+       }
+
        protected virtual string RefTypeModifier {
                get {return "@";}
        }
 
-       protected virtual StringBuilder AppendRefTypeName (StringBuilder buf, TypeReference type)
+       protected virtual StringBuilder AppendRefTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
                TypeSpecification spec = type as TypeSpecification;
-               return _AppendTypeName (buf, spec != null ? spec.ElementType : type.GetElementType ())
+               return _AppendTypeName (buf, spec != null ? spec.ElementType : type.GetElementType (), context)
                                .Append (RefTypeModifier);
        }
 
@@ -3328,10 +3430,10 @@ public abstract class MemberFormatter {
                get {return "*";}
        }
 
-       protected virtual StringBuilder AppendPointerTypeName (StringBuilder buf, TypeReference type)
+       protected virtual StringBuilder AppendPointerTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
                TypeSpecification spec = type as TypeSpecification;
-               return _AppendTypeName (buf, spec != null ? spec.ElementType : type.GetElementType ())
+               return _AppendTypeName (buf, spec != null ? spec.ElementType : type.GetElementType (), context)
                                .Append (PointerModifier);
        }
 
@@ -3343,7 +3445,7 @@ public abstract class MemberFormatter {
                get {return '.';}
        }
 
-       protected virtual StringBuilder AppendGenericType (StringBuilder buf, TypeReference type)
+       protected virtual StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
                List<TypeReference> decls = DocUtils.GetDeclaringTypes (
                                type is GenericInstanceType ? type.GetElementType () : type);
@@ -3357,7 +3459,7 @@ public abstract class MemberFormatter {
                                buf.Append (NestedTypeSeparator);
                        }
                        insertNested = true;
-                       AppendTypeName (buf, declDef);
+                       AppendTypeName (buf, declDef, context);
                        int ac = DocUtils.GetGenericArgumentCount (declDef);
                        int c = ac - prev;
                        prev = ac;
@@ -3365,9 +3467,10 @@ public abstract class MemberFormatter {
                                buf.Append (GenericTypeContainer [0]);
                                var origState = MemberFormatterState;
                                MemberFormatterState = MemberFormatterState.WithinGenericTypeParameters;
-                               _AppendTypeName (buf, genArgs [argIdx++]);
-                               for (int i = 1; i < c; ++i)
-                                       _AppendTypeName (buf.Append (","), genArgs [argIdx++]);
+                               _AppendTypeName (buf, genArgs [argIdx++], context);
+                               for (int i = 1; i < c; ++i) {
+                                       _AppendTypeName (buf.Append (","), genArgs [argIdx++], context);
+                               }
                                MemberFormatterState = origState;
                                buf.Append (GenericTypeContainer [1]);
                        }
@@ -3445,7 +3548,7 @@ public abstract class MemberFormatter {
                if (type == null)
                        throw new ArgumentNullException ("type");
                StringBuilder buf = new StringBuilder (type.Name.Length);
-               _AppendTypeName (buf, type);
+               _AppendTypeName (buf, type, null);
                AppendGenericTypeConstraints (buf, type);
                return buf.ToString ();
        }
@@ -3457,6 +3560,10 @@ public abstract class MemberFormatter {
 
        protected virtual string GetMethodDeclaration (MethodDefinition method)
        {
+               if (method.HasCustomAttributes && method.CustomAttributes.Cast<CustomAttribute>().Any(
+                                       ca => ca.GetDeclaringType() == "System.Diagnostics.Contracts.ContractInvariantMethodAttribute"))
+                       return null;
+
                // Special signature for destructors.
                if (method.Name == "Finalize" && method.Parameters.Count == 0)
                        return GetFinalizerName (method);
@@ -3472,7 +3579,7 @@ public abstract class MemberFormatter {
 
                if (buf.Length != 0)
                        buf.Append (" ");
-               buf.Append (GetName (method.ReturnType)).Append (" ");
+               buf.Append (GetTypeName (method.ReturnType, new DynamicParserContext (method.MethodReturnType))).Append (" ");
 
                AppendMethodName (buf, method);
                AppendGenericMethod (buf, method).Append (" ");
@@ -3590,16 +3697,18 @@ class ILFullMemberFormatter : MemberFormatter {
                return buf.Append (typename);
        }
 
-       protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type)
+       protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
-               var gp = type as GenericParameter;
-               if (type is GenericParameter)
-                       return AppendGenericParameterConstraints (buf, (GenericParameter) type).Append (type.Name);
+               if (type is GenericParameter) {
+                       AppendGenericParameterConstraints (buf, (GenericParameter) type).Append (type.Name);
+                       return buf;
+               }
 
                string s = GetBuiltinType (type.FullName);
-               if (s != null)
+               if (s != null) {
                        return buf.Append (s);
-               return base.AppendTypeName (buf, type);
+               }
+               return base.AppendTypeName (buf, type, context);
        }
 
        private StringBuilder AppendGenericParameterConstraints (StringBuilder buf, GenericParameter type)
@@ -3690,7 +3799,7 @@ class ILFullMemberFormatter : MemberFormatter {
                return buf.ToString ();
        }
 
-       protected override StringBuilder AppendGenericType (StringBuilder buf, TypeReference type)
+       protected override StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
                List<TypeReference> decls = DocUtils.GetDeclaringTypes (
                                type is GenericInstanceType ? type.GetElementType () : type);
@@ -3701,7 +3810,7 @@ class ILFullMemberFormatter : MemberFormatter {
                                buf.Append (NestedTypeSeparator);
                        }
                        first = false;
-                       AppendTypeName (buf, declDef);
+                       AppendTypeName (buf, declDef, context);
                }
                buf.Append ('<');
                first = true;
@@ -3709,7 +3818,7 @@ class ILFullMemberFormatter : MemberFormatter {
                        if (!first)
                                buf.Append (", ");
                        first = false;
-                       _AppendTypeName (buf, arg);
+                       _AppendTypeName (buf, arg, context);
                }
                buf.Append ('>');
                return buf;
@@ -3783,7 +3892,7 @@ class ILFullMemberFormatter : MemberFormatter {
                        buf.Append ("virtual ");
                if (!method.IsStatic)
                        buf.Append ("instance ");
-               _AppendTypeName (buf, method.ReturnType);
+               _AppendTypeName (buf, method.ReturnType, new DynamicParserContext (method.MethodReturnType));
                buf.Append (' ')
                        .Append (method.Name);
                if (method.IsGenericMethod ()) {
@@ -3792,9 +3901,9 @@ class ILFullMemberFormatter : MemberFormatter {
                        IList<GenericParameter> args = method.GenericParameters;
                        if (args.Count > 0) {
                                buf.Append ("<");
-                               _AppendTypeName (buf, args [0]);
+                               _AppendTypeName (buf, args [0], null);
                                for (int i = 1; i < args.Count; ++i)
-                                       _AppendTypeName (buf.Append (", "), args [i]);
+                                       _AppendTypeName (buf.Append (", "), args [i], null);
                                buf.Append (">");
                        }
                        MemberFormatterState = state;
@@ -3806,7 +3915,7 @@ class ILFullMemberFormatter : MemberFormatter {
                        if (!first)
                                buf.Append (", ");
                        first = false;
-                       _AppendTypeName (buf, method.Parameters [i].ParameterType);
+                       _AppendTypeName (buf, method.Parameters [i].ParameterType, new DynamicParserContext (method.Parameters [i]));
                        buf.Append (' ');
                        buf.Append (method.Parameters [i].Name);
                }
@@ -3934,12 +4043,11 @@ class ILFullMemberFormatter : MemberFormatter {
                if ((set_visible == null) && (get_visible == null))
                        return null;
 
-               string visibility;
                StringBuilder buf = new StringBuilder ()
                        .Append (".property ");
                if (!(gm ?? sm).IsStatic)
                        buf.Append ("instance ");
-               _AppendTypeName (buf, property.PropertyType);
+               _AppendTypeName (buf, property.PropertyType, new DynamicParserContext (property));
                buf.Append (' ').Append (property.Name);
                if (!property.HasParameters || property.Parameters.Count == 0)
                        return buf.ToString ();
@@ -3950,7 +4058,7 @@ class ILFullMemberFormatter : MemberFormatter {
                        if (!first)
                                buf.Append (", ");
                        first = false;
-                       _AppendTypeName (buf, p.ParameterType);
+                       _AppendTypeName (buf, p.ParameterType, new DynamicParserContext (p));
                }
                buf.Append (')');
 
@@ -3976,7 +4084,7 @@ class ILFullMemberFormatter : MemberFormatter {
                        buf.Append ("initonly ");
                if (field.IsLiteral)
                        buf.Append ("literal ");
-               _AppendTypeName (buf, field.FieldType);
+               _AppendTypeName (buf, field.FieldType, new DynamicParserContext (field));
                buf.Append (' ').Append (field.Name);
                AppendFieldValue (buf, field);
 
@@ -4094,23 +4202,32 @@ class CSharpFullMemberFormatter : MemberFormatter {
                return null;
        }
 
-       protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type)
+       protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
+               if (context != null && context.TransformFlags != null &&
+                               (context.TransformFlags.Count == 0 || context.TransformFlags [context.TransformIndex])) {
+                       context.TransformIndex++;
+                       return buf.Append ("dynamic");
+               }
+
                if (type is GenericParameter)
-                       return AppendGenericParameterConstraints (buf, (GenericParameter) type).Append (type.Name);
+                       return AppendGenericParameterConstraints (buf, (GenericParameter) type, context).Append (type.Name);
                string t = type.FullName;
                if (!t.StartsWith ("System.")) {
-                       return base.AppendTypeName (buf, type);
+                       return base.AppendTypeName (buf, type, context);
                }
 
                string s = GetCSharpType (t);
-               if (s != null)
+               if (s != null) {
+                       if (context != null)
+                               context.TransformIndex++;
                        return buf.Append (s);
+               }
                
-               return base.AppendTypeName (buf, type);
+               return base.AppendTypeName (buf, type, context);
        }
 
-       private StringBuilder AppendGenericParameterConstraints (StringBuilder buf, GenericParameter type)
+       private StringBuilder AppendGenericParameterConstraints (StringBuilder buf, GenericParameter type, DynamicParserContext context)
        {
                if (MemberFormatterState != MemberFormatterState.WithinGenericTypeParameters)
                        return buf;
@@ -4140,7 +4257,7 @@ class CSharpFullMemberFormatter : MemberFormatter {
                if (DocUtils.IsDelegate (type)) {
                        buf.Append("delegate ");
                        MethodDefinition invoke = type.GetMethod ("Invoke");
-                       buf.Append (full.GetName (invoke.ReturnType)).Append (" ");
+                       buf.Append (full.GetName (invoke.ReturnType, new DynamicParserContext (invoke.MethodReturnType))).Append (" ");
                        buf.Append (GetName (type));
                        AppendParameters (buf, invoke, invoke.Parameters);
                        AppendGenericTypeConstraints (buf, type);
@@ -4391,8 +4508,12 @@ class CSharpFullMemberFormatter : MemberFormatter {
                        else
                                buf.Append ("ref ");
                }
-               buf.Append (GetName (parameter.ParameterType)).Append (" ");
-               return buf.Append (parameter.Name);
+               buf.Append (GetTypeName (parameter.ParameterType, new DynamicParserContext (parameter))).Append (" ");
+               buf.Append (parameter.Name);
+               if (parameter.HasDefault && parameter.IsOptional && parameter.HasConstant) {
+                       buf.AppendFormat (" = {0}", MDocUpdater.MakeAttributesValueString (parameter.Constant, parameter.ParameterType));
+               }
+               return buf;
        }
 
        protected override string GetPropertyDeclaration (PropertyDefinition property)
@@ -4444,7 +4565,7 @@ class CSharpFullMemberFormatter : MemberFormatter {
                        modifiers = "";
                buf.Append (modifiers).Append (' ');
 
-               buf.Append (GetName (property.PropertyType)).Append (' ');
+               buf.Append (GetTypeName (property.PropertyType, new DynamicParserContext (property))).Append (' ');
 
                IEnumerable<MemberReference> defs = property.DeclaringType.GetDefaultMembers ();
                string name = property.Name;
@@ -4461,16 +4582,16 @@ class CSharpFullMemberFormatter : MemberFormatter {
                }
 
                buf.Append (" {");
-               if (set_visible != null) {
-                       if (set_visible != visibility)
-                               buf.Append (' ').Append (set_visible);
-                       buf.Append (" set;");
-               }
                if (get_visible != null) {
                        if (get_visible != visibility)
                                buf.Append (' ').Append (get_visible);
                        buf.Append (" get;");
                }
+               if (set_visible != null) {
+                       if (set_visible != visibility)
+                               buf.Append (' ').Append (set_visible);
+                       buf.Append (" set;");
+               }
                buf.Append (" }");
        
                return buf [0] != ' ' ? buf.ToString () : buf.ToString (1, buf.Length-1);
@@ -4497,7 +4618,7 @@ class CSharpFullMemberFormatter : MemberFormatter {
                if (field.IsLiteral)
                        buf.Append (" const");
 
-               buf.Append (' ').Append (GetName (field.FieldType)).Append (' ');
+               buf.Append (' ').Append (GetTypeName (field.FieldType, new DynamicParserContext (field))).Append (' ');
                buf.Append (field.Name);
                AppendFieldValue (buf, field);
                buf.Append (';');
@@ -4551,7 +4672,7 @@ class CSharpFullMemberFormatter : MemberFormatter {
                AppendModifiers (buf, e.AddMethod);
 
                buf.Append (" event ");
-               buf.Append (GetName (e.EventType)).Append (' ');
+               buf.Append (GetTypeName (e.EventType, new DynamicParserContext (e.AddMethod.Parameters [0]))).Append (' ');
                buf.Append (e.Name).Append (';');
 
                return buf.ToString ();
@@ -4591,7 +4712,7 @@ class SlashDocMemberFormatter : MemberFormatter {
        private TypeReference genDeclType;
        private MethodReference genDeclMethod;
 
-       protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type)
+       protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
                if (type is GenericParameter) {
                        int l = buf.Length;
@@ -4630,7 +4751,7 @@ class SlashDocMemberFormatter : MemberFormatter {
                        }
                }
                else {
-                       base.AppendTypeName (buf, type);
+                       base.AppendTypeName (buf, type, context);
                        if (AddTypeCount) {
                                int numArgs = type.GenericParameters.Count;
                                if (type.DeclaringType != null)
@@ -4643,16 +4764,29 @@ class SlashDocMemberFormatter : MemberFormatter {
                return buf;
        }
 
-       protected override StringBuilder AppendGenericType (StringBuilder buf, TypeReference type)
+       protected override StringBuilder AppendArrayModifiers (StringBuilder buf, ArrayType array)
+       {
+               buf.Append (ArrayDelimeters [0]);
+               int rank = array.Rank;
+               if (rank > 1) {
+                       buf.Append ("0:");
+                       for (int i = 1; i < rank; ++i) {
+                               buf.Append (",0:");
+                       }
+               }
+               return buf.Append (ArrayDelimeters [1]);
+       }
+
+       protected override StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
                if (!AddTypeCount)
-                       base.AppendGenericType (buf, type);
+                       base.AppendGenericType (buf, type, context);
                else
-                       AppendType (buf, type);
+                       AppendType (buf, type, context);
                return buf;
        }
 
-       private StringBuilder AppendType (StringBuilder buf, TypeReference type)
+       private StringBuilder AppendType (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
                List<TypeReference> decls = DocUtils.GetDeclaringTypes (type);
                bool insertNested = false;
@@ -4661,7 +4795,7 @@ class SlashDocMemberFormatter : MemberFormatter {
                        if (insertNested)
                                buf.Append (NestedTypeSeparator);
                        insertNested = true;
-                       base.AppendTypeName (buf, decl);
+                       base.AppendTypeName (buf, decl, context);
                        int argCount = DocUtils.GetGenericArgumentCount (decl);
                        int numArgs = argCount - prevParamCount;
                        prevParamCount = argCount;