ENHANCING A DESIGN BY CONTRACT TOOL

USING INFERENCE RULES OF PROGRAMMING LOGIC

A Project

Presented to the faculty of the Department of Computer Science

California State University, Sacramento

Submitted in partial satisfaction of the requirements for the degree of

MASTER OF SCIENCE

in

Computer Science

by

Nuha Aldausari

FALL 2017

© 2017

Nuha Aldausari

ALL RIGHTS RESERVED

ii

ENHANCING A DESIGN BY CONTRACT TOOL

USING INFERENCE RULES OF PROGRAMMING LOGIC

A Project

by

Nuha Aldausari

Approved by:

______, Committee Chair Dr. Cui Zhang

______, Second Reader Dr. Jun Dai

______Date

iii

Student: Nuha Aldausari

I certify that this student has met the requirements for format contained in the University format manual, and that this project is suitable for shelving in the Library and credit is to be awarded for the project.

______, Graduate Coordinator ______Dr. Jinsong Ouyang Date

Department of Computer Science

iv

Abstract

of

ENHANCING A DESIGN BY CONTACT TOOL

USING INFERENCE RULES OF PROGRAMMING LOGIC

by

Nuha Aldausari

Design by contract (DBC) is an effective methodology that dynamically checks whether a program meets its specifications which are also called design contracts. The contracts for object-oriented programs are defined in terms of preconditions and postconditions for methods as well as invariants for classes. However, if there is an error in a large piece of code that has a design contract, it is still tedious and difficult to spot the exact location of that error.

To address this issue, a tool named Subcontractor has been developed. Subcontractor is implemented in Eclipse environment using libraries such as Java Development Tools

(JDT), Plugin Development Environment (PDE), and JFace. The tool Subcontractor is built upon an open source DBC tool, OpenJML Runtime Assertion Checking (RAC), which is a tool that verifies specifications at runtime. Subcontractor enhances this DBC tool by automatically generating subcontracts for programs using inference rules of

v

program logic for if-statements and loop-statements. When the programs with the automatically generated and inserted subcontracts are verified using OpenJML Runtime

Assertion Checking (RAC), identification of errors in the code can be facilitated.

______, Committee Chair Dr. Cui Zhang

______Date

vi

Acknowledgements

I cannot believe this moment, the moment of finishing my Master’s project, is finally here. It was a full year of learning experiences, struggles, and achievements. I would not have reached the finish line without the support I had from the great people who I was lucky to have around me. Fortunately, this support was always there when I needed it, and I am sincerely thankful for such motivation, supervision, and assistance.

Foremost, I would like to thank my adviser, Dr. Cui Zhang, for her continuous care, patience, and enthusiasm. She provided me with valuable guidance during the journey of working in this project. She endeavored to keep me on the right path. To achieve the outcome of this Master’s project, her aspiring views and insightful comments were fundamental. I am very honored to work with her during this project.

I would also like to acknowledge Dr. Jun Dai as the second reader of this Master’s project. His remarks were useful to abolish this project.

I must express my gratitude to my amazing parents: Nasser Aldausari and Noura

Alrobaqi for their continuous encouragements throughout not only this project, but also through my Master’s life. Even though they were far away, their supports and prayers were always with me when I needed them.

Last but not the least, I must not to forget my beloved small family. My husband, Basel

Qenam, was always the first support that I approach when I encounter a problem. This

vii

project would not have been possible to progress without him. I would like to thank my little one, Dana. She was born with the idea of this project. She was and is the source of happiness in this project and in my life. Her simile keeps me going to overcome my struggles. Thank you all.

viii

TABLE OF CONTENTS Page Acknowledgements ...... vii

List of Tables ...... xi

List of Figures ...... xii

Chapter

1. INTRODUCTION ...... 1

2. BACKGROUND AND RELATED WORK ...... 4

2.1 Programming Logic ...... 4

2.2 DBC ...... 5

2.3 DBC in Java ...... 8

2.3.1 COFOJA ...... 9

2.3.2 JML ...... 10

3. DESIGN AND IMPLEMENTATION ...... 13

3.1 External Components Related to the Tool Subcontractor ...... 13

3.1.1 Eclipse ...... 13

3.1.2 Plugin Development Environment (PDE) ...... 14

3.1.3 Java Development Tools (JDT) ...... 15

3.1.4 JFace ...... 16

3.1.4.1 Viewers ...... 16

3.1.4.2 Content Provider ...... 18

3.1.4.3 Label Provider ...... 19

ix

3.1.4.4 ASTVisitor ...... 20

3.1.4.5 ASTRewiter ...... 23

3.1.4.6 Comment ...... 23

3.2 for the Tool Subcontractor ...... 24

3.3 Flow Chart for Contracts Unit in the Tool Subcontractor ...... 25

3.4 for the Tool Subcontractor ...... 30

4. EXAMPLES USING THE TOOL SUBCONTRACTOR ...... 39

4.1 Loop-Statement Example and Valid Contracts ...... 40

4.2 If-Statement Example and Invalid Contracts ...... 43

5. CONCLUSION AND FUTURE ENHANCEMENTS ...... 49

Appendix A. Project Source Code ...... 52

References ...... 85

x

List of Tables

Tables Page

1. Table 2.1 Client-supplier example of design by contract ...... 6

2. Table 3.1 List of the visitor classes in the tool Subcontractor ...... 22

xi

List of Figures

Figures Page

3. Figure 1.1 State diagram of the programming code in the tool Subcontractor ...... 3

4. Figure 3.1 Subcontractor in Eclipse architecture ...... 13

5. Figure 3.2 Converting from source code to TreeViewer in tab Generate (a) and tab

Delete (b) in the tool Subcontractor ...... 18

6. Figure 3.3 Sequence diagram of a JFace viewer in the tool Subcontractor ...... 19

7. Figure 3.4 Class diagram for the visitor pattern in the tool Subcontractor ...... 21

8. Figure 3.5 Sequence diagram of the tool Subcontractor ...... 25

9. Figure 3.6 Flow chart of the Contracts Unit in the tool Subcontracto ...... 29

10. Figure 3.7 Class diagram for the package dialogbox in the tool Subcontractor ...... 33

11. Figure 3.8 Class diagram for package programminglogic in the tool Subcontractor . 37

12. Figure 4.1 Source code of the Factorial example with a precondition and

a postcondition ...... 41

13. Figure 4.2 Dialog box after writing the loop invariant and choosing loop statement 42

14. Figure 4.3 Source code after generating and inserting subcontracts ...... 43

15. Figure 4.4 Source code of Account example with a precondition and postconditions 44

16. Figure 4.5 The output of OpenJML shows invalid postcondition ...... 44

xii

17. Figure 4.6 Dialog box that shows the chosen if-statements ...... 45

18. Figure 4.7 Source code after generating subcontracts ...... 47

19. Figure 4.8 The output of OpenJML shows invalid postcondition and assert

statement ...... 48

xiii

1

1. INTRODUCTION

A plethora of applications are created every day; however, most of them are eliminated after a while for different reasons. One reason is that these applications are not robust enough to face attacks and/or incorrect entry of data. Introducing Design By Contract

(DBC) [1] in software development processes and providing DBC support in the programming environment can improve the reliability of produced software. There are multiple tools that support DBC for Java such as Java Modeling

Language (JML) [2], Jass [3], and Contracts for Java (C4J) [4]. In these tools, DBC assists in improving the quality of the code. However, one main limitation in these DBC tools is that when the code is lengthy, it is still difficult to locate errors. For example, if a program has 100 lines, and the precondition is valid, but the postcondition is not valid.

The programmer needs to search the whole code to find the errors. If inference rules of programming logic [5] can be used to automatically generate subcontracts, and if the subcontracts can be automatically inserted into the large source code for if-statements and/or loop-statements, the large verification task can be automatically partitioned into smaller ones. Therefore, automating the generation of sub assertion statements aid in spotting the places of errors and tracing the program.

For this purpose, a tool called Subcontractor was built upon an open source DBC tool called OpenJML [6]. Subcontractor is a developed Eclipse plugin that provides the benefit of automatically generating and adding into code subcontracts in terms of JML assert statements using inference rules for if-statements and/or loop-statements.

2

Subcontractor enhances DBC, dynamic program analysis technique, with programming logic, which is originally for static program verification. When these rules are integrated with DBC tools, these tools can help locate defects in the code.

Figure 1.1 illustrates the life cycle of the programing code in response to different events.

First, the programmer provides the source code and design contracts in terms of preconditions and postconditions. Then, OpenJML Runtime Assertion Checking (RAC) can be used to verify the preconditions, postconditions. If the contracts are valid, there is no need to add subcontracts. However, if the contracts are not valid, the tool

Subcontractor can be used to automatically generate and insert subcontracts for the programmer for the selected if-statements and/or loop-statements. Again, OpenJML

Runtime Assertion Checking (RAC) can be used to verify the preconditions, postconditions, and JML assert statements. The output after running OpenJML can facilitate finding the locations of the errors. Afterwards, the programmer can modify the code, and then uses OpenJML to check the contracts until the errors are fixed.

The rest of this report is structured as follows: Chapter 2 provides important concepts that are used to construct the tool Subcontractor. In addition, it gives an overview of two DBC tools and provides the justification of enhancing one of them using inference rules of programming logic. Chapter 3 describes the design and implementation of the tool

Subcontractor including how Java libraries and Eclipse plugins are used. Chapter 4 presents two examples using the tool Subcontractor, one with valid contracts and the other with invalid contracts. Chapter 5 summarizes the purpose of the tool Subcontractor

3 and provides multiple future enhancements.

Figure 1.1 State diagram of the programming code in the tool Subcontractor

4

2. BACKGROUND AND RELATED WORK

2.1 Programming Logic

Axiomatic semantics for a programming language is specified as programing logic, which has both axioms and inference rules. The axioms and inference rules are used for program verification, a static approach to reasoning about program correctness [5]. The axioms and inference rules are defined in the format of Hoare logic triple {P} C {Q} [1], where P is the precondition, Q is the postcondition, and C is the implementation code. A

Hoare triple for a program specification is valid if the precondition P is satisfied and the code C is executed. In this case, the postcondition Q is guaranteed to be true. However, a

Hoare triple is invalid if the precondition P is true and the code C is executed, but the postcondition Q is false. When the precondition is false, the postcondition might be true or false [7], i.e., the program does not have to guarantee anything when preconditions is not satisfied. While the axioms are for primitive statements, the inference rules are for compound statements. For example, the inference rule for any sequence of statements is in the following form [5]:

{P} S1 {R}, {R} S2 {Q}

{P} S1; S2 {Q}

The inference rule for if-statements is in the following form [5]:

{P and B} S1 {Q}, {P and (not B)} S2 {Q}

{P} if B then S1 else S2 {Q}

5

For loop-statements, the inference rules can be written in the following form, taking into consideration that Inv is the loop invariant [5].

P => Inv, {Inv and B} S {Inv}, Inv and (not B) => Q

{P} while B do S {Q}

The loop invariant should be true before and after each execution of the loop body, but the loop invariant does not have to be always satisfied in the middle of each execution of the loop body [7].

2.2 DBC

DBC was first introduced by , and was first implemented in Eiffel programming language [1]. DBC is a dynamic approach. A design contract for a class consists of preconditions and postconditions for methods, and class invariants.

Preconditions, postconditions, and invariants are written as Boolean assertions that are evaluated at runtime. Preconditions are checked before entering the functions, while the postconditions are checked after the functions executions. In the case of class invariants, the conditions must be satisfied when the class instances are created, and before and after functions are executed [1]

DBC adds a great value to the software development process. In addition, it improves the test phase by automatically checking the DBC assertions when the program is executed.

As stated by Dijkstra [8 , p7], “Program testing can be used to show the presence of bugs, but never to show their absence!” According to Meyer [1], using proper contracts help in validating against the program specification defined in terms of its preconditions and

6 postconditions, which leads to program correctness. DBC also promotes the program robustness which means that programs can handle abnormal behaviors. Correctness and robustness together form a reliable software.

