Skip to content

Commit

Permalink
Custom type mapping with generics (#197, #236)
Browse files Browse the repository at this point in the history
  • Loading branch information
vojtechhabarta committed Nov 22, 2018
1 parent 6723aa3 commit 76f587e
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

package cz.habarta.typescript.generator;

import cz.habarta.typescript.generator.util.Utils;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

Expand All @@ -16,13 +16,30 @@ public CustomMappingTypeProcessor(Map<String, String> customMappings) {

@Override
public Result processType(Type javaType, Context context) {
final Class<?> rawClass = Utils.getRawClassOrNull(javaType);
if (rawClass != null) {
final String tsTypeName = customMappings.get(rawClass.getName());
if (javaType instanceof Class) {
final Class<?> javaClass = (Class<?>) javaType;
final String tsTypeName = customMappings.get(javaClass.getName());
if (tsTypeName != null) {
return new Result(new TsType.BasicType(tsTypeName));
}
}
if (javaType instanceof ParameterizedType) {
final ParameterizedType parameterizedType = (ParameterizedType) javaType;
if (parameterizedType.getRawType() instanceof Class) {
final Class<?> javaClass = (Class<?>) parameterizedType.getRawType();
final String tsTypeName = customMappings.get(javaClass.getName());
if (tsTypeName != null) {
final List<Class<?>> discoveredClasses = new ArrayList<>();
final List<TsType> tsTypeArguments = new ArrayList<>();
for (Type typeArgument : parameterizedType.getActualTypeArguments()) {
final TypeProcessor.Result typeArgumentResult = context.processType(typeArgument);
tsTypeArguments.add(typeArgumentResult.getTsType());
discoveredClasses.addAll(typeArgumentResult.getDiscoveredClasses());
}
return new Result(new TsType.GenericBasicType(tsTypeName, tsTypeArguments), discoveredClasses);
}
}
}
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,25 @@ public String format(Settings settings) {
}
}

public static class GenericBasicType extends TsType.BasicType {

public final List<TsType> typeArguments;

public GenericBasicType(String name, TsType... typeArguments) {
this(name, Arrays.asList(typeArguments));
}

public GenericBasicType(String name, List<? extends TsType> typeArguments) {
super(name);
this.typeArguments = new ArrayList<TsType>(typeArguments);
}

@Override
public String format(Settings settings) {
return name + "<" + Emitter.formatList(settings, typeArguments) + ">";
}
}

public static class VerbatimType extends TsType {

public final String verbatimType;
Expand Down Expand Up @@ -254,6 +273,14 @@ public String format(Settings settings) {

public static TsType transformTsType(Context context, TsType tsType, Transformer transformer) {
final TsType type = transformer.transform(context, tsType);
if (type instanceof TsType.GenericBasicType) {
final GenericBasicType genericBasicType = (TsType.GenericBasicType) type;
final List<TsType> typeArguments = new ArrayList<>();
for (TsType typeArgument : genericBasicType.typeArguments) {
typeArguments.add(transformTsType(context, typeArgument, transformer));
}
return new TsType.GenericBasicType(genericBasicType.name, typeArguments);
}
if (type instanceof TsType.GenericReferenceType) {
final GenericReferenceType genericReferenceType = (TsType.GenericReferenceType) type;
final List<TsType> typeArguments = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

package cz.habarta.typescript.generator;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;


public class GenericCustomTypeMappingsTest {

@Test
public void testListWrapper() {
final Settings settings = TestUtils.settings();
settings.customTypeNaming = Collections.singletonMap(ListWrapper1.class.getName(), "ListWrapper");
settings.customTypeMappings = Collections.singletonMap(ListWrapper2.class.getName(), "ListWrapper");
final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(Class1.class));
Assert.assertTrue(output.contains("list1: ListWrapper<string>"));
Assert.assertTrue(output.contains("list2: ListWrapper<number>"));
}

private static class Class1 {
public ListWrapper1<String> list1;
public ListWrapper2<Number> list2;
}

private static class ListWrapper1<T> {
public List<T> values;
}

private static class ListWrapper2<T> {
public List<T> values;
}

@Test
public void testMap() {
final Settings settings = TestUtils.settings();
settings.customTypeMappings = Collections.singletonMap("java.util.Map", "Map");
settings.mapDate = DateMapping.asString;
final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(Class2.class));
Assert.assertTrue(output.contains("someMap: Map<string, any>"));
Assert.assertTrue(output.contains("dateMap: Map<string, DateAsString>"));
}

private static class Class2 {
public Map<String, Object> someMap;
public Map<String, Date> dateMap;
}

}

0 comments on commit 76f587e

Please sign in to comment.