@Documented @Retention(value=RUNTIME) @Target(value={TYPE,CONSTRUCTOR,METHOD,FIELD}) public @interface Assume
This annotation is trusted, i.e., it is not verified.
The scope of the assumption is the entire compilation unit that the
annotation appears within—regardless of the annotated element (e.g.,
type, constructor, method, or field). Allowing the Assume annotation
on declarations within the compilation unit lets the programmer place the
assumption closer, syntactically, to where it is needed. The scope of the
assumption is not changed, it remains the entire compilation unit.
The general form of an Assume annotation is
@Assume("promise for target
")
Where the promise is assumed on all declarations matched by
target. For example, the below assumes a
@Starts("nothing") annotation on the no-argument
constructor for IllegalArgumentException. The assumption supports the
@Starts("nothing") promised on the method.
@Starts("nothing")
@Assume("Starts(nothing) for new() in IllegalArgumentException in java.lang")
public Rendezvous(int parties, RendezvousFunction function) {
if (parties <= 0)
throw new IllegalArgumentException();
...
}
It is a modeling error to omit the for clause. Further, it is a
modeling error for target to match code within the scope of the
assumption. For example, the below annotation making an assumption within the
scope that the assumption applies is not well-formed.
package com.surelogic.example;
// BAD - Modeling Error
@Assume("Starts(nothing) for init() in Foo in com.surelogic.example")
class Foo {
public void init() { ... }
}
The syntax for promise is the same as if the promise was written in
the code except that all "'s are removed (e.g.,
@Borrowed("this") becomes @Borrowed(this)
).
To declare more than one scoped promise for an entity use the Assumes
annotation. It is a modeling error for an entity to have both a
Assumes and a Assume annotation.
Assume annotation
appears, from the point of view of the verifying analyses, it is as if these
virtual promises were annotated by the programmer. If a virtual promise
exists as a real promise then the assumption has no semantics. If the virtual
promise does not exist as a real promise then it is "trusted" (i.e., not
verified). The results reported from tools, such as SureLogic JSure, should
make it clear to the programmer that the promise has not been verified.
Note that Assume serves a different role than Vouch.
Assumptions are used to express an expectation by the programmer about the
evolving model—irrespective of whether or not the expectation can be
verified. Assumptions act as a cut point for the programmer, allowing them to
formally express their belief that the assumed property is true, and continue
model expression based upon that belief. For example, the programmer assumes
something about code that they are not allowed to change, perhaps due to an
organizational constraint of some sort. In contrast, vouches made by the
programmer are typically applied in situations where a static verification
tool, such as JSure, is unable to verify the programmer's implementation to
be consistent with the expressed model.
Assume annotations on a class
C:
Foo. The '**'
pattern indicates any number of parameters including zero. If there is more
than one Foo type then the assumption is made for all of them.com.surelogic. The '**(**)' pattern
matches both methods and constructors. The '*(**)' pattern only
matches methods.@annotate tag.
/**
* @annotate Assume("Starts(nothing) for new() in IllegalArgumentException in java.lang")
*/
public Rendezvous(int parties, RendezvousFunction function) { ... }
| Modifier and Type | Required Element and Description |
|---|---|
String |
value
The value of this attribute must conform to the following grammar (in Augmented Backus–Naur
Form):
|
public abstract String value
value = Payload [ "for" Target ]
Payload = A promise with "'s removed, e.g., @Borrowed("this") becomes @Borrowed(this)
Target =
TypeDecPat / FieldDecPat / MethodDecPat/ ConstructorDecPat /
Target "|" Target /
Target "&" Target /
[ "!" ] "(" Target ")"
TypeDecPat = [ Visibility ] ( QualifiedName / IdentifierPat [ InPackagePat ] )
FieldDecPat = [ Visibility ] [ Static ] TypeSigPat IdentifierPat [ InTypePat ]
MethodDecPat = [ Visibility ] [ Static ] IdentifierPat "(" [ ParameterSigPat ] ")" [ InTypePat ]
ConstructorDecPat = [ Visibility ] "new" "(" [ ParameterSigPat ] ")" [ InTypePat ]
TypeSigPat =
"*" /
( "boolean" / "char" / "byte" / "short" /
"int" / "long" / "float" / "double" / "void" /
IdentifierPat / QualifiedName ) *( "[]" )
ParameterSigPat = ( TypeSigPat / "**" ) *("," ( TypeSigPat / "**" ) )
InNameExp =
QualifiedNamePat /
InNameExp "|" InNameExp /
InNameExp "&" InNameExp /
[ "!" ] "(" InNameExp ")"
InNamePat =
QualifiedNamePat /
"(" InNameExp ")"
InPackagePat = "in" InNamePat
InTypePat = "in" InNamePat [ InPackagePat ]
Visibility = "public" / "protected" / "private"
Static = [ "!" ] "static"
IdentifierPat = [ "*" ] ( Identifier *("*" Identifier) ) [ "*" ]
QualifiedNamePat = ( IdentifierPat / "*" / "**" ) *("." ( IdentifierPat / "*" / "**" ) )
QualifiedName = Identifier *("." Identifier)
IDENTIFIER = Legal Java Identifier
Copyright © 2012 Surelogic, Inc.. All Rights Reserved.