A commonly cited example to understand DBC is the client-supplier example [1]. Both parties have some obligations and they are expecting benefits in return. In DBC, the function call serves as the client while the implemented function serves as the supplier. A precondition and postcondition form a contract for a method between the caller and callee. The function call, the client, needs to fulfill a precondition to expect the postcondition that needs to be guaranteed by the function, the supplier. For example, if there is a method that calculates the factorial of a number, the precondition is supposed to check whether the number is greater than or equal to zero, while the postcondition should be the factorial of the provided number. These obligations and benefits can be expressed in Table 2.1. Once the precondition is violated, the method should not be executed and an exception should be raised. However, if the precondition is satisfied, but the postcondition is not fulfilled, there are likely errors in the implemented function.

Table 2.1 Client-supplier example of design by contract Party Obligations Benefits Provide numbers that are Get the factorial of the Function Call (Client) greater than or equal zero. number that is provided. Do not need to calculate Function Implementation Compute the factorial of the the factorial of the (Supplier) number that is provided. numbers that are less than zero.

7

DBC is not exclusively for constructing assertions for methods and classes. In general,

DBC is a vital programming methodology that facilitates verification, testing, and debugging. Moreover, it is a way to document the responsibilities of each method or routine. A design contract is an abstraction of the semantic of the code being developed.

Users of the code understand the functionality of the code without seeing the implementation details. Nevertheless, it is more beneficial than informal comments in the code, since the contract can be evaluated at runtime to help programmers locate the error and ensure the consistency between the code and the contracts. In addition, comparing

DBC with defensive checking, which is a programming methodology that offers multiple checking to detect any type of errors, DBC is more effective since it is not based on the redundant checking [2]. For these reasons, there should be more efforts to promote application of DBC in programming languages.

According to Oliveira e Silva and Francisco [9], there are multiple requirements for proper DBC implementation. The first requirement is that the tool needs to support the check of different types of assertions such as preconditions, postconditions and class invariants. The second requirement is that assertions should be as close as possible to the object that is being specified. Moreover, the assertions can be accessed without modifying its implementation, since the implementation code can be modified without affecting the contracts; similarly, the contracts can be edited while preserving the implementation code. One of the object-oriented characteristics is inheritance, and DBC should not eliminate that. Another requirement is that DBC should be part of the documentation. Lastly, error handling techniques should be involved in any DBC tool to

8 handle abnormal behaviors in case of error occurrences. However, based on the study [9] of following tools: Jass, Modern Jass, JML, Cofoja, ezContract, and DbC4J, none of them fully support the last requirement of proper handling of errors.

2.3 DBC in Java

As other programming languages, Java does not support DBC as a built-in feature. Java has the basic assertion facility using the assert keyword. Since the simple assert facility will not satisfy the DBC requirements that are mentioned in section 2.2, there are different third party tools that support DBC for Java programing language, such as Java

Modeling Language (JML) [2], Jass [3], and Contracts for Java (C4J) [4].

DBC can be implemented in a language in different ways, such as the preprocessor approach, Java methods, and behind the scene approach. In the preprocessor approach, developers write contract elements using annotations that reside in comments, or pure comments. These comments are non-compilable, thus, contract elements are preprocessed to be part of the original program using bytecode instrumentation [10]. By inserting the contracts in the program, the resulted code can be compiled normally. There are advantages of using this method in applying DBC. First, since the code is converted from a non-compilable form to a code that can be compiled, there is no need to develop a compiler to parse the DBC elements. The developer can use pluggable annotation processing API. This API is part of the Java compiler and helps in the process of annotations. However, developers also have the option to develop annotation processing tools which could require more effort. Another advantage could be that DBC elements

9 and implementation codes are written in the same module.

According to Henne-Wu, Mitchell, and Zhang, the preprocessor approach is a common approach in DBC [10]. In the following sections, two different DBC tools that support the preprocessor approach and Eclipse, which is an IDE for Java programming language, are discussed in detail. The reason behind choosing Eclipse is that it is one of the most popular IDEs for Java programming language, and it offers a library that facilitates accessing the source code and editing the code [11].

2.3.1 COFOJA

COFOJA stands for COntracts FOr JAva. It is a DBC tool that was developed by interns at Google in 2010. It has been an open sourced tool since 2011 [12]. Preconditions, postconditions, and class invariants are written in forms of annotations. It borrows a lot of concepts from Modern Jass [13]. Processing contracts can be done in two stages. First, the entire code, with contracts, converted into .class files and contract files using annotation processing which is part of the Java compiler. Second, using Java bytecode manipulation, the contracts bytecode is inserted into the corresponding class bytecode.

Because the bytecode files, contracts files, and class files, are separated during the compilation time, that gives protection to the class files from modifications. Another advantage is that if the code is error-free, but its contracts have errors, it is possible to execute the code normally, because the contracts are saved in a separate file [14].

COFOJA uses @Requires for preconditions, @Ensures for postconditions, and

@Invariant for class invariants. In addition, @ThrowEnsures and @Contracted are other

10 annotations that can be used. A primary goal of COFOJA is usability since any assertion statement that can be written in Java can also be used in the COFOJA clauses [12].

COFOJA supports inheritance, since a child of a class can inherit their parent contracts.

COFOJA also supports exceptions. For example, @ThrowEnsures is a complement for

@Ensures. When a method has both @ThrowEnsures and @Ensures, and the exception is thrown, the postconditions will not be checked and the condition in

@ThrowEnsures will be checked [12].

As mentioned in the technical report of COFOJA [14], this tool has inconsistency in reporting errors. For instance, this tool might report errors that are not related to source code. In addition, COFOJA does not support an annotation that can be verified at some point in the code. For example, a user cannot insert a COFOJA annotation to be verified inside an if-statement within a method.

This tool was experimented to operate as a fundamental component in verifying the contracts in the tool Subcontracts. However, since COFOJA cannot be used to insert subcontracts in terms of inference rules for if-statements and loop-statements inside a method, COFOJA will not facilitate achieving the purpose of the tool Subcontractor.

2.3.2 JML

One of the tools that support DBC is Java Modeling Language (JML), which is an open source tool [2]. It was developed at Iowa State University by Gary Leavens and his colleagues. JML is a specification language that addresses both the behavioral and the

11 syntactic aspect of Java programming language. JML tools assist different fields such as static checking, DBC, JML compiler, and documentations [2]. In this section, the focus is on the DBC aspect of JML.

JML expresses contracts using special annotation comments, /*@ ... @*/, for multiple lines. For a single line specification, the annotation starts with //@. Contracts are written in the form of comments to be ignored by Java compiler in case the specifications affect the performance negatively. When contracts are taken into consideration, JML compiler evaluates the contracts as Boolean expressions. The keyword requires specifies the precondition, while ensures clause determines the postconditions. To verify a contract at a specific point in the code, JML assert keyword can be used. If the preconditions of a method are not satisfied, the method will not be executed. On the other hand, if the preconditions are satisfied, the program will be in a proper pre-state. In this case, if the postconditions are satisfied, the program will be in a normal post-state, however if there is an exception in the code and the program does not terminate normally, the program will be in an exception post-state [2].

OpenJML is the current version of the basic JML for the current Java. There are efforts to include different features in this version. According to the official page of OpenJML [6], the features that are covered are Eclipse support, static and dynamic checking, and auto testing cases. OpenJML extends JML by introducing new expressions, and more flexibility in the contracts for methods.

One advantage of JML is usability, since it extends Java programming language with

12 more quantifiers. As mentioned earlier, there are a lot of efforts that are devoted to build tools that support different aspects of this specification language. These tools are for verifications, parsing, runtime checking, and testing [2]. Since JML has continuous progress and attention, this counts as another advantage.

There are different methods for dealing with specifications. Extended Static Checking

(ESC) is a way to check specifications at compile time. ESC can be used to try to prove the correctness of the specifications [15]. First ESC checks the programming errors such as uninitialized variables and out-of-bounds index. Afterwards, ESC executes the specification of the code by the automated theorem prover [16]. Another method for checking the program contracts is Runtime Assertion Checking (RAC). RAC tests the correctness of the program at runtime. RAC converts the program specifications into assert statements. These assert statements will be inserted into the program to form an instrumented program that can be used to see whether the contracts are violated during runtime [17].

OpenJML is installed as a plugin in Eclipse before creating the tool Subcontractor. The plugin Subcontractor uses OpenJML without modifying its source code. OpenJML

(RAC) plugin is used to do two main verification tasks. First, OpenJML (RAC) checks the preconditions and the postconditions before generating the subcontracts. Moreover, it is used to verify the JML assert statements after the tool Subcontractor generates the subcontracts based on the inference rules.

13

3. DESIGN AND IMPLEMENTATION

3.1 External Components Related to the Tool Subcontractor

Figure 3.1 demonstrates the Eclipse architecture and the relationships between Eclipse

elements and the plugin Subcontractor. Figure 3.1 is based on the diagram that is

presented in [18] with modification and extension to cover the scope of the tool

Subcontractor. Sections 3.1.1, 3.1.2, 3.1.3, and 3.1.4 focus on explaining these

components and how they relate to the tool Subcontractor.

Figure 3.1 Subcontractor in Eclipse architecture

3.1.1 Eclipse

Eclipse is a popular integrated development environment (IDE) with graphical user interfaces that facilitates the development process. Eclipse supports multiple operating systems. The main language that is supported in Eclipse is Java, but there are other

14 languages such as C++, C#, Perl, PHP, and JavaScript that can be supplemented using plugins [18].

Eclipse is an open source environment, and one of its neat functionalities is its expandability. The user can add/extend a feature by adding a plugin. For example, in

Figure 3.1, PDE extends the functionalities of JDT, and the developed Subcontractor tool extends the capabilities of PDE, JDT, and OpenJML. Plugins can provide a variety of functional and non-functional requirements such as testing, diagramming, compiling, and more. The Eclipse marketplace website has a myriad of plugins. The main advantage of having plugins is that it makes the component of this environment loosely coupled.

Moreover, it maintains lightweight core application, since the user has the choice to install only the needed plugins [18].

One reason for choosing Eclipse is that it is an open source application that is built upon plugins. Thus, it is easier to extend an IDE with a plugin than establishing a basic IDE with the proposed idea of the tool Subcontractor. In addition, according to RebelLabs’ report in 2012 [19], this application is the most used IDE for Java programming. Eclipse provides libraries that have the benefit of accessing and modifying the source code.

3.1.2 Plugin Development Environment (PDE)

The Plugin Development Environment (PDE) is a plugin that can facilitate building other plugins, features, and Rich Client Platform (RCP) applications. When PDE is installed in the Eclipse platform, new functionalities can be added to support the plugin life cycle, such as establishing, debugging, running, maintaining, and publishing a plugin [20]. The

15 developed plugin Subcontractor and OpenJML cannot be built without installing the PDE plugin.

3.1.3 Java Development Tools (JDT)

Java Development Tools (JDT) is one of the fundamental plugins in Eclipse. JDT includes five components which are: User Interface (UI), Annotation Processing Tool

(APT), text, debug, and core. The Subcontractor plugin deals with multiple classes in the

JDT core component [21].

One of the JDT core functionalities is developing an application. Moreover, it provides the access to the source code in different forms, such as a Java model or abstract syntax tree (AST) to modify the source code. A Java model represents a Java project in Eclipse.

It contains different components such as IPackageFragment, IPackageFragmentRoot,

IJavaProject, ICompilationUnit, IType, Ifield, and IMethod - which illustrates package, src folder / bin folder, Java project, Java source file, type, field, and method respectively.

The other representation is AST, which is an alternative to the DOM tree of an XML file.

AST is more informative than a Java model. As a result, it takes longer to be created than the Java model. A node in the AST can represent a declaration using

VariableDeclarationFragment, a method using MethodDeclaration, or SimpleName for any string that is not a reserved word in Java. AST is derived from ICompilationUnit, which is a component of a Java model [21].

The tool Subcontractor handles the source code using AST because the first approach, the

Java model, does not contain enough details about the source code. For example, in the

16

Java model, the name, signature, and return type of a method can be retrieved. Moreover, the content of that method cannot be provided, which is an important component for the tool Subcontractor to analyze and to find the if-statements and loop-statements.

3.1.4 JFace

JFace provides collection of classes and frameworks that deal with user interface components. JFace is designed to work with SWT. SWT is an open source interface toolkit that provides the native widgets and the basic functionalities with high performance. JFace extends certain SWT widgets by providing actions and viewers mechanisms. For example, the JFace TreeViewer widget extends SWT tree widget. In the

