Skip to content

Commit

Permalink
add signature to method pretty names
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Kroening committed May 8, 2018
1 parent a9bb35c commit b008bf3
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 20 deletions.
2 changes: 1 addition & 1 deletion regression/cbmc-java/package_friendly1/test.desc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
CORE symex-driven-lazy-loading-expected-failure
main.class
package_friendly1.class package_friendly2.class --show-goto-functions
^main[.]main[\(][\)].*$
^main[.]main[\(].*[\)].*$
^package_friendly2[.]operation2[\(][\)].*$
^EXIT=0$
^SIGNAL=0$
Expand Down
43 changes: 26 additions & 17 deletions src/java_bytecode/java_bytecode_convert_method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ void java_bytecode_convert_method_lazy(
method_symbol.mode=ID_java;
method_symbol.location=m.source_location;
method_symbol.location.set_function(method_identifier);

if(m.is_public)
member_type.set_access(ID_public);
else if(m.is_protected)
Expand All @@ -363,20 +364,6 @@ void java_bytecode_convert_method_lazy(
else
member_type.set_access(ID_default);

if(is_constructor(method_symbol.base_name))
{
// we use full.class_name.class_name(...) as pretty name
// for constructors
method_symbol.pretty_name=
id2string(class_symbol.pretty_name)+"."+
id2string(class_symbol.base_name)+"()";
member_type.set_is_constructor();
}
else
method_symbol.pretty_name=
id2string(class_symbol.pretty_name)+"."+
id2string(m.base_name)+"()";

// do we need to add 'this' as a parameter?
if(!m.is_static)
{
Expand All @@ -389,6 +376,23 @@ void java_bytecode_convert_method_lazy(
parameters.insert(parameters.begin(), this_p);
}

const std::string signature_string = pretty_signature(member_type);

if(is_constructor(method_symbol.base_name))
{
// we use full.class_name.class_name(...) as pretty name
// for constructors
method_symbol.pretty_name=
id2string(class_symbol.pretty_name) + "." +
id2string(class_symbol.base_name) + signature_string;
member_type.set_is_constructor();
}
else
{
method_symbol.pretty_name = id2string(class_symbol.pretty_name) + "." +
id2string(m.base_name) + signature_string;
}

// Load annotations
if(!m.annotations.empty())
{
Expand Down Expand Up @@ -561,22 +565,27 @@ void java_bytecode_convert_methodt::convert(
method_symbol.location=m.source_location;
method_symbol.location.set_function(method_identifier);

const std::string signature_string = pretty_signature(code_type);

// Set up the pretty name for the method entry in the symbol table.
// The pretty name of a constructor includes the base name of the class
// instead of the internal method name "<init>". For regular methods, it's
// just the base name of the method.
if(is_constructor(method_symbol.base_name))
{
method_symbol.pretty_name = id2string(class_symbol.pretty_name) + "." +
id2string(class_symbol.base_name) + "()";
// we use full.class_name(...) as pretty name
// for constructors -- the idea is that they have
// an empty declarator.
method_symbol.pretty_name =
id2string(class_symbol.pretty_name) + signature_string;
INVARIANT(
code_type.get_is_constructor(),
"Member type should have already been marked as a constructor");
}
else
{
method_symbol.pretty_name = id2string(class_symbol.pretty_name) + "." +
id2string(method_symbol.base_name) + "()";
id2string(m.base_name) + signature_string;
}

method_symbol.type = code_type;
Expand Down
61 changes: 61 additions & 0 deletions src/java_bytecode/java_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -884,3 +884,64 @@ optionalt<size_t> java_generic_symbol_typet::generic_type_index(
}
return {};
}

std::string pretty_java_type(const typet &type)
{
if(type == java_int_type())
return "int";
else if(type == java_long_type())
return "long";
else if(type == java_short_type())
return "short";
else if(type == java_byte_type())
return "byte";
else if(type == java_char_type())
return "char";
else if(type == java_float_type())
return "float";
else if(type == java_double_type())
return "double";
else if(type == java_boolean_type())
return "boolean";
else if(type == java_byte_type())
return "byte";
else if(is_reference(type))
{
if(type.subtype().id() == ID_symbol)
{
const auto &symbol_type = to_symbol_type(type.subtype());
const irep_idt &id = symbol_type.get_identifier();
if(is_java_array_tag(id))
return pretty_java_type(java_array_element_type(symbol_type)) + "[]";
else
return id2string(strip_java_namespace_prefix(id));
}
else
return "?";
}
else
return "?";
}

std::string pretty_signature(const code_typet &code_type)
{
std::ostringstream result;
result << '(';

bool first = true;
for(const auto p : code_type.parameters())
{
if(p.get_this())
continue;

if(first)
first = false;
else
result << ", ";

result << pretty_java_type(p.type());
}

result << ')';
return result.str();
}
10 changes: 8 additions & 2 deletions src/java_bytecode/java_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -626,12 +626,18 @@ inline java_generic_symbol_typet &to_java_generic_symbol_type(typet &type)
/// the type to be parsed normally, for example
/// `java.util.HashSet<java.lang.Integer>` will be turned into
/// `java.util.HashSet`
std::string erase_type_arguments(const std::string &src);
std::string erase_type_arguments(const std::string &);
/// Returns the full class name, skipping over the generics. This turns any of
/// these:
/// 1. Signature: Lcom/package/OuterClass<TT;>.Inner;
/// 2. Descriptor: Lcom.pacakge.OuterClass$Inner;
/// into `com.package.OuterClass.Inner`
std::string gather_full_class_name(const std::string &src);
std::string gather_full_class_name(const std::string &);

// turn java type into string
std::string pretty_java_type(const typet &);

// pretty signature for methods
std::string pretty_signature(const code_typet &);

#endif // CPROVER_JAVA_BYTECODE_JAVA_TYPES_H

0 comments on commit b008bf3

Please sign in to comment.