示例#1
0
        public void InitializeTest()
        {
            var type    = typeof(string);
            var builder = new TypeNameBuilder(type);

            Assert.Equal(builder.AssemblyName, type.Assembly().FullName);
            Assert.Equal(type, Type.GetType(builder.ToString()));

            builder = new TypeNameBuilder(type, assembly => assembly.GetName().Name);
            Assert.Equal(builder.AssemblyName, type.Assembly().GetName().Name);
            Assert.Equal(type, Type.GetType(builder.ToString()));

            type    = typeof(string[]);
            builder = new TypeNameBuilder(type);
            Assert.Equal(type, Type.GetType(builder.ToString()));

            type    = typeof(string[][, ]);
            builder = new TypeNameBuilder(type);
            Assert.Equal(type, Type.GetType(builder.ToString()));

            type    = typeof(Foo <,>);
            builder = new TypeNameBuilder(type);
            Assert.Equal(type, Type.GetType(builder.ToString()));

            type    = typeof(Foo <int, string>);
            builder = new TypeNameBuilder(type);
            Assert.Equal(type, Type.GetType(builder.ToString()));

            type    = typeof(Foo <int, string>[][, ][, , ]);
            builder = new TypeNameBuilder(type);
            Assert.Equal(type, Type.GetType(builder.ToString()));

            type    = typeof(Foo <,> .Bar <>);
            builder = new TypeNameBuilder(type);
            Assert.Equal(type, Type.GetType(builder.ToString()));

            type    = typeof(Foo <int, string> .Bar <bool>);
            builder = new TypeNameBuilder(type);
            Assert.Equal(type, Type.GetType(builder.ToString()));

            type    = typeof(Foo <int, string> .Bar <bool>[]);
            builder = new TypeNameBuilder(type);
            Assert.Equal(type, Type.GetType(builder.ToString()));

            type    = typeof(Foo <int, List <string> > .Bar <bool>);
            builder = new TypeNameBuilder(type);
            Assert.Equal(type, Type.GetType(builder.ToString()));

            type    = typeof(Foo <(int, string), List <string>[][, ]> .Bar <bool>[]);
            builder = new TypeNameBuilder(type);
            Assert.Equal(type, Type.GetType(builder.ToString()));
        }
示例#2
0
        private static void Parse(string input, int startIndex, int endIndex, TypeNameBuilder builder)
        {
            startIndex = ParseTypeName(input, startIndex, endIndex, builder, out builder._namespace);

            if (startIndex < endIndex)
            {
                if (input[startIndex] == '[')
                {
                    startIndex = ParseBrackets(input, startIndex + 1, endIndex, builder);
                }

                if (startIndex < endIndex && input[startIndex] == ',')
                {
                    builder._assemblyName = GetAssemblyName(input, startIndex + 1, endIndex);
                }
            }
        }
示例#3
0
        private static TypeNameBuilder Initialize(TypeNameBuilder builder, Type type, Func <Assembly, string> getAssemblyName)
        {
            int i, j, n, m;

            if (type.IsArray)
            {
                do
                {
                    builder.ArrayDimensions.Add(type.GetArrayRank());
                    type = type.GetElementType();
                }while (type.IsArray);

                for (i = 0, j = builder.ArrayDimensions.Count - 1; i < j; i++, j--)
                {
                    GeneralUtils.Swap(builder.ArrayDimensions, i, j);
                }
            }

            Type[] genericTypeArguments;
            bool   isOpenGeneric;

            if (type.IsGenericType())
            {
                genericTypeArguments = type.GetGenericTypeArguments();
                isOpenGeneric        = type.IsGenericTypeDefinition();
            }
            else
            {
                genericTypeArguments = null;
                isOpenGeneric        = false;
            }

            TypeName currentTypeName = null;

            do
            {
                if (type.DeclaringType == null)
                {
                    builder.Nested  = currentTypeName;
                    currentTypeName = builder;

                    builder.AssemblyName = getAssemblyName(type.Assembly());

                    builder.Namespace = type.Namespace;
                }
                else
                {
                    currentTypeName = new TypeName {
                        Nested = currentTypeName
                    }
                };

                var index = type.Name.LastIndexOf('`');
                if (index >= 0)
                {
                    currentTypeName.BaseName = type.Name.Substring(0, index);
                    n = int.Parse(type.Name.Substring(index + 1), CultureInfo.InvariantCulture);
                    for (; n > 0; n--)
                    {
                        currentTypeName.GenericArguments.Add(null);
                    }
                }
                else
                {
                    currentTypeName.BaseName = type.Name;
                }

                type = type.DeclaringType;
            }while (type != null);

            if (genericTypeArguments != null && !isOpenGeneric)
            {
                for (i = 0, n = genericTypeArguments.Length; i < n;)
                {
                    for (j = 0, m = currentTypeName.GenericArguments.Count; j < m; j++)
                    {
                        currentTypeName.GenericArguments[j] = Initialize(new TypeNameBuilder(), genericTypeArguments[i++], getAssemblyName);
                    }

                    currentTypeName = currentTypeName.Nested;
                }
            }

            return(builder);
        }
