Skip to content

Commit

Permalink
add more complex generic type cases (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
Skleni committed Jul 1, 2022
1 parent 9f25e65 commit 296b744
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 10 deletions.
45 changes: 40 additions & 5 deletions DotNet/Packer.Test/DeclarationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -291,14 +291,49 @@ public void DefinitionIsGeneratedForTypeWithListProperty ()
}

[Fact]
public void DefinitionIsGeneratedForSimpleGenericType ()
public void DefinitionIsGeneratedForGenericClass ()
{
AddAssembly(
With("n", "public class GenericType<T> { public T Value { get; set; } }"),
With("n", "[JSInvokable] public static void Method (GenericType<string> p) { }"));
With("n", "public class GenericClass<T> { public T Value { get; set; } }"),
With("n", "[JSInvokable] public static void Method (GenericClass<string> p) { }"));
Task.Execute();
Matches(@"export class GenericType<T> {\s*value: T;\s*}");
Contains("Method(p: n.GenericType<string>): void");
Matches(@"export class GenericClass<T> {\s*value: T;\s*}");
Contains("Method(p: n.GenericClass<string>): void");
}

[Fact]
public void DefinitionIsGeneratedForGenericInterface()
{
AddAssembly(
With("n", "public interface GenericInterface<T> { public T Value { get; set; } }"),
With("n", "[JSInvokable] public static GenericInterface<string> Method () => default;"));
Task.Execute();
Matches(@"export interface GenericInterface<T> {\s*value: T;\s*}");
Contains("Method(): n.GenericInterface<string>");
}

[Fact]
public void DefinitionIsGeneratedForNestedGenericTypes()
{
AddAssembly(
With("Foo", "public class GenericClass<T> { public T Value { get; set; } }", false),
With("Bar", "public interface GenericInterface<T> { public T Value { get; set; } }", false),
With("n", "[JSInvokable] public static void Method (Foo.GenericClass<Bar.GenericInterface<string>> p) { }"));
Task.Execute();
Matches(@"export namespace Foo {\s*export class GenericClass<T> {\s*value: T;\s*}\s*}");
Matches(@"export namespace Bar {\s*export interface GenericInterface<T> {\s*value: T;\s*}\s*}");
Contains("Method(p: Foo.GenericClass<Bar.GenericInterface<string>>): void");
}

[Fact]
public void DefinitionIsGeneratedForGenericClassWithMultipleTypeArguments()
{
AddAssembly(
With("n", "public class GenericClass<T1, T2> { public T1 Key { get; set; } public T2 Value { get; set; } }"),
With("n", "[JSInvokable] public static void Method (GenericClass<string, int> p) { }"));
Task.Execute();
Matches(@"export class GenericClass<T1, T2> {\s*key: T1;\s*value: T2;\s*}");
Contains("Method(p: n.GenericClass<string, number>): void");
}

[Fact]
Expand Down
13 changes: 8 additions & 5 deletions DotNet/Packer/DeclarationGenerator/TypeConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ private bool ShouldConvertToObject (Type type)
{
type = GetUnderlyingType(type);
return (Type.GetTypeCode(type) == TypeCode.Object || type.IsEnum) &&
!type.IsGenericTypeParameter &&
!ShouldIgnoreAssembly(type.Assembly.FullName!);
}

Expand Down Expand Up @@ -103,21 +104,23 @@ private void CrawlObjectType (Type type)
{
type = GetUnderlyingType(type);

if (type.IsGenericType && !type.IsGenericTypeDefinition)
if (!type.IsGenericType || type.IsGenericTypeDefinition)
{
if (!objectTypes.Add(type)) return;
}
else
{
// don't add GenericType<string>, only its definition GenericType<T>
foreach (var argument in type.GenericTypeArguments)
{
if (ShouldConvertToObject(argument))
CrawlObjectType(argument);
}

var definition = type.GetGenericTypeDefinition();
if (ShouldConvertToObject(definition))
CrawlObjectType(definition);
CrawlObjectType(definition);
}

if (!objectTypes.Add(type)) return;

CrawlProperties(type);
CrawlBaseType(type);
}
Expand Down

0 comments on commit 296b744

Please sign in to comment.