Skip to content

Commit 4b36fc6

Browse files
author
Matthias Güdemann
authored
Merge pull request diffblue#1533 from mgudemann/fix/support_class_bounds_generics
TG-1179 Skip '::' instead of just ':' for class bounds in generics
2 parents b25630a + 6b88eb8 commit 4b36fc6

File tree

13 files changed

+49
-2
lines changed

13 files changed

+49
-2
lines changed
84 Bytes
Binary file not shown.
84 Bytes
Binary file not shown.
84 Bytes
Binary file not shown.
831 Bytes
Binary file not shown.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
interface A{}
2+
interface B{}
3+
interface C{}
4+
interface L<T> extends A,B,C{}
5+
6+
public class Gn<T extends L<? extends B>>{
7+
Gn<?> ex1;
8+
public void foo1(Gn<?> ex1){
9+
if(ex1 != null)
10+
this.ex1 = ex1;
11+
}
12+
public static void main(String[] args) {
13+
System.out.println("ddfsdf");
14+
}
15+
}
183 Bytes
Binary file not shown.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
Gn.class
3+
--cover location
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
.*file Gn.java line 6 function java::Gn.\<init\>:\(\)V bytecode-index 1 block 1: FAILED
7+
.*file Gn.java line 9 function java::Gn.foo1:\(LGn;\)V bytecode-index 1 block 1: FAILED
8+
.*file Gn.java line 10 function java::Gn.foo1:\(LGn;\)V bytecode-index 4 block 2: FAILED
9+
.*file Gn.java line 11 function java::Gn.foo1:\(LGn;\)V bytecode-index 5 block 3: FAILED
10+
.*file Gn.java line 13 function java::Gn.main:\(\[Ljava/lang/String;\)V bytecode-index 2 block 1: SATISFIED
11+
--

src/java_bytecode/java_types.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,8 @@ char java_char_from_type(const typet &type)
599599
/// Converts the content of a generic class type into a vector of Java types,
600600
/// that is each type variable of the class has one entry in the returned
601601
/// vector.
602+
/// This also supports parsing of bounds in the form of `<T:CBound>` for classes
603+
/// or `<T::IBound>` for interfaces.
602604
///
603605
/// For example for `HashMap<K, V>` a vector with two elements would be returned
604606
///
@@ -607,8 +609,9 @@ std::vector<typet> java_generic_type_from_string(
607609
const std::string &class_name,
608610
const std::string &src)
609611
{
610-
/// the class signature is of the form <TX:Bound_X;:BoundZ;TY:Bound_Y;>
611-
size_t signature_end=find_closing_delimiter(src, 0, '<', '>');
612+
/// the class signature is of the form <TX:Bound_X;:BoundZ;TY:Bound_Y;> or of
613+
/// the form <TX::Bound_X;:BoundZ;TY:Bound_Y;> if Bound_X is an interface
614+
size_t signature_end = find_closing_delimiter(src, 0, '<', '>');
612615
INVARIANT(
613616
src[0]=='<' && signature_end!=std::string::npos,
614617
"Class signature has unexpected format");
@@ -625,6 +628,16 @@ std::vector<typet> java_generic_type_from_string(
625628
{
626629
size_t bound_sep=signature.find(':');
627630
INVARIANT(bound_sep!=std::string::npos, "No bound for type variable.");
631+
632+
// is bound an interface?
633+
// in this case the separator is '::'
634+
if(signature[bound_sep + 1] == ':')
635+
{
636+
INVARIANT(
637+
signature[bound_sep + 2] != ':', "Unknown bound for type variable.");
638+
bound_sep++;
639+
}
640+
628641
std::string type_var_name(
629642
"java::"+class_name+"::"+signature.substr(0, bound_sep));
630643
std::string bound_type(signature.substr(bound_sep+1, var_sep-bound_sep));
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class C{
2+
}
3+
interface I{
4+
}
5+
class interface_bound<T extends I> {
6+
}
7+
class class_bound<T extends C> {
8+
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)