SWT tree, the items need to be defined, and it is also necessary to specify the parent/child relation between these items. The resulting tree will be static. It is also possible to add selection listener. However, in the JFace TreeViewer, the tree needs to be assigned to a data model. Each data model has a label provider and content provider. This supports having dynamic content for the TreeViewer. Moreover, JFace viewers will allow the user to add a custom behavior. For example, the user can specify how the tree will be filtered, searched, and labeled. The next subsections provide details about multiple classes of

JFace and its relation to the tool Subcontractor [22].

3.1.4.1 Viewers

A JFace viewer is an SWT widget with more complex features. Each viewer is connected to a label provider and content provider which is connected to a domain/data model [22].

Figure 3.3 demonstrates the relation between the latter objects. There are different types

17 of viewers such as TableViewer and TreeViewer. A viewer life cycle starts with initializing the viewer, setting input, and ends with disposing the viewer.

The TreeViewer was chosen in the tool Subcontractor to support dynamic content. When the subcontracts need to be generated, the TreeViewer presents the locations of if- statements and/or loop-statements within a method. In other words, for each method in the source code, TreeViewer displays the name of the method, and a list of if-statements and loop-statements in the order that they appear in the source code. On the other hand, if the user chooses to delete the subcontracts, the TreeViewer illustrates the different methods. Figure 3.2 shows the source code and the corresponding TreeViewer in the tab

Generate (a) and tab Delete (b). The TreeViewer has a listener that is triggered when an element in the tree is selected. If a user selects an item in the tree, it changes from checked to unchecked or vice versa, and adds the selected items in a list. This list is then sent to be used to manipulate the code.

18

Figure 3.2 Converting from source code to TreeViewer in tab Generate (a) and tab

Delete (b) in the tool Subcontractor

3.1.4.2 Content Provider

For each viewer, there is a need to assign a content provider to it. In the case of

TreeViewer, the content provider is responsible for traversing the data model and

19 specifying the elements in parent/child structure for displaying purposes [23]. As Figure

3.3 illustrates, whenever there are modifications in the input of the TreeViewer, the

InputChanged() method of the content provider should be invoked. Another essential method in the content provider is getElement(). This method calls another method which is getChildren(). The latter can return the children of the passed parent.

3.1.4.3 Label Provider

After providing the content of the tree from the content provider, the label provider is called for each element to provide a string and icon, if there are any, then display the value in the tree through setText() and setImage() respectively [24] , as shown in Figure

3.4. In other words, the label provider simply converts the content/data to image/text.

Figure 3.3 Sequence diagram of a JFace viewer in the tool Subcontractor

20

3.1.4.4 ASTVisitor

One of the popular in is the visitor pattern. The visitor pattern can be used to represent an operation for different elements instead of representing the same operation for every element. One advantage of this pattern is that the operation can be extended without changing the elements. However, adding a new element is costly, since there is a need to add new methods in each visitor class. Another benefit of using the visitor pattern is that the operation is separated from the structure.

This pattern can be implemented using a visitor class that has visit() methods for each element. These methods accept a call with one argument, which is a reference to the original element. In order to use the visitor pattern to perform one operation for different elements, an instance of the visitor class needs to be created first. Afterwards, there is a need to call the accept() method with a pointer to an element. The accept call in turn calls the visit() method. The visitor pattern can automatically help in dispatching to a specific method based on the node type, instead of checking the node type and then dispatching based on that [24].

In the tool Subcontractor, the visitor pattern is used by extending ASTVisitor class. Table

3.1 illustrates the classes that use the visitor pattern, the classes that has the accept() method, the different node types used in these classes, and the functionalities of these classes. Moreover, Figure 3.4 shows the structure of the visitor pattern in the tool

Subcontractor. For example, ContractsManager is a subclass of ASTVisitor.

ContractsManager has two visit() methods: one for LineComment and one for

21

BlockComment. Both methods do one task, which is collecting the preconditions and the postconditions. These methods are called from an accept() method with a pointer to a

Comment.

Figure 3.4 Class diagram for the visitor pattern in the tool Subcontractor

22

Table 3.1 List of the visitor classes in the tool Subcontractor

Classes Name Nodes Functionalities

Extends ASTVisitor: Collects the different preconditions and ContractsManager LineComment postconditions that reside in line or block Has accept(): BlockComment comments, and then saves them into two Generation different HashMaps Extends ASTVisitor: PlacingSubcontracts Adds the contracts in the right place WhileStatement based on the inference rules and on the IfStatement Has accept(): type of the node. Generation Extends ASTVisitor: Generation TypeDeclaration is a class declaration. For each method in a class, the upper and lower limits of contracts that are allowed TypeDeclaration for a specific method are calculated. In Has accept(): addition, it appends all the preconditions Generation and postconditions in that limits in two different strings.

Extends ASTVisitor: Gets the body of the methods inside a DialogboxCreation class that are going to be used in the TypeDeclaration following class. In addition, the methods Has accept(): inside the class are added in data model DialogboxCreation of the TreeViewer.

Extends ASTVisitor: DialogboxCreation WhileStatement While-statements and if-statements are Has accept(): IfStatement added in data model of the TreeViewer. DialogboxCreation

Extends ASTVisitor: GettingReturnStatemen Returns the ReturnStatement of a t ReturnStatement method. Has accept(): Generation Extends ASTVisitor: SubContractsManager Provides the subcontracts that are inside LineComment Has accept(): a method to be deleted. Deletion

23

3.1.4.5 ASTRewiter

One approach to editing the abstract syntax tree is prettyprinting, which is simple and easy to implement, as it does not maintain the locations of the comment and the source code in the modification process. The second approach uses textual edits. In this approach, each node has a corresponding offset and length. When changes are made, the modifications are applied to the AST directly, or into ASTRewrite and then to the AST.

This approach is more complicated to implement, but it preserves the code formatting

[25].

The tool Subcontractor uses textual edits since it is important to preserve the locations of the comments in the source code. More specifically, the modifications in the source code are applied to an instance of ASTRewrite, then to the AST. This protects the AST from unwanted changes. For example, if the modification process is interrupted, then the final

AST will not be touched since the modifications are not final.

3.1.4.6 Comment

An ASTNode can be an Expression, VariableDeclaration, Statement, or Comment. There are types of comments which are line comments, block comments, and doc comments

(Javadoc).

According to Eclipse documentation, the AST for a compilation unit has the nodes in a tree structure. Each node has the source code, a start point, and an end point. These nodes could be any part of the code except the whitespaces and the comments. The AST is not

24 preserving information about the comments and the whitespace [26].

The tool Subcontractor uses OpenJML preconditions, postconditions, and assert statements that reside in comments. It is essential to access to the comments and find its locations to form the subcontracts. However, it is problematic to deal with comments and find its location since the comments do not exist in the AST. This issue can be addressed through calling accept() method for each comment in the list that is returned from getCommentList().

3.2 Sequence Diagram for the Tool Subcontractor

Figure 3.5 represents the interactions between the major components in Subcontractor.

The following steps illustrate how the objects operate based on Figure 3.5:

Step 1. The user adds preconditions and postconditions into the source code and right

click on the (.java) file and choose (Generate/Delete Subcontracts).

Step 2. The parser will take the source code as an input, and generate the abstract syntax

tree and send it to the dialog box.

Step 3. In the tab Generate, the TreeViewer in dialog box illustrates the different methods

that are inside each class and the if-statements and/or loop-statements in the order

they appear. In the tab Delete, the TreeViewer shows the different methods.

Step 4. In the tab Generate, the user can choose the loop-statements and/or if-statements

and enter the loop invariants for the chosen loop-statements that he/she wants to

25

generate the subcontracts. In the tab Delete, the user can choose the methods that

he/she wants to delete the subcontracts.

Step 5. In the contracts unit, the system generates subcontracts based on the type of the

statement, whether it is an if-statement or/and a loop-statement. In case of

deletion, the contracts unit collects the subcontracts, and then deletes them.

Section 3.3 explains this unit in details.

Step 6. In manipulation, the automatically generated subcontracts will be inserted in the

chosen if-statements and/or loop-statements in case the tab Generate is selected.

In case of deletion, the collected subcontracts will be deleted.

Figure 3.5 Sequence diagram of the tool Subcontractor

3.3 Flow Chart for Contracts Unit in the Tool Subcontractor

Section 3.2 provides the sequence diagram for the main components in the tool

Subcontractor. This section presents the major component Contracts Unit that represents

26 the stages in the contracts lifecycle. The following steps are illustrated in Figure 3.6:

Step 1. The user enters the preconditions and postconditions along with the

implementation code in the editor.

Step 2. The user invokes the dialog box by right-clicking on the Java file and choosing

Generate/Delete Subcontracts.

Step 3. The source code will be traversed.

Step 4. The dialog box will pop up with tab Generate selected as a default. The

TreeViewer shows the methods in the source code and the corresponding if-

statements and loop-statements. The user can also go to step 18.

Step 5. The user can choose the if-statements and/or the loop-statements and enter the

loop invariants for the chosen loop-statements.

Step 6. The user can click on “Generate”, or go to step 16.

Step 7. Check if the user checked an item. If not, inform the user and go back to step 6.

Step 8. Check if the user entered the loop invariants for the checked loop-statements. If

not, inform the user and go back to step 6.

Step 9. Check if there are already subcontracts in the methods that have the selected

items. If not, inform the user and go back to step 6.

Step 10. Check if there is an if-statement and/or loop-statement. If not, inform the user

27

and go back to step 6.

Step 11. Check if there is a precondition and/or postcondition. If not, inform the user and

go back to step 6.

Step 12. The source code will be traversed.

Step 13. Store the preconditions and the postconditions into two HashMap structures

with their line numbers.

Step 14. Visit every method in the code and do the following:

a. Calculate the upper limit and lower limit for the allowed range of contracts of

a specific method.

b. Append all the contracts in that range into two strings: one for preconditions

and one for postconditions.

c. Visit every if-statement and/or loop-statement and place the inference rules.

Step 15. Go on to step 27.

Step 16. The user can click on “Cancel”, or can go back to step 6.

Step 17. Go on to step 27.

Step 18. The user can choose the tab Delete, or go back to step 4.

Step 19. The user chooses the methods that he/she wants to delete its specifications.

28

Step 20. The user can click on “Delete”, or can go on to step 26.

Step 21. Check if the user checked an item. If not, inform the user and go back to step

20.

Step 22. The source code will be traversed to see the contracts for the selected items.

Step 23. Check if there are contracts in the selected methods, if not, inform the user and

go back to step 20.

Step 24. Delete the contracts for the selected items.

Step 25. Go on to step 27.

Step 26. The user can click on “Cancel”, or can go back to step 20.

Step 27. The dialog box will be closed and the modifications, if there are any, will be

applied.

29

Figure 3.6 Flow chart of the Contracts Unit in the tool Subcontracto

30

3.4 Class Diagram for the Tool Subcontractor

There are two packages in the tool Subcontractor. The first package is csus.masterproject.DBC.programminglogic.dialogbox. This package is responsible for creating the dialog box, managing its contents, and sending the desired information to the second package. This package has the following classes as shown in Figure 3.7:

• AbstractCategory.java: This abstract class is the domain model of the

TreeViewers. Each AbstractCategory instance represents one element in the

TreeViewer, and has a parent, name, id, type. The id is a unique identifier that

identifies an AbstractCategory. If the class has two while-statements that have the

same expression, the id can identify these statements. The id is based on the order

of a node in the class. For example, if there is a program that have a loop-

statement, sequence statements, and then an if-statement, then the loop-statement

id is 1 and the if-statement id is 2. The parent field is the parent node of the

AbstractCategory instance in the abstract syntax tree. The name field is the name

of the method in case of a node is a MethodDeclaration, or the condition of the if-

statement or the loop-statement. This class has the following methods:

addSubCategory, getSubCategories, hasSubCategories, getName, getParent,

getId, and toString.

• AllCategory.java: This class extends the AbstractCategory class. This class serves

as a data model for the TreeViewer in the tab Generate. This class has an

additional field which is type, and a method getType. The type field can represent

31

either a TypeDeclaration, MethodDeclaration, WhileStatement, or IfStatement.

The type of the node is an integer that can be 1 for if-statements, 2 for while-

statements. This field also can be helpful to know when to dynamically create

loop invariant text boxes.

