# Supported docblock annotations Psalm supports a wide range of docblock annotations. ## PHPDoc tags Psalm uses the following PHPDoc tags to understand your code: - [`@var`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/var.html) Used for specifying the types of properties and variables - [`@return`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/return.html) Used for specifying the return types of functions, methods and closures - [`@param`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/param.html) Used for specifying types of parameters passed to functions, methods and closures - [`@property`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/property.html) Used to specify what properties can be accessed on an object that uses `__get` and `__set` - [`@property-read`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/property.html) Used to specify what properties can be read on object that uses `__get` - [`@property-write`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/property.html) Used to specify what properties can be written on object that uses `__set` - [`@method`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/method.html) Used to specify which magic methods are available on object that uses `__call`. - [`@deprecated`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/deprecated.html) Used to mark functions, methods, classes and interfaces as being deprecated - [`@internal`](https://docs.phpdoc.org/latest/guide/references/phpdoc/tags/internal.html) Used to mark classes, functions and properties that are internal to an application or library. - [`@mixin`](#mixins) Used to tell Psalm that the current class proxies the methods and properties of the referenced class. ### Off-label usage of the `@var` tag The `@var` tag is supposed to only be used for properties. Psalm, taking a lead from PHPStorm and other static analysis tools, allows its use inline in the form `@var Type [VariableReference]`. If `VariableReference` is provided, it should be of the form `$variable` or `$variable->property`. If used above an assignment, Psalm checks whether the `VariableReference` matches the variable being assigned. If they differ, Psalm will assign the `Type` to `VariableReference` and use it in the expression below. If no `VariableReference` is given, the annotation tells Psalm that the right-hand side of the expression, whether an assignment or a return, is of type `Type`. ```php $name(...$arguments); } public function __get($name) { (new A())->$name; } } $b = new B(); $b->doB(); $b->doA(); // works echo $b->b; echo $b->a; // works ``` ## Psalm-specific tags There are a number of custom tags that determine how Psalm treats your code. ### `@psalm-consistent-constructor` See [UnsafeInstantiation](../running_psalm/issues/UnsafeInstantiation.md) ### `@psalm-consistent-templates` See [UnsafeGenericInstantiation](../running_psalm/issues/UnsafeGenericInstantiation.md) ### `@param-out`, `@psalm-param-out` This is used to specify that a by-ref type is different from the one that entered. In the function below the first param can be null, but once the function has executed the by-ref value is not null. ```php $f */ function getTimes(int $n): iterable { while ($n--) { yield new \DateTime(); } }; /** * @var \Datetime[] $times * @psalm-ignore-var */ $times = getTimes(3); // this trace shows "iterable" instead of "array" /** @psalm-trace $times */ foreach ($times as $time) { echo $time->format('Y-m-d H:i:s.u') . PHP_EOL; } ``` ### `@psalm-suppress SomeIssueName` This annotation is used to suppress issues. It can be used in function docblocks, class docblocks and also inline, applying to the following statement. Function docblock example: ```php 1 ? new Foo() : null; } takesFoo(getFoo()); ``` ### `@psalm-ignore-falsable-return` This provides the same, but for `false`. Psalm uses this internally for functions like `preg_replace`, which can return false if the given input has encoding errors, but where 99.9% of the time the function operates as expected. ### `@psalm-seal-properties`, `@psalm-no-seal-properties` If you have a magic property getter/setter, you can use `@psalm-seal-properties` to instruct Psalm to disallow getting and setting any properties not contained in a list of `@property` (or `@property-read`/`@property-write`) annotations. This is automatically enabled with the configuration option `sealAllProperties` and can be disabled for a class with `@psalm-no-seal-properties` ```php bar = 5; // this call fails ``` ### `@psalm-seal-methods`, `@psalm-no-seal-methods` If you have a magic method caller, you can use `@psalm-seal-methods` to instruct Psalm to disallow calling any methods not contained in a list of `@method` annotations. This is automatically enabled with the configuration option `sealAllMethods` and can be disabled for a class with `@psalm-no-seal-methods` ```php bar(); // this call fails ``` ### `@psalm-internal` Used to mark a class, property or function as internal to a given namespace. Psalm treats this slightly differently to the PHPDoc `@internal` tag. For `@internal`, an issue is raised if the calling code is in a namespace completely unrelated to the namespace of the calling code, i.e. not sharing the first element of the namespace. In contrast for `@psalm-internal`, the docblock line must specify a namespace. An issue is raised if the calling code is not within the given namespace. ```php s = $s; } } $b = new B("hello"); echo $b->s; $b->s = "boo"; // disallowed ``` ### `@psalm-mutation-free` Used to annotate a class method that does not mutate state, either internally or externally of the class's scope. This requires that the return value depend only on the instance's properties. For example, `random_int` is considered mutating here because it mutates the random number generator's internal state. ```php s = $s; } /** * @psalm-mutation-free */ public function getShort() : string { return substr($this->s, 0, 5); } /** * @psalm-mutation-free */ public function getShortMutating() : string { $this->s .= "hello"; // this is a bug return substr($this->s, 0, 5); } } ``` ### `@psalm-external-mutation-free` Used to annotate a class method that does not mutate state externally of the class's scope. ```php s = $s; } /** * @psalm-external-mutation-free */ public function getShortMutating() : string { $this->s .= "hello"; // this is fine return substr($this->s, 0, 5); } /** * @psalm-external-mutation-free */ public function save() : void { file_put_contents("foo.txt", $this->s); // this is a bug } } ``` ### `@psalm-immutable` Used to annotate a class where every property is treated by consumers as `@psalm-readonly` and every instance method is treated as `@psalm-mutation-free`. ```php baz = $baz; } public function bar(): int { return 0; } } $anonymous = new /** @psalm-immutable */ class extends Foo { public string $baz = "B"; public function bar(): int { return 1; } }; ``` ### `@psalm-pure` Used to annotate a [pure function](https://en.wikipedia.org/wiki/Pure_function) - one whose output is just a function of its input. ```php random_int(1, 2) ); ``` ### `@psalm-allow-private-mutation` Used to annotate readonly properties that can be mutated in a private context. With this, public properties can be read from another class but only be mutated within a method of its own class. ```php count++; } } $counter = new Counter(); echo $counter->count; // outputs 0 $counter->increment(); // Method can mutate property echo $counter->count; // outputs 1 $counter->count = 5; // This will fail, as it's mutating a property directly ``` ### `@psalm-readonly-allow-private-mutation` This is a shorthand for the property annotations `@readonly` and `@psalm-allow-private-mutation`. ```php count++; } } $counter = new Counter(); echo $counter->count; // outputs 0 $counter->increment(); // Method can mutate property echo $counter->count; // outputs 1 $counter->count = 5; // This will fail, as it's mutating a property directly ``` ### `@psalm-trace` You can use this annotation to trace inferred type (applied to the *next* statement). ```php ``` ### `@psalm-check-type` You can use this annotation to ensure the inferred type matches what you expect. ```php "Nokia"]; } } ``` ### `@psalm-import-type` You can use this annotation to import a type defined with [`@psalm-type`](#psalm-type) if it was defined somewhere else. ```php toArray()); } } ``` You can also alias a type when you import it: ```php toArray()); } } ``` ### `@psalm-require-extends` The `@psalm-require-extends` annotation allows you to define the requirements that a trait imposes on the using class. ```php ` without `@no-named-arguments` but becomes `list` with it, because it excludes the case where the offset would be a string with the name of the parameter ### `@psalm-ignore-variable-property` and `@psalm-ignore-variable-method` Instructs Psalm to ignore variable property fetch / variable method call when looking for dead code. ```php class Foo { // this property can be deleted by Psalter, // as potential reference in get() is ignored public string $bar = 'bar'; public function get(string $name): mixed { /** @psalm-ignore-variable-property */ return $this->{$name}; } } ``` When Psalm encounters variable property, it treats all properties in given class as potentially referenced. With `@psalm-ignore-variable-property` annotation, this reference is ignored. While `PossiblyUnusedProperty` would be emitted in both cases, using `@psalm-ignore-variable-property` would allow [Psalter](../manipulating_code/fixing.md) to delete `Foo::$bar`. `@psalm-ignore-variable-method` behaves the same way, but for variable method calls. ### `@psalm-yield` Used to specify the type of value which will be sent back to a generator when an annotated object instance is yielded. ```php */ class Success implements Promise { /** * @psalm-param TValue $value */ public function __construct($value) {} } /** * @return Promise */ function fetch(): Promise { return new Success('{"data":[]}'); } function (): Generator { $data = yield fetch(); // this is fine, Psalm knows that $data is a string return json_decode($data); }; ``` This annotation supports only generic types, meaning that e.g. `@psalm-yield string` would be ignored. ### `@api`, `@psalm-api` Used to tell Psalm that a class or method is used, even if no references to it can be found. Unused issues will be suppressed. For example, in frameworks, controllers are often invoked "magically" without any explicit references to them in your code. You should mark these classes with `@psalm-api`. ```php /** * @psalm-api */ class UnreferencedClass {} ``` ### `@psalm-inheritors` Used to tell Psalm that a class can only be extended by a certain subset of classes. For example, ```php