Skip to content

Commit

Permalink
Merge pull request diffblue#1871 from mgudemann/bugfix/superclass_ref…
Browse files Browse the repository at this point in the history
…erences_for_implicit_generic

[TG-2585] Support implicitly generic superclasses
  • Loading branch information
Matthias Güdemann authored Feb 22, 2018
2 parents 71b32f4 + 25eb1a3 commit 1dfb5cd
Show file tree
Hide file tree
Showing 12 changed files with 93 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/java_bytecode/java_bytecode_convert_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,10 @@ extract_generic_superclass_reference(const optionalt<std::string> &signature)
signature.value().substr(start, (end - start) + 1);

// if the superclass is generic then the reference is of form
// Lsuperclass-name<generic-types;>;
if(has_suffix(superclass_ref, ">;"))
// `Lsuperclass-name<generic-types;>;` if it is implicitly generic, then the
// reference is of the form
// `Lsuperclass-name<Tgeneric-types;>.Innerclass-Name`
if(superclass_ref.find('<') != std::string::npos)
return superclass_ref;
}
return {};
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ public class DerivedGenerics {
ExtendsAndImplementsSameInterface new14;
ExtendsAndImplementsSameInterface2 new15;
ExtendsAndImplementsSameInterfaceGeneric new16;
GenericBase<?>.ExtendImplicit new17;
GenericBase<?>.ExtendImplicitAndExplicit<?> new18;
GenericBase2<?, ?>.ExtendImplicitAndExplicit new19;
}

class DerivedGenericInst extends Generic<Interface_Implementation>
Expand Down Expand Up @@ -189,3 +192,25 @@ public Class<? extends Class> someMethod(){
return null;
}
}

// This class exists to test that subclasses of implicit generic classes have a
// base class entry which is a Java generic symbol.
class GenericBase<T> {
class ImplicitGeneric {
}
class ExtendImplicit extends ImplicitGeneric {
}
class ImplicitAndExplicitGeneric<S> {
}
class ExtendImplicitAndExplicit<S> extends ImplicitAndExplicitGeneric<S> {
}
}

// This class exists to test the subclasses of generic and implicitly generic
// classes have a base class entry which is a Java generic symbol.
class GenericBase2<T, S> {
class ImplicitAndExplicitGeneric<S> {
}
class ExtendImplicitAndExplicit extends ImplicitAndExplicitGeneric<S> {
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -559,4 +559,68 @@ SCENARIO(

// TODO: Check that specialised superclass is created. TG-1418, TG-1419
}

THEN("There should be a symbol for the `ExtendImplicit` class")
{
std::string class_prefix = "java::GenericBase$ExtendImplicit";
REQUIRE(new_symbol_table.has_symbol(class_prefix));

const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix);
const class_typet &derived_class_type =
require_type::require_java_implicitly_generic_class(derived_symbol.type);

THEN("The base for superclass is implicitly generic")
{
REQUIRE(derived_class_type.bases().size() == 1);
const typet &base_type = derived_class_type.bases().at(0).type();
require_type::require_java_generic_symbol_type(
base_type,
"java::GenericBase$ImplicitGeneric",
{{require_type::type_argument_kindt::Var, "java::GenericBase::T"}});
}
}

THEN("There should be a symbol for the `ExtendImplicitAndExplicit` class")
{
std::string class_prefix = "java::GenericBase$ExtendImplicitAndExplicit";
REQUIRE(new_symbol_table.has_symbol(class_prefix));

const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix);
const class_typet &derived_class_type =
require_type::require_java_implicitly_generic_class(derived_symbol.type);

THEN("The base for superclass is generic *and* implicitly generic")
{
REQUIRE(derived_class_type.bases().size() == 1);
const typet &base_type = derived_class_type.bases().at(0).type();
require_type::require_java_generic_symbol_type(
base_type,
"java::GenericBase$ImplicitAndExplicitGeneric",
{{require_type::type_argument_kindt::Var, "java::GenericBase::T"},
{require_type::type_argument_kindt::Var,
"java::GenericBase$ExtendImplicitAndExplicit::S"}});
}
}

THEN("There should be a symbol for the `ExtendImplicitAndExplicit` class")
{
std::string class_prefix = "java::GenericBase2$ExtendImplicitAndExplicit";
REQUIRE(new_symbol_table.has_symbol(class_prefix));

const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix);
const class_typet &derived_class_type =
require_type::require_java_implicitly_generic_class(derived_symbol.type);

THEN("The base for superclass is generic *and* implicitly generic")
{
REQUIRE(derived_class_type.bases().size() == 1);
const typet &base_type = derived_class_type.bases().at(0).type();
require_type::require_java_generic_symbol_type(
base_type,
"java::GenericBase2$ImplicitAndExplicitGeneric",
{{require_type::type_argument_kindt::Var, "java::GenericBase2::T"},
{require_type::type_argument_kindt::Var, "java::GenericBase2::S"},
{require_type::type_argument_kindt::Var, "java::GenericBase2::S"}});
}
}
}

0 comments on commit 1dfb5cd

Please sign in to comment.