Skip to content

Commit 09431fd

Browse files
author
svorenova
committed
Adding unit tests for the signature/descripture mismatch
1 parent b61cb56 commit 09431fd

11 files changed

+199
-52
lines changed
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
public abstract class AbstractGenericClass<T>
2+
{
3+
4+
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
public class Outer<T>
2+
{
3+
private class Inner
4+
{
5+
private final AbstractGenericClass<T> u;
6+
7+
Inner (AbstractGenericClass<T> t)
8+
{
9+
this.u = t;
10+
}
11+
}
12+
13+
private enum InnerEnum
14+
{
15+
16+
}
17+
}

unit/java_bytecode/java_bytecode_parse_generics/parse_derived_generic_class.cpp

+3-6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <java_bytecode/java_bytecode_language.h>
1818
#include <iostream>
1919
#include <testing-utils/load_java_class.h>
20+
#include <testing-utils/require_symbol.h>
2021

2122
SCENARIO(
2223
"java_bytecode_parse_derived_generic_class",
@@ -33,12 +34,8 @@ SCENARIO(
3334
REQUIRE(new_symbol_table.has_symbol(class_prefix));
3435

3536
const symbolt &derived_symbol=new_symbol_table.lookup_ref(class_prefix);
36-
REQUIRE(derived_symbol.is_type);
37-
const typet &derived_type=derived_symbol.type;
38-
REQUIRE(derived_type.id()==ID_struct);
39-
const class_typet &class_type=to_class_type(derived_type);
40-
REQUIRE(class_type.is_class());
41-
REQUIRE_FALSE(class_type.get_bool(ID_incomplete_class));
37+
const class_typet &derived_class_type=
38+
require_symbol::require_complete_class(derived_symbol);
4239

4340
// TODO(tkiley): Currently we do not support extracting information
4441
// about the base classes generic information.

unit/java_bytecode/java_bytecode_parse_generics/parse_generic_class.cpp

+41-46
Original file line numberDiff line numberDiff line change
@@ -174,57 +174,52 @@ SCENARIO(
174174
.has_symbol("java::generics$bound_element.f:()Ljava/lang/Number;"));
175175

176176
// TODO: methods should have generic return type (the tests needs to be
177-
// extended), reintroduce when the issue of signature/descriptor for methods is
178-
// resolved
179-
// THEN("The method should have generic return type")
180-
// {
181-
// const symbolt &method_symbol=
182-
// new_symbol_table
183-
// .lookup("java::generics$bound_element.f:()Ljava/lang/Number;")
184-
// .value().get();
185-
// const typet &symbol_type=method_symbol.type;
186-
//
187-
// REQUIRE(symbol_type.id()==ID_code);
188-
//
189-
// const code_typet &code=to_code_type(symbol_type);
190-
// }
177+
// extended)
178+
THEN("The method should have generic return type")
179+
{
180+
const symbolt &method_symbol=
181+
new_symbol_table
182+
.lookup_ref("java::generics$bound_element.f:()Ljava/lang/Number;");
183+
const typet &symbol_type=method_symbol.type;
184+
185+
REQUIRE(symbol_type.id()==ID_code);
186+
187+
const code_typet &code=to_code_type(symbol_type);
188+
}
191189

192190
REQUIRE(
193191
new_symbol_table
194192
.has_symbol("java::generics$bound_element.g:(Ljava/lang/Number;)V"));
193+
THEN("The method should have a generic parameter.")
194+
{
195+
const symbolt &method_symbol=
196+
new_symbol_table
197+
.lookup_ref("java::generics$bound_element.g:(Ljava/lang/Number;)V");
198+
const typet &symbol_type=method_symbol.type;
195199

196-
// TODO: methods are not recognized as generic, reintroduce when
197-
// the issue of signature/descriptor for methods is resolved
198-
// THEN("The method should have a generic parameter.")
199-
// {
200-
// const symbolt &method_symbol=
201-
// new_symbol_table
202-
// .lookup("java::generics$bound_element.g:(Ljava/lang/Number;)V");
203-
// const typet &symbol_type=method_symbol.type;
204-
//
205-
// REQUIRE(symbol_type.id()==ID_code);
206-
//
207-
// const code_typet &code=to_code_type(symbol_type);
208-
//
209-
// bool found=false;
210-
// for(const auto &p : code.parameters())
211-
// {
212-
// if(p.get_identifier()==
213-
// "java::generics$bound_element.g:(Ljava/lang/Number;)V::e")
214-
// {
215-
// found=true;
216-
// const typet &t=p.type();
217-
// REQUIRE(is_java_generic_parameter(p.type()));
218-
// const java_generic_parametert &gen_type=
219-
// to_java_generic_parameter(p.type());
220-
// const symbol_typet &type_var=gen_type.type_variable();
221-
// REQUIRE(type_var.get_identifier()==
222-
// "java::generics$bound_element::NUM");
223-
// break;
224-
// }
225-
// }
226-
// REQUIRE(found);
227-
// }
200+
REQUIRE(symbol_type.id()==ID_code);
201+
202+
const code_typet &code=to_code_type(symbol_type);
203+
204+
bool found=false;
205+
for(const auto &p : code.parameters())
206+
{
207+
if(p.get_identifier()==
208+
"java::generics$bound_element.g:(Ljava/lang/Number;)V::e")
209+
{
210+
found=true;
211+
const typet &t=p.type();
212+
REQUIRE(is_java_generic_parameter(p.type()));
213+
const java_generic_parametert &gen_type=
214+
to_java_generic_parameter(p.type());
215+
const symbol_typet &type_var=gen_type.type_variable();
216+
REQUIRE(type_var.get_identifier()==
217+
"java::generics$bound_element::NUM");
218+
break;
219+
}
220+
}
221+
REQUIRE(found);
222+
}
228223
}
229224
}
230225
GIVEN("A class with multiple bounds")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for parsing generic classes
4+
5+
Author: DiffBlue Limited. All rights reserved.
6+
7+
\*******************************************************************/
8+
9+
#include <testing-utils/catch.hpp>
10+
11+
#include <memory>
12+
13+
#include <util/config.h>
14+
#include <util/language.h>
15+
#include <java_bytecode/java_bytecode_language.h>
16+
#include <iostream>
17+
#include <testing-utils/load_java_class.h>
18+
#include <testing-utils/require_symbol.h>
19+
20+
SCENARIO(
21+
"java_bytecode_parse_signature_descriptor_mismatch",
22+
"[core][java_bytecode][java_bytecode_parse_generics]")
23+
{
24+
const symbol_tablet &new_symbol_table=
25+
load_java_class(
26+
"Outer",
27+
"./java_bytecode/java_bytecode_parse_generics");
28+
29+
const std::string class_prefix="java::Outer";
30+
REQUIRE(new_symbol_table.has_symbol(class_prefix));
31+
32+
const std::string inner_prefix=class_prefix+"$Inner";
33+
THEN("There is a (complete) symbol for the inner class Inner")
34+
{
35+
REQUIRE(new_symbol_table.has_symbol(inner_prefix));
36+
37+
const symbolt &inner_symbol=new_symbol_table.lookup_ref(inner_prefix);
38+
const class_typet &inner_class_type=
39+
require_symbol::require_complete_class(inner_symbol);
40+
}
41+
42+
THEN("There is a symbol for the constructor of the inner class with correct"
43+
" descriptor")
44+
{
45+
const std::string func_name=".<init>";
46+
const std::string func_descriptor=":(LOuter;LAbstractGenericClass;)V";
47+
const std::string process_func_name=
48+
inner_prefix+func_name+func_descriptor;
49+
REQUIRE(new_symbol_table.has_symbol(process_func_name));
50+
51+
const code_typet func_code=
52+
to_code_type(new_symbol_table.lookup_ref(process_func_name).type);
53+
REQUIRE(func_code.parameters().size()==3);
54+
}
55+
56+
const std::string inner_enum_prefix=class_prefix+"$InnerEnum";
57+
THEN("There is a (complete) symbol for the inner enum InnerEnum")
58+
{
59+
REQUIRE(new_symbol_table.has_symbol(inner_enum_prefix));
60+
61+
const symbolt &inner_enum_symbol=
62+
new_symbol_table.lookup_ref(inner_enum_prefix);
63+
const class_typet &inner_enum_class_type=
64+
require_symbol::require_complete_class(inner_enum_symbol);
65+
}
66+
67+
THEN("There is a symbol for the constructor of the inner enum with correct"
68+
" number of parameters")
69+
{
70+
const std::string func_name=".<init>";
71+
const std::string func_descriptor=":(Ljava/lang/String;I)V";
72+
const std::string process_func_name=
73+
inner_enum_prefix+func_name+func_descriptor;
74+
REQUIRE(new_symbol_table.has_symbol(process_func_name));
75+
76+
const code_typet func_code=
77+
to_code_type(new_symbol_table.lookup_ref(process_func_name).type);
78+
REQUIRE(func_code.parameters().size()==3);
79+
}
80+
}

unit/testing-utils/require_symbol.cpp

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*******************************************************************\
2+
3+
Module: Unit test utilities
4+
5+
Author: DiffBlue Limited. All rights reserved.
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// Helper functions for requiring properties of symbols
11+
12+
#include "require_symbol.h"
13+
14+
#include <testing-utils/catch.hpp>
15+
16+
const class_typet &require_symbol::require_complete_class(
17+
const symbolt &class_symbol)
18+
{
19+
REQUIRE(class_symbol.is_type);
20+
21+
const typet &class_symbol_type=class_symbol.type;
22+
REQUIRE(class_symbol_type.id()==ID_struct);
23+
24+
const class_typet &class_class_type=to_class_type(class_symbol_type);
25+
REQUIRE(class_class_type.is_class());
26+
REQUIRE_FALSE(class_class_type.get_bool(ID_incomplete_class));
27+
28+
return class_class_type;
29+
}

unit/testing-utils/require_symbol.h

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*******************************************************************\
2+
3+
Module: Unit test utilities
4+
5+
Author: DiffBlue Limited. All rights reserved.
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// Helper functions for requiring properties of symbols
11+
12+
#include <util/symbol.h>
13+
#include <util/std_types.h>
14+
15+
#ifndef CPROVER_TESTING_UTILS_REQUIRE_SYMBOL_H
16+
#define CPROVER_TESTING_UTILS_REQUIRE_SYMBOL_H
17+
18+
// NOLINTNEXTLINE(readability/namespace)
19+
namespace require_symbol
20+
{
21+
const class_typet &require_complete_class(
22+
const symbolt &class_symbol);
23+
}
24+
25+
#endif // CPROVER_TESTING_UTILS_REQUIRE_SYMBOL_H

0 commit comments

Comments
 (0)