Skip to content

Commit

Permalink
Fixed behaviour of the type analysis when the clr type is a generic type
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelstaib committed Jul 9, 2018
1 parent 38ef66b commit 10a7746
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 9 deletions.
83 changes: 83 additions & 0 deletions src/Core.Tests/Internal/ReflectionUtilsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System;
using Xunit;

namespace HotChocolate.Internal
{
public class ReflectionUtilsTests
{
[Fact]
public void GetTypeNameFromGenericType()
{
// arrange
Type type = typeof(GenericNonNestedFoo<string>);

// act
string typeName = type.GetTypeName();

// assert
Assert.Equal(
"HotChocolate.Internal.GenericNonNestedFoo<System.String>",
typeName);
}

[Fact]
public void GetTypeNameFromType()
{
// arrange
Type type = typeof(ReflectionUtilsTests);

// act
string typeName = type.GetTypeName();

// assert
Assert.Equal(
"HotChocolate.Internal.ReflectionUtilsTests",
typeName);
}

[Fact]
public void GetTypeNameFromGenericNestedType()
{
// arrange
Type type = typeof(GenericNestedFoo<string>);

// act
string typeName = type.GetTypeName();

// assert
Assert.Equal(
"HotChocolate.Internal.ReflectionUtilsTests.GenericNestedFoo<System.String>",
typeName);
}

[Fact]
public void GetTypeNameFromNestedType()
{
// arrange
Type type = typeof(Foo);

// act
string typeName = type.GetTypeName();

// assert
Assert.Equal(
"HotChocolate.Internal.ReflectionUtilsTests.Foo",
typeName);
}

public class GenericNestedFoo<T>
{
public T Value { get; }
}

public class Foo
{
public string Value { get; }
}
}

public class GenericNonNestedFoo<T>
{
public T Value { get; }
}
}
43 changes: 43 additions & 0 deletions src/Core.Tests/Types/ObjectTypeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,49 @@ public void ObjectTypeWithDynamicField_TypeDeclarationOrderShouldNotMatter()
Assert.IsType<StringType>(((ListType)field.Type).ElementType);
}

[Fact]
public void GenericObjectTypes()
{
// arrange
ServiceManager services = new ServiceManager();
List<SchemaError> errors = new List<SchemaError>();
SchemaContext context = new SchemaContext(services);

// act
ObjectType<GenericFoo<string>> genericType =
new ObjectType<GenericFoo<string>>();
((INeedsInitialization)genericType).RegisterDependencies(
context, e => errors.Add(e));
context.CompleteTypes();

// assert
Assert.Equal("GenericFooOfString", genericType.Name);
}

[Fact]
public void NestedGenericObjectTypes()
{
// arrange
ServiceManager services = new ServiceManager();
List<SchemaError> errors = new List<SchemaError>();
SchemaContext context = new SchemaContext(services);

// act
ObjectType<GenericFoo<GenericFoo<string>>> genericType =
new ObjectType<GenericFoo<GenericFoo<string>>>();
((INeedsInitialization)genericType).RegisterDependencies(
context, e => errors.Add(e));
context.CompleteTypes();

// assert
Assert.Equal("GenericFooOfGenericFooOfString", genericType.Name);
}

public class GenericFoo<T>
{
public T Value { get; }
}

public class Foo
{
public string Description { get; } = "hello";
Expand Down
19 changes: 19 additions & 0 deletions src/Core/Internal/AttributeExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace HotChocolate.Internal
Expand Down Expand Up @@ -31,6 +33,11 @@ public static string GetGraphQLName(this MemberInfo member)
return NormalizeName(member.Name);
}

if (member is Type t)
{
return GetFromType(t);
}

return member.Name;
}

Expand All @@ -43,6 +50,18 @@ public static string GetGraphQLName(this ParameterInfo parameter)
return NormalizeName(parameter.Name);
}

private static string GetFromType(Type type)
{
if (type.IsGenericType)
{
string name = type.Name.Substring(0, type.Name.Length - 2);
IEnumerable<string> arguments = type.GetGenericArguments()
.Select(GetFromType);
return $"{name}Of{string.Join("Of", arguments)}";
}
return type.Name;
}

private static string NormalizeName(string name)
{
if (name.Length > 1)
Expand Down
34 changes: 25 additions & 9 deletions src/Core/Internal/ReflectionUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,30 +66,46 @@ private static bool IsPublic(this MemberInfo member)
return false;
}


internal static string GetTypeName(this Type type)
{
if (type == null)
{
throw new ArgumentNullException(nameof(type));
}

string name = type.FullName ?? type.Name;

if (type.IsGenericType)
{
name = CreateGenericName(type);
}
string name = type.IsGenericType
? CreateGenericTypeName(type)
: CreateTypeName(type, type.Name);

return name.Replace("+", ".");
}

private static string CreateGenericName(Type type)
private static string CreateGenericTypeName(Type type)
{
string name = type.Name.Substring(0, type.Name.Length - 2);
IEnumerable<string> arguments = type.GetGenericArguments()
.Select(GetTypeName);
return $"{name}<{string.Join(", ", arguments)}>";
return CreateTypeName(type,
$"{name}<{string.Join(", ", arguments)}>");;
}

private static string CreateTypeName(Type type, string typeName)
{
string ns = GetNamespace(type);
if (ns == null)
{
return typeName;
}
return $"{ns}.{typeName}";
}

private static string GetNamespace(Type type)
{
if (type.IsNested)
{
return $"{GetNamespace(type.DeclaringType)}.{type.DeclaringType.Name}";
}
return type.Namespace;
}

public static Type GetReturnType(this MemberInfo member)
Expand Down

0 comments on commit 10a7746

Please sign in to comment.