Permalink
Browse files

Fix #295 - Added support for converting nested types

  • Loading branch information...
1 parent d8219df commit ca9a63928379802d1c8b17970d3e095b521efba6 @nikmd23 nikmd23 committed Mar 28, 2013
View
54 source/Glimpse.Core/SerializationConverter/CSharpTypeConverter.cs
@@ -50,16 +50,22 @@ public override object Convert(Type type)
private string GetName(Type type)
{
var typeName = new StringBuilder();
- GetName(type, typeName);
+ GetName(type, typeName, new Queue<Type>(type.GetGenericArguments()));
return typeName.ToString();
}
- private void GetName(Type type, StringBuilder output)
+ private void GetName(Type type, StringBuilder output, Queue<Type> genericArgsStack)
{
+ if (type.IsNested)
+ {
+ GetName(type.DeclaringType, output, genericArgsStack);
+ output.Append(".");
+ }
+
if (type.IsArray)
{
// Array
- GetName(type.GetElementType(), output);
+ GetName(type.GetElementType(), output, genericArgsStack);
output.Append("[]");
}
else if (!type.IsGenericType)
@@ -70,30 +76,52 @@ private void GetName(Type type, StringBuilder output)
else if (type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
// Null types
- GetName(type.GetGenericArguments().First(), output);
+ GetName(type.GetGenericArguments().First(), output, genericArgsStack);
output.Append("?");
}
- else
+ else
{
// Generics
var genericBaseType = type.GetGenericTypeDefinition();
var genericName = genericBaseType.Name;
- output.Append(genericName, 0, genericName.LastIndexOf('`'));
- output.Append("<");
- var genericArguments = type.GetGenericArguments();
- for (int i = 0; i < genericArguments.Length; i++)
+ if (genericName.Contains("`"))
{
- if (i > 0)
+ output.Append(genericName, 0, genericName.LastIndexOf('`'));
+
+ output.Append("<");
+
+ var typeArgsCount = GetGenericArgumentCount(type);
+ var remainingArgsCount = genericArgsStack.Count;
+
+ for (int i = 0; i < Math.Min(typeArgsCount, remainingArgsCount); i++)
{
- output.Append(", ");
+ if (i > 0)
+ {
+ output.Append(", ");
+ }
+
+ var arg = genericArgsStack.Dequeue();
+ GetName(arg, output, new Queue<Type>(arg.GetGenericArguments()));
}
- GetName(genericArguments[i], output);
+ output.Append(">");
}
+ else
+ {
+ output.Append(genericName);
+ }
+ }
+ }
- output.Append(">");
+ private int GetGenericArgumentCount(Type type)
+ {
+ if (type.DeclaringType == null)
+ {
+ return type.GetGenericArguments().Length;
}
+
+ return type.GetGenericArguments().Length - type.DeclaringType.GetGenericArguments().Length;
}
}
}
View
56 source/Glimpse.Test.Core/SerializationConverter/CSharpTypeConverterShould.cs
@@ -27,35 +27,71 @@ public class CSharpTypeConverterShould
[InlineData(typeof(ushort), "ushort")]
[InlineData(typeof(DateTime), "DateTime")]
[InlineData(typeof(CSharpTypeConverterShould), "CSharpTypeConverterShould")]
- //Converter supports N levels of generics
+
+ // Converter supports N levels of generics
[InlineData(typeof(IDictionary<string, object>), "IDictionary<string, object>")]
[InlineData(typeof(IDictionary<string, List<int>>), "IDictionary<string, List<int>>")]
[InlineData(typeof(IDictionary<string, IDictionary<int, IEnumerable<CSharpTypeConverterShould>>>), "IDictionary<string, IDictionary<int, IEnumerable<CSharpTypeConverterShould>>>")]
- //Converter supports arrays
+
+ // Converter supports arrays
[InlineData(typeof(int[]), "int[]")]
[InlineData(typeof(Test[]), "Test[]")]
[InlineData(typeof(IEnumerable<int[]>[]), "IEnumerable<int[]>[]")]
[InlineData(typeof(int[][]), "int[][]")]
- //Converter supports nullable types
+
+ // Converter supports nullable type
[InlineData(typeof(int?), "int?")]
[InlineData(typeof(DateTime?), "DateTime?")]
[InlineData(typeof(Test?), "Test?")]
[InlineData(typeof(int?[]), "int?[]")]
- //Converter - everything together
+
+ // Converter supports nested types
+ [InlineData(typeof(Dictionary<string, object>.ValueCollection), "Dictionary<string, object>.ValueCollection")]
+ [InlineData(typeof(CSharpTypeConverterShould.DummyClass), "CSharpTypeConverterShould.DummyClass")]
+ [InlineData(typeof(CSharpTypeConverterShould.DummyClass.StandardNestedClass), "CSharpTypeConverterShould.DummyClass.StandardNestedClass")]
+ [InlineData(typeof(CSharpTypeConverterShould.DummyClass.GenericNestedClass<string, object>), "CSharpTypeConverterShould.DummyClass.GenericNestedClass<string, object>")]
+ [InlineData(typeof(CSharpTypeConverterShould.DummyClass.GenericNestedClass<string, object>.InnerClass<int, DateTime>), "CSharpTypeConverterShould.DummyClass.GenericNestedClass<string, object>.InnerClass<int, DateTime>")]
+ [InlineData(typeof(CSharpTypeConverterShould.DummyClass.GenericNestedClass<string, object>.InnerClass<int, DateTime>.DeepClass), "CSharpTypeConverterShould.DummyClass.GenericNestedClass<string, object>.InnerClass<int, DateTime>.DeepClass")]
+ [InlineData(typeof(CSharpTypeConverterShould.DummyClass.GenericNestedClass<string, CSharpTypeConverterShould.DummyClass.GenericNestedClass<string, object>>.InnerClass), "CSharpTypeConverterShould.DummyClass.GenericNestedClass<string, CSharpTypeConverterShould.DummyClass.GenericNestedClass<string, object>>.InnerClass")]
+ [InlineData(typeof(CSharpTypeConverterShould.DummyClass.GenericNestedClass<string, CSharpTypeConverterShould.DummyClass>), "CSharpTypeConverterShould.DummyClass.GenericNestedClass<string, CSharpTypeConverterShould.DummyClass>")]
+ [InlineData(typeof(CSharpTypeConverterShould.DummyClass.GenericNestedClass<string, Dictionary<CSharpTypeConverterShould.DummyClass, object>.ValueCollection>.InnerClass), "CSharpTypeConverterShould.DummyClass.GenericNestedClass<string, Dictionary<CSharpTypeConverterShould.DummyClass, object>.ValueCollection>.InnerClass")]
+
+ // Converter - everything together
[InlineData(typeof(Tuple<IDictionary<int?, string[]>, char, Test>), "Tuple<IDictionary<int?, string[]>, char, Test>")]
- public void ConvertToDisplayString(Type intput, string output)
+ public void ConvertToDisplayString(Type input, string output)
{
var converter = new CSharpTypeConverter();
- var result = converter.Convert(intput);
+ var result = converter.Convert(input);
Assert.Equal(output, result);
}
- internal enum Test
+ private class DummyClass
{
- A = 1,
- B = 2,
- C = 3,
+ public class GenericNestedClass<TA, TB>
+ {
+ public class InnerClass<TC, TD>
+ {
+ public class DeepClass
+ {
+ }
+ }
+
+ public class InnerClass
+ {
+ }
+ }
+
+ public class StandardNestedClass
+ {
+ }
}
}
+
+ internal enum Test
+ {
+ A = 1,
+ B = 2,
+ C = 3,
+ }
}

0 comments on commit ca9a639

Please sign in to comment.