21
21
#include " java_bytecode_language.h"
22
22
#include " java_utils.h"
23
23
24
+ #include < util/c_types.h>
24
25
#include < util/arith_tools.h>
25
26
#include < util/namespace.h>
26
27
#include < util/std_expr.h>
@@ -93,6 +94,33 @@ void java_bytecode_convert_classt::convert(const classt &c)
93
94
}
94
95
95
96
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
+ }
96
124
97
125
class_type.set_tag (c.name );
98
126
class_type.set (ID_base_name, c.name );
@@ -166,7 +194,7 @@ void java_bytecode_convert_classt::convert(const classt &c)
166
194
const irep_idt method_identifier=
167
195
id2string (qualified_classname)+
168
196
" ." +id2string (method.name )+
169
- " :" +method.signature ;
197
+ " :" +method.descriptor ;
170
198
// Always run the lazy pre-stage, as it symbol-table
171
199
// registers the function.
172
200
debug () << " Adding symbol: method '" << method_identifier << " '" << eom;
@@ -187,7 +215,49 @@ void java_bytecode_convert_classt::convert(
187
215
symbolt &class_symbol,
188
216
const fieldt &f)
189
217
{
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 );
191
261
192
262
// is this a static field?
193
263
if (f.is_static )
0 commit comments