public static String GetCSharpTypeArgsClause(this Type[] targs, ToCSharpOptions opt)
        {
            if (targs.Count() == 0)
            {
                return(String.Empty);
            }
            else
            {
                var buffer = new StringBuilder();
                buffer.Append("<");

                targs.ForEach((targ, i) =>
                {
                    if (opt.EmitAttributes && targ.IsGenericParameter && targ.Attrs().IsNotEmpty())
                    {
                        buffer.Append(targ.GetCSharpAttributesClause(opt)).Append(" ");
                    }
                    buffer.Append(targ.GetCSharpRef(opt));

                    if (i != targs.Count() - 1)
                    {
                        buffer.Append(", ");
                    }
                });

                buffer.Append(">");
                return(buffer.ToString());
            }
        }
        public static String GetCSharpDecl(this FieldInfo f, ToCSharpOptions opt)
        {
            opt = opt ?? ToCSharpOptions.Terse;
            var buffer = new StringBuilder();

            if (opt.EmitAttributes && f.Attrs().IsNotEmpty())
            {
                buffer.Append(f.GetCSharpAttributesClause(opt)).Append(" ");
            }
            if (opt.EmitVisibilityQualifier)
            {
                buffer.Append(f.GetCSharpVisibilityQualifier()).Append(" ");
            }
            if (opt.EmitStaticQualifier && f.IsStatic)
            {
                buffer.Append("static ");
            }
            buffer.Append(f.FieldType.GetCSharpRef(opt)).Append(" ");
            if (opt.EmitDeclaringType)
            {
                buffer.Append(f.DeclaringType.GetCSharpRef(ToCSharpOptions.Terse) + "::");
            }
            buffer.Append(f.Name);

            if (opt.EmitSemicolon)
            {
                buffer.Append(";");
            }
            return(buffer.ToString());
        }
 public static String GetCSharpDecl(this MemberInfo mi, ToCSharpOptions opt)
 {
     if (mi is Type) return ((Type)mi).GetCSharpDecl(opt);
     else if (mi is FieldInfo) return ((FieldInfo)mi).GetCSharpDecl(opt);
     else if (mi is MethodBase) return ((MethodBase)mi).GetCSharpDecl(opt);
     else if (mi is PropertyInfo) return ((PropertyInfo)mi).GetCSharpDecl(opt);
     else throw AssertionHelper.Fail();
 }
        public static String GetCSharpTypeConstraintsClause(this MethodBase mb, ToCSharpOptions opt)
        {
            var gargs   = mb.XGetGenericArguments().Where(garg => garg.IsGenericParameter);
            var clauses = gargs.Select(garg => garg.GetCSharpTypeConstraintsClause_Impl(opt));

            clauses = clauses.Where(clause => clause.IsNotEmpty());
            return(opt.EmitTypeArgsConstraints && clauses.IsNotEmpty() ?
                   (String.Empty.MkArray().Concat(clauses).StringJoin(Environment.NewLine)) : String.Empty);
        }
        public static String GetCSharpRef(this Type t, ToCSharpOptions opt)
        {
            // since this is only ref, we can ignore loads of stuff
            opt = (opt ?? ToCSharpOptions.Terse).Clone();
            opt.EmitAttributes          = false;
            opt.EmitVisibilityQualifier = false;
            opt.EmitStaticQualifier     = false;
            opt.EmitAttributes          = false;
            opt.EmitDeclaringType       = true;
            opt.EmitSemicolon           = false;

            return(t.GetCSharpDecl(opt));
        }
        public static String GetCSharpRef(this Type t, ToCSharpOptions opt)
        {
            // since this is only ref, we can ignore loads of stuff
            opt = (opt ?? ToCSharpOptions.Terse).Clone();
            opt.EmitAttributes = false;
            opt.EmitVisibilityQualifier = false;
            opt.EmitStaticQualifier = false;
            opt.EmitAttributes = false;
            opt.EmitDeclaringType = true;
            opt.EmitSemicolon = false;

            return t.GetCSharpDecl(opt);
        }
        public static String GetCSharpDecl(this Type t, ToCSharpOptions opt)
        {
            if (t == typeof(byte)) return "byte";
            if (t == typeof(sbyte)) return "sbyte";
            if (t == typeof(short)) return "short";
            if (t == typeof(ushort)) return "ushort";
            if (t == typeof(int)) return "int";
            if (t == typeof(uint)) return "uint";
            if (t == typeof(long)) return "long";
            if (t == typeof(ulong)) return "ulong";
            if (t == typeof(float)) return "float";
            if (t == typeof(double)) return "double";
            if (t == typeof(decimal)) return "decimal";
            if (t == typeof(bool)) return "bool";
            if (t == typeof(char)) return "char";
            if (t == typeof(void)) return "void";

            if (t.IsNullable())
            {
                return t.UndecorateNullable().GetCSharpRef(opt) + "?";
            }
            else
            {
                opt = opt ?? ToCSharpOptions.Terse;
                var buffer = new StringBuilder();

                if (opt.EmitAttributes && t.Attrs().IsNotEmpty())
                    buffer.Append(t.GetCSharpAttributesClause(opt)).Append(" ");
                if (opt.EmitStaticQualifier && t.IsStatic()) buffer.Append("static ");
                buffer.Append(t.GetCSharpTypeNameQualifier(opt));
                if (t.DeclaringType != null && !t.IsGenericParameter)
                {
                    var dt = t.DeclaringType;
                    buffer.Append(dt.Name.Slice(0, dt.Name.IndexOf("`") == -1 ? dt.Name.Length : dt.Name.IndexOf("`")));
                    if (opt.EmitTypeArgsCount && dt.XGetGenericArguments().IsNotEmpty())
                        buffer.Append("`").Append(dt.XGetGenericArguments().Count());
                    if (opt.EmitTypeArgs && dt.XGetGenericArguments().IsNotEmpty())
                        buffer.Append(dt.GetCSharpTypeArgsClause(opt));
                    buffer.Append(".");
                }
                buffer.Append(t.Name.Slice(0, t.Name.IndexOf("`") == -1 ? t.Name.Length : t.Name.IndexOf("`")));
                if (opt.EmitTypeArgsCount && t.XGetGenericArguments().IsNotEmpty())
                    buffer.Append("`").Append(t.XGetGenericArguments().Count());
                if (opt.EmitTypeArgs && t.XGetGenericArguments().IsNotEmpty()) 
                    buffer.Append(t.GetCSharpTypeArgsClause(opt));

                if (opt.EmitSemicolon) buffer.Append(";");
                return buffer.ToString();
            }
        }
        public static String GetCSharpDecl(this PropertyInfo p, ToCSharpOptions opt)
        {
            opt = opt ?? ToCSharpOptions.Terse;
            var buffer = new StringBuilder();

            if (opt.EmitAttributes && p.Attrs().IsNotEmpty())
            {
                buffer.Append(p.GetCSharpAttributesClause(opt)).Append(" ");
            }
            if (opt.EmitVisibilityQualifier)
            {
                buffer.Append(p.GetCSharpVisibilityQualifier()).Append(" ");
            }
            if (opt.EmitStaticQualifier && p.IsStatic())
            {
                buffer.Append("static ");
            }
            buffer.Append(p.PropertyType.GetCSharpRef(opt)).Append(" ");
            if (opt.EmitDeclaringType)
            {
                buffer.Append(p.DeclaringType.GetCSharpRef(ToCSharpOptions.Terse) + "::");
            }
            buffer.Append(p.Name);

            buffer.Append(" { ");
            if (p.CanRead)
            {
                var getter = p.GetGetMethod(true);
                if (opt.EmitVisibilityQualifier)
                {
                    buffer.Append(getter.GetCSharpVisibilityQualifier()).Append(" ");
                }
                buffer.Append("get; ");
            }
            if (p.CanWrite)
            {
                var setter = p.GetSetMethod(true);
                if (opt.EmitVisibilityQualifier)
                {
                    buffer.Append(setter.GetCSharpVisibilityQualifier()).Append(" ");
                }
                buffer.Append("set; ");
            }
            buffer.Append("}");

            return(buffer.ToString());
        }
 public static String GetCSharpTypeNameQualifier(this Type t, ToCSharpOptions opt)
 {
     if (t.IsGenericParameter)
     {
         return String.Empty;
     }
     else
     {
         switch (opt.NameQualifiers)
         {
             case NameQualifiers.None:
                 return String.Empty;
             case NameQualifiers.Namespace:
                 return t.Namespace + ".";
             case NameQualifiers.GlobalAndNamespace:
                 return "global::" + t.Namespace + ".";
             default:
                 throw AssertionHelper.Fail();
         }
     }
 }
 public static String GetCSharpDecl(this MemberInfo mi, ToCSharpOptions opt)
 {
     if (mi is Type)
     {
         return(((Type)mi).GetCSharpDecl(opt));
     }
     else if (mi is FieldInfo)
     {
         return(((FieldInfo)mi).GetCSharpDecl(opt));
     }
     else if (mi is MethodBase)
     {
         return(((MethodBase)mi).GetCSharpDecl(opt));
     }
     else if (mi is PropertyInfo)
     {
         return(((PropertyInfo)mi).GetCSharpDecl(opt));
     }
     else
     {
         throw AssertionHelper.Fail();
     }
 }
        public static String GetCSharpTypeNameQualifier(this Type t, ToCSharpOptions opt)
        {
            if (t.IsGenericParameter)
            {
                return(String.Empty);
            }
            else
            {
                switch (opt.NameQualifiers)
                {
                case NameQualifiers.None:
                    return(String.Empty);

                case NameQualifiers.Namespace:
                    return(t.Namespace + ".");

                case NameQualifiers.GlobalAndNamespace:
                    return("global::" + t.Namespace + ".");

                default:
                    throw AssertionHelper.Fail();
                }
            }
        }
        private static String GetCSharpTypeConstraintsClause_Impl(this Type t, ToCSharpOptions opt)
        {
            t.IsGenericParameter.AssertTrue();
            var mods = new List <String>();

            if ((t.GenericParameterAttributes & GenericParameterAttributes.ReferenceTypeConstraint) == GenericParameterAttributes.ReferenceTypeConstraint)
            {
                mods.Add("class");
            }
            if ((t.GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) == GenericParameterAttributes.NotNullableValueTypeConstraint)
            {
                mods.Add("struct");
            }
            if ((t.GenericParameterAttributes & GenericParameterAttributes.DefaultConstructorConstraint) == GenericParameterAttributes.DefaultConstructorConstraint)
            {
                mods.Add("new()");
            }
            var inheritance = t.GetGenericParameterConstraints();

            inheritance.ForEach(t_c => mods.Add(t_c.GetCSharpRef(opt)));

            if (mods.IsEmpty())
            {
                return(String.Empty);
            }
            else
            {
                var buffer = new StringBuilder();
                buffer.Append("    ");
                buffer.Append("where ");
                buffer.Append(t.GetCSharpRef(opt));
                buffer.Append(" : ");
                buffer.Append(mods.StringJoin());
                return(buffer.ToString());
            }
        }
        public static String GetCSharpAttributesClause(this ICustomAttributeProvider cap, ToCSharpOptions opt)
        {
            if (cap.Attrs().Count() == 0)
            {
                return String.Empty;
            }
            else
            {
                var buffer = new StringBuilder();
                buffer.Append("[");

                var prefix = String.Empty;
                if (cap is ParameterInfo)
                {
                    /*IsRetVal ain't work */
                    var mb = ((ParameterInfo)cap).Member;
                    if (mb is MethodInfo && ((MethodInfo)(mb)).ReturnParameter == cap)
                    {
                        prefix = "return: ";
                    }
                }

                // todo. implement this using CustomAttributeData
                // that will preserve info about ctor and setters
                var attrs = cap.GetCustomAttributes(false);
                attrs.ForEach((attr, i) =>
                {
                    buffer.Append(prefix);
                    buffer.Append(attr.GetType().GetCSharpRef(opt));
                    if (i != attrs.Count() - 1) buffer.Append(", ");
                });

                buffer.Append("]");
                return buffer.ToString();
            }
        }
 public static String GetCSharpTypeArgsClause(this Type t, ToCSharpOptions opt)
 {
     return(GetCSharpTypeArgsClause(t.XGetGenericArguments(), opt));
 }
        public static String GetCSharpDecl(this Type t, ToCSharpOptions opt)
        {
            if (t == typeof(byte))
            {
                return("byte");
            }
            if (t == typeof(sbyte))
            {
                return("sbyte");
            }
            if (t == typeof(short))
            {
                return("short");
            }
            if (t == typeof(ushort))
            {
                return("ushort");
            }
            if (t == typeof(int))
            {
                return("int");
            }
            if (t == typeof(uint))
            {
                return("uint");
            }
            if (t == typeof(long))
            {
                return("long");
            }
            if (t == typeof(ulong))
            {
                return("ulong");
            }
            if (t == typeof(float))
            {
                return("float");
            }
            if (t == typeof(double))
            {
                return("double");
            }
            if (t == typeof(decimal))
            {
                return("decimal");
            }
            if (t == typeof(bool))
            {
                return("bool");
            }
            if (t == typeof(char))
            {
                return("char");
            }
            if (t == typeof(void))
            {
                return("void");
            }

            if (t.IsNullable())
            {
                return(t.UndecorateNullable().GetCSharpRef(opt) + "?");
            }
            else
            {
                opt = opt ?? ToCSharpOptions.Terse;
                var buffer = new StringBuilder();

                if (opt.EmitAttributes && t.Attrs().IsNotEmpty())
                {
                    buffer.Append(t.GetCSharpAttributesClause(opt)).Append(" ");
                }
                if (opt.EmitStaticQualifier && t.IsStatic())
                {
                    buffer.Append("static ");
                }
                buffer.Append(t.GetCSharpTypeNameQualifier(opt));
                if (t.DeclaringType != null && !t.IsGenericParameter)
                {
                    var dt = t.DeclaringType;
                    buffer.Append(dt.Name.Slice(0, dt.Name.IndexOf("`") == -1 ? dt.Name.Length : dt.Name.IndexOf("`")));
                    if (opt.EmitTypeArgsCount && dt.XGetGenericArguments().IsNotEmpty())
                    {
                        buffer.Append("`").Append(dt.XGetGenericArguments().Count());
                    }
                    if (opt.EmitTypeArgs && dt.XGetGenericArguments().IsNotEmpty())
                    {
                        buffer.Append(dt.GetCSharpTypeArgsClause(opt));
                    }
                    buffer.Append(".");
                }
                buffer.Append(t.Name.Slice(0, t.Name.IndexOf("`") == -1 ? t.Name.Length : t.Name.IndexOf("`")));
                if (opt.EmitTypeArgsCount && t.XGetGenericArguments().IsNotEmpty())
                {
                    buffer.Append("`").Append(t.XGetGenericArguments().Count());
                }
                if (opt.EmitTypeArgs && t.XGetGenericArguments().IsNotEmpty())
                {
                    buffer.Append(t.GetCSharpTypeArgsClause(opt));
                }

                if (opt.EmitSemicolon)
                {
                    buffer.Append(";");
                }
                return(buffer.ToString());
            }
        }
        private static String GetCSharpTypeConstraintsClause_Impl(this Type t, ToCSharpOptions opt)
        {
            t.IsGenericParameter.AssertTrue();
            var mods = new List<String>();

            if ((t.GenericParameterAttributes & GenericParameterAttributes.ReferenceTypeConstraint) == GenericParameterAttributes.ReferenceTypeConstraint)
                mods.Add("class");
            if ((t.GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) == GenericParameterAttributes.NotNullableValueTypeConstraint)
                mods.Add("struct");
            if ((t.GenericParameterAttributes & GenericParameterAttributes.DefaultConstructorConstraint) == GenericParameterAttributes.DefaultConstructorConstraint)
                mods.Add("new()");
            var inheritance = t.GetGenericParameterConstraints();
            inheritance.ForEach(t_c => mods.Add(t_c.GetCSharpRef(opt)));

            if (mods.IsEmpty())
            {
                return String.Empty;
            }
            else
            {
                var buffer = new StringBuilder();
                buffer.Append("    ");
                buffer.Append("where ");
                buffer.Append(t.GetCSharpRef(opt));
                buffer.Append(" : ");
                buffer.Append(mods.StringJoin());
                return buffer.ToString();
            }
        }
 public static String GetCSharpTypeConstraintsClause(this MethodBase mb, ToCSharpOptions opt)
 {
     var gargs = mb.XGetGenericArguments().Where(garg => garg.IsGenericParameter);
     var clauses = gargs.Select(garg => garg.GetCSharpTypeConstraintsClause_Impl(opt));
     clauses = clauses.Where(clause => clause.IsNotEmpty());
     return opt.EmitTypeArgsConstraints && clauses.IsNotEmpty() ? 
         (String.Empty.MkArray().Concat(clauses).StringJoin(Environment.NewLine)) : String.Empty;
 }
        public static String GetCSharpTypeArgsClause(this Type[] targs, ToCSharpOptions opt)
        {
            if (targs.Count() == 0)
            {
                return String.Empty;
            }
            else
            {
                var buffer = new StringBuilder();
                buffer.Append("<");

                targs.ForEach((targ, i) =>
                {
                    if (opt.EmitAttributes && targ.IsGenericParameter && targ.Attrs().IsNotEmpty())
                        buffer.Append(targ.GetCSharpAttributesClause(opt)).Append(" ");
                    buffer.Append(targ.GetCSharpRef(opt));

                    if (i != targs.Count() - 1) buffer.Append(", ");
                });

                buffer.Append(">");
                return buffer.ToString();
            }
        }
 public static String GetCSharpTypeArgsClause(this MethodBase mb, ToCSharpOptions opt)
 {
     return GetCSharpTypeArgsClause(mb.XGetGenericArguments(), opt);
 }
 public static String GetCSharpTypeArgsClause(this MethodBase mb, ToCSharpOptions opt)
 {
     return(GetCSharpTypeArgsClause(mb.XGetGenericArguments(), opt));
 }
        public static String GetCSharpDecl(this PropertyInfo p, ToCSharpOptions opt)
        {
            opt = opt ?? ToCSharpOptions.Terse;
            var buffer = new StringBuilder();

            if (opt.EmitAttributes && p.Attrs().IsNotEmpty())
                buffer.Append(p.GetCSharpAttributesClause(opt)).Append(" ");
            if (opt.EmitVisibilityQualifier) buffer.Append(p.GetCSharpVisibilityQualifier()).Append(" ");
            if (opt.EmitStaticQualifier && p.IsStatic()) buffer.Append("static ");
            buffer.Append(p.PropertyType.GetCSharpRef(opt)).Append(" ");
            if (opt.EmitDeclaringType) buffer.Append(p.DeclaringType.GetCSharpRef(ToCSharpOptions.Terse) + "::");
            buffer.Append(p.Name);

            buffer.Append(" { ");
            if (p.CanRead)
            {
                var getter = p.GetGetMethod(true);
                if (opt.EmitVisibilityQualifier) buffer.Append(getter.GetCSharpVisibilityQualifier()).Append(" ");
                buffer.Append("get; ");
            }
            if (p.CanWrite)
            {
                var setter = p.GetSetMethod(true);
                if (opt.EmitVisibilityQualifier) buffer.Append(setter.GetCSharpVisibilityQualifier()).Append(" ");
                buffer.Append("set; ");
            }
            buffer.Append("}");

            return buffer.ToString();
        }
        public static String GetCSharpDecl(this MethodBase m, ToCSharpOptions opt)
        {
            opt = opt ?? ToCSharpOptions.Terse;
            var buffer = new StringBuilder();

            if (opt.EmitAttributes && m.Attrs().IsNotEmpty()) 
                buffer.Append(m.GetCSharpAttributesClause(opt)).Append(" ");
            if (opt.EmitAttributes && m is MethodInfo && (((MethodInfo)m).ReturnParameter).Attrs().IsNotEmpty())
                buffer.Append(((MethodInfo)m).ReturnParameter.GetCSharpAttributesClause(opt)).Append(" ");
            if (opt.EmitVisibilityQualifier) buffer.Append(m.GetCSharpVisibilityQualifier()).Append(" ");
            if (opt.EmitStaticQualifier && m.IsStatic) buffer.Append("static ");
            if (!(m is ConstructorInfo)) buffer.Append(m.Ret().GetCSharpRef(opt)).Append(" ");
            if (opt.EmitDeclaringType) buffer.Append(m.DeclaringType.GetCSharpRef(ToCSharpOptions.Terse) + "::");
            if (!(m is ConstructorInfo)) buffer.Append(m.Name.Slice(0, m.Name.IndexOf("`") == -1 ? m.Name.Length : m.Name.IndexOf("`")));
            else if (opt.EmitCtorNameAsClassName) buffer.Append(m.DeclaringType.Name.Slice(0, m.DeclaringType.Name.IndexOf("`") == -1 ? m.DeclaringType.Name.Length : m.DeclaringType.Name.IndexOf("`")));
            else buffer.Append(m.Name.Slice(0, m.Name.IndexOf("`") == -1 ? m.Name.Length : m.Name.IndexOf("`")));
            if (opt.EmitTypeArgs) buffer.Append(m.GetCSharpTypeArgsClause(opt));

            buffer.Append("(");
            m.GetParameters().ForEach((pi, i) =>
            {
                if (opt.EmitAttributes && pi.Attrs().IsNotEmpty())
                    buffer.Append(pi.GetCSharpAttributesClause(opt)).Append(" ");

                var mod = "";
                if (pi.ParameterType.IsByRef && pi.IsOut) mod = "out";
                if (pi.ParameterType.IsByRef && !pi.IsOut) mod = "ref";
                if (mod.IsNotEmpty()) buffer.Append(mod).Append(" ");

                var t_par = pi.ParameterType.IsByRef ? pi.ParameterType.GetElementType() : pi.ParameterType;
                buffer.Append(t_par.GetCSharpRef(opt)).Append(" ");
                buffer.Append(pi.Name);

                if (i != m.GetParameters().Count() - 1) buffer.Append(", ");
            });
            buffer.Append(")");

            if (opt.EmitTypeArgsConstraints) buffer.Append(m.GetCSharpTypeConstraintsClause(opt));

            if (opt.EmitSemicolon) buffer.Append(";");
            return buffer.ToString();
        }
 public static String GetCSharpTypeArgsClause(this Type t, ToCSharpOptions opt)
 {
     return GetCSharpTypeArgsClause(t.XGetGenericArguments(), opt);
 }
        public static String GetCSharpDecl(this MethodBase m, ToCSharpOptions opt)
        {
            opt = opt ?? ToCSharpOptions.Terse;
            var buffer = new StringBuilder();

            if (opt.EmitAttributes && m.Attrs().IsNotEmpty())
            {
                buffer.Append(m.GetCSharpAttributesClause(opt)).Append(" ");
            }
            if (opt.EmitAttributes && m is MethodInfo && (((MethodInfo)m).ReturnParameter).Attrs().IsNotEmpty())
            {
                buffer.Append(((MethodInfo)m).ReturnParameter.GetCSharpAttributesClause(opt)).Append(" ");
            }
            if (opt.EmitVisibilityQualifier)
            {
                buffer.Append(m.GetCSharpVisibilityQualifier()).Append(" ");
            }
            if (opt.EmitStaticQualifier && m.IsStatic)
            {
                buffer.Append("static ");
            }
            if (!(m is ConstructorInfo))
            {
                buffer.Append(m.Ret().GetCSharpRef(opt)).Append(" ");
            }
            if (opt.EmitDeclaringType)
            {
                buffer.Append(m.DeclaringType.GetCSharpRef(ToCSharpOptions.Terse) + "::");
            }
            if (!(m is ConstructorInfo))
            {
                buffer.Append(m.Name.Slice(0, m.Name.IndexOf("`") == -1 ? m.Name.Length : m.Name.IndexOf("`")));
            }
            else if (opt.EmitCtorNameAsClassName)
            {
                buffer.Append(m.DeclaringType.Name.Slice(0, m.DeclaringType.Name.IndexOf("`") == -1 ? m.DeclaringType.Name.Length : m.DeclaringType.Name.IndexOf("`")));
            }
            else
            {
                buffer.Append(m.Name.Slice(0, m.Name.IndexOf("`") == -1 ? m.Name.Length : m.Name.IndexOf("`")));
            }
            if (opt.EmitTypeArgs)
            {
                buffer.Append(m.GetCSharpTypeArgsClause(opt));
            }

            buffer.Append("(");
            m.GetParameters().ForEach((pi, i) =>
            {
                if (opt.EmitAttributes && pi.Attrs().IsNotEmpty())
                {
                    buffer.Append(pi.GetCSharpAttributesClause(opt)).Append(" ");
                }

                var mod = "";
                if (pi.ParameterType.IsByRef && pi.IsOut)
                {
                    mod = "out";
                }
                if (pi.ParameterType.IsByRef && !pi.IsOut)
                {
                    mod = "ref";
                }
                if (mod.IsNotEmpty())
                {
                    buffer.Append(mod).Append(" ");
                }

                var t_par = pi.ParameterType.IsByRef ? pi.ParameterType.GetElementType() : pi.ParameterType;
                buffer.Append(t_par.GetCSharpRef(opt)).Append(" ");
                buffer.Append(pi.Name);

                if (i != m.GetParameters().Count() - 1)
                {
                    buffer.Append(", ");
                }
            });
            buffer.Append(")");

            if (opt.EmitTypeArgsConstraints)
            {
                buffer.Append(m.GetCSharpTypeConstraintsClause(opt));
            }

            if (opt.EmitSemicolon)
            {
                buffer.Append(";");
            }
            return(buffer.ToString());
        }
        public static String GetCSharpAttributesClause(this ICustomAttributeProvider cap, ToCSharpOptions opt)
        {
            if (cap.Attrs().Count() == 0)
            {
                return(String.Empty);
            }
            else
            {
                var buffer = new StringBuilder();
                buffer.Append("[");

                var prefix = String.Empty;
                if (cap is ParameterInfo)
                {
                    /*IsRetVal ain't work */
                    var mb = ((ParameterInfo)cap).Member;
                    if (mb is MethodInfo && ((MethodInfo)(mb)).ReturnParameter == cap)
                    {
                        prefix = "return: ";
                    }
                }

                // todo. implement this using CustomAttributeData
                // that will preserve info about ctor and setters
                var attrs = cap.GetCustomAttributes(false);
                attrs.ForEach((attr, i) =>
                {
                    buffer.Append(prefix);
                    buffer.Append(attr.GetType().GetCSharpRef(opt));
                    if (i != attrs.Count() - 1)
                    {
                        buffer.Append(", ");
                    }
                });

                buffer.Append("]");
                return(buffer.ToString());
            }
        }
        public static String GetCSharpDecl(this FieldInfo f, ToCSharpOptions opt)
        {
            opt = opt ?? ToCSharpOptions.Terse;
            var buffer = new StringBuilder();

            if (opt.EmitAttributes && f.Attrs().IsNotEmpty()) 
                buffer.Append(f.GetCSharpAttributesClause(opt)).Append(" ");
            if (opt.EmitVisibilityQualifier) buffer.Append(f.GetCSharpVisibilityQualifier()).Append(" ");
            if (opt.EmitStaticQualifier && f.IsStatic) buffer.Append("static ");
            buffer.Append(f.FieldType.GetCSharpRef(opt)).Append(" ");
            if (opt.EmitDeclaringType) buffer.Append(f.DeclaringType.GetCSharpRef(ToCSharpOptions.Terse) + "::");
            buffer.Append(f.Name);

            if (opt.EmitSemicolon) buffer.Append(";");
            return buffer.ToString();
        }