Skip to content

Commit 9419454

Browse files
authored
Merge pull request #1084 from thk123/feature/mark-abstract-classes
Mark abstract classes as such
2 parents 6c7d6d4 + 4193022 commit 9419454

File tree

10 files changed

+191
-1
lines changed

10 files changed

+191
-1
lines changed

src/java_bytecode/java_bytecode_convert_class.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ void java_bytecode_convert_classt::convert(const classt &c)
9393

9494
class_type.set_tag(c.name);
9595
class_type.set(ID_base_name, c.name);
96+
class_type.set(ID_abstract, c.is_abstract);
9697
if(c.is_enum)
9798
{
9899
class_type.set(

src/util/std_types.h

+5
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,11 @@ class class_typet:public struct_typet
401401

402402
return false;
403403
}
404+
405+
bool is_abstract() const
406+
{
407+
return get_bool(ID_abstract);
408+
}
404409
};
405410

406411
/*! \brief Cast a generic typet to a \ref class_typet

unit/Makefile

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
SRC = unit_tests.cpp \
44
catch_example.cpp \
5+
java_bytecode/java_bytecode_convert_class/convert_abstract_class.cpp \
56
solvers/refinement/string_constraint_generator_valueof/is_digit_with_radix.cpp \
67
solvers/refinement/string_constraint_generator_valueof/get_numeric_value_from_character.cpp \
78
# Empty last line
@@ -14,7 +15,9 @@ include ../src/common
1415
cprover.dir:
1516
$(MAKE) $(MAKEARGS) -C ../src
1617

17-
LIBS += ../src/ansi-c/ansi-c$(LIBEXT) \
18+
LIBS += ../src/java_bytecode/java_bytecode$(LIBEXT) \
19+
../src/miniz/miniz$(OBJEXT) \
20+
../src/ansi-c/ansi-c$(LIBEXT) \
1821
../src/cpp/cpp$(LIBEXT) \
1922
../src/json/json$(LIBEXT) \
2023
../src/linking/linking$(LIBEXT) \
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
interface I
2+
{
3+
void interface_method();
4+
}
5+
6+
abstract class A
7+
{
8+
abstract void method();
9+
10+
int i;
11+
}
12+
13+
class C
14+
{
15+
16+
int j;
17+
void concreteMethod() {
18+
19+
}
20+
}
21+
22+
class Extendor extends A {
23+
void method() {
24+
25+
}
26+
}
27+
28+
class Implementor implements I {
29+
public void interface_method(){
30+
31+
}
32+
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for converting abstract classes
4+
5+
Author: DiffBlue Limited. All rights reserved.
6+
7+
\*******************************************************************/
8+
9+
#include <catch.hpp>
10+
11+
#include <istream>
12+
#include <memory>
13+
14+
#include <util/config.h>
15+
#include <util/language.h>
16+
#include <util/message.h>
17+
#include <java_bytecode/java_bytecode_language.h>
18+
19+
SCENARIO("java_bytecode_convert_abstract_class",
20+
"[core][java_bytecode][java_bytecode_convert_class]")
21+
{
22+
std::unique_ptr<languaget>java_lang(new_java_bytecode_language());
23+
24+
// Configure the path loading
25+
cmdlinet command_line;
26+
command_line.set(
27+
"java-cp-include-files",
28+
"./java_bytecode/java_bytecode_convert_class");
29+
config.java.classpath.push_back(
30+
"./java_bytecode/java_bytecode_convert_class");
31+
32+
// Configure the language
33+
null_message_handlert message_handler;
34+
java_lang->get_language_options(command_line);
35+
java_lang->set_message_handler(message_handler);
36+
37+
std::istringstream java_code_stream("ignored");
38+
39+
GIVEN("Some class files in the class path")
40+
{
41+
WHEN("Parsing an interface")
42+
{
43+
java_lang->parse(java_code_stream, "I.class");
44+
45+
symbol_tablet new_symbol_table;
46+
java_lang->typecheck(new_symbol_table, "");
47+
48+
java_lang->final(new_symbol_table);
49+
50+
REQUIRE(new_symbol_table.has_symbol("java::I"));
51+
THEN("The symbol type should be abstract")
52+
{
53+
const symbolt &class_symbol=new_symbol_table.lookup("java::I");
54+
const typet &symbol_type=class_symbol.type;
55+
56+
REQUIRE(symbol_type.id()==ID_struct);
57+
class_typet class_type=to_class_type(symbol_type);
58+
REQUIRE(class_type.is_class());
59+
REQUIRE(class_type.is_abstract());
60+
}
61+
}
62+
WHEN("Parsing an abstract class")
63+
{
64+
java_lang->parse(java_code_stream, "A.class");
65+
66+
symbol_tablet new_symbol_table;
67+
java_lang->typecheck(new_symbol_table, "");
68+
69+
java_lang->final(new_symbol_table);
70+
71+
REQUIRE(new_symbol_table.has_symbol("java::A"));
72+
THEN("The symbol type should be abstract")
73+
{
74+
const symbolt &class_symbol=new_symbol_table.lookup("java::A");
75+
const typet &symbol_type=class_symbol.type;
76+
77+
REQUIRE(symbol_type.id()==ID_struct);
78+
class_typet class_type=to_class_type(symbol_type);
79+
REQUIRE(class_type.is_class());
80+
REQUIRE(class_type.is_abstract());
81+
}
82+
}
83+
WHEN("Passing a concrete class")
84+
{
85+
java_lang->parse(java_code_stream, "C.class");
86+
87+
symbol_tablet new_symbol_table;
88+
java_lang->typecheck(new_symbol_table, "");
89+
90+
java_lang->final(new_symbol_table);
91+
92+
REQUIRE(new_symbol_table.has_symbol("java::C"));
93+
THEN("The symbol type should not be abstract")
94+
{
95+
const symbolt &class_symbol=new_symbol_table.lookup("java::C");
96+
const typet &symbol_type=class_symbol.type;
97+
98+
REQUIRE(symbol_type.id()==ID_struct);
99+
class_typet class_type=to_class_type(symbol_type);
100+
REQUIRE(class_type.is_class());
101+
REQUIRE_FALSE(class_type.is_abstract());
102+
}
103+
}
104+
WHEN("Passing a concrete class that implements an interface")
105+
{
106+
java_lang->parse(java_code_stream, "Implementor.class");
107+
108+
symbol_tablet new_symbol_table;
109+
java_lang->typecheck(new_symbol_table, "");
110+
111+
java_lang->final(new_symbol_table);
112+
113+
REQUIRE(new_symbol_table.has_symbol("java::Implementor"));
114+
THEN("The symbol type should not be abstract")
115+
{
116+
const symbolt &class_symbol=
117+
new_symbol_table.lookup("java::Implementor");
118+
const typet &symbol_type=class_symbol.type;
119+
120+
REQUIRE(symbol_type.id()==ID_struct);
121+
class_typet class_type=to_class_type(symbol_type);
122+
REQUIRE(class_type.is_class());
123+
REQUIRE_FALSE(class_type.is_abstract());
124+
}
125+
}
126+
WHEN("Passing a concrete class that extends an abstract class")
127+
{
128+
java_lang->parse(java_code_stream, "Extendor.class");
129+
130+
symbol_tablet new_symbol_table;
131+
java_lang->typecheck(new_symbol_table, "");
132+
133+
java_lang->final(new_symbol_table);
134+
135+
REQUIRE(new_symbol_table.has_symbol("java::Extendor"));
136+
THEN("The symbol type should not be abstract")
137+
{
138+
const symbolt &class_symbol=
139+
new_symbol_table.lookup("java::Extendor");
140+
const typet &symbol_type=class_symbol.type;
141+
142+
REQUIRE(symbol_type.id()==ID_struct);
143+
class_typet class_type=to_class_type(symbol_type);
144+
REQUIRE(class_type.is_class());
145+
REQUIRE_FALSE(class_type.is_abstract());
146+
}
147+
}
148+
}
149+
}

0 commit comments

Comments
 (0)