Skip to content

Commit c6c0eff

Browse files
Merge pull request #4897 from diffblue/cleanup/generic_parameter_specialization_map_keys
Cleanup generic_parameter_specialization_map_keys
2 parents da8a63e + 508a717 commit c6c0eff

File tree

4 files changed

+74
-80
lines changed

4 files changed

+74
-80
lines changed

jbmc/src/java_bytecode/generic_parameter_specialization_map_keys.cpp

Lines changed: 61 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#include "generic_parameter_specialization_map_keys.h"
44

5-
#include <iterator>
5+
#include <util/range.h>
66

77
/// \param type: Source type
88
/// \return The vector of implicitly generic and (explicitly) generic type
@@ -44,26 +44,12 @@ void generic_parameter_specialization_map_keyst::insert_pairs(
4444
const std::vector<reference_typet> &types)
4545
{
4646
INVARIANT(erase_keys.empty(), "insert_pairs should only be called once");
47-
PRECONDITION(parameters.size() == types.size());
4847

49-
// Pair up the parameters and types for easier manipulation later
50-
std::vector<std::pair<java_generic_parametert, reference_typet>> pairs;
51-
pairs.reserve(parameters.size());
52-
std::transform(
53-
parameters.begin(),
54-
parameters.end(),
55-
types.begin(),
56-
std::back_inserter(pairs),
57-
[&](java_generic_parametert param, reference_typet type)
58-
{
59-
return std::make_pair(param, type);
60-
});
61-
62-
for(const auto &pair : pairs)
48+
for(const auto &pair : make_range(parameters).zip(types))
6349
{
6450
// Only add the pair if the type is not the parameter itself, e.g.,
6551
// pair.first = pair.second = java::A::T. This can happen for example
66-
// when initiating a pointer to an implicitly java generic class type
52+
// when initializing a pointer to an implicitly generic Java class type
6753
// in gen_nondet_init and would result in a loop when the map is used
6854
// to look up the type of the parameter.
6955
if(
@@ -72,13 +58,13 @@ void generic_parameter_specialization_map_keyst::insert_pairs(
7258
pair.first.get_name()))
7359
{
7460
const irep_idt &key = pair.first.get_name();
75-
if(generic_parameter_specialization_map.count(key) == 0)
76-
generic_parameter_specialization_map.emplace(
77-
key, std::vector<reference_typet>());
78-
(*generic_parameter_specialization_map.find(key))
79-
.second.push_back(pair.second);
61+
const auto map_it = generic_parameter_specialization_map
62+
.emplace(key, std::vector<reference_typet>{})
63+
.first;
64+
map_it->second.push_back(pair.second);
8065

81-
// We added something, so pop it when this is destroyed:
66+
// We added something; pop it when this
67+
// generic_parameter_specialization_map_keyst is destroyed
8268
erase_keys.push_back(key);
8369
}
8470
}
@@ -94,40 +80,42 @@ void generic_parameter_specialization_map_keyst::insert_pairs_for_pointer(
9480
const pointer_typet &pointer_type,
9581
const typet &pointer_subtype_struct)
9682
{
97-
if(is_java_generic_type(pointer_type))
83+
if(!is_java_generic_type(pointer_type))
84+
return;
85+
// The supplied type must be the full type of the pointer's subtype
86+
PRECONDITION(
87+
pointer_type.subtype().get(ID_identifier) ==
88+
pointer_subtype_struct.get(ID_name));
89+
90+
// If the pointer points to:
91+
// - an incomplete class or
92+
// - a class that is neither generic nor implicitly generic (this
93+
// may be due to unsupported class signature)
94+
// then ignore the generic types in the pointer and do not add any pairs.
95+
// TODO TG-1996 should decide how mocking and generics should work
96+
// together. Currently an incomplete class is never marked as generic. If
97+
// this changes in TG-1996 then the condition below should be updated.
98+
if(to_java_class_type(pointer_subtype_struct).get_is_stub())
99+
return;
100+
if(
101+
!is_java_generic_class_type(pointer_subtype_struct) &&
102+
!is_java_implicitly_generic_class_type(pointer_subtype_struct))
98103
{
99-
// The supplied type must be the full type of the pointer's subtype
100-
PRECONDITION(
101-
pointer_type.subtype().get(ID_identifier) ==
102-
pointer_subtype_struct.get(ID_name));
104+
return;
105+
}
103106

104-
// If the pointer points to:
105-
// - an incomplete class or
106-
// - a class that is neither generic nor implicitly generic (this
107-
// may be due to unsupported class signature)
108-
// then ignore the generic types in the pointer and do not add any pairs.
109-
// TODO TG-1996 should decide how mocking and generics should work
110-
// together. Currently an incomplete class is never marked as generic. If
111-
// this changes in TG-1996 then the condition below should be updated.
112-
if(
113-
!to_java_class_type(pointer_subtype_struct).get_is_stub() &&
114-
(is_java_generic_class_type(pointer_subtype_struct) ||
115-
is_java_implicitly_generic_class_type(pointer_subtype_struct)))
116-
{
117-
const java_generic_typet &generic_pointer =
118-
to_java_generic_type(pointer_type);
119-
const std::vector<java_generic_parametert> &generic_parameters =
120-
get_all_generic_parameters(pointer_subtype_struct);
107+
const java_generic_typet &generic_pointer =
108+
to_java_generic_type(pointer_type);
121109

122-
INVARIANT(
123-
generic_pointer.generic_type_arguments().size() ==
124-
generic_parameters.size(),
125-
"All generic parameters of the pointer type need to be specified");
110+
const std::vector<java_generic_parametert> &generic_parameters =
111+
get_all_generic_parameters(pointer_subtype_struct);
112+
const java_generic_typet::generic_type_argumentst &type_args =
113+
generic_pointer.generic_type_arguments();
114+
INVARIANT(
115+
type_args.size() == generic_parameters.size(),
116+
"All generic parameters of the pointer type need to be specified");
126117

127-
insert_pairs(
128-
generic_parameters, generic_pointer.generic_type_arguments());
129-
}
130-
}
118+
insert_pairs(generic_parameters, type_args);
131119
}
132120

