This snippet gives Method "specialMethod" does not exist on class "Node" on the last line (and also no completion), but the @implements generic annotation should tell Phpactor that $node is an instance of SpecificNode (both PHPStan and Psalm support this).
interface Node {}
/** @template T of Node */
interface NodeVisitor
{
/** @param T $node */
public function enter(Node $node): void;
}
class SpecificNode implements Node
{
public function specialMethod(): string
{
return 'special';
}
}
/** @implements NodeVisitor<SpecificNode> */
class SpecificNodeVisitor implements NodeVisitor
{
public function enter(Node $node): void
{
$node->specialMethod(); // E: Method "specialMethod" does not exist on class "Node"
}
}
This snippet gives
Method "specialMethod" does not exist on class "Node"on the last line (and also no completion), but the@implementsgeneric annotation should tell Phpactor that$nodeis an instance ofSpecificNode(both PHPStan and Psalm support this).