Skip to content

Commit 8337e5a

Browse files
authored
Merge pull request #4 from okapi-web/develop
Develop
2 parents 8969d3b + 4a88cdb commit 8337e5a

12 files changed

+128
-51
lines changed

README.md

+10
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ composer require okapi/code-transformer
6363
- [Create a transformer](#create-a-transformer)
6464
- [Initialize the kernel](#initialize-the-kernel)
6565
- [Result](#result)
66+
- [Limitations](#limitations)
6667

6768

6869

@@ -251,6 +252,15 @@ $iAmAppended = true;
251252
```
252253

253254

255+
# Limitations
256+
257+
- Normally xdebug will point to the original source code, not the transformed
258+
one. The problem with this is if you add or remove a line of code, xdebug
259+
will point to the wrong line, so try to keep the number of lines the same
260+
as the original source code.
261+
262+
263+
254264
# How it works
255265

256266
- The `Kernel` registers multiple services

TODO.md

+5
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,8 @@ need optimization (e.g. Profilers or benchmarking suites).
2525

2626
# 7. Testing
2727
- Add tests for the `order` property of the `Transformer` class
28+
29+
# 8. Production/Development support
30+
- Add support for production/development environments:
31+
- Production: Cache will not be checked for updates (better performance).
32+
- Development: Cache will be checked for updates (better debugging experience).

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "okapi/code-transformer",
33
"description": "PHP Code Transformer is a PHP library that allows you to modify and transform the source code of a loaded PHP class.",
4-
"version": "1.3.0",
4+
"version": "1.3.1",
55
"type": "library",
66
"homepage": "https://github.com/okapi-web/php-code-transformer",
77
"license": "MIT",

phpunit.xml

+18-18
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
<?xml version="1.0" encoding="UTF-8"?>
2-
<phpunit
3-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
5-
colors="true"
6-
>
7-
<testsuites>
8-
<testsuite name="Tests">
9-
<directory>tests/</directory>
10-
</testsuite>
11-
</testsuites>
12-
13-
<coverage>
14-
<include>
15-
<directory suffix=".php">src/</directory>
16-
</include>
17-
</coverage>
18-
</phpunit>
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
5+
colors="true"
6+
>
7+
<testsuites>
8+
<testsuite name="Tests">
9+
<directory>tests/</directory>
10+
</testsuite>
11+
</testsuites>
12+
13+
<source>
14+
<include>
15+
<directory>src/</directory>
16+
</include>
17+
</source>
18+
</phpunit>

src/CodeTransformerKernel.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ abstract class CodeTransformerKernel
3232
private Options $options;
3333

3434
#[Inject]
35-
protected TransformerManager $transformerContainer;
35+
protected TransformerManager $transformerManager;
3636

3737
#[Inject]
3838
private CacheStateManager $cacheStateManager;
@@ -146,7 +146,7 @@ protected function preInit(): void
146146
);
147147

148148
// Add the transformers
149-
$this->transformerContainer->addTransformers($this->transformers);
149+
$this->transformerManager->addTransformers($this->transformers);
150150
}
151151

152152
/**
@@ -160,7 +160,7 @@ protected function registerServices(): void
160160
$this->options->register();
161161

162162
// Manage the user-defined transformers
163-
$this->transformerContainer->register();
163+
$this->transformerManager->register();
164164

165165
// Cache path manager
166166
$this->cacheStateManager->register();

src/Core/AutoloadInterceptor.php

+12-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
<?php
2-
2+
/** @noinspection PhpPropertyOnlyWrittenInspection */
33
namespace Okapi\CodeTransformer\Core;
44

55
use Composer\Autoload\ClassLoader as ComposerClassLoader;
6+
use DI\Attribute\Inject;
67
use Okapi\CodeTransformer\Core\AutoloadInterceptor\ClassLoader;
8+
use Okapi\CodeTransformer\Core\Util\ReflectionHelper;
79

810
/**
911
* # Autoload Interceptor
@@ -19,10 +21,12 @@
1921
*/
2022
class AutoloadInterceptor implements ServiceInterface
2123
{
22-
/**
23-
* The DI key for the original composer class loader.
24-
*/
25-
public const DI = 'okapi.code-transformer.service.composer.class-loader';
24+
// region DI
25+
26+
#[Inject]
27+
private ReflectionHelper $reflectionHelper;
28+
29+
// endregion
2630

2731
/**
2832
* Register the autoload interceptor.
@@ -59,17 +63,17 @@ private function overloadComposerLoaders(): void
5963

6064
// Get the original composer loader
6165
$originalClassLoader = $loader[0];
62-
DI::set(static::DI, $originalClassLoader);
66+
$this->reflectionHelper->setClassLoader($originalClassLoader);
6367

64-
// Register the AOP class loader
68+
// Create the Code Transformer class loader
6569
$loader[0] = DI::make(ClassLoader::class, [
6670
'originalClassLoader' => $originalClassLoader,
6771
]);
6872

6973
// Unregister the original composer loader
7074
spl_autoload_unregister($loaderToUnregister);
7175

72-
// Register the AOP class loader
76+
// Register the Code Transformer class loader
7377
spl_autoload_register($loader);
7478
}
7579
}

src/Core/AutoloadInterceptor/ClassLoader.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class ClassLoader extends ComposerClassLoader
2727
// region DI
2828

2929
#[Inject]
30-
private TransformerMatcher $transformerMatcher;
30+
protected TransformerMatcher $transformerMatcher;
3131

3232
#[Inject]
3333
protected CacheStateManager $cacheStateManager;

src/Core/Cache/CacheState/TransformedCacheState.php

+4
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ public function isFresh(): bool
5252
return false;
5353
// @codeCoverageIgnoreEnd
5454
}
55+
56+
if (filemtime($transformerFilePath) > $this->modificationTime) {
57+
return false;
58+
}
5559
}
5660

5761
return true;

src/Core/Cache/CacheStateManager.php

+1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ private function initializeCacheDirectory(): void
9292
Filesystem::mkdir(
9393
$this->options->getCacheDir(),
9494
$this->options->getCacheFileMode(),
95+
recursive: true,
9596
);
9697
}
9798

src/Core/Util/ReflectionHelper.php

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
/** @noinspection PhpInternalEntityUsedInspection */
3+
namespace Okapi\CodeTransformer\Core\Util;
4+
5+
use Composer\Autoload\ClassLoader;
6+
use Roave\BetterReflection\BetterReflection;
7+
use Roave\BetterReflection\Reflection\ReflectionClass;
8+
use Roave\BetterReflection\Reflector\DefaultReflector;
9+
use Roave\BetterReflection\SourceLocator\SourceStubber\ReflectionSourceStubber;
10+
use Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator;
11+
use Roave\BetterReflection\SourceLocator\Type\ComposerSourceLocator;
12+
use Roave\BetterReflection\SourceLocator\Type\PhpInternalSourceLocator;
13+
14+
/**
15+
* # Reflection Helper
16+
*
17+
* This class is used to get reflection class.
18+
*/
19+
class ReflectionHelper
20+
{
21+
private ClassLoader $classLoader;
22+
23+
/**
24+
* Set class loader.
25+
*
26+
* @param ClassLoader $classLoader
27+
*
28+
* @return void
29+
*/
30+
public function setClassLoader(ClassLoader $classLoader): void
31+
{
32+
$this->classLoader = $classLoader;
33+
}
34+
35+
/**
36+
* Get reflection class.
37+
*
38+
* @param class-string $namespacedClass
39+
*
40+
* @return ReflectionClass
41+
*/
42+
public function getReflectionClass(string $namespacedClass): ReflectionClass
43+
{
44+
$astLocator = (new BetterReflection())->astLocator();
45+
$reflector = new DefaultReflector(new AggregateSourceLocator([
46+
new ComposerSourceLocator($this->classLoader, $astLocator),
47+
new PhpInternalSourceLocator($astLocator, new ReflectionSourceStubber()),
48+
]));
49+
50+
return $reflector->reflectClass($namespacedClass);
51+
}
52+
}

src/Transformer/Code.php

+20-19
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
<?php
2-
2+
/** @noinspection PhpPropertyOnlyWrittenInspection */
33
namespace Okapi\CodeTransformer\Transformer;
44

5+
use DI\Attribute\Inject;
6+
use Microsoft\PhpParser\Node;
57
use Microsoft\PhpParser\Node\SourceFileNode;
68
use Microsoft\PhpParser\Parser;
79
use Microsoft\PhpParser\Token;
8-
use Okapi\CodeTransformer\Core\AutoloadInterceptor;
910
use Okapi\CodeTransformer\Core\DI;
1011
use Okapi\CodeTransformer\Core\Util\CodeChecker;
12+
use Okapi\CodeTransformer\Core\Util\ReflectionHelper;
1113
use Okapi\CodeTransformer\Core\Util\StringMutator;
12-
use Roave\BetterReflection\BetterReflection;
1314
use Roave\BetterReflection\Reflection\ReflectionClass as BetterReflectionClass;
14-
use Roave\BetterReflection\Reflector\DefaultReflector;
15-
use Roave\BetterReflection\SourceLocator\Type\ComposerSourceLocator;
1615

1716
/**
1817
* # Code
@@ -22,6 +21,13 @@
2221
*/
2322
class Code
2423
{
24+
// region DI
25+
26+
#[Inject]
27+
private ReflectionHelper $reflectionHelper;
28+
29+
// endregion
30+
2531
/**
2632
* String mutator.
2733
*
@@ -64,13 +70,16 @@ public function __construct(
6470
/**
6571
* Add an edit to the source code.
6672
*
67-
* @param Token $token The token to edit.
68-
* @param string $replacement The replacement string.
73+
* @param Token|Node $token The token or node to edit.
74+
* @param string $replacement The replacement string.
6975
*
7076
* @return void
77+
*
78+
* @noinspection PhpDocMissingThrowsInspection
7179
*/
72-
public function edit(Token $token, string $replacement): void
80+
public function edit(Token|Node $token, string $replacement): void
7381
{
82+
/** @noinspection PhpUnhandledExceptionInspection */
7483
$this->stringMutator->edit(
7584
$token->getStartPosition(),
7685
$token->getWidth(),
@@ -146,17 +155,9 @@ public function getSourceFileNode(): SourceFileNode
146155
*/
147156
public function getReflectionClass(): BetterReflectionClass
148157
{
149-
static $classLoader, $astLocator, $reflector;
150-
151-
if (!isset($classLoader, $astLocator, $reflector)) {
152-
$classLoader = DI::get(AutoloadInterceptor::DI);
153-
$astLocator = (new BetterReflection)->astLocator();
154-
$reflector = (new DefaultReflector(
155-
new ComposerSourceLocator($classLoader, $astLocator)
156-
));
157-
}
158-
159-
return $reflector->reflectClass($this->getNamespacedClass());
158+
return $this->reflectionHelper->getReflectionClass(
159+
$this->getNamespacedClass(),
160+
);
160161
}
161162

162163
/**

tests/Stubs/Kernel/AddedTransformerKernel.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ protected function preInit(): void
1414
{
1515
parent::preInit();
1616

17-
$this->transformerContainer->addTransformers($this->addedTransformers);
17+
$this->transformerManager->addTransformers($this->addedTransformers);
1818
}
1919
}

0 commit comments

Comments
 (0)