Skip to content

Commit 12ef25e

Browse files
committed
bypassed keywords are configurable
1 parent 8ad37fb commit 12ef25e

File tree

5 files changed

+35
-5
lines changed

5 files changed

+35
-5
lines changed

readme.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ preferably right after `vendor/autoload.php` is loaded.
4040

4141
Note that final internal PHP classes like `Closure` cannot be mocked.
4242

43+
The removal of `readonly` keywords can be disabled using the parameter:
44+
45+
```php
46+
DG\BypassFinals::enable(bypassReadOnly: false);
47+
```
48+
4349
You can choose to only bypass keywords in specific files or directories:
4450

4551
```php

src/BypassFinals.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,17 @@ class BypassFinals
2828
private static $cacheDir;
2929

3030
/** @var array */
31-
private static $tokens = [
32-
T_FINAL => 'final',
33-
];
31+
private static $tokens = [];
3432

3533

36-
public static function enable(): void
34+
public static function enable(bool $bypassReadOnly = true, bool $bypassFinal = true): void
3735
{
38-
if (PHP_VERSION_ID >= 80100) {
36+
if ($bypassReadOnly && PHP_VERSION_ID >= 80100) {
3937
self::$tokens[T_READONLY] = 'readonly';
4038
}
39+
if ($bypassFinal) {
40+
self::$tokens[T_FINAL] = 'final';
41+
}
4142

4243
$wrapper = stream_get_meta_data(fopen(__FILE__, 'r'))['wrapper_data'] ?? null;
4344
if ($wrapper instanceof self) {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/** @phpVersion 8.2 */
4+
5+
declare(strict_types=1);
6+
7+
use Tester\Assert;
8+
9+
require __DIR__ . '/../../vendor/autoload.php';
10+
11+
Tester\Environment::setup();
12+
13+
14+
DG\BypassFinals::enable(bypassReadOnly: false);
15+
16+
require __DIR__ . '/fixtures/final.readonly.class.php';
17+
18+
$rc = new ReflectionClass('FinalReadonlyClass');
19+
Assert::true($rc->isReadOnly());
20+
Assert::false($rc->isFinal());
21+
Assert::true($rc->getProperty('foo')->isReadOnly());

tests/BypassFinals/BypassFinals.readonly+final.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ $rc = new ReflectionClass('FinalReadonlyClass');
1919
Assert::false($rc->isReadOnly());
2020
Assert::false($rc->isFinal());
2121
Assert::false($rc->getMethod('finalMethod')->isFinal());
22+
Assert::false($rc->getProperty('foo')->isReadOnly());
2223
Assert::same(123, FinalReadonlyClass::FINAL);
2324
Assert::same(456, (new FinalReadonlyClass)->final());

tests/BypassFinals/fixtures/final.readonly.class.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
final readonly class FinalReadonlyClass
55
{
66
const FINAL = 123;
7+
public readonly int $foo;
78

89
final function finalMethod()
910
{

0 commit comments

Comments
 (0)