|
11 | 11 | #include <java_bytecode/java_types.h>
|
12 | 12 | #include <java_bytecode/java_utils.h>
|
13 | 13 |
|
14 |
| - |
15 | 14 | generate_java_generic_typet::generate_java_generic_typet(
|
16 | 15 | message_handlert &message_handler):
|
17 | 16 | message_handler(message_handler)
|
@@ -43,31 +42,14 @@ symbolt generate_java_generic_typet::operator()(
|
43 | 42 |
|
44 | 43 | // Small auxiliary function, to perform the inplace
|
45 | 44 | // modification of the generic fields.
|
46 |
| - auto replace_type_for_generic_field= |
47 |
| - [&](struct_union_typet::componentt &component) |
48 |
| - { |
49 |
| - if(is_java_generic_parameter(component.type())) |
50 |
| - { |
51 |
| - auto replacement_type_param= |
52 |
| - to_java_generic_class_type(replacement_type); |
53 |
| - |
54 |
| - auto component_identifier= |
55 |
| - to_java_generic_parameter(component.type()).type_variable() |
56 |
| - .get_identifier(); |
57 |
| - |
58 |
| - optionalt<size_t> results=java_generics_get_index_for_subtype( |
59 |
| - replacement_type_param, component_identifier); |
60 |
| - |
61 |
| - INVARIANT( |
62 |
| - results.has_value(), |
63 |
| - "generic component type not found"); |
64 |
| - |
65 |
| - if(results) |
66 |
| - { |
67 |
| - component.type()= |
68 |
| - existing_generic_type.generic_type_variables()[*results]; |
69 |
| - } |
70 |
| - } |
| 45 | + auto replace_type_for_generic_field = |
| 46 | + [&](struct_union_typet::componentt &component) { |
| 47 | + |
| 48 | + component.type() = substitute_type( |
| 49 | + component.type(), |
| 50 | + to_java_generic_class_type(replacement_type), |
| 51 | + existing_generic_type); |
| 52 | + |
71 | 53 | return component;
|
72 | 54 | };
|
73 | 55 |
|
@@ -98,6 +80,65 @@ symbolt generate_java_generic_typet::operator()(
|
98 | 80 | return *symbol;
|
99 | 81 | }
|
100 | 82 |
|
| 83 | +/// For a given type, if the type contains a Java generic parameter, we look |
| 84 | +/// that parameter up and return the relevant type. This works recursively on |
| 85 | +/// arrays so that T [] is converted to RelevantType []. |
| 86 | +/// \param parameter_type: The type under consideration |
| 87 | +/// \param generic_class: The generic class that the \p parameter_type |
| 88 | +/// belongs to (e.g. the type of a component of the class). This is used to |
| 89 | +/// look up the mapping from name of generic parameter to its index. |
| 90 | +/// \param generic_reference: The instantiated version of the generic class |
| 91 | +/// used to look up the instantiated type. This is expected to be fully |
| 92 | +/// instantiated. |
| 93 | +/// \return A newly constructed type with generic parameters replaced, or if |
| 94 | +/// there are none to replace, the original type. |
| 95 | +typet generate_java_generic_typet::substitute_type( |
| 96 | + const typet ¶meter_type, |
| 97 | + const java_generics_class_typet &generic_class, |
| 98 | + const java_generic_typet &generic_reference) const |
| 99 | +{ |
| 100 | + if(is_java_generic_parameter(parameter_type)) |
| 101 | + { |
| 102 | + auto component_identifier = to_java_generic_parameter(parameter_type) |
| 103 | + .type_variable() |
| 104 | + .get_identifier(); |
| 105 | + |
| 106 | + optionalt<size_t> results = |
| 107 | + java_generics_get_index_for_subtype(generic_class, component_identifier); |
| 108 | + |
| 109 | + INVARIANT(results.has_value(), "generic component type not found"); |
| 110 | + |
| 111 | + if(results) |
| 112 | + { |
| 113 | + return generic_reference.generic_type_variables()[*results]; |
| 114 | + } |
| 115 | + else |
| 116 | + { |
| 117 | + return parameter_type; |
| 118 | + } |
| 119 | + } |
| 120 | + else if( |
| 121 | + parameter_type.id() == ID_pointer && |
| 122 | + parameter_type.subtype().id() == ID_symbol) |
| 123 | + { |
| 124 | + const symbol_typet &array_subtype = |
| 125 | + to_symbol_type(parameter_type.subtype()); |
| 126 | + if(is_java_array_tag(array_subtype.get_identifier())) |
| 127 | + { |
| 128 | + const typet &array_element_type = java_array_element_type(array_subtype); |
| 129 | + |
| 130 | + const typet &new_array_type = |
| 131 | + substitute_type(array_element_type, generic_class, generic_reference); |
| 132 | + |
| 133 | + typet replacement_array_type = java_array_type('a'); |
| 134 | + replacement_array_type.subtype().set( |
| 135 | + ID_C_element_type, new_array_type); |
| 136 | + return replacement_array_type; |
| 137 | + } |
| 138 | + } |
| 139 | + return parameter_type; |
| 140 | +} |
| 141 | + |
101 | 142 | /// Build a unique tag for the generic to be instantiated.
|
102 | 143 | /// \param existing_generic_type The type we want to concretise
|
103 | 144 | /// \param original_class
|
|
0 commit comments