• MethodsCategory.java: This class also extends the AbstractCategory class. This

class only represents the MethodDeclaration nodes. This class serves as a data

model for the TreeViewer in the tab Delete. This class has two local fields which

are startline and endline. These fields play an important role to know start line and

end line of a method. In the deletion process, the JML assert statements in that

limits should be deleted. This class has the following methods: getStartLine and

getStartLine.

• DialogboxControls.java: The components of the dialog box such as buttons,

labels, and TreeViewers are created in this class. This class establishes the user

interface for both the tab Delete and tab Generate. This class has the following

methods: createControls, getTreeViewer, GetLabelWarning, and

createImageDescriptor.

• DomainModelContent.java: This class provides the content of the domain model

by instantiating AllCategory.java. The data of the TreeViewer is collected by

using the visitor pattern for each TypeDeclaration, MethodDeclaration,

WhileStatement, and IfStatement. This class has the following methods:

addNodeContent, addLoopInv, and visit for each type of node.

32

• DialogboxCreation.java: The controls are built in DialogboxControls.java. The

content provider for the tree viewer is set to be

CategoryTreeContentProvider.java. This class has the following methods:

createContents and main.

• CategoryTreeContentProvider.java: This class provides the content for The

TreeViewer that is created in DialogboxCreation.java. This class is an

implantation of the interface ITreeContentProvider. This class maps between the

domain model and the structure of the TreeViewer. The domain model in this

package is represented in a collection of classes: AbstractCategory.java,

MethodsCategory.java, and AllCategory.java. This content provider traverses the

data structure in the data model classes and observes the relationship between the

child and the parent to display in a tree form. This class has the following

methods: getChildren, getElements, hasChildren, and getParent.

• CategoryTreeLabelProvider.java: This class facilitates linking between the model

object and the displayable labels of the TreeViewer widget in

DialogboxCreation.java. The label provider is responsible for specifying the text

label and the icon the are displayed in the tree for each element in the content

provider. This class has the following methods: getText, getImage, getIdentifier,

getType, getStartLine, getEndLine.

33

• InvEditor.java: This class is to convert an element in the TreeViewer into a

textbox and change the setting for that. This class has the following methods:

InvEditor and getLayoutData.

• LoopInvEditing.java: This class is to enable editing an element in the TreeViewer

if the element is a loop invariant. Also, this class is to set and get the value of the

loop invariant. This class has the following methods: getValue, setValue, and

canEdit.

Figure 3.7 Class diagram for the package dialogbox in the tool Subcontractor

34

The second package is csus.masterproject.DBC.programminglogic. This package has different classes that support traversing the source code, finding the contracts, forming the subcontracts, and manipulating the source code. This package has the following classes as shown in Figure 3.8:

• AddSubContractsActionDelegate.java: This is an implementation of

IObjectActionDelegate interface. This class is triggered on the right-click action

of a specific Java class. It facilitates specifying the active part of the execution,

which is the Java class that a user wants to add subcontracts to. This class also

forward the active parts to the ParsingAssistant.java class. This class has the

following methods: setActivePart, run, and selectionChanged.

• ParsingAssistant.java: This class receives the ICompilationUnit, which is the Java

file that is chosen to generate subcontracts to it. Then, the ICompilationUnit is

parsed to produce CompilationUnit that is sent to be presented in the TreeViewer.

The CompilationUnit also can be used in generating or deleting subcontracts. This

class has the following methods: treeviewerparser, contractparser, contractparser,

and parse.

• ContractsManager.java: There are two main HashMap data structures for the

preconditions and postcondition that are collected using the visitor design pattern

for LineComment and BlockComment nodes. This class has the following

methods: visit for each type of node, getPreconditions, and getPostconditions.

35

• GettingReturnStatement.java: This class provides the return statement for a

method. The return statement variable can replace the JML keyword /result in a

JML assert statement inside a method. This class has the following methods: visit

for ReturnStatement, and getretstsat.

• Generation.java: After creating ASTRewrite, the comments are retrieved from

ContractsManager.java. Then, it forms the subcontract based on the line number.

For each method, one string forms the preconditions and the other string forms the

postconditions. Another class, PlacingSubcontracts.java, is called to place the

contracts in the if-statements or/and loop-statements. Lastly, the modifications are

applied in the source code. This class has the following methods:

beforeManipulate, manipulate, and afterManipulate.

• PlacingSubcontracts.java: This class visits each if-statement and loop-statement

and form the different subcontracts based on the inference rules. After that, the

subcontracts are inserted in the right place in the selected if-statements or loop-

statements. This class has the following methods: visit for each node type,

loopPlacing, getHasifORfor, and setHasifORfor.

• Deletion.java: After creating ASTRewrite, each comment that is retrieved from

getCommentList will be visited in the SubContractsManager.java. After that, the

modifications, if there are any, will be applied. This class only has the method

manipulate.

36

• SubContractsManager.java: This class visits every LineComment and deletes the

comment if the line of that comment is in the range of the method that is selected.

This class has the following methods: visit for every LineComment,

getDoesExist, and setDoesExist.

37

Figure 3.8 Class diagram for package programminglogic in the tool Subcontractor

38

The Figure 3.7 and 3.8 are connected by instantiating an object of ParsingAssistant class in the second package and use it in DialogboxCreation class in the first package. This object along with two methods are invoked when the generate and delete buttons and clicked.

39

4. EXAMPLES USING THE TOOL SUBCONTRACTOR

In this chapter, examples using the tool Subcontractor are provided with screenshots for each step to show in detail the functionalities of this tool. The following steps are for the examples that have contracts that are verified to be true:

Step 1. Show the source code with preconditions and postconditions.

Step 2. Show a screenshot of the dialog box with selected elements.

Step 3. Show the code after inserting the subcontracts.

However, if the example has preconditions or postconditions that are not valid, then the steps are as follows:

Step 1. Show the source code with preconditions and postconditions.

Step 2. Show a screenshot of the output of OpenJML (RAC).

Step 3. Show a screenshot of the dialog box with selected elements.

Step 4. Show the code after inserting the subcontracts.

Step 5. Show a screenshot of the output of OpenJML (RAC).

The reason for having two extra steps is to show the output of OpenJML before and after inserting the subcontracts, and how these subcontracts narrow down the process of finding the place of the error.

40

To experiment the tool Subcontractor, the implementation code should be run.

Afterwards, a new instance of Eclipse will pop up with all views, features, plugins, and the editor. After that, a Java project can be created from File > New > Java project. Then, a class can be added by right-clicking on the project, then New > Class. The user can add code with design contracts and then right-click on the java file to add subcontracts.

4.1 Loop-Statement Example and Valid Contracts

Since the preconditions and the postconditions are valid, the first set of steps are followed in this example.

Step 1. The source code with preconditions and postconditions, as shown in Figure 4.1.

This program calculates the factorial of a number. The precondition is (n>=0 && f==1

&& k==1). The postcondition is (\result == (\product int I; 1<=I && i<=n; i)).

41

Figure 4.1 Source code of the Factorial example with a precondition and a

postcondition

Step 2. The dialog box with selected elements, as shown in Figure 4.2.

This dialog box will pop up after choosing (Generate Subcontracts) that is triggered by right-clicking on the Java file. In this dialog box, the TreeViewer shows two methods:

CalFactorial and main. The first method has a loop-statement, and a text box under it to specify the loop invariant. The other method does not have any loop-statement or if- statement.

42

Figure 4.2 Dialog box after writing the loop invariant and choosing loop statement

Step 3. The code after inserting the subcontracts, as shown in Figure 4.3.

For the loop-statement, the subcontracts are generated based on inference rules [5] as follows:

P => Inv, {Inv and B} S {Inv}, Inv and (not B) => Q

{P} while B do S {Q}

Where P is (n>=0 && f==1 && k==1), B is (k<=n), Q is (\result == (\product int I; 1<=I

&& i<=n; i)), and Inv is ((f * (\product int i; i<=1 && i<=k; i) == (\product int i; i<=1

&& i<=n; i)) && (k >=0)).

When comparing Figure 4.1 with 4.3, there are four inserted subcontracts, or smaller verification tasks. The first one is (0 <= n && f==1 && k==1) ==> (f * (\product int i;

1<=i && i<=k; i) == (\product int i; 1<=i && i<=n; i) && (k>=0)) which is based on the inference rule P => Inv. While the second and third verification tasks in terms of the

43 inference rules, {Inv and B} S {Inv}, are (f * (\product int i; 1<=i && i<=k; i) ==

(\product int i; 1<=i && i<=n; i) && (k>=0)) && k <= n, and the third one is ( f *

(\product int i; 1<=i && i<=k; i) == (\product int i; 1<=i && i<=n; i) && (k>=0)). The last verification task is (f * (\product int i; 1<=i && i<=k; i) == (\product int i; 1<=i && i<=n; i) && (k>=0) && !(k <= n)) è ((f == (\product int i; 1<=i && i<=n; i))) which is based on the following rule: Inv and (not B) => Q.

Figure 4.3 Source code after generating and inserting subcontracts

4.2 If-Statement Example and Invalid Contracts

Step 1. The source code with preconditions and postconditions, as shown in Figure 4.4.

This program does a simple withdraw or deposit operation for a bank account. The precondition is (amount > 0) while the postconditions are ((operation == "deposit") ==> balance == \old(balance) + amount ) or ((operation == "withdraw") ==> balance ==

\old(balance)-amount ).

44

There is an intentional error for testing in line 17 which is: this.balance = this.balance - amount; The statement should be this.balance = this.balance + amount;

Figure 4.4 Source code of Account example with a precondition and postconditions

Step 2. The output of OpenJML (RAC), as shown in Figure 4.5.

The output in the console shows that the postcondition is not satisfied.

Figure 4.5 The output of OpenJML shows invalid postcondition

45

Step 3. The dialog box with selected elements, as shown in Figure 4.6.

This dialog box will pop up after choosing (Generate Subcontracts) that is triggered by right-clicking on the Java file. The TreeViewer represents three methods; however, inside the second method there is an if-else-if-statement that has a nested if-statement in the else-if part. It is important to note that ASTVisitor interface deals with the else-if part as a separate if-statement. Therefore, the viewer shows three if-statements. In this example, the user chose the first two if-statements.

Figure 4.6 Dialog box that shows the chosen if-statements

Step 4. The code after inserting the subcontracts, as shown in Figure 4.7.

For the if-statements, the inference rules [5] are generated as follows:

46

{P and B} S1 {Q}, {P and (not B)} S2 {Q}

{P} if B then S1 else S2 {Q}

Where P is (amount > 0), B is (operation.equals("deposit")) for the first if-statement and

(operation.equals("withdraw")) for the second statement, and Q is (operation==

"deposit") ==> balance == \old(balance) + amount or (operation== "withdraw") ==> balance == \old(balance)-amount.

When comparing Figure 4.4 with 4.7, there are four inserted subcontracts, or smaller verification tasks. The first one is amount > 0 && operation.equals("deposit") which is based on the inference rule {P and B}. While the second verification task is the postcondition, the third verification task is amount > 0 && operation.equals("withdraw") which is based on the following rule: {P and not B }. The last subcontract is the postcondition.

47

Figure 4.7 Source code after generating subcontracts

Step 5. The output of OpenJML (RAC), as shown in Figure 4.8.

When comparing Figure 4.5 with Figure 4.8, there is an extra assert statement that is false. As a result, this assert statement facilitates finding the location of the error. In

Figure 4.5, since there is a false contract that is at the beginning of the source code, there is a need to search in the whole program to find where the error is. On the other hand, in

Figure 4.8, since there is an additional assert statement that is false, then the error should

48 be between these false contracts.

Figure 4.8 The output of OpenJML shows invalid postcondition and assert statement

49

5. CONCLUSION AND FUTURE ENHANCEMENTS

Although DBC is a technique for improving the reliability of software by ensuring the program correctness and robustness, the effectiveness of DBC diminishes with large blocks of code that has invalid contracts. The tool Subcontractor addresses this issue by generating and inserting subcontracts using inference rules for if-statements and loop- statements in the large pieces of code. After that, the contracts can be verified using the

DBC open source tool named OpenJML (RAC). By using the DBC tool enhanced by the tool Subcontractor, spotting the locations of the errors can be facilitated.

A number of future enhancements can provide additional features to the tool

