• No results found

The Object Flow Graph

2.6 The eLib Program

Let us consider the object insensitive (with no main available) construction of the OFG for the eLib program given in Appendix A. The first step consists of transforming the original program, written according to the Java syntax, into a program that respects the abstract syntax provided in Fig. 2.1. During the transformation, containers are taken into account by converting insertion and extraction instructions into assignments.

Fig. 2.6. Concrete (top) and abstract (bottom) syntax of method borrowDocument

from classLibrary.

Fig. 2.6 shows the translation of method borrowDocument from class

Library (line 56) into its abstract representation. An abstract declaration of the method is generated first. The method name is prefixed by the class name, and all parameter names are fully scoped, being prefixed by class and method name. Then, abstract statements are generated only for statements that in- volve object flows. Thus, the first conditional statement is skipped. From the second conditional statement, only the method invocations contained in the condition need be transformed. Correspondingly, the abstract representation contains the invocation ofnumberOf Loans (class User), isAvailable (class

Document), andauthorizedLoan (classDocument). Targets of these invoca- tions are parameters ofborrowDocument. They are abstracted into their fully

2.6 The eLib Program 37

Fig. 2.7. Concrete and abstract syntax of methods addLoan from classes Library, User and Document.

scoped names. The same holds for the actual parameter ofauthorizedLoan

(see Fig. 2.6).

The next statement that is abstracted is the allocation of a Loan ob- ject (line 60). The local variable to which the allocated object is assigned is fully scoped, similarly to the method parameters. Finally, the call to method

addLoan (line 61) from the same class (Library) is given an abstract repre- sentation in which the target of the call is the special location this, indicating explicitly that the method is called on the current object.

Other abstractions for the eLib program are reported in Fig. 2.7. Note that the same method nameaddLoan has been left in more than one class, instead of

introducing method identifiers (such as addLoan1,addLoan2,addLoan3), just to improve the readability. However, method calls are assumed to be uniquely solved when OFG edges are constructed (e.g., the statement at line 45 inside

Library.addLoanis a call to User.addLoan,while the statement at line 46 is a call toDocument. addLoan).

Methods getUser and getDocument, invoked inside addLoan in class Library (lines 42, 43), have a return value, which is assigned to a left hand side variable. Correspondingly, their abstract representations are assignments with the invocation in the right hand side and the fully scoped variable as left hand side (see Fig. 2.7). The method add is called at line 44 on the class attributeloans, aCollection type object. Since this is an insertion method, the related abstract representation is an assignment with the parameter of the call (loan) on the right hand side, and the container (loans) on the left hand side. It should be noted that the fully scoped name of the class attribute

loans consists of class name and attribute name only. The last two calls inside

Library.addLoan are similar to the first two ones, without any return value. The body of methodaddLoan from classUser is transformed (see Fig. 2.7) into an assignment, associated with a container insertion, where the container is the attributeloans (of typeCollection) of classUser. Finally, the body of methodaddLoan from classDocument is abstracted into an assignment with the fully scoped method’s parameter on the right hand side and the class field

loan on the left hand side.

Transforming the remainder of the eLib program into its abstract syntax representation is quite straightforward, along the lines given above for the examples in Fig 2.6 and 2.7. Once the program’s abstraction is completed, it is possible to construct the OFG by applying the rules in Fig. 2.2.

Fig. 2.8 shows the OFG nodes and edges that are induced by the abstract code in Fig. 2.6 and 2.7. The number labeling each edge refers to the statement that generates it. Method calls cause an edge whose target is athis location (properly prefixed). For example, the first two statements (following the dec- laration) in the abstract code of Fig. 2.6 (method calls: numberOfLoans()

andisAvailable() at lines 58 and 59) generate respectively the edges (Library.borrowDocument.user, User.numberOfLoans.this) and (Libra- ry .borrowDocument.doc, Document.isAvailable.this), labeled 58 and 59. Parameter passing induces edges that end at formal parameter locations. For example, the third abstract statement in Fig. 2.6 (associated with line 59) is a call to the method authorizedLoan with actual parameter Library.borrowDo- cument.user and formal parameter Document.authorizedLoan.user. Cor- respondingly, in Fig. 2.8 the topmost edge labeled 59 connects these two lo- cations.

Allocation statements, such as the fourth abstract statement in Fig. 2.6 (line 60), induce edges between actual and formal parameters, similarly to method calls. In addition, they induce an edge between the constructor’sthis

2.6 The eLib Program 39

Fig. 2.8. OFG associated with the abstract code in Fig. 2.6 (method

borrowDocument in class Library) and 2.7 (method addLoan in classes Library,

40 2 The Object Flow Graph

and the allocation’s left hand side variable, Library.borrowDocument.loan

(Fig. 2.8 center, edge labeled 60).

An example of a method call with a return value is provided by the first abstract statement (after the declaration) of method Library. addLoan (see Fig. 2.7 top, line 42). The left hand side location (Library.addLoan.user)

is the target of an edge outgoing fromLoan.getUser.return, the location associated with the value returned by the method call (see Fig. 2.8 bottom, edge labeled 42).

Container operations are also responsible for some edges in the OFG of Fig. 2.8. For example, the body ofUser.addLoan contains just an insertion statement (line 315). The container User.loans, into which a Loan object is inserted, becomes the target of an edge starting at the inserted object location,User .addLoan. loan (Fig. 2.8 center, edge labeled 44). This indicates an object flow from the parameterloan of methodaddLoan into the container

User .loans.

The OFG constructed for the code in Fig. 2.6 and 2.7 shows the data flows through which objects are propagated from location to location. Thus, the parameteruser of methodborrowDocument becomes the current object (this) insidenumberOfLoans, while it is the parameteruser inside method

authorizedLoan and it is the parameter usr inside the constructor of class

Loan, as depicted at the top of Fig 2.8. Similarly, the other parameter of

borrowDocument, doc, flows intoisAvailable andauthorizedLoan asthis, and into the constructor of classLoan as the parameter doc. The object of class

Document returned by Loan.getDocument (bottom-right of Fig. 2.8) flows into the local variable doc ofLibrary. addLoan, and then becomes the current object (this) insideDocument. addLoan.