44import cz .habarta .typescript .generator .compiler .Symbol ;
55import cz .habarta .typescript .generator .type .JTypeWithNullability ;
66import cz .habarta .typescript .generator .type .JUnionType ;
7+ import cz .habarta .typescript .generator .util .GenericsResolver ;
78import cz .habarta .typescript .generator .util .Utils ;
89import java .lang .reflect .GenericArrayType ;
910import java .lang .reflect .Method ;
@@ -42,7 +43,11 @@ public DefaultTypeProcessor(LoadedDataLibraries dataLibraries) {
4243 }
4344
4445 private static boolean isAssignableFrom (List <Class <?>> classes , Class <?> cls ) {
45- return classes .stream ().anyMatch (c -> c .isAssignableFrom (cls ));
46+ return assignableFrom (classes , cls ).isPresent ();
47+ }
48+
49+ private static Optional <Class <?>> assignableFrom (List <Class <?>> classes , Class <?> cls ) {
50+ return classes .stream ().filter (c -> c .isAssignableFrom (cls )).findFirst ();
4651 }
4752
4853 @ Override
@@ -87,21 +92,16 @@ public Result processType(Type javaType, Context context) {
8792 if (javaClass .isEnum ()) {
8893 return new Result (new TsType .EnumReferenceType (context .getSymbol (javaClass )), javaClass );
8994 }
90- if (isAssignableFrom (known .listClasses , javaClass )) {
91- final Result result = context .processTypeInsideCollection (Object .class );
92- return new Result (new TsType .BasicArrayType (result .getTsType ()), result .getDiscoveredClasses ());
93- }
94- if (isAssignableFrom (known .mapClasses , javaClass )) {
95- return processMapType (String .class , Object .class , context );
95+ // list, map, optional, wrapper
96+ final Result knownGenericTypeResult = processKnownGenericType (javaClass , javaClass , context );
97+ if (knownGenericTypeResult != null ) {
98+ return knownGenericTypeResult ;
9699 }
97100 if (OptionalInt .class .isAssignableFrom (javaClass ) ||
98101 OptionalLong .class .isAssignableFrom (javaClass ) ||
99102 OptionalDouble .class .isAssignableFrom (javaClass )) {
100103 return new Result (TsType .Number .optional ());
101104 }
102- if (isAssignableFrom (known .wrapperClasses , javaClass )) {
103- return new Result (TsType .Any );
104- }
105105 // generic structural type used without type arguments
106106 if (javaClass .getTypeParameters ().length > 0 ) {
107107 final List <TsType > tsTypeArguments = new ArrayList <>();
@@ -117,20 +117,10 @@ public Result processType(Type javaType, Context context) {
117117 final ParameterizedType parameterizedType = (ParameterizedType ) javaType ;
118118 if (parameterizedType .getRawType () instanceof Class ) {
119119 final Class <?> javaClass = (Class <?>) parameterizedType .getRawType ();
120- if (isAssignableFrom (known .listClasses , javaClass )) {
121- final Result result = context .processTypeInsideCollection (parameterizedType .getActualTypeArguments ()[0 ]);
122- return new Result (new TsType .BasicArrayType (result .getTsType ()), result .getDiscoveredClasses ());
123- }
124- if (isAssignableFrom (known .mapClasses , javaClass )) {
125- return processMapType (parameterizedType .getActualTypeArguments ()[0 ], parameterizedType .getActualTypeArguments ()[1 ], context );
126- }
127- if (isAssignableFrom (known .optionalClasses , javaClass )) {
128- final Result result = context .processType (parameterizedType .getActualTypeArguments ()[0 ]);
129- return new Result (result .getTsType ().optional (), result .getDiscoveredClasses ());
130- }
131- if (isAssignableFrom (known .wrapperClasses , javaClass )) {
132- final Result result = context .processType (parameterizedType .getActualTypeArguments ()[0 ]);
133- return new Result (result .getTsType (), result .getDiscoveredClasses ());
120+ // list, map, optional, wrapper
121+ final Result knownGenericTypeResult = processKnownGenericType (javaType , javaClass , context );
122+ if (knownGenericTypeResult != null ) {
123+ return knownGenericTypeResult ;
134124 }
135125 // generic structural type
136126 final List <Class <?>> discoveredClasses = new ArrayList <>();
@@ -189,21 +179,49 @@ public Result processType(Type javaType, Context context) {
189179 return null ;
190180 }
191181
192- private Result processMapType (Type keyType , Type valueType , Context context ) {
193- final Result keyResult = context .processType (keyType );
194- final Result valueResult = context .processTypeInsideCollection (valueType );
195- final TsType valueTsType = valueResult .getTsType ();
196- if (keyResult .getTsType () instanceof TsType .EnumReferenceType ) {
197- return new Result (
198- new TsType .MappedType (keyResult .getTsType (), TsType .MappedType .QuestionToken .Question , valueTsType ),
199- Utils .concat (keyResult .getDiscoveredClasses (), valueResult .getDiscoveredClasses ())
200- );
201- } else {
202- return new Result (
203- new TsType .IndexedArrayType (TsType .String , valueTsType ),
204- valueResult .getDiscoveredClasses ()
205- );
182+ private Result processKnownGenericType (Type javaType , Class <?> rawClass , Context context ) {
183+
184+ final Optional <Class <?>> listBaseClass = assignableFrom (known .listClasses , rawClass );
185+ if (listBaseClass .isPresent ()) {
186+ final List <Type > resolvedGenericVariables = GenericsResolver .resolveBaseGenericVariables (listBaseClass .get (), javaType );
187+ final Result result = context .processTypeInsideCollection (resolvedGenericVariables .get (0 ));
188+ return new Result (new TsType .BasicArrayType (result .getTsType ()), result .getDiscoveredClasses ());
189+ }
190+
191+ final Optional <Class <?>> mapBaseClass = assignableFrom (known .mapClasses , rawClass );
192+ if (mapBaseClass .isPresent ()) {
193+ final List <Type > resolvedGenericVariables = GenericsResolver .resolveBaseGenericVariables (mapBaseClass .get (), javaType );
194+ final Result keyResult = context .processType (resolvedGenericVariables .get (0 ));
195+ final Result valueResult = context .processTypeInsideCollection (resolvedGenericVariables .get (1 ));
196+ final TsType valueTsType = valueResult .getTsType ();
197+ if (keyResult .getTsType () instanceof TsType .EnumReferenceType ) {
198+ return new Result (
199+ new TsType .MappedType (keyResult .getTsType (), TsType .MappedType .QuestionToken .Question , valueTsType ),
200+ Utils .concat (keyResult .getDiscoveredClasses (), valueResult .getDiscoveredClasses ())
201+ );
202+ } else {
203+ return new Result (
204+ new TsType .IndexedArrayType (TsType .String , valueTsType ),
205+ valueResult .getDiscoveredClasses ()
206+ );
207+ }
206208 }
209+
210+ final Optional <Class <?>> optionalBaseClass = assignableFrom (known .optionalClasses , rawClass );
211+ if (optionalBaseClass .isPresent ()) {
212+ final List <Type > resolvedGenericVariables = GenericsResolver .resolveBaseGenericVariables (optionalBaseClass .get (), javaType );
213+ final Result result = context .processType (resolvedGenericVariables .get (0 ));
214+ return new Result (result .getTsType ().optional (), result .getDiscoveredClasses ());
215+ }
216+
217+ final Optional <Class <?>> wrapperBaseClass = assignableFrom (known .wrapperClasses , rawClass );
218+ if (wrapperBaseClass .isPresent ()) {
219+ final List <Type > resolvedGenericVariables = GenericsResolver .resolveBaseGenericVariables (wrapperBaseClass .get (), javaType );
220+ final Result result = context .processType (resolvedGenericVariables .get (0 ));
221+ return new Result (result .getTsType (), result .getDiscoveredClasses ());
222+ }
223+
224+ return null ;
207225 }
208226
209227 private static LoadedDataLibraries getKnownClasses () {
0 commit comments