Skip to content

Commit

Permalink
Add Dictionary and List support
Browse files Browse the repository at this point in the history
  • Loading branch information
fakefeik committed Feb 22, 2019
1 parent c02856a commit d992c2a
Show file tree
Hide file tree
Showing 17 changed files with 178 additions and 80 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;

using SkbKontur.TypeScript.ContractGenerator.CodeDom;
using SkbKontur.TypeScript.ContractGenerator.TypeBuilders;

namespace SkbKontur.TypeScript.ContractGenerator.Tests.CustomTypeGenerators
{
public class CollectionTypeBuildingContext : ITypeBuildingContext
{
public CollectionTypeBuildingContext(Type arrayType)
{
elementType = arrayType.GetGenericArguments()[0];
}

public static bool Accept(Type type)
{
return type.IsGenericType &&
type.GetGenericArguments().Length == 1 &&
type.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICollection<>));
}

public bool IsDefinitionBuilt => true;

public void Initialize(ITypeGenerator typeGenerator)
{
}

public void BuildDefinition(ITypeGenerator typeGenerator)
{
}

public FlowTypeType ReferenceFrom(FlowTypeUnit targetUnit, ITypeGenerator typeGenerator)
{
var itemType = typeGenerator.ResolveType(elementType).ReferenceFrom(targetUnit, typeGenerator);
return new FlowTypeArrayType(itemType);
}

private readonly Type elementType;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@ public string GetTypeLocation(Type type)

public ITypeBuildingContext ResolveType(string initialUnitPath, Type type, IFlowTypeUnitFactory unitFactory)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
return new ListTypeBuildingContext(type);
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>))
return new DictionaryTypeBuildingContext(type);
if (type == typeof(Guid))
if (CollectionTypeBuildingContext.Accept(type))
return new CollectionTypeBuildingContext(type);

if (type == typeof(TimeSpan))
return new StringBuildingContext();

return null;
Expand Down
2 changes: 2 additions & 0 deletions TypeScript.ContractGenerator.Tests/EndToEndTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public void GenerateFilesTest(Type type)
CheckDirectoriesEquivalence($"Files/{type.Name}.Expected", $"{type.Name}.Actual");
}

[TestCase(typeof(SimpleRootType), "simple-types.expected")]
[TestCase(typeof(SimpleNullableRootType), "nullable-types.expected")]
[TestCase(typeof(ArrayRootType), "array-types.expected")]
public void CustomGeneratorTest(Type rootType, string expectedFileName)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export type ArrayRootType = {
customTypesDict?: null | {
[key: string]: AnotherCustomType;
};
set?: null | string[];
};
export type AnotherEnum = 'B' | 'C';
export const AnotherEnums = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export type ArrayRootType = {
customTypesDict?: null | {
[key in string]?: AnotherCustomType;
};
set?: null | string[];
};
export type AnotherEnum = 'B' | 'C';
export const AnotherEnums = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