Subcontractor. Handling nested structures is an important functionality that helps to enhance the usability of the tool Subcontractor. For instance, if there is a loop-statement that has if-statement inside it, there is a need to generate the subcontracts based on the inference rule of the loop-statement first in the following form:

P => Inv, {Inv and B1} if B then S1 else S2 {Inv}, Inv and (not B1) => Q

{P} while B1 do if B2 then S1 else S2 {Q}

Afterwards, the verification tasks in terms of the inference rules of the if-statement needs to be generated as following:

{Inv and B1 and B2} S1 {Inv}, {Inv and B1 and (not B2)} S2 {Inv}

{Inv and B} if B2 then S1 else S2 {Inv}

An important question when applying nested structures is how to know if a node is part of a nested structure? There are two possible methods to specify the precondition and

50 postcondition of a nested node. One is to collect the subcontracts along with visiting the nested nodes. An alternative way is to reach to a node that is selected by the user and then track back to collect the subcontracts. It is important to know which method is more efficient since the first method might spend execution time in collecting subcontracts that a user might not select. On the other hand, if the second method is applied, tracking back the parent of the selected node may consume a great deal of time.

Moreover, the inclusion of inference rules for sequence statements would give additional sub specifications that facilitates finding the errors. In this enhancement, there are at least two issues that need to be taken into consideration. First, the representation of the sequence statements in the dialog box. For instance, if there are multiple of sequence statements that are scattered in the code, how should these statements be combined in the dialog box? What are the starting points and the ending points of these statements?

Another issue is that if there is a block of assignments, there is a need to traverse each statement to check whether this statement needs to be taken into consideration. Therefore, unlike inference rules for if-statements and loop-statements, performance of the

Subcontractor might be an issue since we need to traverse each statement in that block.

Additional future enhancements can include uploading the plugin Subcontractor in the website rise4fun [27], which has a collection of software engineering tools. In this website, the user can experiment the uploaded tools without diving into the hassle of installing and configuring the tools. The website is categorized based on the institute that created the tools. The common factor of these tools is that they can be used in

51 verification, testing, or security purposes. Examples of tools that are existing in this website are z3 and OpenJML (ESC). Uploading the tool Subcontractor could make this tool more accessible for further enhancements.

52

Appendix A. Project Source Code

AbstractCategory.java package csus.masterproject.dcb.programminglogic.dialogbox; import java.util.HashMap; import java.util.Map; public abstract class AbstractCategory { private String name; private int id; private AbstractCategory parent; private Map contentMap = new HashMap();

public AbstractCategory(String name, AbstractCategory parent, int id) { this.name = name; this.parent=parent; this.id=id; } public void addSubCategory(AbstractCategory parent,AbstractCategory category[]) { contentMap.put(parent, category); }

public AbstractCategory[] getSubCategories(AbstractCategory category) { return contentMap.get(category); }

public boolean hasSubCategories(AbstractCategory category) { return contentMap.containsKey(category); }

public String getName() { return name; }

public void setName(String newName) { name=newName; }

public AbstractCategory getParent() { return parent; }

public int getId() { return id; }

public String toString() { return name; } }

53

MethodsCategory.java package csus.masterproject.dcb.programminglogic.dialogbox; public class MethodsCategory extends AbstractCategory { private int startline; private int endline; public MethodsCategory(String name, AbstractCategory parent, int id, int startline, int endline) { super (name,parent,id); this.startline=startline; this.endline=endline; }

public int getStartLine() { return startline; }

public int getEndLine() { return endline; }

}

AllCategory.java package csus.masterproject.dcb.programminglogic.dialogbox; public class AllCategory extends AbstractCategory{

private int type; // type of a node 1.if statement 2.while 5.others 6.loopinv 7.no if or loop statement 8.methods

public AllCategory(String name, AbstractCategory parent, int id, int type) { super (name,parent,id); this.type=type; }

public int getType() { return type; } }

DialogboxControls.java package csus.masterproject.dcb.programminglogic.dialogbox; import java.net.URL; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Path; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button;

54 import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.TabFolder; import org.eclipse.swt.widgets.TabItem; import org.osgi.framework.Bundle; import org.osgi.framework.FrameworkUtil; public class DialogboxControls { private Composite parent; private TabFolder folder; private TreeViewer treeViewer; private Button addDeletebtn; private Label warning; private AbstractCategory rootCategory; private boolean isChecked=false;

public DialogboxControls(Composite parent, TabFolder folder,AbstractCategory rootCategory){ this.parent=parent; this.folder=folder; this.rootCategory=rootCategory;

} public void createControls( String tabName, String LabelText ){

folder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); TabItem item = new TabItem(folder, SWT.TOP);

//create tab item.setText(tabName);

//create composit Composite allcomposite = new Composite(folder, SWT.NONE); GridData gridData = new GridData(GridData.END, GridData.CENTER, false, false); allcomposite.setLayoutData(gridData); GridLayout layout = new GridLayout(); layout.numColumns = 1; allcomposite.setLayout(layout);

//create Label Label title= new Label(allcomposite, SWT.LEFT); title.setText(LabelText);

//create TreeViewer treeViewer = new TreeViewer(allcomposite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION); gridData = new GridData(); gridData = new GridData(GridData.FILL, GridData.FILL, true, true); treeViewer.getTree().setLayoutData(gridData); treeViewer.setContentProvider(new CategoryTreeContentProvider());

55 treeViewer.setInput(rootCategory); treeViewer.setLabelProvider((new CategoryTreeLabelProvider(createImageDescriptor(isChecked)))); treeViewer.expandAll();

//create Label warning= new Label(allcomposite, SWT.LEFT); warning.setText("");

//create a composite to hold the two buttons in the upper right Composite composite = new Composite(allcomposite, SWT.NONE); gridData = new GridData(GridData.END, GridData.CENTER, false, false); composite.setLayoutData(gridData); layout = new GridLayout(); layout.numColumns = 2; composite.setLayout(layout);

//create delete or generate button addDeletebtn = new Button(composite, SWT.PUSH); addDeletebtn.setText(tabName); gridData = new GridData(GridData.END, GridData.CENTER, false, false); addDeletebtn.setLayoutData(gridData);

//button Button cancelbtn = new Button(composite, SWT.PUSH); cancelbtn.setText("close"); gridData = new GridData(GridData.END, GridData.CENTER, false, false); cancelbtn.setLayoutData(gridData); Listener cancelbtnListener = new Listener() { public void handleEvent(Event event) { parent.dispose(); } }; cancelbtn.addListener(SWT.Selection, cancelbtnListener); item.setControl(allcomposite); } public TreeViewer getTreeViewer(){ return treeViewer; } public Button getFirstBtn(){ return addDeletebtn; } public Label GetLabelWarning(){ return warning; } public boolean GetisChecked(){ return isChecked; }

56

private ImageDescriptor createImageDescriptor(boolean i) { Bundle bundle = FrameworkUtil.getBundle(CategoryTreeLabelProvider.class); URL url = null; if (i== false) url = FileLocator.find(bundle, new Path("icons/unchecked.png"), null); else if (i==true) url = FileLocator.find(bundle, new Path("icons/checked.png"), null);

return ImageDescriptor.createFromURL(url); } }

DialogboxCreation.java package csus.masterproject.dcb.programminglogic.dialogbox; import csus.masterproject.dcb.programminglogic.ParsingAssistant; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jface.viewers.*; import org.eclipse.jface.window.*; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.*; import org.eclipse.swt.layout.GridLayout; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.LocalResourceManager; import org.eclipse.jface.resource.ResourceManager; import org.osgi.framework.Bundle; import org.osgi.framework.FrameworkUtil; import java.net.URL; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Path; import org.eclipse.swt.graphics.Image; public class DialogboxCreation extends ApplicationWindow { private AllCategory rootCategory; private MethodsCategory classCategory; private CompilationUnit cu; private ICompilationUnit lwUnit; private int id = 0; private int methodOnlyId = 0; private TextCellEditor cellEditor = null; boolean isChecked = false;

57

private Map Inv = new HashMap(); boolean hasifORloop = false;

public DialogboxCreation(CompilationUnit cu, ICompilationUnit lwUnit) { super(null); this.lwUnit = lwUnit; this.cu = cu; cu.accept(new ASTVisitor() { public boolean visit(TypeDeclaration classNode) { // creating content for the TreeViewers id = id + 1; String className = classNode.getName().toString(); rootCategory = new AllCategory("Class" + className, null, id, 5); classCategory = new MethodsCategory("Class" + className, null, 0, 0, 0); // For each method MethodDeclaration[] methodNodes = classNode.getMethods(); ArrayList methodsList = new ArrayList(); ArrayList methodsList2 = new ArrayList(); for (MethodDeclaration methodNode : methodNodes) { id = id + 1; methodOnlyId = methodOnlyId + 1; if (methodNode.getModifiers() > 0) { int startlineNumber = cu.getLineNumber(methodNode.getStartPosition()); int endlineNumber = cu.getLineNumber(methodNode.getStartPosition() + methodNode.getLength()); AllCategory aMethod = new AllCategory(methodNode.getName().toString(), rootCategory, id, 8); MethodsCategory aMethod2 = new MethodsCategory(methodNode.getName().toString(), classCategory, methodOnlyId, startlineNumber, endlineNumber); methodsList.add(aMethod); methodsList2.add(aMethod2); // to convert form arraylist to array AllCategory[] simpleArrayMethod = new AllCategory[methodsList.size()]; methodsList.toArray(simpleArrayMethod); MethodsCategory[] simpleArrayMethod2 = new MethodsCategory[methodsList2.size()]; methodsList2.toArray(simpleArrayMethod2); // replace the sub category after adding a method to the // methodslist rootCategory.addSubCategory(rootCategory, simpleArrayMethod); classCategory.addSubCategory(classCategory, simpleArrayMethod2); ASTNode methodBody = methodNode.getBody(); ArrayList othersList = new ArrayList(); AllCategory parent = aMethod; DomainModelContent domainModelContent = new DomainModelContent(id, parent, Inv); methodBody.accept(domainModelContent); hasifORloop = domainModelContent.getHasifORloop(); if (hasifORloop == false) { String msg = "There is no if or loop statement"; AllCategory nocont = new AllCategory(msg, parent, id, 7); AllCategory[] simpleArrayNoifORloop = { nocont };

58

parent.addSubCategory(parent, simpleArrayNoifORloop); } else { hasifORloop = false; }

} } return false; } }); } protected Control createContents(Composite parent) { parent.setBounds(400, 200, 450, 340); parent.setLayout(new GridLayout(1, true)); parent.setToolTipText("SubContactor");

// 1. the generate tab final TabFolder folder = new TabFolder(parent, SWT.BORDER); DialogboxControls dialogboxControls = new DialogboxControls(parent, folder, rootCategory); dialogboxControls.createControls("Generate", "Choose Loop-statement(s) or If-statement(s) to Generate Subcontacts:"); TreeViewer treeViewer = dialogboxControls.getTreeViewer(); isChecked = dialogboxControls.GetisChecked(); // Listener for the TreeViewer Map checkedMethods = new HashMap(); ArrayList checkedItems = new ArrayList(); treeViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent e) { CategoryTreeLabelProvider categoryTreeLabelProvider = new CategoryTreeLabelProvider(null); IStructuredSelection selection = (IStructuredSelection) e.getSelection(); CategoryTreeContentProvider tcp = (CategoryTreeContentProvider) treeViewer.getContentProvider();

for (TreeItem item : treeViewer.getTree().getSelection()) { if (item.getImage() != null) { Object checkedParent = tcp.getParent(selection.getFirstElement()); int startline = categoryTreeLabelProvider.getStartLine(checkedParent); int endline = categoryTreeLabelProvider.getEndLine(checkedParent); int parentvalue = categoryTreeLabelProvider.getIdentifier(checkedParent); System.out.println( "parentvalue" + parentvalue + " startline" + startline + " endline" + endline);

59 int value = categoryTreeLabelProvider.getIdentifier(selection.getFirstElement()); ResourceManager resourceManager = new LocalResourceManager(JFaceResources.getResources()); System.out.println("selection.getFirstElement()" + selection.getFirstElement()); if (isChecked == false) { isChecked = true; ImageDescriptor ch = createImageDescriptor(isChecked); Image img = resourceManager.createImage(ch); item.setImage(img); checkedItems.add(value); checkedMethods.put(parentvalue, new Integer[] { startline, endline }); } else { isChecked = false; ImageDescriptor unch = createImageDescriptor(isChecked); Image img2 = resourceManager.createImage(unch); item.setImage(img2); checkedItems.remove(new Integer(value)); checkedMethods.remove(new Integer(parentvalue));

} } }

} }); // to support editing in MOUSE_DOUBLE_CLICK cellEditor = new InvEditor(treeViewer.getTree()); TreeViewerEditor.create(treeViewer, new ColumnViewerEditorActivationStrategy(treeViewer) { protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) { return event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION; }

}, TreeViewerEditor.DEFAULT); LoopInvEditing loopInvEditing = new LoopInvEditing(); loopInvEditing.enableEditing(treeViewer, Inv, cellEditor); Button addsubbtn = dialogboxControls.getFirstBtn(); Label warning = dialogboxControls.GetLabelWarning(); // Listener Listener myListener = new Listener() { public void handleEvent(Event event) {

// to check if there are checked items if (checkedItems.size() == 0) { warning.setText("You need to select items from the tree to add subcontracts."); warning.getParent().layout(); } else {

60

System.out.println( "checkedItems.size():" + checkedItems.size() + "checkedItems.get(0)" + checkedItems.get(0)); for (int i = 0; i < checkedItems.size(); i++) { System.out.println("checkedItems.get(i)+1" + (checkedItems.get(0) + 1)); if (Inv.get(checkedItems.get(i) + 1) == "true") { System.out.println(" true"); warning.setText("Edit the loop invariant by double click on it."); warning.getParent().layout(); break; } else if (i == (checkedItems.size() - 1)) { ParsingAssistant newparser = new ParsingAssistant(); boolean doesexist = false; try { doesexist = newparser.deleteContractParser(lwUnit, checkedMethods, false); } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } if (doesexist) { warning.setText( "There are subcontracts in the methods that has the selected items, change the tab and delete them first."); warning.getParent().layout(); } else { boolean exception[] = new boolean[2]; try { exception = newparser.contractparser(lwUnit, checkedItems, Inv); } catch (CoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (exception[0] == true && exception[1] == true) { parent.dispose(); } else { if (exception[0] == false) { warning.setText("There is no preconditions and postconditions"); warning.getParent().layout(); } else { warning.setText("threr is no if/loop statements");

warning.getParent().layout(); } } } } } } } }; addsubbtn.addListener(SWT.Selection, myListener);

61

// 2. the delete tab dialogboxControls = new DialogboxControls(parent, folder, classCategory); dialogboxControls.createControls("Delete", "Choose Method(s) to Delete Subcontacts:"); TreeViewer methodsTreeViewer = dialogboxControls.getTreeViewer(); isChecked = dialogboxControls.GetisChecked(); checkedMethods.clear(); methodsTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent e) { CategoryTreeLabelProvider categoryMethodsLabelProvider = new CategoryTreeLabelProvider(null); IStructuredSelection selection = (IStructuredSelection) e.getSelection();

for (TreeItem item : methodsTreeViewer.getTree().getSelection()) { if (item.getImage() != null) {

int value = categoryMethodsLabelProvider.getIdentifier(selection.getFirstElement()); int startline = categoryMethodsLabelProvider.getStartLine(selection.getFirstElement()); int endline = categoryMethodsLabelProvider.getEndLine(selection.getFirstElement()); ResourceManager resourceManager = new LocalResourceManager(JFaceResources.getResources()); System.out.println("selection.getFirstElement()" + selection.getFirstElement()); if (isChecked == false) { isChecked = true; ImageDescriptor ch = createImageDescriptor(isChecked); Image img = resourceManager.createImage(ch); item.setImage(img); checkedMethods.put(value, new Integer[] { startline, endline }); // checkedMethods.add(value); } else { isChecked = false; ImageDescriptor unch = createImageDescriptor(isChecked); Image img2 = resourceManager.createImage(unch); item.setImage(img2); checkedMethods.remove(new Integer(value)); } } }

} }); addsubbtn = dialogboxControls.getFirstBtn(); Label warning1 = dialogboxControls.GetLabelWarning(); // Listener

62

Listener deletebtnListener = new Listener() { public void handleEvent(Event event) { if (checkedMethods.size() == 0) { warning1.setText("You need to select methods from the tree to delete subcontracts."); warning1.getParent().layout(); } else { ParsingAssistant newparser = new ParsingAssistant(); try { boolean doesexist = newparser.deleteContractParser(lwUnit, checkedMethods, true); if (!doesexist) { warning1.setText("There is no subcontracts in the selected method(s)."); warning1.getParent().layout(); } else parent.dispose();

} catch (CoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }

} } }; addsubbtn.addListener(SWT.Selection, deletebtnListener); return treeViewer.getTree(); } public static void main(CompilationUnit cu, ICompilationUnit lwUnit) { DialogboxCreation main = new DialogboxCreation(cu, lwUnit); main.setBlockOnOpen(true); main.open(); main.getShell().setText("SubContractor"); main.getShell().addListener(SWT.Close, new Listener() { @Override public void handleEvent(Event event) { main.close(); } }); Display.getCurrent().dispose(); } private ImageDescriptor createImageDescriptor(boolean i) { Bundle bundle = FrameworkUtil.getBundle(CategoryTreeLabelProvider.class); URL url = null; if (i == false) url = FileLocator.find(bundle, new Path("icons/unchecked.png"), null); else if (i == true)

63

url = FileLocator.find(bundle, new Path("icons/checked.png"), null); return ImageDescriptor.createFromURL(url); }

}

