Skip to content
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
26 changes: 20 additions & 6 deletions src/Console/Command/DebugWeavingCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
namespace Go\Console\Command;

use FilesystemIterator;
use Go\Core\AspectContainer;
use Go\Instrument\ClassLoading\CachePathManager;
use Go\Instrument\ClassLoading\CacheWarmer;
use RecursiveDirectoryIterator;
Expand Down Expand Up @@ -104,7 +105,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
*/
private function getProxies(CachePathManager $cachePathManager): array
{
$path = $cachePathManager->getCacheDir() . '/_proxies';
$path = $cachePathManager->getCacheDir();
if ($path === null) {
return [];
}
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(
$path,
Expand All @@ -119,11 +123,21 @@ private function getProxies(CachePathManager $cachePathManager): array
* @var SplFileInfo $splFileInfo
*/
foreach ($iterator as $splFileInfo) {
if ($splFileInfo->isFile()) {
$content = file_get_contents($splFileInfo->getPathname());
if ($content !== false) {
$proxies[$splFileInfo->getPathname()] = $content;
}
if (!$splFileInfo->isFile() || $splFileInfo->getExtension() !== 'php') {
continue;
}
$pathname = $splFileInfo->getPathname();
if (str_contains($pathname, AspectContainer::AOP_PROXIED_SUFFIX)) {
continue;
}
// Only collect proxy files: they have a sibling __AopProxied trait file
$traitSibling = str_replace('.php', AspectContainer::AOP_PROXIED_SUFFIX . '.php', $pathname);
if (!file_exists($traitSibling)) {
continue;
}
$content = file_get_contents($pathname);
if ($content !== false) {
$proxies[$pathname] = $content;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Instrument/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ WeavingTransformer converts original class to trait + proxy class. Two generated
### Woven file (replaces original in php stream filtering)
```php
trait Foo__AopProxied { /* original methods verbatim */ }
include_once AOP_CACHE_DIR . '/_proxies/.../Foo.php';
include_once AOP_CACHE_DIR . '/Foo.php';
```

### Proxy file (loaded by include_once)
Expand Down
5 changes: 5 additions & 0 deletions src/Instrument/ClassLoading/CachePathManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ public function getCachePathForResource(string $resource)
return false;
}

$cacheState = $this->queryCacheState($resource);
if ($cacheState !== null && isset($cacheState['cacheUri']) && is_string($cacheState['cacheUri'])) {
return $cacheState['cacheUri'];
}

return $this->appDir !== null
? str_replace($this->appDir, $this->cacheDir, $resource)
: $resource;
Expand Down
6 changes: 6 additions & 0 deletions src/Instrument/Transformer/CachingTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
namespace Go\Instrument\Transformer;

use Closure;
use Go\Core\AspectContainer;
use Go\Core\AspectKernel;
use Go\Instrument\ClassLoading\CachePathManager;
use Go\ParserReflection\ReflectionEngine;
Expand Down Expand Up @@ -77,6 +78,11 @@ public function transform(StreamMetaData $metadata): TransformerResultEnum
) {
$processingResult = $this->processTransformers($metadata);
if ($processingResult === TransformerResultEnum::RESULT_TRANSFORMED) {
if (!str_contains($cacheUri, AspectContainer::AOP_PROXIED_SUFFIX)
&& str_contains($metadata->source, AspectContainer::AOP_PROXIED_SUFFIX)
) {
$cacheUri = str_replace('.php', AspectContainer::AOP_PROXIED_SUFFIX . '.php', $cacheUri);
}
$parentCacheDir = dirname($cacheUri);
if (!is_dir($parentCacheDir)) {
mkdir($parentCacheDir, $this->cacheFileMode, true);
Expand Down
15 changes: 7 additions & 8 deletions src/Instrument/Transformer/MagicConstantTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

namespace Go\Instrument\Transformer;

use Go\Core\AspectContainer;
use Go\Core\AspectKernel;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
Expand Down Expand Up @@ -66,14 +67,12 @@ public function transform(StreamMetaData $metadata): TransformerResultEnum
*/
public static function resolveFileName(string $fileName): string
{
$suffix = '.php';
$pathParts = explode($suffix, str_replace(
[self::$rewriteToPath, DIRECTORY_SEPARATOR . '_proxies'],
[self::$rootPath, ''],
$fileName
));
// throw away namespaced path from actual filename
return $pathParts[0] . $suffix;
if (self::$rewriteToPath !== '' && str_starts_with($fileName, self::$rewriteToPath)) {
$fileName = str_replace(self::$rewriteToPath, self::$rootPath, $fileName);
$fileName = str_replace(AspectContainer::AOP_PROXIED_SUFFIX . '.php', '.php', $fileName);
}

return $fileName;
}

/**
Expand Down
12 changes: 5 additions & 7 deletions src/Instrument/Transformer/WeavingTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
class WeavingTransformer extends BaseSourceTransformer
{
private const FUNCTIONS_CACHE_SUFFIX = '/_functions/';
private const PROXIES_CACHE_SUFFIX = '/_proxies/';

/**
* Advice matcher for class
Expand Down Expand Up @@ -708,18 +707,17 @@ private function processFunctions(
*/
private function saveProxyToCache(ReflectionClass $class, string $childCode): string
{
$cacheRootDir = $this->cachePathManager->getCacheDir();
$cacheRootDir = $this->cachePathManager->getCacheDir();
if ($cacheRootDir === null) {
return '';
}
$cacheDir = $cacheRootDir . self::PROXIES_CACHE_SUFFIX;
$classFileName = $class->getFileName();
$classFileName = $class->getFileName();
if ($classFileName === false) {
return '';
}
$relativePath = str_replace($this->options['appDir'] . DIRECTORY_SEPARATOR, '', $classFileName);
$proxyRelativePath = str_replace('\\', '/', $relativePath . '/' . $class->getName() . '.php');
$proxyFileName = $cacheDir . $proxyRelativePath;
$proxyRelativePath = str_replace('\\', '/', $relativePath);
$proxyFileName = $cacheRootDir . '/' . $proxyRelativePath;
$dirname = dirname($proxyFileName);
if (!file_exists($dirname)) {
mkdir($dirname, $this->options['cacheFileMode'], true);
Expand All @@ -732,7 +730,7 @@ private function saveProxyToCache(ReflectionClass $class, string $childCode): st
// For cache files we don't want executable bits by default
chmod($proxyFileName, $this->options['cacheFileMode'] & (~0111));

return 'include_once AOP_CACHE_DIR . ' . var_export(self::PROXIES_CACHE_SUFFIX . $proxyRelativePath, true) . ';';
return 'include_once AOP_CACHE_DIR . ' . var_export('/' . $proxyRelativePath, true) . ';';
}

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/Instrument/Transformer/WeavingTransformerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public function testWeaverForTypeHint(): void
$expected = $this->normalizeWhitespaces($this->loadTestMetadata('class-typehint-woven')->source);
$this->assertEquals($expected, $actual);

$proxyContent = file_get_contents($this->cachePathManager->getCacheDir() . '_proxies/Transformer/_files/class-typehint.php/TestClassTypehint.php');
$proxyContent = file_get_contents($this->cachePathManager->getCacheDir() . '/Transformer/_files/class-typehint.php');
$this->assertFalse(strpos($proxyContent, '\\\\Exception'));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ trait TestClassTypehint__AopProxied {
public function publicMethodFixedArguments(Exception $a, $b, $c = null) {}
}

include_once AOP_CACHE_DIR . '/_proxies/Transformer/_files/class-typehint.php/TestClassTypehint.php';
include_once AOP_CACHE_DIR . '/Transformer/_files/class-typehint.php';
2 changes: 1 addition & 1 deletion tests/Instrument/Transformer/_files/class-woven.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ public function publicMethodFixedArguments($a, $b, $c = null) {}

public function methodWithSpecialTypeArguments(self $instance) {}
}
include_once AOP_CACHE_DIR . '/_proxies/Transformer/_files/class.php/Test/ns1/TestClass.php';
include_once AOP_CACHE_DIR . '/Transformer/_files/class.php';
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ public static function staticMethod(): string
return static::class;
}
}
include_once AOP_CACHE_DIR . '/_proxies/Transformer/_files/final-readonly-class.php/Test/ns1/TestReadonlyClass.php';
include_once AOP_CACHE_DIR . '/Transformer/_files/final-readonly-class.php';
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
trait TestClass1__AopProxied {
public static function test() {}
}
include_once AOP_CACHE_DIR . '/_proxies/Transformer/_files/multiple-classes.php/Test/ns3/TestClass1.php';
include_once AOP_CACHE_DIR . '/Transformer/_files/multiple-classes.php';
TestClass1::test();
trait TestClass11__AopProxied {
public static function test() {}
}
include_once AOP_CACHE_DIR . '/_proxies/Transformer/_files/multiple-classes.php/Test/ns3/TestClass11.php';
include_once AOP_CACHE_DIR . '/Transformer/_files/multiple-classes.php';
TestClass11::test();
trait TestClass2__AopProxied {
public static function test() {}
}
include_once AOP_CACHE_DIR . '/_proxies/Transformer/_files/multiple-classes.php/Test/ns3/TestClass2.php';
include_once AOP_CACHE_DIR . '/Transformer/_files/multiple-classes.php';
TestClass2::test();
4 changes: 2 additions & 2 deletions tests/Instrument/Transformer/_files/multiple-ns-woven.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
trait TestClass1__AopProxied {
public static function test() {}
}
include_once AOP_CACHE_DIR . '/_proxies/Transformer/_files/multiple-ns.php/Test/ns1/TestClass1.php';
include_once AOP_CACHE_DIR . '/Transformer/_files/multiple-ns.php';
}
namespace Test\ns2 {
trait TestClass2__AopProxied {
public static function test() {}
}
include_once AOP_CACHE_DIR . '/_proxies/Transformer/_files/multiple-ns.php/Test/ns2/TestClass2.php';
include_once AOP_CACHE_DIR . '/Transformer/_files/multiple-ns.php';
}
2 changes: 1 addition & 1 deletion tests/Instrument/Transformer/_files/php7-class-woven.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ public function exceptionRth(\Exception $exception) : \Exception {}
public function noRth(LocalException $exception) {}
public function returnSelf(): self {}
}
include_once AOP_CACHE_DIR . '/_proxies/Transformer/_files/php7-class.php/Test/ns1/TestPhp7Class.php';
include_once AOP_CACHE_DIR . '/Transformer/_files/php7-class.php';
2 changes: 1 addition & 1 deletion tests/Instrument/Transformer/_files/php81-enum-woven.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ public function label(): string
};
}
}
include_once AOP_CACHE_DIR . '/_proxies/Transformer/_files/php81-enum.php/Test/ns1/TestStatus.php';
include_once AOP_CACHE_DIR . '/Transformer/_files/php81-enum.php';
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ public function normalMethod(): int
return 42;
}
}
include_once AOP_CACHE_DIR . '/_proxies/Transformer/_files/php83-override.php/Test/ns1/TestClassWithOverride.php';
include_once AOP_CACHE_DIR . '/Transformer/_files/php83-override.php';
5 changes: 3 additions & 2 deletions tests/PhpUnit/ClassIsNotWovenConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