示例#4
0
        private static StringBuilder Build(StringBuilder sb, TypeNameBuilder builder, bool appendAssemblyName)
        {
            const int isNestedTypeFlag  = 0x1;
            const int isGenericFlag     = 0x2;
            const int isOpenGenericFlag = 0x4;

            int flags = 0;
            int i, n;

            if (!string.IsNullOrEmpty(builder.Namespace))
            {
                sb.Append(builder.Namespace).Append('.');
            }

            TypeName typeName = builder;

            do
            {
                if (flags == 0)
                {
                    flags = isNestedTypeFlag;
                }
                else
                {
                    sb.Append('+');
                }

                BuildTypeName(sb, typeName);

                if (typeName.IsGeneric)
                {
                    flags |= isGenericFlag;

                    if (typeName.IsOpenGeneric)
                    {
                        flags |= isOpenGenericFlag;
                    }
                }
            }while ((typeName = typeName._nested) != null);

            if ((flags & (isGenericFlag | isOpenGenericFlag)) == isGenericFlag)
            {
                sb.Append('[');

                typeName = builder;
                do
                {
                    if (typeName._genericArguments != null)
                    {
                        for (i = 0, n = typeName._genericArguments.Count; i < n; i++)
                        {
                            sb.Append('[');
                            Build(sb, typeName._genericArguments[i], appendAssemblyName: true);
                            sb.Append(']').Append(',');
                        }
                    }
                }while ((typeName = typeName._nested) != null);

                sb[sb.Length - 1] = ']';
            }

            if (builder.IsArray)
            {
                for (i = 0, n = builder._arrayDimensions.Count; i < n; i++)
                {
                    sb.Append('[');
                    var count = builder._arrayDimensions[i];
                    if (--count > 0)
                    {
                        sb.Append(',', count);
                    }
                    sb.Append(']');
                }
            }

            if (appendAssemblyName && !string.IsNullOrEmpty(builder._assemblyName))
            {
                sb.Append(',').Append(' ').Append(builder._assemblyName);
            }

            return(sb);
        }
示例#5
0
        private static int ParseBrackets(string input, int startIndex, int endIndex, TypeNameBuilder builder)
        {
            TypeName typeName          = builder;
            var      genericArgIndex   = -1;
            var      sectionStartIndex = -1;
            var      counter           = 0;

            const int inBracketsState = 0;
            const int inGenericBracketsBeforeArgState = 1;
            const int inNestedBracketsState           = 2;
            const int inGenericBracketsAfterArgState  = 3;
            const int inArrayBracketsState            = 4;
            const int inAfterBracketsState            = 5;

            int state = inBracketsState;
            int i;

            for (i = startIndex; i < endIndex; i++)
            {
                var c = input[i];

                switch (state)
                {
                case inBracketsState:
                    switch (c)
                    {
                    case '[':
                        sectionStartIndex = i + 1;
                        state             = inNestedBracketsState;
                        break;

                    case ']':
                        builder.ArrayDimensions.Add(counter + 1);
                        state = inAfterBracketsState;
                        break;

                    case ',':
                        counter++;
                        state = inArrayBracketsState;
                        break;

                    default:
                        if (!char.IsWhiteSpace(c))
                        {
                            throw new FormatException();
                        }
                        break;
                    }
                    break;

                case inGenericBracketsBeforeArgState:
                    switch (c)
                    {
                    case '[':
                        sectionStartIndex = i + 1;
                        state             = inNestedBracketsState;
                        break;

                    default:
                        if (!char.IsWhiteSpace(c))
                        {
                            throw new FormatException();
                        }
                        break;
                    }
                    break;

                case inNestedBracketsState:
                    switch (c)
                    {
                    case '[':
                        counter++;
                        break;

                    case ']':
                        if (counter == 0)
                        {
                            SeekNextGenericArg(ref typeName, ref genericArgIndex);
                            // too much generic argument?
                            if (typeName == null)
                            {
                                throw new FormatException();
                            }

                            Parse(input, sectionStartIndex, i, typeName._genericArguments[genericArgIndex] = new TypeNameBuilder());

                            state = inGenericBracketsAfterArgState;
                        }
                        else
                        {
                            counter--;
                        }
                        break;
                    }
                    break;

                case inGenericBracketsAfterArgState:
                    switch (c)
                    {
                    case ']':
                        SeekNextGenericArg(ref typeName, ref genericArgIndex);
                        // too few generic argument?
                        if (typeName != null)
                        {
                            throw new FormatException();
                        }

                        state = inAfterBracketsState;
                        break;

                    case ',':
                        state = inGenericBracketsBeforeArgState;
                        break;

                    default:
                        if (!char.IsWhiteSpace(c))
                        {
                            throw new FormatException();
                        }
                        break;
                    }
                    break;

                case inArrayBracketsState:
                    switch (c)
                    {
                    case ']':
                        builder.ArrayDimensions.Add(counter + 1);
                        state = inAfterBracketsState;
                        break;

                    case ',':
                        counter++;
                        break;

                    default:
                        if (!char.IsWhiteSpace(c))
                        {
                            throw new FormatException();
                        }
                        break;
                    }
                    break;

                case inAfterBracketsState:
                    switch (c)
                    {
                    case ',':
                        return(i);

                    case '[':
                        counter = 0;
                        state   = inArrayBracketsState;
                        break;

                    default:
                        if (!char.IsWhiteSpace(c))
                        {
                            throw new FormatException();
                        }
                        break;
                    }
                    break;
                }
            }

            switch (state)
            {
            case inAfterBracketsState:
                return(i);

            case inBracketsState:
            case inGenericBracketsBeforeArgState:
            case inGenericBracketsAfterArgState:
            case inArrayBracketsState:
            case inNestedBracketsState:
                throw new FormatException();

            default:
                throw new InvalidOperationException();
            }
        }
示例#6
0
        public void GenerateTest()
        {
            #region simple

            var builder = new TypeNameBuilder
            {
                BaseName     = "System.String",
                AssemblyName = "mscorlib"
            };
            Assert.Equal("System.String, mscorlib", builder.ToString());

            #endregion

            #region generic

            builder = new TypeNameBuilder
            {
                AssemblyName     = "mscorlib",
                Namespace        = "System.Collections.Generic",
                BaseName         = "List",
                GenericArguments =
                {
                    new TypeNameBuilder
                    {
                        AssemblyName = "mscorlib",
                        Namespace    = "System",
                        BaseName     = "Int32",
                    },
                }
            };
            Assert.Equal("System.Collections.Generic.List`1[[System.Int32, mscorlib]], mscorlib", builder.ToString());

            builder.GenericArguments[0] = null;

            Assert.Equal("System.Collections.Generic.List`1, mscorlib", builder.ToString());

            #endregion

            #region array

            builder = new TypeNameBuilder
            {
                AssemblyName     = "mscorlib",
                Namespace        = "System.Collections.Generic",
                BaseName         = "List",
                GenericArguments =
                {
                    new TypeNameBuilder
                    {
                        AssemblyName    = "mscorlib",
                        Namespace       = "System",
                        BaseName        = "Int32",
                        ArrayDimensions ={                       1 }
                    },
                },
                ArrayDimensions = { 2, 3 }
            };
            Assert.Equal("System.Collections.Generic.List`1[[System.Int32[], mscorlib]][,][,,], mscorlib", builder.ToString());
            Assert.Equal("List`1", builder.GetName());

            builder.GenericArguments[0] = null;

            Assert.Equal("System.Collections.Generic.List`1[,][,,]", builder.GetFullName());

            builder.BaseName = "";

            Assert.Equal("System.Collections.Generic.?`1[,][,,]", builder.GetFullName());

            #endregion

            #region nested

            builder = new TypeNameBuilder
            {
                BaseName = "X",
                Nested   = new TypeName {
                    BaseName = "Y"
                },
                Namespace = "NS"
            };
            Assert.Equal("NS.X+Y", builder.ToString());

            builder.ArrayDimensions.Add(1);
            Assert.Equal("NS.X+Y[]", builder.ToString());

            builder.Nested.GenericArguments.Add(new TypeNameBuilder {
                BaseName = "T"
            });
            Assert.Equal("NS.X+Y`1[[T]][]", builder.ToString());

            #endregion
            #region complex

            builder = new TypeNameBuilder
            {
                BaseName         = "System.Collections.Generic.Dictionary",
                AssemblyName     = "mscorlib",
                GenericArguments =
                {
                    new TypeNameBuilder
                    {
                        BaseName     = "System.Int32",
                        AssemblyName = "mscorlib",
                    },
                    new TypeNameBuilder
                    {
                        BaseName         = "System.Collections.Generic.List",
                        AssemblyName     = "mscorlib",
                        GenericArguments =
                        {
                            new TypeNameBuilder
                            {
                                BaseName        = "System.String",
                                AssemblyName    = "mscorlib",
                                ArrayDimensions ={                       1, 2 }
                            },
                        }
                    },
                },
                Nested = new TypeName {
                    BaseName = "Enumerator"
                }
            };
            Assert.Equal("System.Collections.Generic.Dictionary`2+Enumerator[[System.Int32, mscorlib],[System.Collections.Generic.List`1[[System.String[][,], mscorlib]], mscorlib]], mscorlib", builder.ToString());

            #endregion
        }
