Skip to content

Commit 897aaf6

Browse files
author
Thomas Kiley
authored
Merge pull request #1431 from thk123/feature/java-load-class-utility
Created utility function for loading a class file
2 parents 8151e91 + 774bfdb commit 897aaf6

File tree

10 files changed

+107
-58
lines changed

10 files changed

+107
-58
lines changed

unit/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# Source files for test utilities
44
SRC = src/expr/require_expr.cpp \
55
src/ansi-c/c_to_expr.cpp \
6+
src/java_bytecode/load_java_class.cpp \
67
unit_tests.cpp \
78
catch_example.cpp \
89
util/expr_iterator.cpp \
Binary file not shown.
Binary file not shown.

unit/java_bytecode/java_bytecode_convert_class/ExampleClasses.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ void concreteMethod() {
1919
}
2020
}
2121

22-
class Extendor extends A {
22+
class Extender extends A {
2323
void method() {
2424

2525
}
Binary file not shown.
Binary file not shown.
Binary file not shown.

unit/java_bytecode/java_bytecode_convert_class/convert_abstract_class.cpp

+16-57
Original file line numberDiff line numberDiff line change
@@ -15,39 +15,18 @@
1515
#include <util/language.h>
1616
#include <util/message.h>
1717
#include <java_bytecode/java_bytecode_language.h>
18+
#include <src/java_bytecode/load_java_class.h>
1819

1920
SCENARIO("java_bytecode_convert_abstract_class",
2021
"[core][java_bytecode][java_bytecode_convert_class]")
2122
{
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-
3923
GIVEN("Some class files in the class path")
4024
{
4125
WHEN("Parsing an interface")
4226
{
43-
java_lang->parse(java_code_stream, "I.class");
44-
45-
symbol_tablet new_symbol_table;
46-
java_lang->typecheck(new_symbol_table, "");
27+
const symbol_tablet &new_symbol_table=
28+
load_java_class("I", "./java_bytecode/java_bytecode_convert_class");
4729

48-
java_lang->final(new_symbol_table);
49-
50-
REQUIRE(new_symbol_table.has_symbol("java::I"));
5130
THEN("The symbol type should be abstract")
5231
{
5332
const symbolt &class_symbol=new_symbol_table.lookup("java::I");
@@ -61,14 +40,8 @@ SCENARIO("java_bytecode_convert_abstract_class",
6140
}
6241
WHEN("Parsing an abstract class")
6342
{
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"));
43+
const symbol_tablet &new_symbol_table=
44+
load_java_class("A", "./java_bytecode/java_bytecode_convert_class");
7245
THEN("The symbol type should be abstract")
7346
{
7447
const symbolt &class_symbol=new_symbol_table.lookup("java::A");
@@ -82,14 +55,8 @@ SCENARIO("java_bytecode_convert_abstract_class",
8255
}
8356
WHEN("Passing a concrete class")
8457
{
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"));
58+
const symbol_tablet &new_symbol_table=
59+
load_java_class("C", "./java_bytecode/java_bytecode_convert_class");
9360
THEN("The symbol type should not be abstract")
9461
{
9562
const symbolt &class_symbol=new_symbol_table.lookup("java::C");
@@ -103,14 +70,10 @@ SCENARIO("java_bytecode_convert_abstract_class",
10370
}
10471
WHEN("Passing a concrete class that implements an interface")
10572
{
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"));
73+
const symbol_tablet &new_symbol_table=
74+
load_java_class(
75+
"Implementor",
76+
"./java_bytecode/java_bytecode_convert_class");
11477
THEN("The symbol type should not be abstract")
11578
{
11679
const symbolt &class_symbol=
@@ -125,18 +88,14 @@ SCENARIO("java_bytecode_convert_abstract_class",
12588
}
12689
WHEN("Passing a concrete class that extends an abstract class")
12790
{
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"));
91+
const symbol_tablet &new_symbol_table=
92+
load_java_class(
93+
"Extender",
94+
"./java_bytecode/java_bytecode_convert_class");
13695
THEN("The symbol type should not be abstract")
13796
{
13897
const symbolt &class_symbol=
139-
new_symbol_table.lookup("java::Extendor");
98+
new_symbol_table.lookup("java::Extender");
14099
const typet &symbol_type=class_symbol.type;
141100

142101
REQUIRE(symbol_type.id()==ID_struct);
+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*******************************************************************\
2+
3+
Module: Unit test utilities
4+
5+
Author: DiffBlue Limited. All rights reserved.
6+
7+
\*******************************************************************/
8+
9+
#include "load_java_class.h"
10+
#include <catch.hpp>
11+
#include <iostream>
12+
13+
#include <util/config.h>
14+
#include <util/language.h>
15+
#include <util/suffix.h>
16+
17+
#include <java_bytecode/java_bytecode_language.h>
18+
19+
/// Go through the process of loading, typechecking and finalising loading a
20+
/// specific class file to build the symbol table.
21+
/// \param java_class_name: The name of the class file to load. It should not
22+
/// include the .class extension.
23+
/// \param class_path: The path to load the class from. Should be relative to
24+
/// the unit directory.
25+
/// \return The symbol table that is generated by parsing this file.
26+
symbol_tablet load_java_class(
27+
const std::string &java_class_name,
28+
const std::string &class_path)
29+
{
30+
// We don't expect the .class suffix to allow us to check the name of the
31+
// class
32+
PRECONDITION(!has_suffix(java_class_name, ".class"));
33+
34+
// Configure the path loading
35+
cmdlinet command_line;
36+
command_line.set("java-cp-include-files", class_path);
37+
config.java.classpath.clear();
38+
config.java.classpath.push_back(class_path);
39+
40+
symbol_tablet new_symbol_table;
41+
42+
std::unique_ptr<languaget>java_lang(new_java_bytecode_language());
43+
44+
std::istringstream java_code_stream("ignored");
45+
null_message_handlert message_handler;
46+
47+
// Configure the language, load the class files
48+
java_lang->get_language_options(command_line);
49+
java_lang->set_message_handler(message_handler);
50+
java_lang->parse(java_code_stream, java_class_name + ".class");
51+
java_lang->typecheck(new_symbol_table, "");
52+
java_lang->final(new_symbol_table);
53+
54+
// Verify that the class was loaded
55+
const std::string class_symbol_name="java::"+java_class_name;
56+
REQUIRE(new_symbol_table.has_symbol(class_symbol_name));
57+
const symbolt &class_symbol=new_symbol_table.lookup(class_symbol_name);
58+
REQUIRE(class_symbol.is_type);
59+
const typet &class_type=class_symbol.type;
60+
REQUIRE(class_type.id()==ID_struct);
61+
62+
// if this fails it indicates the class was not loaded
63+
// Check your working directory and the class path is correctly configured
64+
// as this often indicates that one of these is wrong.
65+
REQUIRE_FALSE(class_type.get_bool(ID_incomplete_class));
66+
return new_symbol_table;
67+
}
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*******************************************************************\
2+
3+
Module: Unit test utilities
4+
5+
Author: DiffBlue Limited. All rights reserved.
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// Utility for loading and parsing a specified java class file, returning
11+
/// the symbol table generated by this.
12+
13+
#ifndef CPROVER_SRC_JAVA_BYTECODE_LOAD_JAVA_CLASS_H
14+
#define CPROVER_SRC_JAVA_BYTECODE_LOAD_JAVA_CLASS_H
15+
16+
#include <util/symbol_table.h>
17+
18+
symbol_tablet load_java_class(
19+
const std::string &java_class_name,
20+
const std::string &class_path);
21+
22+
#endif // CPROVER_SRC_JAVA_BYTECODE_LOAD_JAVA_CLASS_H

0 commit comments

Comments
 (0)