|
JML | ||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||||
java.lang.Objectorg.multijava.util.Utils
org.jmlspecs.jmlrac.TransUtils
org.jmlspecs.jmlrac.TransType
An abstract class for translating JML type declarations. The translation may produce (1) a set of assertion check methods and supporting fields (e.g., to hold old values) for classes, and (2) for an interface declaration, a surrogate class as a static inner class.
This class implements the Template Method
Pattern [GoF94]. The main template method is
translate which deines the major flow of control and
calls such translation methods as:
translateInvarianttranslateConstrainttranslateRepresentstranslateBodyfinalizeTranslationTransClass and TransInterface.
(David Cok): THIS IS NOT UP TO DATE The original code (which is intact) has been embellished to handle the situation in which source code is not available to be used to generate new java code containing runtime assertion checks. This is the case, for example, in checking the assertions of classes in java.* . This situation obtains when the assertion check code is being generated from a non-.java file and the object being tested is a class, not an interface. In this case the variable genSpecTestFile is set true, and the generated code is produced as follows. (If genSpecTestFile==false, the original rewrite-the-java-file mechanism is used unchanged.)
The generated class must be different from the class under test, since it cannot replace it. We presume that we cannot add to the package of the class under test either, and in any case it is convenient to have the generated class have the same name as the class under test (convenient for generating test code). Thus we use the same class name but a different package for the generated class. For clarity, we will call the class under test class p.C and the generated class testspecs.p.C . The actual generated class name is determined by the --packageName option.
There are two subcases. One in which we generate a subclass of p.C, which is called Wrapper, and one in which we do not generate such a subclass. The variable genWrapperClass is true in the first case, false in the second.
We generate testspecs.p.C with the following content.
TransClass,
TransInterface| Field Summary | |
private static CClass |
currentCClass
CClass of the target type declaration. |
protected static boolean |
dynamicInvocationMethodNeeded
True if a dynamic invocation method need be generated for the current type declaration as the result of the translation. |
static boolean |
genSpecTestFile
true if we are operating on spec files |
static boolean |
genWrapperClass
|
private ArrayList |
laterMethods
|
protected Set |
modelMethods
The set of model or spec_public field names whose access methods have alredy been generated. |
static boolean |
specInheritanceMethodNeeded
True if a specification inheritance method need be generated for the current type declaration as the result of the translation. |
protected JmlTypeDeclaration |
typeDecl
Target type declaration to be translated. |
protected VarGenerator |
varGen
Variable generator for generating fresh variable names. |
| Fields inherited from class org.jmlspecs.jmlrac.TransUtils |
|
| Fields inherited from class org.multijava.util.Utils |
DBG_LEVEL_HIGH, DBG_LEVEL_LOW, DBG_LEVEL_NO |
| Fields inherited from interface org.jmlspecs.jmlrac.RacConstants |
MN_CHECK_HC, MN_CHECK_INV, MN_CHECK_POST, MN_CHECK_PRE, MN_CHECK_XPOST, MN_EVAL_OLD, MN_GHOST, MN_INIT, MN_INTERNAL, MN_MODEL, MN_MODEL_PUBLIC, MN_RESTORE_FROM, MN_SAVE_TO, MN_SPEC, MN_SPEC_PUBLIC, TN_JMLCHECKABLE, TN_JMLSURROGATE, TN_JMLUNIT_TEST_POSTFIX, TN_JMLUNIT_TESTDATA_POSTFIX, TN_JMLVALUE, TN_SURROGATE, VN_ASSERTION, VN_CATCH_VAR, VN_CLASS_INIT, VN_CONSTRUCTED, VN_DELEGEE, VN_ERROR_SET, VN_EXCEPTION, VN_FREE_VAR, VN_INIT, VN_OLD_VAR, VN_POST_VAR, VN_PRE_VAR, VN_PRECOND, VN_RAC_COMPILED, VN_RAC_LEVEL, VN_RESULT, VN_STACK_VAR, VN_XRESULT |
| Constructor Summary | |
protected |
TransType(JmlTypeDeclaration typeDecl)
Constructs a TransType object. |
| Method Summary | |
protected abstract void |
addNewMethod(JmlMethodDeclaration mdecl)
Adds a new method declaration, mdecl, to the
instrumented type. |
static boolean |
dynamicCallNeeded(CClass clazz)
Returns true if dynamic calls are needed to access model, ghost, spec_public, and spec_protected fields declared in the given class clazz. |
protected JmlMethodDeclaration |
dynamicInvocationMethod()
Returns a method declaration that makes a dynamic call to the given method using the Java's reflection facility. |
protected void |
finalizeTranslation()
Finalizes translation of the type declaration. |
protected JmlTypeDeclaration |
findTypeWithRepresentsFor(JmlTypeDeclaration tdecl,
CField field)
Finds the applicable representsclause for a given
model field by searching through the superclass and interface
hierachies starting from the given type declaration. |
protected JmlMethodDeclaration |
forNameMethod()
Returns a method declaration that returns the class object associated with the class or interface with the given string name. |
protected JmlMethodDeclaration |
ghostFieldAccessors(JmlFieldDeclaration fdecl)
Returns a pair of ghost field accessor methods (getter and setter) for the given ghost field declaration. |
static String |
ident()
Returns the identifier of the type currently being tranlated. |
protected JmlMethodDeclaration |
initFlags()
Returns declarations of class/instance initialization flags. |
protected boolean |
isAccessorGenerated(CField field)
Returns true if an accessor (or a delegation method) is already generated for a model or spec_public field, field. |
static boolean |
isInterface()
Returns true if the currently tranlated type is an interface. |
private static boolean |
isRepresentsDeclExecutable(JmlRepresentsDecl rdecl)
Returns true if the given represents
declaration is translatable. |
private JmlMethodDeclaration |
modelFieldAccessor(JmlSourceField field,
JExpression expr)
Returns a model accessor method for a model field with the given expression (of the represents clause). |
void |
postTranslationChangesForSpecTestFile(String wrapperClass)
|
private void |
prepareSpecTestFile()
|
protected abstract String |
receiver(String className,
String clazz,
String receiver)
Returns a string form of code that, if executed, returns the receiver of for a dynamic call. |
protected void |
setAccessorGenerated(CField field)
Indicates that an accessor (or a delegation method) has been generated for a model or spec_public field, field. |
void |
translate()
Translates the given type declaration. |
protected void |
translateBody(ArrayList inners,
ArrayList methods,
JPhylum[] fieldsAndInits)
Translates a class body, either of class or interface. |
protected abstract void |
translateConstraint()
Translates history constraints, both static and non-static. |
protected JmlFieldDeclaration |
translateField(JmlFieldDeclaration fieldDecl)
Translates a JML field declaration, fieldDecl. |
String |
translateForSpecTestFile()
|
protected abstract void |
translateInvariant()
Translates invariants, both static and non-static invariants. |
protected abstract void |
translateMethod(JmlMethodDeclaration mdecl)
Translates a JML method declaration. |
protected void |
translateModelMethod(JmlMethodDeclaration mdecl)
Translates the given model method (or constructor), mdecl. ! |
protected void |
translateRepresents(JmlRepresentsDecl[] repDecls)
Translates represents clauses of this type declaration. |
private String |
unwrap(CType t,
String val)
|
private String |
wrap(CType t,
String val)
|
| Methods inherited from class org.multijava.util.Utils |
assertTrue, assertTrue, combineArrays, escapeString, escapeString, fail, fail, getFilePath, hasFlag, hasOtherFlags, parsePathParts, relativePathTo, splitQualifiedName, splitQualifiedName, stripJavaModifiers, stripNonJavaModifiers, stripPrivateModifier, unescapeString, vectorToArray, vectorToIntArray |
| Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Field Detail |
public static boolean genSpecTestFile
public static boolean genWrapperClass
private ArrayList laterMethods
protected JmlTypeDeclaration typeDecl
protected invariant typeDecl.getCClass() == currentCClass;
protected VarGenerator varGen
private static CClass currentCClass
protected static boolean dynamicInvocationMethodNeeded
dynamicInvocationMethod()public static boolean specInheritanceMethodNeeded
TransExpression#visitJmlInvariantForExpression()protected Set modelMethods
translateRepresents(JmlRepresentsDecl[]),
translateField(JmlFieldDeclaration)| Constructor Detail |
protected TransType(JmlTypeDeclaration typeDecl)
TransType object.
typeDecl - target type declaration to be translated
requires typeDecl != null;
| Method Detail |
private void prepareSpecTestFile()
public void translate()
protected abstract void translateInvariant()
protected abstract void translateConstraint()
public String translateForSpecTestFile()
private String wrap(CType t,
String val)
private String unwrap(CType t,
String val)
public void postTranslationChangesForSpecTestFile(String wrapperClass)
protected void translateRepresents(JmlRepresentsDecl[] repDecls)
represents clauses of this type declaration.
For each executable (i.e., functinal abstraction) form of
represents clause, this method generates a
model field accessor method that calculates the value
of the model field in terms of the represents clause's
expression. The accessor method has the following general form:
[[represents m <- E;]] ==
protected T m() {
T v = T_init;
[[E, v]]
return v;
}
where T is the type of expression E
and v is a unique local variable.
The generated method declaration is added to the current type
(or surrogate class if the type is an interface), and the field
is marked that its model access method is generated.
requires repDecls != null;
translateField(JmlFieldDeclaration),
addNewMethod(JmlMethodDeclaration),
setAccessorGenerated(CField)protected void finalizeTranslation()
protected void translateBody(ArrayList inners,
ArrayList methods,
JPhylum[] fieldsAndInits)
inners - inner classesmethods - mthod declarationsfieldsAndInits - field declarations
requires inners != null && methods != null && fieldsAndInits != null;
protected JmlFieldDeclaration translateField(JmlFieldDeclaration fieldDecl)
fieldDecl. This method strips off the final
modifier from the field declaration. If necessary, this method
should be overwritten by subclasses to specially handle final,
model, model, spec_public, and spec_protected fields.
requires fieldDecl != null; modifies fieldDecl.*; ensures \result != null && \result == fieldDecl;
protected void translateModelMethod(JmlMethodDeclaration mdecl)
mdecl. !FIXME!describe translation rules.
protected abstract void translateMethod(JmlMethodDeclaration mdecl)
PreconditionMethod).
PostconditionMethod and
ExceptionalPostconditionMethod).
WappersMethod).
The translation also generate several new instance fields to store temporally values used by the assertion checking methods. There are three kinds of variables that are generated and declared as instance fields.
Similarly, translation of JML constructor declaration also produces
four new methods, and the original constructor becomes a wrapper
method (refer to the class TransConstructor).
requires mdecl != null;
protected JmlMethodDeclaration ghostFieldAccessors(JmlFieldDeclaration fdecl)
MN_GHOST + ident + "$" + className,
where the constant MN_GHOST is usually "ghost$"
and ident is the name of the ghost field. The
accessor methods has the following general structure:
public [static] T ghost$v$C() {
return v;
}
public [static] void ghost$v$C(T x) {
v = x;
}
This method also generates a private field for storing ghost
values and possibly an initializer block too. They are stored
in the given field declaration for later pretty-printing (see
RacPrettyPrinter.visitJmlFieldDeclaration).
private [static] T v;
[static] {
v = initializer;
}
requires fdecl != null && hasFlag(fdecl.modifiers(), ACC_GHOST); modifies fdecl.*; ensures \result != null;
protected JmlMethodDeclaration initFlags()
protected abstract void addNewMethod(JmlMethodDeclaration mdecl)
mdecl, to the
instrumented type.
private JmlMethodDeclaration modelFieldAccessor(JmlSourceField field,
JExpression expr)
represents clause).
field - model fieldexpr - the right hand side of the represents
clause (e.g., E in m <- E.
requires field != null && field.isModel() && expr != null; ensures \result != null;
protected JmlTypeDeclaration findTypeWithRepresentsFor(JmlTypeDeclaration tdecl,
CField field)
representsclause for a given
model field by searching through the superclass and interface
hierachies starting from the given type declaration. If such a
clause is found, returns the type declaration that includes the
clause; otherwise, returns null.
requires tdecl != null && field != null && hasFlag(field.modifiers(),ACC_MODEL); ensures \result != null ==> (* \result has represents clause r such that !r.isRedundantly() && r.usesAbstractionFunction() && r.storeRef() refers to field *);
private static boolean isRepresentsDeclExecutable(JmlRepresentsDecl rdecl)
true if the given represents
declaration is translatable. A represents declaration is
translatable if the following conditions are satisfied:
x <- E).
requires rdecl != null;
protected JmlMethodDeclaration dynamicInvocationMethod()
ensures \result != null;
protected JmlMethodDeclaration forNameMethod()
ensures \result != null;
protected abstract String receiver(String className,
String clazz,
String receiver)
dynamicInvocationMethod to define a
subclass-specific dynamic invocation method.
dynamicInvocationMethod()protected boolean isAccessorGenerated(CField field)
field.
protected void setAccessorGenerated(CField field)
field.
public static boolean dynamicCallNeeded(CClass clazz)
clazz. The return value is true if the
given class is not the same as the one being translated
now.
public static boolean isInterface()
public static String ident()
|
JML | ||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||||