@@ -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>
@@ -101,6 +102,25 @@ void java_bytecode_convert_classt::convert(const classt &c)
101102 }
102103
103104 java_class_typet class_type;
105+ if (c.signature .has_value ())
106+ {
107+ java_generics_class_typet generic_class_type;
108+ #ifdef DEBUG
109+ std::cout << " INFO: found generic class signature "
110+ << c.signature .value ()
111+ << " in parsed class "
112+ << c.name << " \n " ;
113+ #endif
114+ for (auto t : java_generic_type_from_string (
115+ id2string (c.name ),
116+ c.signature .value ()))
117+ {
118+ generic_class_type.generic_types ()
119+ .push_back (to_java_generic_parameter (t));
120+ }
121+
122+ class_type=generic_class_type;
123+ }
104124
105125 class_type.set_tag (c.name );
106126 class_type.set (ID_base_name, c.name );
@@ -174,7 +194,7 @@ void java_bytecode_convert_classt::convert(const classt &c)
174194 const irep_idt method_identifier=
175195 id2string (qualified_classname)+
176196 " ." +id2string (method.name )+
177- " :" +method.signature ;
197+ " :" +method.descriptor ;
178198 // Always run the lazy pre-stage, as it symbol-table
179199 // registers the function.
180200 debug () << " Adding symbol: method '" << method_identifier << " '" << eom;
@@ -195,7 +215,48 @@ void java_bytecode_convert_classt::convert(
195215 symbolt &class_symbol,
196216 const fieldt &f)
197217{
198- 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 (
222+ f.signature .value (),
223+ id2string (class_symbol.name ));
224+
225+ // / this is for a free type variable, e.g., a field of the form `T f;`
226+ if (is_java_generic_parameter (field_type))
227+ {
228+ #ifdef DEBUG
229+ std::cout << " fieldtype: generic "
230+ << to_java_generic_parameter (field_type).type_variable ()
231+ .get_identifier ()
232+ << " name " << f.name << " \n " ;
233+ #endif
234+ }
235+
236+ // / this is for a field that holds a generic type, wither with instantiated
237+ // / or with free type variables, e.g., `List<T> l;` or `List<Integer> l;`
238+ else if (is_java_generic_type (field_type))
239+ {
240+ java_generic_typet &with_gen_type=
241+ to_java_generic_type (field_type);
242+ #ifdef DEBUG
243+ std::cout << " fieldtype: generic container type "
244+ << std::to_string (with_gen_type.generic_type_variables ().size ())
245+ << " type " << with_gen_type.id ()
246+ << " name " << f.name
247+ << " subtype id " << with_gen_type.subtype ().id () << " \n " ;
248+ #endif
249+ field_type=with_gen_type;
250+ }
251+
252+ // / This case is not possible, a field is either a non-instantiated type
253+ // / variable or a generics container type.
254+ INVARIANT (
255+ !is_java_generic_inst_parameter (field_type),
256+ " Cannot be an instantiated type variable here." );
257+ }
258+ else
259+ field_type=java_type_from_string (f.descriptor );
199260
200261 // is this a static field?
201262 if (f.is_static )
0 commit comments