Contexts And Capabilities: Local Operations
Note: Context and capabilities are enabled by default since HHVM 4.93.
The existence of a capability (or lack thereof) within the contexts of a function plays a direct role in the operations allowed within that function.
Consider the following potential (although not necessarily planned) contexts (with implied matching capabilities):
throws<T>
, representing the permission to throw an exception typeTe <: T
io
, representing the permission to do iostatics
, representing the permission to access static members and global variableswrite_prop
, representing the permission to mutate properties of objectsdynamic
, representing the permission to cast a value to thedynamic
type
In all of the below cases, the relevant local operations successfully typecheck due to the matching capabilities within the context of the function.
function io_good()[io]: void {
echo "good"; // ok
print "also ok"; // also ok
}
class FooException extends Exception {}
class FooChildException extends FooException {}
class BarException extends Exception {}
function throws_foo_exception()[throws<FooException>]: void {
throw new FooException(); // ok: FooException <: FooException
throw new FooChildException(); // ok: FooChildException <: FooException
}
function throws_bar_exception()[throws<BarException>]: void {
throw new BarException(); // ok: BarException <: BarException
}
function throws_foo_and_bar_exceptions()[throws<FooException>, throws<BarException>]: void {
throw new FooException(); // ok: FooException <: FooException
throw new FooChildException(); // ok: FooChildException <: FooException
throw new BarException(); // ok: BarException <: BarException
}
class HasAStatic {
public static int $i = 0;
}
function reads_and_writes_static()[statics]: void {
HasAStatic::$i++;
}
class SomeClass {
public int $i = 0;
}
function reads_and_writes_prop(SomeClass $sc)[write_props]: void {
$sc->i++;
}
function casts_to_dynamic(int $in)[dynamic]: void {
invokes_off_dynamic($in as dynamic);
}
function invokes_off_dynamic(dynamic $in)[]: void {
$in->thisIsbananasAndDefinitelyThrowsButTypechecks();
}
Thank You!
Thank You! If you'd like to share more feedback, please file an issue.