Skip to content

Develop #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ composer require okapi/code-transformer
- [Create a transformer](#create-a-transformer)
- [Initialize the kernel](#initialize-the-kernel)
- [Result](#result)
- [Limitations](#limitations)



Expand Down Expand Up @@ -251,6 +252,15 @@ $iAmAppended = true;
```


# Limitations

- Normally xdebug will point to the original source code, not the transformed
one. The problem with this is if you add or remove a line of code, xdebug
will point to the wrong line, so try to keep the number of lines the same
as the original source code.



# How it works

- The `Kernel` registers multiple services
Expand Down
5 changes: 5 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,8 @@ need optimization (e.g. Profilers or benchmarking suites).

# 7. Testing
- Add tests for the `order` property of the `Transformer` class

# 8. Production/Development support
- Add support for production/development environments:
- Production: Cache will not be checked for updates (better performance).
- Development: Cache will be checked for updates (better debugging experience).
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "okapi/code-transformer",
"description": "PHP Code Transformer is a PHP library that allows you to modify and transform the source code of a loaded PHP class.",
"version": "1.3.0",
"version": "1.3.1",
"type": "library",
"homepage": "https://github.com/okapi-web/php-code-transformer",
"license": "MIT",
Expand Down
36 changes: 18 additions & 18 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
colors="true"
>
<testsuites>
<testsuite name="Tests">
<directory>tests/</directory>
</testsuite>
</testsuites>
<coverage>
<include>
<directory suffix=".php">src/</directory>
</include>
</coverage>
</phpunit>
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
colors="true"
>
<testsuites>
<testsuite name="Tests">
<directory>tests/</directory>
</testsuite>
</testsuites>

<source>
<include>
<directory>src/</directory>
</include>
</source>
</phpunit>
6 changes: 3 additions & 3 deletions src/CodeTransformerKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ abstract class CodeTransformerKernel
private Options $options;

#[Inject]
protected TransformerManager $transformerContainer;
protected TransformerManager $transformerManager;

#[Inject]
private CacheStateManager $cacheStateManager;
Expand Down Expand Up @@ -146,7 +146,7 @@ protected function preInit(): void
);

// Add the transformers
$this->transformerContainer->addTransformers($this->transformers);
$this->transformerManager->addTransformers($this->transformers);
}

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

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

// Cache path manager
$this->cacheStateManager->register();
Expand Down
20 changes: 12 additions & 8 deletions src/Core/AutoloadInterceptor.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<?php

/** @noinspection PhpPropertyOnlyWrittenInspection */
namespace Okapi\CodeTransformer\Core;

use Composer\Autoload\ClassLoader as ComposerClassLoader;
use DI\Attribute\Inject;
use Okapi\CodeTransformer\Core\AutoloadInterceptor\ClassLoader;
use Okapi\CodeTransformer\Core\Util\ReflectionHelper;

/**
* # Autoload Interceptor
Expand All @@ -19,10 +21,12 @@
*/
class AutoloadInterceptor implements ServiceInterface
{
/**
* The DI key for the original composer class loader.
*/
public const DI = 'okapi.code-transformer.service.composer.class-loader';
// region DI

#[Inject]
private ReflectionHelper $reflectionHelper;

// endregion

/**
* Register the autoload interceptor.
Expand Down Expand Up @@ -59,17 +63,17 @@ private function overloadComposerLoaders(): void

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

// Register the AOP class loader
// Create the Code Transformer class loader
$loader[0] = DI::make(ClassLoader::class, [
'originalClassLoader' => $originalClassLoader,
]);

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

// Register the AOP class loader
// Register the Code Transformer class loader
spl_autoload_register($loader);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Core/AutoloadInterceptor/ClassLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class ClassLoader extends ComposerClassLoader
// region DI

#[Inject]
private TransformerMatcher $transformerMatcher;
protected TransformerMatcher $transformerMatcher;

#[Inject]
protected CacheStateManager $cacheStateManager;
Expand Down
4 changes: 4 additions & 0 deletions src/Core/Cache/CacheState/TransformedCacheState.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ public function isFresh(): bool
return false;
// @codeCoverageIgnoreEnd
}

if (filemtime($transformerFilePath) > $this->modificationTime) {
return false;
}
}

return true;
Expand Down
1 change: 1 addition & 0 deletions src/Core/Cache/CacheStateManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ private function initializeCacheDirectory(): void
Filesystem::mkdir(
$this->options->getCacheDir(),
$this->options->getCacheFileMode(),
recursive: true,
);
}

Expand Down
52 changes: 52 additions & 0 deletions src/Core/Util/ReflectionHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php
/** @noinspection PhpInternalEntityUsedInspection */
namespace Okapi\CodeTransformer\Core\Util;

use Composer\Autoload\ClassLoader;
use Roave\BetterReflection\BetterReflection;
use Roave\BetterReflection\Reflection\ReflectionClass;
use Roave\BetterReflection\Reflector\DefaultReflector;
use Roave\BetterReflection\SourceLocator\SourceStubber\ReflectionSourceStubber;
use Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator;
use Roave\BetterReflection\SourceLocator\Type\ComposerSourceLocator;
use Roave\BetterReflection\SourceLocator\Type\PhpInternalSourceLocator;

/**
* # Reflection Helper
*
* This class is used to get reflection class.
*/
class ReflectionHelper
{
private ClassLoader $classLoader;

/**
* Set class loader.
*
* @param ClassLoader $classLoader
*
* @return void
*/
public function setClassLoader(ClassLoader $classLoader): void
{
$this->classLoader = $classLoader;
}

/**
* Get reflection class.
*
* @param class-string $namespacedClass
*
* @return ReflectionClass
*/
public function getReflectionClass(string $namespacedClass): ReflectionClass
{
$astLocator = (new BetterReflection())->astLocator();
$reflector = new DefaultReflector(new AggregateSourceLocator([
new ComposerSourceLocator($this->classLoader, $astLocator),
new PhpInternalSourceLocator($astLocator, new ReflectionSourceStubber()),
]));

return $reflector->reflectClass($namespacedClass);
}
}
39 changes: 20 additions & 19 deletions src/Transformer/Code.php
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
<?php

/** @noinspection PhpPropertyOnlyWrittenInspection */
namespace Okapi\CodeTransformer\Transformer;

use DI\Attribute\Inject;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Node\SourceFileNode;
use Microsoft\PhpParser\Parser;
use Microsoft\PhpParser\Token;
use Okapi\CodeTransformer\Core\AutoloadInterceptor;
use Okapi\CodeTransformer\Core\DI;
use Okapi\CodeTransformer\Core\Util\CodeChecker;
use Okapi\CodeTransformer\Core\Util\ReflectionHelper;
use Okapi\CodeTransformer\Core\Util\StringMutator;
use Roave\BetterReflection\BetterReflection;
use Roave\BetterReflection\Reflection\ReflectionClass as BetterReflectionClass;
use Roave\BetterReflection\Reflector\DefaultReflector;
use Roave\BetterReflection\SourceLocator\Type\ComposerSourceLocator;

/**
* # Code
Expand All @@ -22,6 +21,13 @@
*/
class Code
{
// region DI

#[Inject]
private ReflectionHelper $reflectionHelper;

// endregion

/**
* String mutator.
*
Expand Down Expand Up @@ -64,13 +70,16 @@ public function __construct(
/**
* Add an edit to the source code.
*
* @param Token $token The token to edit.
* @param string $replacement The replacement string.
* @param Token|Node $token The token or node to edit.
* @param string $replacement The replacement string.
*
* @return void
*
* @noinspection PhpDocMissingThrowsInspection
*/
public function edit(Token $token, string $replacement): void
public function edit(Token|Node $token, string $replacement): void
{
/** @noinspection PhpUnhandledExceptionInspection */
$this->stringMutator->edit(
$token->getStartPosition(),
$token->getWidth(),
Expand Down Expand Up @@ -146,17 +155,9 @@ public function getSourceFileNode(): SourceFileNode
*/
public function getReflectionClass(): BetterReflectionClass
{
static $classLoader, $astLocator, $reflector;

if (!isset($classLoader, $astLocator, $reflector)) {
$classLoader = DI::get(AutoloadInterceptor::DI);
$astLocator = (new BetterReflection)->astLocator();
$reflector = (new DefaultReflector(
new ComposerSourceLocator($classLoader, $astLocator)
));
}

return $reflector->reflectClass($this->getNamespacedClass());
return $this->reflectionHelper->getReflectionClass(
$this->getNamespacedClass(),
);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/Stubs/Kernel/AddedTransformerKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ protected function preInit(): void
{
parent::preInit();

$this->transformerContainer->addTransformers($this->addedTransformers);
$this->transformerManager->addTransformers($this->addedTransformers);
}
}