@Documented @Retention(value=RUNTIME) @Target(value={FIELD,CONSTRUCTOR,METHOD,PARAMETER}) public @interface Unique
Borrowed. That is,
Unique values can be safely passed to the parameter or used as the
receiver with the guarantee that they will still be unique when the method
returns. Said another way we create a temporary alias on the stack then
ensure that it goes away.
Setting the allowRead=true attribute weakens the uniqueness
guarantees: it permits there to be @ReadOnly aliases.
In other words, only the ability to write (mutate) is restricted to this
alias. Once a unique reference has granted allowRead, there is no
going back, unlike with (temporary) borrowed references.
This attribute is not currently
checked by analysis.
Annotating @Unique("return") on a constructor is defined to
be equivalent to annotating @Borrowed("this"). Either of
these annotations indicates that the object being constructed is not aliased
during construction, which implies that the reference "returned" by the
new expression that invokes the constructor is unique. Which
annotation is preferred, @Unique("return") or
@Borrowed("this"), is a matter of programmer preference.
Methods that override a method annotated with
@Unique("return") must also be explicitly annotated
@Unique("return"). It is a modeling error if they are not.
Methods that override a method with a @Unique parameter are
not required to maintain that parameter's uniqueness (uniqueness on a
parameter is contravariant), but may via explicit annotation.
Annotating @Unique on a field is defined to mean that the
Instance region of the object referenced by the annotated field is
mapped into the Instance region of the object that contains the
annotated field if the annotated field is final. If the annotated
field is not final, the Instance region of the object
referenced by the annotated field is mapped into the field itself. A
final static field cannot be annotated with
@Unique: the annotation UniqueInRegion must be used
instead.
It is a modeling error to annotate a reference if the type is primitive. For example,
@Unique("return") public int getValue() { … }
and
public void setValue(@Unique int value) { … }
would generate modeling errors.
null or refers to an object that is not
referenced by a field of any object.
Return Value: The value returned by the annotated method is
null or is an object that is not referenced by a field of any
object.
Receiver: For a method, the object the method was invoked upon, at any call to the method must be a unique reference. This places an assertion on the caller of a method, not upon the method implementation itself.
Field: At all times, the value of the annotated field is either
null or is an object that is not referenced by a field of any
other object or another field of the same object. The Instance region
of the object referenced by the annotated field is mapped into the
Instance region of the object that contains the annotated field.
getUniqueObject ensures
that the returned reference is unique by creating a new object.
public class UniqueField {
@Unique
private Object o;
public void setField(@Unique Object value) {
o = value;
process(o);
}
@Unique("return")
public Object getUniqueObject() {
return new Object();
}
@RegionEffects("reads value:Instance")
public static void process(@Borrowed Object value) {
// for future processing
}
}
The call to process is allowed because that method promises that the
alias to o created by the value parameter will be returned
once the method call completes. However, process must also promise
not to read state outside of its passed parameters. This is done with the
RegionEffects annotation on the process method declaration.
This annotation is often used to support a RegionLock assertion on a
constructor because if the receiver is not leaked during object construction
then the state under construction will remain within the thread that invoked
new.
@RegionLock("Lock is this protects Instance")
public class Example {
int x = 1;
int y;
@Unique("return")
public Example(int y) {
this.y = y;
}
...
}
The scoped promise Promise can be used if the constructor is implicit
(i.e., generated by the compiler). It has the ability to place promises on
implicit and explicit constructors.
@RegionLock("Lock is this protects Instance")
@Promise("@Unique(return) for new(**)")
public class Example {
int x = 1;
int y = 1;
...
}
@annotate tag. One complication is that the parameter being
annotated must be explicitly specified because the annotation can no longer
appear in the context of the parameter declaration.
/**
* @annotate Unique("a, b, c")
*/
public void m1(Object a, Object b, Object c) { ... }
This annotation states that the three parameters are unique. Alternatively,
you can use several annotations as shown below.
/**
* @annotate Unique("a")
* @annotate Unique("b")
* @annotate Unique("c")
*/
public void m1(Object a, Object b, Object c) { ... }
| Modifier and Type | Optional Element and Description |
|---|---|
boolean |
allowRead
Setting the this attribute to
true weakens the uniqueness
guarantees: it permits there to be @ReadOnly aliases of
the referenced object. |
String |
value
When annotating a method, this attribute is used to disambiguate whether
the annotation refers to the method's receiver, the method's return value,
or both.
|
public abstract String value
""
"this"
"return"
"this, return"
"return, this"
The values are interpreted thusly
"this", it indicates the
receiver is unique. This value is only allowed on methods.
"return", it indicates the
return value is unique. This value is allowed on methods and constructors.
"this" and "return", it
indicates that both the receiver and the return value are unique. This
value is only allowed on methods.
This attribute is not used when annotating a parameter or a field: the attribute value must be the empty string in these cases.
The value of this attribute must conform to the following grammar (in Augmented Backus–Naur Form):
value = [("this" ["," "return"]) / ("return" ["," "this"])] ; See above comments
public abstract boolean allowRead
true weakens the uniqueness
guarantees: it permits there to be @ReadOnly aliases of
the referenced object. In other words, only the ability to write (mutate)
is restricted to this alias. This attribute is not currently
checked by analysis.Copyright © 2012 Surelogic, Inc.. All Rights Reserved.