Skip to main content

Introduction

Attributes attach metadata to Hack definitions.

Hack provides built-in attributes that can change runtime or typechecker behavior.

<<__Memoize>>
function add_one(int $x): int {
return $x + 1;
}

You can attach multiple attributes to a definition, and attributes can have arguments.

<<__ConsistentConstruct>>
class OtherClass {
<<__Memoize, __Deprecated("Use FooClass methods instead")>>
public function addOne(int $x): int {
return $x + 1;
}
}

Defining an attribute

You can define your own attribute by implementing an attribute interface in the HH namespace.

class Contributors implements HH\ClassAttribute {
public function __construct(private string $author, private ?keyset<string> $maintainers = null) {}
public function getAuthor(): string {
return $this->author;
}
public function getMaintainers(): keyset<string> {
return $this->maintainers ?? keyset[$this->author];
}
}

<<Contributors("John Doe", keyset["ORM Team", "Core Library Team"])>>
class MyClass {}

<<Contributors("You")>>
class YourClass {}

The full set of attribute interfaces is shown below. Each interface restricts where the attribute may be attached.

InterfaceApplies to
HH\ClassAttributea class
HH\ClassConstantAttributea constant of a class
HH\EnumAttributean enum
HH\EnumClassAttributean enum class
HH\TypeAliasAttributea type, newtype or case type
HH\FunctionAttributea function
HH\MethodAttributea method
HH\InstancePropertyAttributean instance property
HH\StaticPropertyAttributea static property
HH\ParameterAttributea parameter
HH\TypeParameterAttributea type parameter
HH\TypeConstantAttributea type constant
HH\FileAttributea file
HH\LambdaAttributea lambda expression
HH\ModuleAttributea module

See the Hack interface reference for the full signature of each interface.

Accessing attribute arguments

You need to use reflection to access attribute arguments.

Given the MyClass example defined above:

$rc = new ReflectionClass('MyClass');
$my_class_contributors = $rc->getAttributeClass(Contributors::class);
$my_class_contributors?->getAuthor(); // "John Doe"
$my_class_contributors?->getMaintainers(); // keyset["ORM Team", "Core Library Team"]