@@ -21,6 +21,7 @@ Author: Daniel Kroening, kroening@kroening.com
2121#include " java_bytecode_language.h"
2222#include " java_utils.h"
2323
24+ #include < util/c_types.h>
2425#include < util/arith_tools.h>
2526#include < util/namespace.h>
2627#include < util/std_expr.h>
@@ -93,6 +94,33 @@ void java_bytecode_convert_classt::convert(const classt &c)
9394 }
9495
9596 java_class_typet class_type;
97+ if (c.signature .has_value () && c.signature .value ()[0 ]==' <' )
98+ {
99+ java_generics_class_typet generic_class_type;
100+ #ifdef DEBUG
101+ std::cout << " INFO: found generic class signature "
102+ << c.signature .value ()
103+ << " in parsed class "
104+ << c.name << " \n " ;
105+ #endif
106+ try
107+ {
108+ const std::vector<typet> &generic_types=java_generic_type_from_string (
109+ id2string (c.name ),
110+ c.signature .value ());
111+ for (const typet &t : generic_types)
112+ {
113+ generic_class_type.generic_types ()
114+ .push_back (to_java_generic_parameter (t));
115+ }
116+ class_type=generic_class_type;
117+ }
118+ catch (unsupported_java_class_signature_exceptiont)
119+ {
120+ warning () << " we currently don't support parsing for example double "
121+ " bounded, recursive and wild card generics" << eom;
122+ }
123+ }
96124
97125 class_type.set_tag (c.name );
98126 class_type.set (ID_base_name, c.name );
@@ -166,7 +194,7 @@ void java_bytecode_convert_classt::convert(const classt &c)
166194 const irep_idt method_identifier=
167195 id2string (qualified_classname)+
168196 " ." +id2string (method.name )+
169- " :" +method.signature ;
197+ " :" +method.descriptor ;
170198 // Always run the lazy pre-stage, as it symbol-table
171199 // registers the function.
172200 debug () << " Adding symbol: method '" << method_identifier << " '" << eom;
@@ -187,7 +215,49 @@ void java_bytecode_convert_classt::convert(
187215 symbolt &class_symbol,
188216 const fieldt &f)
189217{
190- typet field_type=java_type_from_string (f.signature );
218+ typet field_type;
219+ if (f.signature .has_value ())
220+ {
221+ field_type=java_type_from_string_with_exception (
222+ f.descriptor ,
223+ f.signature ,
224+ id2string (class_symbol.name ));
225+
226+ // / this is for a free type variable, e.g., a field of the form `T f;`
227+ if (is_java_generic_parameter (field_type))
228+ {
229+ #ifdef DEBUG
230+ std::cout << " fieldtype: generic "
231+ << to_java_generic_parameter (field_type).type_variable ()
232+ .get_identifier ()
233+ << " name " << f.name << " \n " ;
234+ #endif
235+ }
236+
237+ // / this is for a field that holds a generic type, wither with instantiated
238+ // / or with free type variables, e.g., `List<T> l;` or `List<Integer> l;`
239+ else if (is_java_generic_type (field_type))
240+ {
241+ java_generic_typet &with_gen_type=
242+ to_java_generic_type (field_type);
243+ #ifdef DEBUG
244+ std::cout << " fieldtype: generic container type "
245+ << std::to_string (with_gen_type.generic_type_variables ().size ())
246+ << " type " << with_gen_type.id ()
247+ << " name " << f.name
248+ << " subtype id " << with_gen_type.subtype ().id () << " \n " ;
249+ #endif
250+ field_type=with_gen_type;
251+ }
252+
253+ // / This case is not possible, a field is either a non-instantiated type
254+ // / variable or a generics container type.
255+ INVARIANT (
256+ !is_java_generic_inst_parameter (field_type),
257+ " Cannot be an instantiated type variable here." );
258+ }
259+ else
260+ field_type=java_type_from_string (f.descriptor );
191261
192262 // is this a static field?
193263 if (f.is_static )
0 commit comments