- Move 12 markdown files from root to docs/ subdirectories - Organize documentation by category: • docs/troubleshooting/ (1 file) - Technical troubleshooting guides • docs/deployment/ (4 files) - Deployment and security documentation • docs/guides/ (3 files) - Feature-specific guides • docs/planning/ (4 files) - Planning and improvement proposals Root directory cleanup: - Reduced from 16 to 4 markdown files in root - Only essential project files remain: • CLAUDE.md (AI instructions) • README.md (Main project readme) • CLEANUP_PLAN.md (Current cleanup plan) • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements) This improves: ✅ Documentation discoverability ✅ Logical organization by purpose ✅ Clean root directory ✅ Better maintainability
134 lines
3.8 KiB
PHP
134 lines
3.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Framework\Discovery\Processing;
|
|
|
|
use App\Framework\Core\ValueObjects\ClassName;
|
|
use App\Framework\Discovery\ValueObjects\FileContext;
|
|
use App\Framework\Filesystem\File;
|
|
use App\Framework\Reflection\ReflectionProvider;
|
|
use App\Framework\Reflection\WrappedReflectionClass;
|
|
|
|
/**
|
|
* Shared context for processing files during discovery
|
|
*
|
|
* This context holds reflection instances and other shared data
|
|
* to avoid duplicate work between visitors
|
|
*/
|
|
final class ProcessingContext
|
|
{
|
|
private ?WrappedReflectionClass $currentReflection = null;
|
|
|
|
private ?ClassName $currentClassName = null;
|
|
|
|
private ?FileContext $currentFileContext = null;
|
|
|
|
public function __construct(
|
|
private readonly ReflectionProvider $reflectionProvider
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* Set the current file being processed
|
|
*/
|
|
public function setCurrentFile(FileContext $fileContext): void
|
|
{
|
|
$this->currentFileContext = $fileContext;
|
|
// Clear reflection cache when switching files
|
|
$this->currentReflection = null;
|
|
$this->currentClassName = null;
|
|
}
|
|
|
|
/**
|
|
* Get reflection for a class (cached within the same file)
|
|
*/
|
|
public function getReflection(ClassName $className): ?WrappedReflectionClass
|
|
{
|
|
// Return cached reflection if it's for the same class
|
|
if ($this->currentClassName !== null &&
|
|
$this->currentClassName->equals($className) &&
|
|
$this->currentReflection !== null) {
|
|
return $this->currentReflection;
|
|
}
|
|
|
|
// Clear previous reflection
|
|
if ($this->currentClassName !== null) {
|
|
$this->reflectionProvider->forget($this->currentClassName);
|
|
}
|
|
|
|
// Get new reflection
|
|
try {
|
|
// IMPORTANT: Skip exists() check completely - it would trigger autoloading
|
|
// which could fail if constructor dependencies aren't available yet.
|
|
// Instead, directly try to get reflection and catch any errors.
|
|
$this->currentReflection = $this->reflectionProvider->getClass($className);
|
|
$this->currentClassName = $className;
|
|
|
|
return $this->currentReflection;
|
|
} catch (\Throwable) {
|
|
// Class can't be reflected (missing, parse error, autoload failure, etc.)
|
|
// This is fine during discovery - we skip it and continue
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Get the current file context
|
|
*/
|
|
public function getCurrentFileContext(): ?FileContext
|
|
{
|
|
return $this->currentFileContext;
|
|
}
|
|
|
|
/**
|
|
* Clean up resources for the current file
|
|
*/
|
|
public function cleanup(): void
|
|
{
|
|
if ($this->currentClassName !== null) {
|
|
$this->reflectionProvider->forget($this->currentClassName);
|
|
}
|
|
|
|
$this->currentReflection = null;
|
|
$this->currentClassName = null;
|
|
$this->currentFileContext = null;
|
|
}
|
|
|
|
/**
|
|
* Force garbage collection if needed
|
|
*/
|
|
public function maybeCollectGarbage(int $processedFiles): void
|
|
{
|
|
if ($processedFiles % 50 === 0) {
|
|
gc_collect_cycles();
|
|
|
|
// Clear reflection cache less frequently
|
|
if ($processedFiles % 100 === 0) {
|
|
$this->reflectionProvider->flush();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clear all caches for memory management
|
|
*/
|
|
public function clearCaches(): void
|
|
{
|
|
if ($this->currentClassName !== null) {
|
|
$this->reflectionProvider->forget($this->currentClassName);
|
|
}
|
|
|
|
// Flush the entire reflection provider cache
|
|
$this->reflectionProvider->flush();
|
|
|
|
$this->currentReflection = null;
|
|
$this->currentClassName = null;
|
|
$this->currentFileContext = null;
|
|
|
|
// Force garbage collection
|
|
gc_collect_cycles();
|
|
}
|
|
}
|