DomainModelContent.java package csus.masterproject.dcb.programminglogic.dialogbox; import java.util.ArrayList; import java.util.Map; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.IfStatement; import org.eclipse.jdt.core.dom.WhileStatement; public class DomainModelContent extends ASTVisitor { private int id; private AllCategory parent; private Map Inv; private boolean hasifORloop=false; private ArrayList othersList = new ArrayList();

public DomainModelContent(int id,AllCategory parent,Map Inv){

this.id=id; this.parent=parent; this.Inv= Inv; }

public boolean visit(WhileStatement node) {

AllCategory WhileNode= addNodeContent(node, 2);

//for loop inv addLoopInv(WhileNode); return true; }

public boolean visit(IfStatement node) { addNodeContent(node, 1); return true; }

public boolean getHasifORloop(){ return hasifORloop; }

public AllCategory addNodeContent(ASTNode node, int type){ hasifORloop=true; id=id+1; AllCategory addNode = new AllCategory(node.toString(), parent,id,type);

64

othersList.add(addNode);

AllCategory[] simpleArrayOthers = new AllCategory[ othersList.size() ]; othersList.toArray( simpleArrayOthers ); parent.addSubCategory(parent, simpleArrayOthers); return addNode;

} public void addLoopInv(AllCategory parentNode){ id=id+1; String loopinv; if (Inv.containsKey(id)){ loopinv="loop Inv:"+Inv.get(id)+"(Double-Click to edit)"; } else{ loopinv="loop Inv: true"+"(Double-Click to edit)"; Inv.put(id, "true"); } AllCategory LoopInv = new AllCategory(loopinv, parentNode, id,6); AllCategory[] simpleArrayInv={LoopInv} ; parentNode.addSubCategory(parentNode, simpleArrayInv); }

}

InvEditor.java package csus.masterproject.dcb.programminglogic.dialogbox; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; public class InvEditor extends TextCellEditor { private int minHeight = 0;

public InvEditor(Tree tree) {

super(tree, SWT.BORDER); Text txt = (Text)getControl(); Font fnt = txt.getFont(); FontData[] fontData = fnt.getFontData(); if (fontData != null && fontData.length > 0) minHeight = fontData[0].getHeight() + 10; }

public LayoutData getLayoutData() { LayoutData data = super.getLayoutData(); if (minHeight > 0) data.minimumHeight = minHeight;

65

return data; }

}

LoopInvEditing.java package csus.masterproject.dcb.programminglogic.dialogbox; import java.util.Map; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.EditingSupport; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.TreeViewerColumn; import org.eclipse.swt.SWT; public class LoopInvEditing { public void enableEditing (TreeViewer treeViewer, Map Inv, TextCellEditor cellEditor){

final TreeViewerColumn column = new TreeViewerColumn(treeViewer, SWT.NONE); column.getColumn().setWidth(350); column.setLabelProvider(new TreeLabelProvider()); final TreeViewer finalTreeViewer = treeViewer; column.setEditingSupport(new EditingSupport(treeViewer) {

@Override protected void setValue(Object element, Object value) {

if (element instanceof AllCategory){ AllCategory data = (AllCategory)element; String value2= "loop Inv:" +(value.toString())+ "(Double-Click to edit)"; data.setName ( value2); Inv.put(data.getId(), (value.toString())); } finalTreeViewer.update(element, null); }

@Override protected Object getValue(Object element) { finalTreeViewer.update(element, null); String value=(element.toString()); value= value.replace("loop Inv:", ""); value= value.replace("(Double-Click to edit)", ""); return value; }

@Override protected CellEditor getCellEditor(Object element) { return cellEditor; }

66

@Override protected boolean canEdit(Object element) { if (element instanceof AllCategory){ if (((AllCategory) element).getType()==6) return true; else return false; } else{ return false; }

} });

}

class TreeLabelProvider extends ColumnLabelProvider{

public String getText(Object element) { return element.toString();

} }

}

CategoryTreeContentProvider.java package csus.masterproject.dcb.programminglogic.dialogbox; import org.eclipse.jface.viewers.*; public class CategoryTreeContentProvider implements ITreeContentProvider { public Object[] getChildren(Object element) { AbstractCategory category = (AbstractCategory) element; return category.getSubCategories(category); }

public Object[] getElements(Object element) { return getChildren(element); }

public boolean hasChildren(Object element) { if (element instanceof AbstractCategory) { AbstractCategory category = (AbstractCategory) element; return category.hasSubCategories(category); } return false; }

public Object getParent(Object element) {

67

if (element instanceof AbstractCategory) { return ((AbstractCategory) element).getParent(); } return null; }

public void dispose() {

}

public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {

} }

CategoryTreeLabelProvider.java package csus.masterproject.dcb.programminglogic.dialogbox; import org.eclipse.jface.viewers.*; import org.eclipse.swt.graphics.Image; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.LocalResourceManager; import org.eclipse.jface.resource.ResourceManager; public class CategoryTreeLabelProvider extends LabelProvider {

private ImageDescriptor directoryImage; private ResourceManager resourceManager;

public CategoryTreeLabelProvider(ImageDescriptor directoryImage) { this.directoryImage = directoryImage; }

public int getIdentifier(Object element) { if (element instanceof AbstractCategory) { return ((AbstractCategory) element).getId(); } return 0 ; }

public int getStartLine(Object element) { if (element instanceof MethodsCategory) { return ((MethodsCategory) element).getStartLine(); } return 0 ; }

public int getEndLine(Object element) { if (element instanceof MethodsCategory) { return ((MethodsCategory) element).getEndLine(); } return 0 ; }

68

public int getType(Object element) { if (element instanceof AllCategory) { return ((AllCategory) element).getType(); } return 0 ; }

@Override public Image getImage(Object element) { if(element instanceof AllCategory) { if(((AllCategory) element).getType()==1||((AllCategory) element).getType()==2 ) { return getResourceManager().createImage(directoryImage); } }else if (element instanceof MethodsCategory) { return getResourceManager().createImage(directoryImage); } return null; }

@Override public String getText(Object element) { if(element instanceof AllCategory) if(((AllCategory) element).getType()==8) return "The if and loop statement(s) in "+ ((AbstractCategory) element).getName() + ":"; else return ((AbstractCategory) element).getName(); else if (element instanceof MethodsCategory) { System.out.println(((AbstractCategory) element).getName()); return ((AbstractCategory) element).getName(); } return "" + element; }

@Override public void dispose() { if(resourceManager != null) { resourceManager.dispose(); resourceManager = null; } }

protected ResourceManager getResourceManager() { if(resourceManager == null) { resourceManager = new LocalResourceManager(JFaceResources.getResources()); } return resourceManager; }

}

69

AddSubContractsActionDelegate.java package csus.masterproject.dcb.programminglogic; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IObjectActionDelegate; import org.eclipse.ui.IWorkbenchPart;

/** * The Delegate Provides the selected project and forwards to do an action */ public class AddSubContractsActionDelegate implements IObjectActionDelegate {

private Shell shell; private ISelection selection;

public AddSubContractsActionDelegate() { super(); }

/** * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart) */ public void setActivePart(IAction action, IWorkbenchPart targetPart) { shell = targetPart.getSite().getShell(); }

/** * @see IActionDelegate#run(IAction) */ public void run(IAction action) { if (selection instanceof IStructuredSelection) { ICompilationUnit lwUnit = (ICompilationUnit) ((IStructuredSelection) selection) .getFirstElement();

ParsingAssistant newparser=new ParsingAssistant(); try { newparser.treeviewerparser(lwUnit); } catch (JavaModelException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (CoreException e) { // TODO Auto-generated catch block e.printStackTrace(); }

}

70

}

/** * @see IActionDelegate#selectionChanged(IAction, ISelection) */ public void selectionChanged(IAction action, ISelection selection) { this.selection = selection; }

}

ParsingAssistant.java package csus.masterproject.dcb.programminglogic; import csus.masterproject.dcb.programminglogic.dialogbox.DialogboxCreation; import java.util.ArrayList; import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.CompilationUnit; public class ParsingAssistant {

public void treeviewerparser(ICompilationUnit lwUnit) throws CoreException { CompilationUnit unit = parse(lwUnit); DialogboxCreation treeViewer = new DialogboxCreation(unit, lwUnit); treeViewer.main(unit,lwUnit); }

public boolean[] contractparser( ICompilationUnit lwUnit,ArrayList checkedItems, Map Inv ) throws CoreException { CompilationUnit unit = parse(lwUnit); Generation manip= new Generation(); return manip.manipulate(unit, lwUnit, checkedItems, Inv);

} public boolean deleteContractParser( ICompilationUnit lwUnit,Map checkedMethods, boolean allowToDelete ) throws Exception, Exception { CompilationUnit unit = parse(lwUnit); Deletion manip= new Deletion(); return manip.manipulate(unit, lwUnit, checkedMethods, allowToDelete); }

protected CompilationUnit parse(ICompilationUnit lwUnit) { ASTParser parser = ASTParser.newParser(AST.JLS3); parser.setKind(ASTParser.K_COMPILATION_UNIT); parser.setSource(lwUnit); // set source parser.setResolveBindings(true); // we need bindings later on

71

return (CompilationUnit) parser.createAST(null /* IProgressMonitor */); // parse } }

ContractsManager.java package csus.masterproject.dcb.programminglogic; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.BlockComment; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.LineComment;

/** * The ContractsManager Provides HashMaps for the preconditions and postconditions along with the line numbers */ class ContractsManager extends ASTVisitor{ private Map> preconditionsMap = new HashMap>(); private Map> postconditionsMap = new HashMap>(); private CompilationUnit cu; private String source;

public ContractsManager(CompilationUnit cu, String source) { super(); this.cu = cu; this.source = source; }

public boolean visit(LineComment node) { int start = node.getStartPosition(); int end = start + node.getLength(); String comment = source.substring(start, end); int lineNumber= cu.getLineNumber(node.getStartPosition()); // in case of preconditions if (comment.contains("requires")) { comment=comment.replace("requires", ""); comment=comment.replace("//", ""); comment=comment.replace("@", ""); comment=comment.replace(";", ""); preconditionsMap.put(lineNumber, Arrays.asList(comment.split("(&&)|(\\|\\|)")));

} else if (comment.contains("ensures"))// in case of preconditions { comment=comment.replace("ensures", ""); comment=comment.replace("//", "");

72

comment=comment.replace("@", ""); comment = comment.trim(); if(comment.endsWith(";")) { comment = comment.substring(0,comment.length() - 1); } postconditionsMap.put(lineNumber, Arrays.asList(comment));

} return true; } public boolean visit(BlockComment node) { int start = node.getStartPosition(); int end = start + node.getLength(); String comment = source.substring(start, end); int lineNumber= cu.getLineNumber(node.getStartPosition()); int leng= comment.length(); String subString=comment; end= 0; start=0; int i=0; while (start< leng) { end= leng; if (subString.indexOf("requires", subString.indexOf("requires") + 1) >0) end=subString.indexOf("requires", subString.indexOf("requires") + 1); subString=comment.substring(start, end);

if (subString.contains("requires")) { subString=subString.replace("requires", ""); subString=subString.replace("/*", ""); subString=subString.replace("*/", ""); subString=subString.replace("@", ""); subString=subString.replace(";", ""); subString=subString.replace("\n", ""); preconditionsMap.put(lineNumber+i, Arrays.asList(subString.split("(&&)|(\\|\\|)")));

} else if (subString.contains("ensures"))// in case of preconditions { subString=subString.replace("ensures", ""); subString=subString.replace("/*", ""); subString=subString.replace("*/", ""); subString=subString.replace("@", ""); subString = subString.trim(); if(subString.endsWith(";")) {

73

subString = subString.substring(0,subString.length() - 1); } postconditionsMap.put(lineNumber+i, Arrays.asList(subString));

}

start= end; i++; }

return true; }

public Map> getPreconditions() { return preconditionsMap; }

public Map> getPostconditions() { return postconditionsMap; }

}

GettingReturnStatement.java package csus.masterproject.dcb.programminglogic; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.ReturnStatement; public class GettingReturnStatement extends ASTVisitor{

private ASTNode retstsat=null;

public GettingReturnStatement() { super(); } public boolean visit(ReturnStatement node){ retstsat=node; return true; }

public ASTNode getretstsat(){ return retstsat; } }

Generation.java package csus.masterproject.dcb.programminglogic; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.eclipse.core.filebuffers.FileBuffers; import org.eclipse.core.filebuffers.ITextFileBuffer;

74 import org.eclipse.core.filebuffers.ITextFileBufferManager; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.Comment; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.text.edits.MalformedTreeException; import org.eclipse.text.edits.TextEdit;

/** * The Generation class generates and inserts the assert statements inside the checked if-statements or/and loop-statements */ public class Generation { private ASTRewrite rewrite; private int id=0; // this is an identifier of the different components in the source code to be matched with the tree viewer static boolean hasforORif; static boolean hasCont=false; static boolean stillcheck=true;

protected void beforeManipulate(CompilationUnit unit) { rewrite = ASTRewrite.create(unit.getAST());

} public boolean[] manipulate( CompilationUnit cu, ICompilationUnit lwUnit,ArrayList checkedItems, Map Inv ) throws CoreException { // pre-processing beforeManipulate(cu);

cu.accept(new ASTVisitor() { public boolean visit(TypeDeclaration classNode) { id=id+1;

// 1- get information about contacts (comments) from ContractsManager class String strsource=null; try { strsource = lwUnit.getSource(); } catch (JavaModelException e) { // TODO Auto-generated catch block e.printStackTrace(); }

75

ContractsManager contracts= new ContractsManager(cu, strsource); for (Comment comment : (List) cu.getCommentList()) { comment.accept(contracts); } Map> preconditionsMap = contracts.getPreconditions(); Map> postconditionsMap = contracts.getPostconditions();

//2- for each method do the following: MethodDeclaration[] methodNodes = classNode.getMethods(); int startingpoint=0; for(MethodDeclaration methodNode: methodNodes){ id=id+1;

if(methodNode.getModifiers() > 0){ ASTNode methodBody= methodNode.getBody();

// 1.2 get the upper limit and the lower limit of the lines that contracts can be in int endingpoint= (cu.getLineNumber(methodNode.getStartPosition())-1);

//2.2 building the pre/postconditions StringBuilder preconditionBuilder = new StringBuilder(); for (Map.Entry> entry : preconditionsMap.entrySet()) { Integer key = entry.getKey(); if (key>= startingpoint && key<=endingpoint) {preconditionBuilder.append(entry.getValue()); hasCont=true;} }

StringBuilder postconditionBuilder = new StringBuilder(); int count=0; for (Map.Entry> entry : postconditionsMap.entrySet()) { count=count+1; Integer key = entry.getKey(); //last conditions do not add || (or sign)

if (postconditionsMap.size() == count){ postconditionBuilder.append("("+entry.getValue()+ ")"); hasCont=true;} else

76

{ if (key>= startingpoint && key<=endingpoint)

{postconditionBuilder.append("("+entry.getValue()+ ") &&");}} } String preconditionString = "";

preconditionString=preconditionBuilder.toString(); preconditionString= preconditionString.replace("[", "").replace("]", "");

preconditionString=preconditionString.replace(",", "&&");

String postconditionString = "";

postconditionString=postconditionBuilder.toString(); postconditionString= postconditionString.replace("[", "").replace("]", "");

postconditionString=postconditionString.replace(",", "&&");

// replace the \result with the return statement variable if (postconditionString.contains("\\result")) { GettingReturnStatement retsta=new GettingReturnStatement(); methodBody.accept(retsta); String streturn=null; if (retsta.getretstsat() !=null){ streturn=retsta.getretstsat().toString(); streturn=streturn.replace(";", ""); streturn=streturn.replace("return", ""); streturn=streturn.replace("\n", "");

postconditionString=postconditionString.replace("\\result", streturn);} }

// 2.3 place the contracts in the right places based on the inference rules PlacingSubcontacts placingcontracts=new PlacingSubcontacts(preconditionString, postconditionString, rewrite, checkedItems, id, cu, Inv, hasCont, stillcheck ); methodBody.accept(placingcontracts); hasforORif=placingcontracts.getHasifORfor(); if (hasforORif==true && hasCont==true){ stillcheck=false;} else{ hasCont=false; placingcontracts.setHasifORfor();

77

}

} startingpoint=(cu.getLineNumber(methodNode.getLength() +methodNode.getStartPosition())-1);

} return false;

}

});

// post-processing boolean exception[]=new boolean[2]; exception[0]=hasCont; exception[1]=hasforORif; if (exception[0]==true && exception[1]==true) {afterManipulate(cu, lwUnit, new TextEditProvider() { public TextEdit getTextEdit(IDocument document) { return rewrite.rewriteAST(document, null); } });} return exception;

}

protected void afterManipulate(CompilationUnit unit,ICompilationUnit lwUnit, TextEditProvider textEditProvider) throws CoreException{ ITextFileBufferManager bufferManager = FileBuffers.getTextFileBufferManager(); IPath path = unit.getJavaElement().getPath(); try { // connect the path bufferManager.connect(path, null);

ITextFileBuffer textFileBuffer = bufferManager.getTextFileBuffer(path); // retrieve the buffer IDocument document = textFileBuffer .getDocument();

// ask the textEditProvider for the change information TextEdit edit = textEditProvider.getTextEdit(document);

// apply the changes to the document edit.apply(document);

// write the changes from the buffer to the file

78

textFileBuffer.commit(null /* ProgressMonitor */, false /* Overwrite */); lwUnit.getBuffer().setContents(document.get());

} catch (MalformedTreeException e) { e.printStackTrace(); } catch (BadLocationException e) { e.printStackTrace(); } finally { // disconnect the path bufferManager.disconnect(path, null); }

}

public interface TextEditProvider {

TextEdit getTextEdit(IDocument document); }

}