示例#7
0
        public void ParseTest()
        {
            #region simple

            var typeName = new TypeName("System.String");
            Assert.Equal("String", typeName.BaseName);
            Assert.False(typeName.HasNested);
            Assert.Null(typeName.Nested);
            Assert.False(typeName.IsGeneric);
            Assert.False(typeName.IsOpenGeneric);
            Assert.Equal(0, typeName.GenericArguments.Count);

            var builder = new TypeNameBuilder("System.String");
            Assert.Equal("System", builder.Namespace);
            Assert.Equal("String", builder.BaseName);
            Assert.False(builder.HasNested);
            Assert.Null(builder.Nested);
            Assert.Null(builder.AssemblyName);
            Assert.False(builder.IsGeneric);
            Assert.False(builder.IsOpenGeneric);
            Assert.Equal(0, builder.GenericArguments.Count);
            Assert.False(builder.IsArray);
            Assert.Equal(0, builder.ArrayDimensions.Count);

            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.String, "));
            Assert.Throws <FormatException>(() => new TypeNameBuilder(" .System.String, "));
            Assert.Throws <FormatException>(() => new TypeNameBuilder(" System..String, "));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.String., "));
            Assert.Throws <FormatException>(() => new TypeNameBuilder(" ]System.String "));
            Assert.Throws <FormatException>(() => new TypeNameBuilder(" [System.String "));
            Assert.Throws <FormatException>(() => new TypeNameBuilder(", System.String "));
            new TypeNameBuilder("System.String  ");

            #endregion

            #region nested simple

            builder = new TypeNameBuilder("X+Y");
            Assert.Null(builder.AssemblyName);
            Assert.Null(builder.Namespace);
            Assert.False(builder.IsArray);
            Assert.Equal(0, builder.ArrayDimensions.Count);

            Assert.Equal("X", builder.BaseName);
            Assert.True(builder.HasNested);
            Assert.False(builder.IsGeneric);
            Assert.False(builder.IsOpenGeneric);
            Assert.Equal(0, builder.GenericArguments.Count);

            Assert.Equal("Y", builder.Nested.BaseName);
            Assert.False(builder.Nested.HasNested);
            Assert.False(builder.Nested.IsGeneric);
            Assert.False(builder.Nested.IsOpenGeneric);
            Assert.Equal(0, builder.Nested.GenericArguments.Count);

            Assert.Null(builder.Nested.Nested);

            builder = new TypeNameBuilder(" X+Y+Z ");
            Assert.Null(builder.AssemblyName);
            Assert.Null(builder.Namespace);
            Assert.False(builder.IsArray);
            Assert.Equal(0, builder.ArrayDimensions.Count);

            Assert.Equal("X", builder.BaseName);
            Assert.False(builder.IsGeneric);
            Assert.False(builder.IsOpenGeneric);
            Assert.Equal(0, builder.GenericArguments.Count);

            Assert.Equal("Y", builder.Nested.BaseName);
            Assert.False(builder.Nested.IsGeneric);
            Assert.False(builder.Nested.IsOpenGeneric);
            Assert.Equal(0, builder.Nested.GenericArguments.Count);

            Assert.Equal("Z", builder.Nested.Nested.BaseName);
            Assert.False(builder.Nested.Nested.IsGeneric);
            Assert.False(builder.Nested.Nested.IsOpenGeneric);
            Assert.Equal(0, builder.Nested.Nested.GenericArguments.Count);

            Assert.Null(builder.Nested.Nested.Nested);

            Assert.Throws <FormatException>(() => new TypeNameBuilder("+X"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("X+"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("X+ Y"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("X +Y"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("X+Y+"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("X+.Y"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("X+Y."));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("X+NS.Y"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("X[]+Y"));
            new TypeNameBuilder("X+Y[]");

            #endregion

            #region array

            builder = new TypeNameBuilder("System.String[],mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
            Assert.Equal("System", builder.Namespace);
            Assert.Equal("String", builder.BaseName);
            Assert.Equal("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", builder.AssemblyName);
            Assert.False(builder.IsGeneric);
            Assert.False(builder.IsOpenGeneric);
            Assert.Equal(0, builder.GenericArguments.Count);
            Assert.Equal(1, builder.ArrayDimensions.Count);
            Assert.Equal(1, builder.ArrayDimensions[0]);

            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.String []"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.String[[]]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.String["));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.String]["));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.String[]["));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.String[[["));

            #endregion

            #region array of array

            builder = new TypeNameBuilder("System.String[ , ] [, ,][], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
            Assert.Equal("System", builder.Namespace);
            Assert.Equal("String", builder.BaseName);
            Assert.Equal("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", builder.AssemblyName);
            Assert.False(builder.IsGeneric);
            Assert.False(builder.IsOpenGeneric);
            Assert.Equal(0, builder.GenericArguments.Count);
            Assert.Equal(3, builder.ArrayDimensions.Count);
            Assert.Equal(2, builder.ArrayDimensions[0]);
            Assert.Equal(3, builder.ArrayDimensions[1]);
            Assert.Equal(1, builder.ArrayDimensions[2]);

            #endregion

            #region generic

            builder = new TypeNameBuilder("System.Collections.Generic.List`1[[System.String]]");
            Assert.Equal("System.Collections.Generic", builder.Namespace);
            Assert.Equal("List", builder.BaseName);
            Assert.Null(builder.AssemblyName);
            Assert.True(builder.IsGeneric);
            Assert.False(builder.IsOpenGeneric);
            Assert.Equal(1, builder.GenericArguments.Count);
            Assert.False(builder.IsArray);
            Assert.Equal(0, builder.ArrayDimensions.Count);

            TypeNameBuilder builder2 = builder.GenericArguments[0];
            Assert.Equal("System", builder2.Namespace);
            Assert.Equal("String", builder2.BaseName);
            Assert.Null(builder2.AssemblyName);
            Assert.False(builder2.IsGeneric);
            Assert.False(builder2.IsOpenGeneric);
            Assert.Equal(0, builder2.GenericArguments.Count);
            Assert.False(builder2.IsArray);
            Assert.Equal(0, builder2.ArrayDimensions.Count);

            builder = new TypeNameBuilder("System.Collections.Generic.List`1 , mscorlib ");
            Assert.Equal("System.Collections.Generic", builder.Namespace);
            Assert.Equal("List", builder.BaseName);
            Assert.Equal("mscorlib", builder.AssemblyName);
            Assert.True(builder.IsGeneric);
            Assert.True(builder.IsOpenGeneric);
            Assert.Equal(1, builder.GenericArguments.Count);
            Assert.False(builder.IsArray);
            Assert.Equal(0, builder.ArrayDimensions.Count);
            Assert.Null(builder.GenericArguments[0]);

            Assert.Throws <FormatException>(() => new TypeNameBuilder("`1[[System.String]]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.Collections.Generic.List`a [[System.String]]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.Collections.Generic.`1[[System.String]]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.Collections.Generic.List`[[System.String]]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.Collections.Generic.List`1 [[System.String]]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.Collections.Generic.List`1[[]]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.Collections.Generic.List`2[[System.String]]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.Collections.Generic.Dictionary`2[System.String]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.Collections.Generic.Dictionary`2[System.String, ]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.Collections.Generic.Dictionary`2[[System.String], System.Int32]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.Collections.Generic.List`1[System.String]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.Collections.Generic.List`1[[System.String]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.Collections.Generic.List`1[[System.String] System.Int32]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.Collections.Generic.List`1[System.String]]"));
            new TypeNameBuilder("System.Collections.Generic.List`1");

            #endregion

            #region nested generic

            builder = new TypeNameBuilder("X`1+Y`2[[A[]], [B], [C]]");
            Assert.Null(builder.AssemblyName);
            Assert.Null(builder.Namespace);
            Assert.False(builder.IsArray);
            Assert.Equal(0, builder.ArrayDimensions.Count);

            Assert.Equal("X", builder.BaseName);
            Assert.True(builder.IsGeneric);
            Assert.False(builder.IsOpenGeneric);
            Assert.Equal(1, builder.GenericArguments.Count);

            builder2 = builder.GenericArguments[0];
            Assert.Null(builder2.AssemblyName);
            Assert.Null(builder2.Namespace);
            Assert.True(builder2.IsArray);
            Assert.Equal(1, builder2.ArrayDimensions.Count);
            Assert.Equal(1, builder2.ArrayDimensions[0]);
            Assert.Equal("A", builder2.BaseName);
            Assert.False(builder2.IsGeneric);
            Assert.False(builder2.IsOpenGeneric);
            Assert.Equal(0, builder2.GenericArguments.Count);
            Assert.Null(builder2.Nested);

            Assert.Equal("Y", builder.Nested.BaseName);
            Assert.True(builder.Nested.IsGeneric);
            Assert.False(builder.Nested.IsOpenGeneric);
            Assert.Equal(2, builder.Nested.GenericArguments.Count);

            builder2 = builder.Nested.GenericArguments[0];
            Assert.Null(builder2.AssemblyName);
            Assert.Null(builder2.Namespace);
            Assert.False(builder2.IsArray);
            Assert.Equal(0, builder2.ArrayDimensions.Count);
            Assert.Equal("B", builder2.BaseName);
            Assert.False(builder2.IsGeneric);
            Assert.False(builder2.IsOpenGeneric);
            Assert.Equal(0, builder2.GenericArguments.Count);
            Assert.Null(builder2.Nested);

            builder2 = builder.Nested.GenericArguments[1];
            Assert.Null(builder2.AssemblyName);
            Assert.Null(builder2.Namespace);
            Assert.False(builder2.IsArray);
            Assert.Equal(0, builder2.ArrayDimensions.Count);
            Assert.Equal("C", builder2.BaseName);
            Assert.False(builder2.IsGeneric);
            Assert.False(builder2.IsOpenGeneric);
            Assert.Equal(0, builder2.GenericArguments.Count);
            Assert.Null(builder2.Nested);

            Assert.Null(builder.Nested.Nested);

            Assert.Throws <FormatException>(() => new TypeNameBuilder("X`1+Y`1[[A]]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("X`1+Y`1[[A],[B],[C]]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("X`2+Y[[A],[B],[C]]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("X+Y`1[[A],[B],[C]]"));
            new TypeNameBuilder("X+Y`1[[A]]");

            #endregion

            #region array of generic

            builder = new TypeNameBuilder("System.Collections.Generic.List`1[[System.String[,]]] []");
            Assert.Equal("System.Collections.Generic", builder.Namespace);
            Assert.Equal("List", builder.BaseName);
            Assert.Null(builder.AssemblyName);
            Assert.True(builder.IsGeneric);
            Assert.False(builder.IsOpenGeneric);
            Assert.Equal(1, builder.GenericArguments.Count);
            Assert.True(builder.IsArray);
            Assert.Equal(1, builder.ArrayDimensions.Count);
            Assert.Equal(1, builder.ArrayDimensions[0]);

            builder2 = builder.GenericArguments[0];
            Assert.Equal("System", builder2.Namespace);
            Assert.Equal("String", builder2.BaseName);
            Assert.Null(builder2.AssemblyName);
            Assert.False(builder2.IsGeneric);
            Assert.False(builder2.IsOpenGeneric);
            Assert.Equal(0, builder2.GenericArguments.Count);
            Assert.True(builder2.IsArray);
            Assert.Equal(1, builder2.ArrayDimensions.Count);
            Assert.Equal(2, builder2.ArrayDimensions[0]);

            builder = new TypeNameBuilder("System.Collections.Generic.List`1[],mscorlib");
            Assert.Equal("System.Collections.Generic", builder.Namespace);
            Assert.Equal("List", builder.BaseName);
            Assert.Equal("mscorlib", builder.AssemblyName);
            Assert.True(builder.IsGeneric);
            Assert.True(builder.IsOpenGeneric);
            Assert.Equal(1, builder.GenericArguments.Count);
            Assert.True(builder.IsArray);
            Assert.Equal(1, builder.ArrayDimensions.Count);
            Assert.Null(builder.GenericArguments[0]);

            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.Collections.Generic.List`1[][[System.String]]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("System.Collections.Generic.List`1 [],mscorlib"));

            #endregion

            #region array of nested generic

            builder = new TypeNameBuilder("X`1+Y`2[[A[]], [B], [C]] [,,][]");
            Assert.Null(builder.AssemblyName);
            Assert.Null(builder.Namespace);
            Assert.True(builder.IsArray);
            Assert.Equal(2, builder.ArrayDimensions.Count);
            Assert.Equal(3, builder.ArrayDimensions[0]);
            Assert.Equal(1, builder.ArrayDimensions[1]);

            Assert.Equal("X", builder.BaseName);
            Assert.True(builder.IsGeneric);
            Assert.False(builder.IsOpenGeneric);
            Assert.Equal(1, builder.GenericArguments.Count);

            builder2 = builder.GenericArguments[0];
            Assert.Null(builder2.AssemblyName);
            Assert.Null(builder2.Namespace);
            Assert.True(builder2.IsArray);
            Assert.Equal(1, builder2.ArrayDimensions.Count);
            Assert.Equal(1, builder2.ArrayDimensions[0]);
            Assert.Equal("A", builder2.BaseName);
            Assert.False(builder2.IsGeneric);
            Assert.False(builder2.IsOpenGeneric);
            Assert.Equal(0, builder2.GenericArguments.Count);
            Assert.Null(builder2.Nested);

            Assert.Equal("Y", builder.Nested.BaseName);
            Assert.True(builder.Nested.IsGeneric);
            Assert.False(builder.Nested.IsOpenGeneric);
            Assert.Equal(2, builder.Nested.GenericArguments.Count);

            builder2 = builder.Nested.GenericArguments[0];
            Assert.Null(builder2.AssemblyName);
            Assert.Null(builder2.Namespace);
            Assert.False(builder2.IsArray);
            Assert.Equal(0, builder2.ArrayDimensions.Count);
            Assert.Equal("B", builder2.BaseName);
            Assert.False(builder2.IsGeneric);
            Assert.False(builder2.IsOpenGeneric);
            Assert.Equal(0, builder2.GenericArguments.Count);
            Assert.Null(builder2.Nested);

            builder2 = builder.Nested.GenericArguments[1];
            Assert.Null(builder2.AssemblyName);
            Assert.Null(builder2.Namespace);
            Assert.False(builder2.IsArray);
            Assert.Equal(0, builder2.ArrayDimensions.Count);
            Assert.Equal("C", builder2.BaseName);
            Assert.False(builder2.IsGeneric);
            Assert.False(builder2.IsOpenGeneric);
            Assert.Equal(0, builder2.GenericArguments.Count);
            Assert.Null(builder2.Nested);

            Assert.Null(builder.Nested.Nested);

            builder = new TypeNameBuilder("X+Y`16[ ]");
            Assert.Null(builder.AssemblyName);
            Assert.Null(builder.Namespace);
            Assert.True(builder.IsArray);
            Assert.Equal(1, builder.ArrayDimensions.Count);
            Assert.Equal(1, builder.ArrayDimensions[0]);

            Assert.Equal("X", builder.BaseName);
            Assert.False(builder.IsGeneric);
            Assert.False(builder.IsOpenGeneric);
            Assert.Equal(0, builder.GenericArguments.Count);

            Assert.Equal("Y", builder.Nested.BaseName);
            Assert.True(builder.Nested.IsGeneric);
            Assert.True(builder.Nested.IsOpenGeneric);
            Assert.Equal(16, builder.Nested.GenericArguments.Count);
            Assert.True(builder.Nested.GenericArguments.All(arg => arg == null));

            Assert.Null(builder.Nested.Nested);

            Assert.Throws <FormatException>(() => new TypeNameBuilder("X`1+Y`2[, ,][[A[]], [B], [C]]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("X+Y`16[[]]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("X+Y`16[, []]"));
            Assert.Throws <FormatException>(() => new TypeNameBuilder("X+Y`16[[], ]"));

            #endregion

            #region generic of generic

            builder = new TypeNameBuilder(" System.Collections.Generic.Dictionary`2[[ System.Int32 , mscorlib2 ], [System.Collections.Generic.List`1[[System.String, mscorlib4]] ,mscorlib3] ] , mscorlib1");
            Assert.Equal("System.Collections.Generic", builder.Namespace);
            Assert.Equal("Dictionary", builder.BaseName);
            Assert.Equal("mscorlib1", builder.AssemblyName);
            Assert.True(builder.IsGeneric);
            Assert.False(builder.IsOpenGeneric);
            Assert.Equal(2, builder.GenericArguments.Count);
            Assert.False(builder.IsArray);
            Assert.Equal(0, builder.ArrayDimensions.Count);

            builder2 = builder.GenericArguments[0];
            Assert.Equal("System", builder2.Namespace);
            Assert.Equal("Int32", builder2.BaseName);
            Assert.Equal("mscorlib2", builder2.AssemblyName);
            Assert.False(builder2.IsGeneric);
            Assert.False(builder2.IsOpenGeneric);
            Assert.Equal(0, builder2.GenericArguments.Count);
            Assert.False(builder2.IsArray);
            Assert.Equal(0, builder2.ArrayDimensions.Count);

            builder2 = builder.GenericArguments[1];
            Assert.Equal("System.Collections.Generic", builder2.Namespace);
            Assert.Equal("List", builder2.BaseName);
            Assert.Equal("mscorlib3", builder2.AssemblyName);
            Assert.True(builder2.IsGeneric);
            Assert.False(builder2.IsOpenGeneric);
            Assert.Equal(1, builder2.GenericArguments.Count);
            Assert.False(builder2.IsArray);
            Assert.Equal(0, builder2.ArrayDimensions.Count);

            TypeNameBuilder builder3 = builder2.GenericArguments[0];
            Assert.Equal("System", builder3.Namespace);
            Assert.Equal("String", builder3.BaseName);
            Assert.Equal("mscorlib4", builder3.AssemblyName);
            Assert.False(builder3.IsGeneric);
            Assert.False(builder3.IsOpenGeneric);
            Assert.Equal(0, builder3.GenericArguments.Count);
            Assert.False(builder3.IsArray);
            Assert.Equal(0, builder3.ArrayDimensions.Count);

            #endregion

            #region transforms

            builder = new TypeNameBuilder("System.Collections.Generic.Dictionary`2+Enumerator[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Collections.Generic.List`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
                      .Transform(b =>
            {
                b.AssemblyName = new AssemblyNameBuilder(b.AssemblyName)
                {
                    Version = null, CultureInfo = null, PublicKeyToken = null
                }.ToString();
                b.Namespace = Regex.Replace(b.Namespace, @"^System(.|$)", "");
            });

            Assert.Equal("mscorlib", builder.AssemblyName);
            Assert.Equal("Collections.Generic", builder.Namespace);
            Assert.False(builder.IsArray);
            Assert.Equal(0, builder.ArrayDimensions.Count);

            Assert.Equal("Dictionary", builder.BaseName);
            Assert.True(builder.IsGeneric);
            Assert.False(builder.IsOpenGeneric);
            Assert.Equal(2, builder.GenericArguments.Count);

            builder2 = builder.GenericArguments[0];
            Assert.Equal("", builder2.Namespace);
            Assert.Equal("Int32", builder2.BaseName);
            Assert.Equal("mscorlib", builder2.AssemblyName);
            Assert.False(builder2.IsGeneric);
            Assert.False(builder2.IsOpenGeneric);
            Assert.Equal(0, builder2.GenericArguments.Count);
            Assert.False(builder2.IsArray);
            Assert.Equal(0, builder2.ArrayDimensions.Count);

            builder2 = builder.GenericArguments[1];
            Assert.Equal("Collections.Generic", builder2.Namespace);
            Assert.Equal("List", builder2.BaseName);
            Assert.Equal("mscorlib", builder2.AssemblyName);
            Assert.True(builder2.IsGeneric);
            Assert.False(builder2.IsOpenGeneric);
            Assert.Equal(1, builder2.GenericArguments.Count);
            Assert.False(builder2.IsArray);
            Assert.Equal(0, builder2.ArrayDimensions.Count);

            builder3 = builder2.GenericArguments[0];
            Assert.Equal("", builder3.Namespace);
            Assert.Equal("String", builder3.BaseName);
            Assert.Equal("mscorlib", builder3.AssemblyName);
            Assert.False(builder3.IsGeneric);
            Assert.False(builder3.IsOpenGeneric);
            Assert.Equal(0, builder3.GenericArguments.Count);
            Assert.False(builder3.IsArray);
            Assert.Equal(0, builder3.ArrayDimensions.Count);

            Assert.Equal("Enumerator", builder.Nested.BaseName);
            Assert.False(builder.Nested.IsGeneric);
            Assert.False(builder.Nested.IsOpenGeneric);
            Assert.Equal(0, builder.Nested.GenericArguments.Count);

            Assert.Null(builder.Nested.Nested);

            #endregion
        }