export type SimpleNullableRootType = {
long?: null | string;
uLong?: null | string;
int?: null | number;
uInt?: null | number;
short?: null | number;
uShort?: null | number;
bool?: null | boolean;
double?: null | number;
decimal?: null | number;
float?: null | number;
byte?: null | number;
sByte?: null | number;
char?: null | string;
dateTime?: null | (Date | string);
timeSpan?: null | string;
guid?: null | string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

export type SimpleNullableRootType = {
long?: null | string;
uLong?: null | string;
int?: null | number;
uInt?: null | number;
short?: null | number;
uShort?: null | number;
bool?: null | boolean;
double?: null | number;
decimal?: null | number;
float?: null | number;
byte?: null | number;
sByte?: null | number;
char?: null | string;
dateTime?: null | (Date | string);
timeSpan?: null | string;
guid?: null | string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

export type SimpleRootType = {
long: string;
uLong: string;
int: number;
uInt: number;
short: number;
uShort: number;
bool: boolean;
double: number;
float: number;
decimal: number;
byte: number;
sByte: number;
char: string;
string?: null | string;
dateTime: (Date | string);
timeSpan: string;
guid: string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

export type SimpleRootType = {
long: string;
uLong: string;
int: number;
uInt: number;
short: number;
uShort: number;
bool: boolean;
double: number;
float: number;
decimal: number;
byte: number;
sByte: number;
char: string;
string?: null | string;
dateTime: (Date | string);
timeSpan: string;
guid: string;
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ export type ArrayRootType = {
nullableEnums?: null | Array<null | AnotherEnum>;
strings?: null | string[];
customTypes?: null | AnotherCustomType[];
stringsList?: null | List<string>;
customTypesDict?: null | Dictionary<string, AnotherCustomType>;
stringsList?: null | string[];
customTypesDict?: null | {
[key: string]: AnotherCustomType;
};
set?: null | HashSet<string>;
};
export type AnotherEnum = 'B' | 'C';
export const AnotherEnums = {
Expand All @@ -19,23 +22,9 @@ export const AnotherEnums = {
export type AnotherCustomType = {
d: number;
};
export type List<T> = {
capacity: number;
export type HashSet<T> = {
count: number;
item?: T;
};
export type Dictionary<TKey, TValue> = {
comparer: IEqualityComparer<TKey>;
count: number;
keys?: null | KeyCollection<TKey, TValue>;
values?: null | ValueCollection<TKey, TValue>;
item?: TValue;
comparer: IEqualityComparer<T>;
};
export type IEqualityComparer<T> = {
};
export type KeyCollection<TKey, TValue> = {
count: number;
};
export type ValueCollection<TKey, TValue> = {
count: number;
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ export type ArrayRootType = {
nullableEnums?: null | Array<null | AnotherEnum>;
strings?: null | string[];
customTypes?: null | AnotherCustomType[];
stringsList?: null | List<string>;
customTypesDict?: null | Dictionary<string, AnotherCustomType>;
stringsList?: null | string[];
customTypesDict?: null | {
[key in string]?: AnotherCustomType;
};
set?: null | HashSet<string>;
};
export type AnotherEnum = 'B' | 'C';
export const AnotherEnums = {
Expand All @@ -19,23 +22,9 @@ export const AnotherEnums = {
export type AnotherCustomType = {
d: number;
};
export type List<T> = {
capacity: number;
export type HashSet<T> = {
count: number;
item?: T;
};
export type Dictionary<TKey, TValue> = {
comparer: IEqualityComparer<TKey>;
count: number;
keys?: null | KeyCollection<TKey, TValue>;
values?: null | ValueCollection<TKey, TValue>;
item?: TValue;
comparer: IEqualityComparer<T>;
};
export type IEqualityComparer<T> = {
};
export type KeyCollection<TKey, TValue> = {
count: number;
};
export type ValueCollection<TKey, TValue> = {
count: number;
};
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
<ItemGroup>
<None CopyToOutputDirectory="Always" Update="Files\CustomGenerator\array-types.expected.js" />
<None CopyToOutputDirectory="Always" Update="Files\CustomGenerator\array-types.expected.ts" />
<None CopyToOutputDirectory="Always" Update="Files\CustomGenerator\nullable-types.expected.js" />
<None CopyToOutputDirectory="Always" Update="Files\CustomGenerator\nullable-types.expected.ts" />
<None CopyToOutputDirectory="Always" Update="Files\CustomGenerator\simple-types.expected.js" />
<None CopyToOutputDirectory="Always" Update="Files\CustomGenerator\simple-types.expected.ts" />
<None CopyToOutputDirectory="Always" Update="Files\FlatTypeLocator.Expected\Flow\CommonType.js" />
<None CopyToOutputDirectory="Always" Update="Files\FlatTypeLocator.Expected\Flow\CommonUsingRootType.js" />
<None CopyToOutputDirectory="Always" Update="Files\FlatTypeLocator.Expected\Flow\CommonUsingRootType2.js" />
Expand Down
1 change: 1 addition & 0 deletions TypeScript.ContractGenerator.Tests/Types/ArrayRootType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class ArrayRootType
public AnotherCustomType[] CustomTypes { get; set; }
public List<string> StringsList { get; set; }
public Dictionary<string, AnotherCustomType> CustomTypesDict { get; set; }
public HashSet<string> Set { get; set; }
}

public enum AnotherEnum
Expand Down
7 changes: 5 additions & 2 deletions TypeScript.ContractGenerator/FlowTypeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,11 @@ private ITypeBuildingContext GetTypeBuildingContext(string typeLocation, Type ty
if (BuildInTypeBuildingContext.Accept(type))
return new BuildInTypeBuildingContext(type);

if (type.IsArray)
return new ArrayTypeBuildingContext(type.GetElementType());
if (ArrayTypeBuildingContext.Accept(type))
return new ArrayTypeBuildingContext(type);

if (DictionaryTypeBuildingContext.Accept(type))
return new DictionaryTypeBuildingContext(type);

if (type.IsEnum)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
using System;
using System.Collections.Generic;

using SkbKontur.TypeScript.ContractGenerator.CodeDom;

namespace SkbKontur.TypeScript.ContractGenerator.TypeBuilders
{
public class ArrayTypeBuildingContext : ITypeBuildingContext
{
public ArrayTypeBuildingContext(Type elementType)
public ArrayTypeBuildingContext(Type arrayType)
{
this.elementType = elementType;
elementType = GetElementType(arrayType);
}

private Type GetElementType(Type arrayType)
{
if (arrayType.IsArray)
return arrayType.GetElementType();

if (arrayType.IsGenericType && arrayType.GetGenericTypeDefinition() == typeof(List<>))
return arrayType.GetGenericArguments()[0];

throw new ArgumentException("arrayType should be either Array or List<T>", nameof(arrayType));
}

public static bool Accept(Type type)
{
return type.IsArray || type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>);
}

public bool IsDefinitionBuilt => true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;

using SkbKontur.TypeScript.ContractGenerator.CodeDom;
using SkbKontur.TypeScript.ContractGenerator.TypeBuilders;

namespace SkbKontur.TypeScript.ContractGenerator.Tests.CustomTypeGenerators
namespace SkbKontur.TypeScript.ContractGenerator.TypeBuilders
{
public class DictionaryTypeBuildingContext : ITypeBuildingContext
{
Expand All @@ -13,6 +13,11 @@ public DictionaryTypeBuildingContext(Type dictionaryType)
valueType = dictionaryType.GetGenericArguments()[1];
}

public static bool Accept(Type type)
{
return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>);
}

public bool IsDefinitionBuilt => true;

public void Initialize(ITypeGenerator typeGenerator)
Expand Down

0 comments on commit d992c2a

Please sign in to comment.