PlacingSubcontacts.java package csus.masterproject.dcb.programminglogic; import java.util.ArrayList; import java.util.Map; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.Block; import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.IfStatement; import org.eclipse.jdt.core.dom.Statement; import org.eclipse.jdt.core.dom.WhileStatement; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.dom.rewrite.ListRewrite; public class PlacingSubcontacts extends ASTVisitor{ private ASTRewrite rewrite; private String preconditionString; private String postconditionString; private Map Inv; private ArrayList checkedItems; private int id; static boolean hasCont; private CompilationUnit cu; static boolean hasifORfor=false; static boolean stillcheck; public PlacingSubcontacts(String preconditionString, String postconditionString,ASTRewrite rewrite, ArrayList checkedItems, int id , CompilationUnit cu, Map Inv ,boolean hasCont,boolean stillcheck) { super(); this.preconditionString = preconditionString;

79

this.postconditionString = postconditionString; this.rewrite=rewrite; this.checkedItems= checkedItems; this.id=id; this.cu= cu; this.Inv=Inv; this.hasCont=hasCont; this.stillcheck=stillcheck;

}

public boolean visit(WhileStatement whilenode) { if (hasCont==true && stillcheck==true) hasifORfor=true; id=id+1; System.out.println("while node"+ id); if (checkedItems.contains(id)) { String exp= whilenode.getExpression().toString(); Block loopBody=(Block) whilenode.getBody(); Statement StaLoopbody = whilenode.getBody();

loopPlacing (whilenode, exp, loopBody, StaLoopbody, id ); } id=id+1; return true; }

public boolean visit(IfStatement ifnode) { if (hasCont==true && stillcheck==true) hasifORfor=true; id=id+1; System.out.println("if node"+ id +ifnode.getExpression()); String cont1="//@ assert "+ preconditionString + " && "+ ifnode.getExpression()+ ";"; String cont2="//@ assert "+ postconditionString+ ";"; String cont3="//@ assert "+ preconditionString + " && "+"!(" + ifnode.getExpression()+ ");"; if (checkedItems.contains(id)) { if(ifnode != null){ Statement ifbody=ifnode.getThenStatement(); Block ifBody=(Block) ifnode.getThenStatement(); if (!(ifbody instanceof Block)){ String newSource = "{\n"+cont1+"\n"+ ifbody+ cont2 + "\n}"; ASTNode placeHolder = rewrite.createStringPlaceholder(newSource, ifbody.getNodeType()); rewrite.replace(ifbody, placeHolder, null); } else { Statement placeHolder = (Statement) rewrite.createStringPlaceholder(cont1, ASTNode.EMPTY_STATEMENT);

80

ListRewrite listRewrite = rewrite.getListRewrite(ifBody,Block.STATEMENTS_PROPERTY); listRewrite.insertFirst(placeHolder, null); placeHolder = (Statement) rewrite.createStringPlaceholder(cont2, ASTNode.EMPTY_STATEMENT); listRewrite.insertLast(placeHolder, null); }

Statement ifelsebody=null; ifelsebody = ifnode.getElseStatement(); if (ifelsebody != null && (ifnode.getElseStatement().getNodeType() != ASTNode.IF_STATEMENT)){ Block ifelseBody=(Block) ifnode.getElseStatement(); if (!(ifelsebody instanceof Block)){ String newSource = "{\n"+cont3+"\n"+ ifelsebody+ cont2 + "\n}"; ASTNode placeHolder = rewrite.createStringPlaceholder(newSource, ifelsebody.getNodeType()); rewrite.replace(ifelsebody, placeHolder, null); } else{ Statement placeHolder = (Statement) rewrite.createStringPlaceholder(cont3, ASTNode.EMPTY_STATEMENT); ListRewrite listRewrite = rewrite.getListRewrite(ifelseBody,Block.STATEMENTS_PROPERTY); listRewrite.insertFirst(placeHolder, null); placeHolder = (Statement) rewrite.createStringPlaceholder(cont2, ASTNode.EMPTY_STATEMENT); listRewrite.insertLast(placeHolder, null); } } else { IfStatement myelse=(IfStatement) ifnode.getElseStatement(); }

}

} return true;

}

public void loopPlacing(Statement fornode, String exp, Block loopBody, Statement StaLoopbody, int id) {

String Contract2= "//@ assert "+ Inv.get(id+1) + " && "+ exp+ ";"; String Contract3="//@ assert "+ Inv.get(id+1) +";";

81

ListRewrite listRewrite2 = rewrite.getListRewrite(fornode.getParent(),(ChildListPropertyDescriptor)fornode.getL ocationInParent());

if(fornode != null) { if (!(StaLoopbody instanceof Block)) {

String newSource = "{\n"+Contract2+"\n"+ StaLoopbody+ Contract3 + "\n}"; ASTNode placeHolder = rewrite.createStringPlaceholder(newSource, StaLoopbody.getNodeType()); rewrite.replace(StaLoopbody, placeHolder, null);

} else { Statement placeHolder = (Statement) rewrite.createStringPlaceholder(Contract2, ASTNode.EMPTY_STATEMENT); ListRewrite listRewrite = rewrite.getListRewrite(loopBody,Block.STATEMENTS_PROPERTY); listRewrite.insertFirst(placeHolder, null); placeHolder = (Statement) rewrite.createStringPlaceholder(Contract3, ASTNode.EMPTY_STATEMENT); listRewrite.insertLast(placeHolder, null); }

String Contract1= "\n //@ assert "+ preconditionString+ " ==> "+ Inv.get(id+1) + ";"; String Contract4= "//@ assert "+ Inv.get(id+1) + " && "+"!(" + exp+ ")"+ " ==> "+ postconditionString + ";";

Statement placeHolder = (Statement) rewrite.createStringPlaceholder(Contract4, ASTNode.EMPTY_STATEMENT); listRewrite2.insertAfter(placeHolder, fornode, null);

placeHolder = (Statement) rewrite.createStringPlaceholder(Contract1, ASTNode.EMPTY_STATEMENT); listRewrite2.insertBefore(placeHolder, fornode, null);

} } public boolean getHasifORfor(){ return hasifORfor; }

82

public void setHasifORfor(){ this.hasifORfor=false; } }

Deletion.java package csus.masterproject.dcb.programminglogic; import java.util.List; import java.util.Map; import org.eclipse.jdt.core.dom.Comment; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; import org.eclipse.text.edits.TextEdit;

/** * The Deletion class deletes the assert statements inside the checked methods */ public class Deletion { private ASTRewrite rewrite;

protected void beforeManipulate(CompilationUnit unit) { rewrite = ASTRewrite.create(unit.getAST()); }

public boolean manipulate( CompilationUnit cu, ICompilationUnit lwUnit,Map checkedMethods, boolean allowToDelete ) throws CoreException, Exception, BadLocationException { beforeManipulate(cu);

// to get the source code String strsource=null; try { strsource = lwUnit.getSource(); } catch (JavaModelException e) { // TODO Auto-generated catch block e.printStackTrace(); } Document document = new Document(strsource);

// before refactoring TextEdit textEdit = rewrite.rewriteAST(document, null); textEdit.apply(document);

// get initial value for the startline and endline of the checked items Map.Entry entry=checkedMethods.entrySet().().next(); Integer[] limits=entry.getValue();

83

int startLine=limits[0]; int endLine=limits[1];

SubContractsManager subContractsManager=new SubContractsManager(document,cu,strsource, allowToDelete); subContractsManager.setDoesExist();

for (Comment comment : (List) cu.getCommentList()) { int comlineNumber= cu.getLineNumber(comment.getStartPosition()); System.out.println("inside for com"+comlineNumber); if ( comlineNumber>endLine ) {

entry=checkedMethods.entrySet().iterator().next(); limits=entry.getValue(); startLine=limits[0]; endLine=limits[1]; } if (comlineNumber >=startLine && comlineNumber<=endLine) { comment.accept(subContractsManager); } }

//apply the changes textEdit = rewrite.rewriteAST(document, null); textEdit.apply(document); lwUnit.getBuffer().setContents(document.get());

boolean doesexist= subContractsManager.getDoesExist(); return doesexist;

}

}

SubContractsManager.java package csus.masterproject.dcb.programminglogic; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.LineComment; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; public class SubContractsManager extends ASTVisitor { private IDocument document; private CompilationUnit cu; private String source; private boolean allowToDelete=false; static boolean doesExist=false;

84

public SubContractsManager(IDocument document, CompilationUnit cu, String source, boolean allowToDelete) { this.document = document; this.cu=cu; this.source=source; this.allowToDelete=allowToDelete;

}

/* (non-Javadoc) * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.LineComment) */ @Override public boolean visit(LineComment node) { System.out.printf("Comment.toString(): %s\n", node.toString()); int lineNumber= cu.getLineNumber(node.getStartPosition()); int start = node.getStartPosition(); int end = start + node.getLength(); String comment = source.substring(start, end); if ((comment.contains("assert")) ){ doesExist=true; if (allowToDelete){ System.out.printf("comlineNumber"+lineNumber); try { int commentEndPositions= start + node.getLength(); StringBuffer outputBuffer = new StringBuffer(node.getLength()); for (int i = 0; i < node.getLength(); i++){ outputBuffer.append(" "); } document.replace(node.getStartPosition(), node.getLength(), outputBuffer.toString()); } catch (BadLocationException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } } return true; }

public boolean getDoesExist(){ return doesExist; } public void setDoesExist(){ doesExist=false; } }

85

References

[1] B. Meyer, "Applying design by contract," Computer, vol. 25, no. 10, pp. 40-51, 1992.

[2] G. Leavens. (2013, 8/2/2017). The Java Modeling Language (JML). Available: http://www.eecs.ucf.edu/~leavens/JML//index.shtml

[3] University of Oldenburg. (2001, 8/2/2017). The Jass Page. Available: http://csd.informatik.uni-oldenburg.de/~jass/

[4] J. Bergström. (2012, 8/8/2017). Design By Contract for Java. Available: http://c4j.sourceforge.net/

[5] R. A. Finkel, Advanced programming language design. Addison-Wesley Reading, 1996.

[6] D. Cok. (2015, 7/25/2017). OpenJML. Available: http://www.openjml.org/

[7] C. Hoare and R. Antony, "An axiomatic basis for computer programming," Communications of the ACM, vol. 12, no. 10, pp. 576-580, 1969.

[8] E. W. Dijkstra, Notes on structured programming. Technological University, Department of Mathematics, 1970.

[9] M. Oliveira e Silva and P. G. Francisco, "Contract-Java: Design by Contract in Java with Safe Error Handling," in OASIcs-OpenAccess Series in Informatics, 2014, vol. 38: Schloss Dagstuhl-Leibniz-Zentrum fuer Informatik.

[10] R. Henne-Wu, W. Mitchell, and C. Zhang, "Support for design by contract in the C# programming language," Journal of Object Technology, vol. 4, no. 7, pp. 65- 82, 2004.

[11] The Eclipse Foundation. (2017, 8/2/2017). Eclipse. Available: https://eclipse.org/

86

[12] N. M. Lê. (8/2/2017). Contracts for Java. Available: https://github.com/nhatminhle/cofoja

[13] J. Rieken. (8/1/2017). Modern Jass. Available: http://modernjass.sourceforge.net/

[14] N. M. Lê, "Contracts for java: A practical framework for contract programming," Google Switzerland, Technical report 2011.

[15] L. Burdy et al., "An overview of JML tools and applications," International journal on software tools for technology transfer, vol. 7, no. 3, pp. 212-232, 2005.

[16] D. M. Zimmerman and J. R. Kiniry, "A verification-centric software development process for Java," in 9th International Conference on Quality Software, 2009, pp. 76-85: IEEE.

[17] G. Nelson, "Extended static checking for java," in International Conference on Mathematics of Program Construction, 2004, pp. 1-1: Springer.

[18] The Eclipse Foundation. (6/22/2017). What is Eclipse? Available: http://help.eclipse.org/neon/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2F guide%2Fint_eclipse.htm

[19] ZeroTurnaround, "Developer Productivity Report 2012: Java Tools, Tech, Devs & Data," 2012, Available: https://zeroturnaround.com/rebellabs/developer- productivity-report-2012-java-tools-tech-devs-and-data/.

[20] The Eclipse Foundation. (6/22/2017). PDE. Available: http://www.eclipse.org/pde/

[21] The Eclipse Foundation. (6/22/2017). JDT Core Component. Available: https://eclipse.org/jdt/core/

[22] T. E. Foundation. (2010, 8/1/2017). JFace. Available: https://wiki.eclipse.org/JFace

87

[23] H. Gast, "Structuring Applications with Graphical Interfaces," in How to use objects: code and concepts: Addison-Wesley Professional, 2015.

[24] K. Barclay and J. Savage, Object-oriented Design with UML and Java. Butterworth-Heinemann, 2003.

[25] J. L. Overbey and R. E. Johnson, "Generating rewritable abstract syntax trees," in International Conference on Software Language Engineering, 2008, pp. 114-133: Springer.

[26] The Eclipse Foundation. (2014, 8/22/2017). Class AST. Available: http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.jdt.doc.isv%2Frefere nce%2Fapi%2Forg%2Feclipse%2Fjdt%2Fcore%2Fdom%2FAST.html

[27] Microsoft Corporation. (2017, 8/22/2017). rise4fun. Available: http://rise4fun.com/