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,25 @@ void java_bytecode_convert_classt::convert(const classt &c)
9394 }
9495
9596 java_class_typet class_type;
97+ if (c.signature .has_value ())
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+ for (auto t : java_generic_type_from_string (
107+ id2string (c.name ),
108+ c.signature .value ()))
109+ {
110+ generic_class_type.generic_types ()
111+ .push_back (to_java_generic_parameter (t));
112+ }
113+
114+ class_type=generic_class_type;
115+ }
96116
97117 class_type.set_tag (c.name );
98118 class_type.set (ID_base_name, c.name );
@@ -166,7 +186,7 @@ void java_bytecode_convert_classt::convert(const classt &c)
166186 const irep_idt method_identifier=
167187 id2string (qualified_classname)+
168188 " ." +id2string (method.name )+
169- " :" +method.signature ;
189+ " :" +method.descriptor ;
170190 // Always run the lazy pre-stage, as it symbol-table
171191 // registers the function.
172192 debug () << " Adding symbol: method '" << method_identifier << " '" << eom;
@@ -187,7 +207,48 @@ void java_bytecode_convert_classt::convert(
187207 symbolt &class_symbol,
188208 const fieldt &f)
189209{
190- typet field_type=java_type_from_string (f.signature );
210+ typet field_type;
211+ if (f.signature .has_value ())
212+ {
213+ field_type=java_type_from_string (
214+ f.signature .value (),
215+ id2string (class_symbol.name ));
216+
217+ // / this is for a free type variable, e.g., a field of the form `T f;`
218+ if (is_java_generic_parameter (field_type))
219+ {
220+ #ifdef DEBUG
221+ std::cout << " fieldtype: generic "
222+ << to_java_generic_parameter (field_type).type_variable ()
223+ .get_identifier ()
224+ << " name " << f.name << " \n " ;
225+ #endif
226+ }
227+
228+ // / this is for a field that holds a generic type, wither with instantiated
229+ // / or with free type variables, e.g., `List<T> l;` or `List<Integer> l;`
230+ else if (is_java_generic_type (field_type))
231+ {
232+ java_generic_typet &with_gen_type=
233+ to_java_generic_type (field_type);
234+ #ifdef DEBUG
235+ std::cout << " fieldtype: generic container type "
236+ << std::to_string (with_gen_type.generic_type_variables ().size ())
237+ << " type " << with_gen_type.id ()
238+ << " name " << f.name
239+ << " subtype id " << with_gen_type.subtype ().id () << " \n " ;
240+ #endif
241+ field_type=with_gen_type;
242+ }
243+
244+ // / This case is not possible, a field is either a non-instantiated type
245+ // / variable or a generics container type.
246+ INVARIANT (
247+ !is_java_generic_inst_parameter (field_type),
248+ " Cannot be an instantiated type variable here." );
249+ }
250+ else
251+ field_type=java_type_from_string (f.descriptor );
191252
192253 // is this a static field?
193254 if (f.is_static )
0 commit comments