Skip to content

Commit f390795

Browse files
committed
Add a class to represent specialised generic classes, and change concretisation functions to use that.
1 parent 161787b commit f390795

File tree

4 files changed

+74
-17
lines changed

4 files changed

+74
-17
lines changed

src/java_bytecode/generate_java_generic_type.cpp

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,20 @@
1111
#include <java_bytecode/java_types.h>
1212
#include <java_bytecode/java_utils.h>
1313

14+
/// Strip the package name from a java type, for the type to be
15+
/// pretty printed (java::java.lang.Integer -> Integer).
16+
/// \param fqn_java_type The java type we want to pretty print.
17+
/// \return The pretty printed type if there was a match of the
18+
// qualifiers, or the type as it was passed otherwise.
19+
static std::string pretty_print_java_type(const std::string &fqn_java_type)
20+
{
21+
const std::string java_lang("java::java.lang.");
22+
const std::string package_name(java_class_to_package(fqn_java_type) + ".");
23+
if(package_name == java_lang)
24+
return fqn_java_type.substr(java_lang.length());
25+
return fqn_java_type;
26+
}
27+
1428
generate_java_generic_typet::generate_java_generic_typet(
1529
message_handlert &message_handler):
1630
message_handler(message_handler)
@@ -70,8 +84,8 @@ symbolt generate_java_generic_typet::operator()(
7084
pre_modification_size==after_modification_size,
7185
"All components in the original class should be in the new class");
7286

73-
const java_class_typet &new_java_class = construct_specialised_generic_type(
74-
generic_class_definition, new_tag, replacement_components);
87+
const java_specialized_generic_class_typet new_java_class =
88+
construct_specialised_generic_type(new_tag, replacement_components);
7589
const type_symbolt &class_symbol =
7690
build_symbol_from_specialised_class(new_java_class);
7791

@@ -193,14 +207,14 @@ irep_idt generate_java_generic_typet::build_generic_tag(
193207
.generic_type_arguments())
194208
{
195209
if(!first)
196-
new_tag_buffer << ",";
210+
new_tag_buffer << ", ";
197211
first=false;
198212

199213
INVARIANT(
200214
!is_java_generic_parameter(type_argument),
201215
"Only create full concretized generic types");
202216
const irep_idt &id(id2string(type_argument.subtype().get(ID_identifier)));
203-
new_tag_buffer << id2string(id);
217+
new_tag_buffer << pretty_print_java_type(id2string(id));
204218
if(is_java_array_tag(id))
205219
{
206220
const typet &element_type =
@@ -224,25 +238,17 @@ irep_idt generate_java_generic_typet::build_generic_tag(
224238
return new_tag_buffer.str();
225239
}
226240

227-
/// Build the specalised version of the specific class, with the specified
241+
/// Build the specialised version of the specific class, with the specified
228242
/// parameters and name.
229-
/// \param generic_class_definition: The generic class we are specialising
230243
/// \param new_tag: The new name for the class (like Generic<java::Float>)
231244
/// \param new_components: The specialised components
232245
/// \return The newly constructed class.
233-
java_class_typet
246+
java_specialized_generic_class_typet
234247
generate_java_generic_typet::construct_specialised_generic_type(
235-
const java_generic_class_typet &generic_class_definition,
236248
const irep_idt &new_tag,
237249
const struct_typet::componentst &new_components) const
238250
{
239-
java_class_typet specialised_class = generic_class_definition;
240-
// We are specialising the logic - so we don't want to be marked as generic
241-
specialised_class.set(ID_C_java_generics_class_type, false);
242-
specialised_class.set(ID_name, "java::" + id2string(new_tag));
243-
specialised_class.set(ID_base_name, new_tag);
244-
specialised_class.components() = new_components;
245-
return specialised_class;
251+
return java_specialized_generic_class_typet{new_tag, new_components};
246252
}
247253

248254
/// Construct the symbol to be moved into the symbol table

src/java_bytecode/generate_java_generic_type.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ class generate_java_generic_typet
3333
const java_generic_class_typet &replacement_type,
3434
const java_generic_typet &generic_reference) const;
3535

36-
java_class_typet construct_specialised_generic_type(
37-
const java_generic_class_typet &generic_class_definition,
36+
java_specialized_generic_class_typet construct_specialised_generic_type(
3837
const irep_idt &new_tag,
3938
const struct_typet::componentst &new_components) const;
4039

src/java_bytecode/java_types.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,4 +374,55 @@ void get_dependencies_from_generic_parameters(
374374
const typet &,
375375
std::set<irep_idt> &);
376376

377+
class java_specialized_generic_class_typet : public java_class_typet
378+
{
379+
public:
380+
/// Build the specialised version of the specific class, with the specified
381+
/// parameters and name.
382+
/// \param new_tag: The new name for the class (like Generic<java::Float>)
383+
/// \param new_components: The specialised components
384+
/// \return The newly constructed class.
385+
java_specialized_generic_class_typet(
386+
const irep_idt &new_tag,
387+
const struct_typet::componentst &new_components)
388+
{
389+
set(ID_C_specialized_generic_java_class, true);
390+
// We are specialising the logic - so we don't want to be marked as generic
391+
set(ID_C_java_generics_class_type, false);
392+
set(ID_name, "java::" + id2string(new_tag));
393+
set(ID_base_name, id2string(new_tag));
394+
components() = new_components;
395+
const std::string &class_tag = id2string(new_tag);
396+
set_tag(class_tag.substr(0, class_tag.find('<')));
397+
}
398+
};
399+
400+
inline bool is_java_specialized_generic_class_type(const typet &type)
401+
{
402+
return type.get_bool(ID_C_specialized_generic_java_class);
403+
}
404+
405+
inline bool is_java_specialized_generic_class_type(typet &type)
406+
{
407+
return type.get_bool(ID_C_specialized_generic_java_class);
408+
}
409+
410+
inline java_specialized_generic_class_typet
411+
to_java_specialized_generic_class_type(const typet &type)
412+
{
413+
INVARIANT(
414+
is_java_specialized_generic_class_type(type),
415+
"Tried to convert a type that was not a specialised generic java class");
416+
return static_cast<const java_specialized_generic_class_typet &>(type);
417+
}
418+
419+
inline java_specialized_generic_class_typet
420+
to_java_specialized_generic_class_type(typet &type)
421+
{
422+
INVARIANT(
423+
is_java_specialized_generic_class_type(type),
424+
"Tried to convert a type that was not a specialised generic java class");
425+
return static_cast<const java_specialized_generic_class_typet &>(type);
426+
}
427+
377428
#endif // CPROVER_JAVA_BYTECODE_JAVA_TYPES_H

src/util/irep_ids.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,7 @@ IREP_ID_ONE(integer_dereference)
830830
IREP_ID_TWO(C_java_generic_parameter, #java_generic_parameter)
831831
IREP_ID_TWO(C_java_generic_type, #java_generic_type)
832832
IREP_ID_TWO(C_java_generics_class_type, #java_generics_class_type)
833+
IREP_ID_TWO(C_specialized_generic_java_class, #specialized_generic_java_class)
833834
IREP_ID_TWO(generic_types, #generic_types)
834835
IREP_ID_TWO(type_variables, #type_variables)
835836
IREP_ID_ONE(havoc_object)

0 commit comments

Comments
 (0)