namespace Go\PhpUnit;

use Go\Core\AspectContainer;
use Go\Instrument\PathResolver;
use Go\ParserReflection\ReflectionClass;
use PHPUnit\Framework\Constraint\Constraint;
Expand All @@ -36,8 +37,8 @@ public function matches($other): bool
$filename = (new ReflectionClass($other))->getFileName();
$suffix = substr($filename, strlen(PathResolver::realpath($this->configuration['appDir'])));

$transformedFileExists = file_exists($this->configuration['cacheDir'] . $suffix);
$proxyFileExists = file_exists($this->configuration['cacheDir'] . '/_proxies' . $suffix);
$proxyFileExists = file_exists($this->configuration['cacheDir'] . $suffix);
$transformedFileExists = file_exists($this->configuration['cacheDir'] . str_replace('.php', AspectContainer::AOP_PROXIED_SUFFIX . '.php', $suffix));

// if any of files exists, assert has to fail
return !$transformedFileExists && !$proxyFileExists;
Expand Down
5 changes: 3 additions & 2 deletions tests/PhpUnit/ClassWovenConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

namespace Go\PhpUnit;

use Go\Core\AspectContainer;
use Go\Instrument\PathResolver;
use Go\ParserReflection\ReflectionClass;
use PHPUnit\Framework\Constraint\Constraint;
Expand All @@ -36,8 +37,8 @@ public function matches($other): bool
$filename = (new ReflectionClass($other))->getFileName();
$suffix = substr($filename, strlen(PathResolver::realpath($this->configuration['appDir'])));

