Skip to content

Commit

Permalink
Merge pull request #22 from kirschbaum-development/feature/memory-imp…
Browse files Browse the repository at this point in the history
…rovements

Memory management improvements
  • Loading branch information
brandonferens authored Nov 5, 2024
2 parents 6ea3fe1 + 818d375 commit 5a423a7
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 91 deletions.
33 changes: 15 additions & 18 deletions src/Commands/GenerateEnumsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
use ReflectionEnum;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputOption;
use UnitEnum;

#[AsCommand(name: 'paragon:enum:generate', description: 'Generate Typescript versions of existing PHP enums')]
class GenerateEnumsCommand extends Command
Expand All @@ -30,7 +29,7 @@ public function handle(): int
$builder = $this->builder();

$generatedEnums = $this->enums()
->map(fn (string $enum) => app(EnumGenerator::class, ['enum' => $enum, 'builder' => $builder])())
->map(fn (ReflectionEnum $enum) => app(EnumGenerator::class, ['enum' => $enum, 'builder' => $builder])())
->filter();

$this->components->info("{$generatedEnums->count()} enums have been (re)generated.");
Expand All @@ -45,35 +44,33 @@ public function handle(): int
/**
* Gather all enum namespaces for searching.
*
* @return Collection<int,class-string<UnitEnum>>
* @return Collection<int, ReflectionEnum>
*/
protected function enums(): Collection
{
/** @var string */
$phpPath = config('paragon.enums.paths.php');

return DiscoverEnums::within(app_path($phpPath))
->reject(function (string $enum) {
if (! enum_exists($enum)) {
return true;
}

$reflector = new ReflectionEnum($enum);

$pathsToIgnore = Arr::map(
/**
* @var string $path
*/
$path = config('paragon.enums.paths.php');

return DiscoverEnums::within(app_path($path))
->reject(function (ReflectionEnum $enum) {
$paths = Arr::map(
Arr::wrap(config('paragon.enums.paths.ignore')),
fn (string $path): string => Str::finish(app_path($path), '/'),
);

return $reflector->getAttributes(IgnoreParagon::class)
|| Str::startsWith((string) $reflector->getFileName(), $pathsToIgnore);
return $enum->getAttributes(IgnoreParagon::class)
|| Str::startsWith((string) $enum->getFileName(), $paths);
})
->values();
}

protected function builder(): EnumBuilder
{
/** @var string */
/**
* @var string $generateAs
*/
$generateAs = config('paragon.generate-as');

$builder = match (true) {
Expand Down
71 changes: 43 additions & 28 deletions src/Concerns/DiscoverEnums.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Kirschbaum\Paragon\Concerns;

use Illuminate\Support\Collection;
use ReflectionClass;
use ReflectionEnum;
use ReflectionException;
use SplFileInfo;
use Symfony\Component\Finder\Finder;
Expand All @@ -16,7 +16,7 @@ class DiscoverEnums
*
* @param array<int, string>|string $path
*
* @return Collection<class-string<UnitEnum>, class-string<UnitEnum>>
* @return Collection<int, ReflectionEnum>
*/
public static function within(array|string $path): Collection
{
Expand All @@ -28,7 +28,7 @@ public static function within(array|string $path): Collection
*
* @param Finder<string, SplFileInfo> $files
*
* @return Collection<class-string<UnitEnum>, class-string<UnitEnum>>
* @return Collection<int, ReflectionEnum>
*/
protected static function getEnums(Finder $files): Collection
{
Expand All @@ -38,43 +38,58 @@ protected static function getEnums(Finder $files): Collection
$fileCollection = collect($files);

return $fileCollection
->mapWithKeys(function (SplFileInfo $file) {
->map(function (SplFileInfo $file) {
try {
if (! class_exists($enum = static::classFromFile($file))) {
return [];
}

$reflector = new ReflectionClass($enum);
return static::classFromFile($file);
} catch (ReflectionException) {
return [];
return false;
}

return $reflector->isEnum()
? [$enum => $enum]
: [];
})
->filter();
->filter(fn ($enum) => $enum instanceof ReflectionEnum);
}

/**
* Extract the class name from the given file path.
*
* @return class-string<UnitEnum>
* @throws ReflectionException
*/
protected static function classFromFile(SplFileInfo $file): string
protected static function classFromFile(SplFileInfo $file): ReflectionEnum|false
{
$handle = fopen($file->getRealPath(), 'r');

if (! $handle) {
return false;
}

$namespace = null;
$enumClass = null;

while (($line = fgets($handle)) !== false) {
if (preg_match('/^namespace\s+([^;]+);/', $line, $matches)) {
$namespace = $matches[1];
}

if (preg_match('/^enum\s+(\w+)(?:\s*:\s*\w+)?/', $line, $matches)) {
$enumClass = $matches[1];
}

if (
($namespace && $enumClass)
|| preg_match('/\b(class|trait|interface)\b/', $line)
) {
break;
}
}

fclose($handle);

/**
* @var class-string<UnitEnum>
* @var class-string<UnitEnum>|false $enum
*/
return str($file->getRealPath())
->replaceFirst(base_path(), '')
->trim(DIRECTORY_SEPARATOR)
->replaceLast('.php', '')
->ucfirst()
->replace(
search: [DIRECTORY_SEPARATOR, ucfirst(basename(app()->path())) . '\\'],
replace: ['\\', app()->getNamespace()]
)
->toString();
$enum = $namespace && $enumClass
? "{$namespace}\\{$enumClass}"
: false;

return $enum ? new ReflectionEnum($enum) : false;
}
}
Loading

0 comments on commit 5a423a7

Please sign in to comment.