133121
/// Add a pair of a parameter and its types for each generic parameter of the
@@ -151,24 +139,29 @@ void generic_parameter_specialization_map_keyst::insert_pairs_for_symbol(
151139
// then ignore the generic types in the struct_tag_type and do not add any
152140
// pairs.
153141
// TODO TG-1996 should decide how mocking and generics should work
154-
// together. Currently an incomplete class is never marked as generic. If
155-
// this changes in TG-1996 then the condition below should be updated.
142+
// together. Currently an incomplete class is never marked as generic. If
143+
// this changes in TG-1996 then the condition below should be updated.
144+
if(!is_java_generic_struct_tag_type(struct_tag_type))
145+
return;
146+
if(to_java_class_type(symbol_struct).get_is_stub())
147+
return;
156148
if(
157-
is_java_generic_struct_tag_type(struct_tag_type) &&
158-
!to_java_class_type(symbol_struct).get_is_stub() &&
159-
(is_java_generic_class_type(symbol_struct) ||
160-
is_java_implicitly_generic_class_type(symbol_struct)))
149+
!is_java_generic_class_type(symbol_struct) &&
150+
!is_java_implicitly_generic_class_type(symbol_struct))
161151
{
162-
const java_generic_struct_tag_typet &generic_symbol =
163-
to_java_generic_struct_tag_type(struct_tag_type);
152+
return;
153+
}
154+
const java_generic_struct_tag_typet &generic_symbol =
155+
to_java_generic_struct_tag_type(struct_tag_type);
164156

165-
const std::vector<java_generic_parametert> &generic_parameters =
166-
get_all_generic_parameters(symbol_struct);
157+
const std::vector<java_generic_parametert> &generic_parameters =
158+
get_all_generic_parameters(symbol_struct);
159+
const java_generic_typet::generic_type_argumentst &type_args =
160+
generic_symbol.generic_types();
167161

168-
INVARIANT(
169-
generic_symbol.generic_types().size() == generic_parameters.size(),
170-
"All generic parameters of the superclass need to be concretized");
162+
INVARIANT(
163+
type_args.size() == generic_parameters.size(),
164+
"All generic parameters of the superclass need to be concretized");
171165

172-
insert_pairs(generic_parameters, generic_symbol.generic_types());
173-
}
166+
insert_pairs(generic_parameters, type_args);
174167
}

jbmc/src/java_bytecode/generic_parameter_specialization_map_keys.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ class generic_parameter_specialization_map_keyst
3333
{
3434
for(const auto key : erase_keys)
3535
{
36-
PRECONDITION(generic_parameter_specialization_map.count(key) != 0);
37-
auto &val = generic_parameter_specialization_map.find(key)->second;
36+
const auto map_it = generic_parameter_specialization_map.find(key);
37+
PRECONDITION(map_it != generic_parameter_specialization_map.end());
38+
std::vector<reference_typet> &val = map_it->second;
3839
val.pop_back();
3940
if(val.empty())
40-
generic_parameter_specialization_map.erase(key);
41+
generic_parameter_specialization_map.erase(map_it);
4142
}
4243
}
4344

jbmc/src/java_bytecode/java_object_factory.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,8 @@ void java_object_factoryt::gen_nondet_pointer_init(
487487
// If we are changing the pointer, we generate code for creating a pointer
488488
// to the substituted type instead
489489
// TODO if we are comparing array types we need to compare their element
490-
// types. this is for now done by implementing equality function especially
491-
// for java types, technical debt TG-2707
490+
// types. this is for now done by implementing equality function especially
491+
// for java types, technical debt TG-2707
492492
if(!equal_java_types(replacement_pointer_type, pointer_type))
493493
{
494494
// update generic_parameter_specialization_map for the new pointer

jbmc/src/java_bytecode/select_pointer_type.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@ pointer_typet select_pointer_typet::convert_pointer_type(
1818
const pointer_typet &pointer_type,
1919
const generic_parameter_specialization_mapt
2020
&generic_parameter_specialization_map,
21-
const namespacet &ns) const
21+
const namespacet &) const
2222
{
23-
(void)ns; // unused parameter
2423
// if we have a map of generic parameters -> types and the pointer is
2524
// a generic parameter, specialize it with concrete types
2625
if(!generic_parameter_specialization_map.empty())
@@ -51,23 +50,24 @@ pointer_typet select_pointer_typet::specialize_generics(
5150

5251
// avoid infinite recursion by looking at each generic argument from
5352
// previous assignments
54-
if(visited_nodes.find(parameter_name) != visited_nodes.end())
53+
if(visited_nodes.count(parameter_name) != 0)
5554
{
5655
const optionalt<pointer_typet> result = get_recursively_instantiated_type(
5756
parameter_name, generic_parameter_specialization_map);
5857
return result.has_value() ? result.value() : pointer_type;
5958
}
6059

61-
if(generic_parameter_specialization_map.count(parameter_name) == 0)
60+
const auto specialization =
61+
generic_parameter_specialization_map.find(parameter_name);
62+
if(specialization == generic_parameter_specialization_map.end())
6263
{
6364
// this means that the generic pointer_type has not been specialized
6465
// in the current context (e.g., the method under test is generic);
6566
// we return the pointer_type itself which is basically a pointer to
6667
// its upper bound
6768
return pointer_type;
6869
}
69-
const pointer_typet &type =
70-
generic_parameter_specialization_map.find(parameter_name)->second.back();
70+
const pointer_typet &type = specialization->second.back();
7171

7272
// generic parameters can be adopted from outer classes or superclasses so
7373
// we may need to search for the concrete type recursively
@@ -111,7 +111,7 @@ pointer_typet select_pointer_typet::specialize_generics(
111111
///
112112
/// Example:
113113
/// `class MyGeneric<T,U> { MyGeneric<U,T> gen; T t;}`
114-
/// When instantiating `MyGeneric<Integer,String> my` we need to for example
114+
/// For example, when instantiating `MyGeneric<Integer,String> my` we need to
115115
/// resolve the type of `my.gen.t`. The map would in this context contain
116116
/// - T -> (Integer, U)
117117
/// - U -> (String, T)

0 commit comments

Comments
 (0)