$transformedFileExists = file_exists($this->configuration['cacheDir'] . $suffix);
$proxyFileExists = file_exists($this->configuration['cacheDir'] . '/_proxies' . $suffix);
$proxyFileExists = file_exists($this->configuration['cacheDir'] . $suffix);
$transformedFileExists = file_exists($this->configuration['cacheDir'] . str_replace('.php', AspectContainer::AOP_PROXIED_SUFFIX . '.php', $suffix));

// if any of files is missing, assert has to fail
return $transformedFileExists && $proxyFileExists;
Expand Down
16 changes: 6 additions & 10 deletions tests/PhpUnit/ProxyClassReflectionHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,9 @@ public static function extractAdvicesFromProxyFile(string $className, array $con
$parsedReflectionClass = new ReflectionClass($className);
$originalClassFile = $parsedReflectionClass->getFileName();

$appDir = PathResolver::realpath($configuration['appDir']);
$relativePath = str_replace($appDir . DIRECTORY_SEPARATOR, '', $originalClassFile);
$classSuffix = str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php';
$proxyRelativePath = $relativePath . DIRECTORY_SEPARATOR . $classSuffix;
$proxyFileName = $configuration['cacheDir'] . '/_proxies/' . $proxyRelativePath;
$appDir = PathResolver::realpath($configuration['appDir']);
$relativePath = str_replace($appDir . DIRECTORY_SEPARATOR, '', $originalClassFile);
$proxyFileName = $configuration['cacheDir'] . '/' . str_replace('\\', '/', $relativePath);

if (!file_exists($proxyFileName)) {
return [];
Expand Down Expand Up @@ -212,11 +210,9 @@ public static function createReflectionClass(string $className, array $configura
$originalClassFile = $parsedReflectionClass->getFileName();
$originalNamespace = $parsedReflectionClass->getNamespaceName();

$appDir = PathResolver::realpath($configuration['appDir']);
$relativePath = str_replace($appDir . DIRECTORY_SEPARATOR, '', $originalClassFile);
$classSuffix = str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php';
$proxyRelativePath = $relativePath . DIRECTORY_SEPARATOR . $classSuffix;
$proxyFileName = $configuration['cacheDir'] . '/_proxies/' . $proxyRelativePath;
$appDir = PathResolver::realpath($configuration['appDir']);
$relativePath = str_replace($appDir . DIRECTORY_SEPARATOR, '', $originalClassFile);
$proxyFileName = $configuration['cacheDir'] . '/' . str_replace('\\', '/', $relativePath);
$proxyFileContent = file_get_contents($proxyFileName);

// To prevent deep analysis of parents, we just cut everything after "extends"
Expand Down
Loading