Implements #149, see https://wiki.php.net/rfc/marking_overriden_methods. In comparison with #172, these checks are always performed during compilation (even for PHP 8.3+, as there is no measurable performance impact in doing so and we prevent uncatchable fatal errors).
In a nutshell
This first example works without any problem (as would simply omitting this annotation):
use Override;
use lang\Throwable;
class CannotConnect extends Throwable {
#[Override]
public function compoundMessage() { }
}
The following all raise compile errors:
use Override;
use lang\{Runnable, Throwable};
// No parent class
class CannotConnect {
#[Override]
public function compoundMessage() { }
}
// Parent class doesn't have such a method
class CannotConnect extends Throwable {
#[Override]
public function composeMessage() { }
}
// None of the implemented interfaces have such a method
class RunOnce implements Runnable {
#[Override]
public function doRun() { }
}
Performance impact
👉 Not measurable
Before:
$ xp test src/test/php/
# ...
Test cases: 945 succeeded, 3 skipped
Memory used: 11531.30 kB (11585.42 kB peak)
Time taken: 0.227 seconds (0.636 seconds overall)
After:
$ xp test src/test/php/
# ...
Test cases: 955 succeeded, 3 skipped
Memory used: 11649.20 kB (11703.33 kB peak)
Time taken: 0.233 seconds (0.632 seconds overall)
Implements #149, see https://wiki.php.net/rfc/marking_overriden_methods. In comparison with #172, these checks are always performed during compilation (even for PHP 8.3+, as there is no measurable performance impact in doing so and we prevent uncatchable fatal errors).
In a nutshell
This first example works without any problem (as would simply omitting this annotation):
The following all raise compile errors:
Performance impact
👉 Not measurable
Before:
After: