diff --git a/bin/release.sh b/bin/release.sh index 98ec22aeaebf..789f749e1429 100755 --- a/bin/release.sh +++ b/bin/release.sh @@ -52,7 +52,7 @@ git tag $VERSION git push origin --tags # Tag Components -for REMOTE in auth broadcasting bus cache collections conditionable config console container contracts cookie database encryption events filesystem hashing http json-schema log macroable mail notifications pagination pipeline process queue redis routing session support testing translation validation view +for REMOTE in auth broadcasting bus cache collections conditionable config console container contracts cookie database encryption events filesystem hashing http json-schema log macroable mail notifications pagination pipeline process queue reflection redis routing session support testing translation validation view do echo "" echo "" diff --git a/bin/split.sh b/bin/split.sh index 91fd373dbf0a..aa3c490d4043 100755 --- a/bin/split.sh +++ b/bin/split.sh @@ -44,6 +44,7 @@ remote pagination git@github.com:illuminate/pagination.git remote pipeline git@github.com:illuminate/pipeline.git remote process git@github.com:illuminate/process.git remote queue git@github.com:illuminate/queue.git +remote reflection git@github.com:illuminate/reflection.git remote redis git@github.com:illuminate/redis.git remote routing git@github.com:illuminate/routing.git remote session git@github.com:illuminate/session.git @@ -79,6 +80,7 @@ split 'src/Illuminate/Pagination' pagination split 'src/Illuminate/Pipeline' pipeline split 'src/Illuminate/Process' process split 'src/Illuminate/Queue' queue +split 'src/Illuminate/Reflection' reflection split 'src/Illuminate/Redis' redis split 'src/Illuminate/Routing' routing split 'src/Illuminate/Session' session diff --git a/composer.json b/composer.json index 5dca59525f27..42b08ab2e461 100644 --- a/composer.json +++ b/composer.json @@ -90,6 +90,7 @@ "illuminate/pipeline": "self.version", "illuminate/process": "self.version", "illuminate/queue": "self.version", + "illuminate/reflection": "self.version", "illuminate/redis": "self.version", "illuminate/routing": "self.version", "illuminate/session": "self.version", @@ -143,6 +144,7 @@ "src/Illuminate/Filesystem/functions.php", "src/Illuminate/Foundation/helpers.php", "src/Illuminate/Log/functions.php", + "src/Illuminate/Reflection/helpers.php", "src/Illuminate/Support/functions.php", "src/Illuminate/Support/helpers.php" ], @@ -151,7 +153,8 @@ "Illuminate\\Support\\": [ "src/Illuminate/Macroable/", "src/Illuminate/Collections/", - "src/Illuminate/Conditionable/" + "src/Illuminate/Conditionable/", + "src/Illuminate/Reflection/" ] } }, diff --git a/src/Illuminate/Container/Container.php b/src/Illuminate/Container/Container.php index db543b8da37b..1e6f2909d631 100755 --- a/src/Illuminate/Container/Container.php +++ b/src/Illuminate/Container/Container.php @@ -13,18 +13,19 @@ use Illuminate\Contracts\Container\Container as ContainerContract; use Illuminate\Contracts\Container\ContextualAttribute; use Illuminate\Contracts\Container\SelfBuilding; +use Illuminate\Support\Traits\ReflectsClosures; use LogicException; use ReflectionAttribute; use ReflectionClass; use ReflectionException; use ReflectionFunction; -use ReflectionIntersectionType; use ReflectionParameter; -use ReflectionUnionType; use TypeError; class Container implements ArrayAccess, ContainerContract { + use ReflectsClosures; + /** * The current globally available container (if any). * @@ -563,40 +564,6 @@ protected function bindBasedOnClosureReturnTypes($abstract, $concrete = null, $s } } - /** - * Get the class names / types of the return type of the given Closure. - * - * @return list - * - * @throws \ReflectionException - */ - protected function closureReturnTypes(Closure $closure) - { - $reflection = new ReflectionFunction($closure); - - if ($reflection->getReturnType() === null || - $reflection->getReturnType() instanceof ReflectionIntersectionType) { - return []; - } - - $types = $reflection->getReturnType() instanceof ReflectionUnionType - ? $reflection->getReturnType()->getTypes() - : [$reflection->getReturnType()]; - - $returnTypes = []; - - foreach ($types as $type) { - if ($type->isBuiltin() || - in_array($type->getName(), ['static', 'self'])) { - continue; - } - - $returnTypes[] = $type->getName(); - } - - return $returnTypes; - } - /** * "Extend" an abstract type in the container. * diff --git a/src/Illuminate/Container/composer.json b/src/Illuminate/Container/composer.json index cf80aac08278..fa80d1589b02 100755 --- a/src/Illuminate/Container/composer.json +++ b/src/Illuminate/Container/composer.json @@ -16,6 +16,7 @@ "require": { "php": "^8.2", "illuminate/contracts": "^12.0", + "illuminate/reflection": "^12.0", "psr/container": "^1.1.1|^2.0.1", "symfony/polyfill-php84": "^1.33", "symfony/polyfill-php85": "^1.33" diff --git a/src/Illuminate/Support/Reflector.php b/src/Illuminate/Reflection/Reflector.php similarity index 100% rename from src/Illuminate/Support/Reflector.php rename to src/Illuminate/Reflection/Reflector.php diff --git a/src/Illuminate/Support/Traits/ReflectsClosures.php b/src/Illuminate/Reflection/Traits/ReflectsClosures.php similarity index 100% rename from src/Illuminate/Support/Traits/ReflectsClosures.php rename to src/Illuminate/Reflection/Traits/ReflectsClosures.php diff --git a/src/Illuminate/Reflection/composer.json b/src/Illuminate/Reflection/composer.json new file mode 100644 index 000000000000..495d6ebabb27 --- /dev/null +++ b/src/Illuminate/Reflection/composer.json @@ -0,0 +1,38 @@ +{ + "name": "illuminate/reflection", + "description": "The Illuminate Reflection package.", + "license": "MIT", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "require": { + "php": "^8.2", + "illuminate/contracts": "^12.0", + "illuminate/collections": "^12.0" + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + }, + "files": [ + "helpers.php" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "12.x-dev" + } + }, + "config": { + "sort-packages": true + }, + "minimum-stability": "dev" +} diff --git a/src/Illuminate/Reflection/helpers.php b/src/Illuminate/Reflection/helpers.php new file mode 100644 index 000000000000..cdece52c327b --- /dev/null +++ b/src/Illuminate/Reflection/helpers.php @@ -0,0 +1,97 @@ +|(\Closure(TValue): mixed) $class + * @param (\Closure(TValue): mixed)|int $callback + * @param int $options + * @param array $eager + * @return TValue + */ + function lazy($class, $callback = 0, $options = 0, $eager = []) + { + static $closureReflector; + + $closureReflector ??= new class + { + use ReflectsClosures; + + public function typeFromParameter($callback) + { + return $this->firstClosureParameterType($callback); + } + }; + + [$class, $callback, $options] = is_string($class) + ? [$class, $callback, $options] + : [$closureReflector->typeFromParameter($class), $class, $callback ?: $options]; + + $reflectionClass = new ReflectionClass($class); + + $instance = $reflectionClass->newLazyGhost(function ($instance) use ($callback) { + $result = $callback($instance); + + if (is_array($result)) { + $instance->__construct(...$result); + } + }, $options); + + foreach ($eager as $property => $value) { + $reflectionClass->getProperty($property)->setRawValueWithoutLazyInitialization($instance, $value); + } + + return $instance; + } +} + +if (! function_exists('proxy')) { + /** + * Create a lazy proxy instance. + * + * @template TValue of object + * + * @param class-string|(\Closure(TValue): TValue) $class + * @param (\Closure(TValue): TValue)|int $callback + * @param int $options + * @param array $eager + * @return TValue + */ + function proxy($class, $callback = 0, $options = 0, $eager = []) + { + static $closureReflector; + + $closureReflector = new class + { + use ReflectsClosures; + + public function get($callback) + { + return $this->closureReturnTypes($callback)[0] ?? $this->firstClosureParameterType($callback); + } + }; + + [$class, $callback, $options] = is_string($class) + ? [$class, $callback, $options] + : [$closureReflector->get($class), $class, $callback ?: $options]; + + $reflectionClass = new ReflectionClass($class); + + $proxy = $reflectionClass->newLazyProxy(function () use ($callback, $eager, &$proxy) { + $instance = $callback($proxy, $eager); + + return $instance; + }, $options); + + foreach ($eager as $property => $value) { + $reflectionClass->getProperty($property)->setRawValueWithoutLazyInitialization($proxy, $value); + } + + return $proxy; + } +} diff --git a/src/Illuminate/Support/composer.json b/src/Illuminate/Support/composer.json index 477b5b1f2dda..d81bd96014ad 100644 --- a/src/Illuminate/Support/composer.json +++ b/src/Illuminate/Support/composer.json @@ -23,6 +23,7 @@ "illuminate/conditionable": "^12.0", "illuminate/contracts": "^12.0", "illuminate/macroable": "^12.0", + "illuminate/reflection": "^12.0", "nesbot/carbon": "^3.8.4", "symfony/polyfill-php83": "^1.33", "symfony/polyfill-php85": "^1.33", diff --git a/src/Illuminate/Support/helpers.php b/src/Illuminate/Support/helpers.php index 5de2e5213ab3..0b07595e7ef2 100644 --- a/src/Illuminate/Support/helpers.php +++ b/src/Illuminate/Support/helpers.php @@ -13,7 +13,6 @@ use Illuminate\Support\Sleep; use Illuminate\Support\Str; use Illuminate\Support\Stringable as SupportStringable; -use Illuminate\Support\Traits\ReflectsClosures; if (! function_exists('append_config')) { /** @@ -197,54 +196,6 @@ function literal(...$arguments) } } -if (! function_exists('lazy')) { - /** - * Create a lazy instance. - * - * @template TValue of object - * - * @param class-string|(\Closure(TValue): mixed) $class - * @param (\Closure(TValue): mixed)|int $callback - * @param int $options - * @param array $eager - * @return TValue - */ - function lazy($class, $callback = 0, $options = 0, $eager = []) - { - static $closureReflector; - - $closureReflector ??= new class - { - use ReflectsClosures; - - public function typeFromParameter($callback) - { - return $this->firstClosureParameterType($callback); - } - }; - - [$class, $callback, $options] = is_string($class) - ? [$class, $callback, $options] - : [$closureReflector->typeFromParameter($class), $class, $callback ?: $options]; - - $reflectionClass = new ReflectionClass($class); - - $instance = $reflectionClass->newLazyGhost(function ($instance) use ($callback) { - $result = $callback($instance); - - if (is_array($result)) { - $instance->__construct(...$result); - } - }, $options); - - foreach ($eager as $property => $value) { - $reflectionClass->getProperty($property)->setRawValueWithoutLazyInitialization($instance, $value); - } - - return $instance; - } -} - if (! function_exists('object_get')) { /** * Get an item from an object using "dot" notation. @@ -344,52 +295,6 @@ function preg_replace_array($pattern, array $replacements, $subject): string } } -if (! function_exists('proxy')) { - /** - * Create a lazy proxy instance. - * - * @template TValue of object - * - * @param class-string|(\Closure(TValue): TValue) $class - * @param (\Closure(TValue): TValue)|int $callback - * @param int $options - * @param array $eager - * @return TValue - */ - function proxy($class, $callback = 0, $options = 0, $eager = []) - { - static $closureReflector; - - $closureReflector = new class - { - use ReflectsClosures; - - public function get($callback) - { - return $this->closureReturnTypes($callback)[0] ?? $this->firstClosureParameterType($callback); - } - }; - - [$class, $callback, $options] = is_string($class) - ? [$class, $callback, $options] - : [$closureReflector->get($class), $class, $callback ?: $options]; - - $reflectionClass = new ReflectionClass($class); - - $proxy = $reflectionClass->newLazyProxy(function () use ($callback, $eager, &$proxy) { - $instance = $callback($proxy, $eager); - - return $instance; - }, $options); - - foreach ($eager as $property => $value) { - $reflectionClass->getProperty($property)->setRawValueWithoutLazyInitialization($proxy, $value); - } - - return $proxy; - } -} - if (! function_exists('retry')) { /** * Retry an operation a given number of times.