diff --git a/.editorconfig b/.editorconfig index d240f3e4f..8abbe8cda 100644 --- a/.editorconfig +++ b/.editorconfig @@ -20,3 +20,6 @@ indent_size = 4 [tsconfig.json] indent_size = 2 + +[*.neon] +indent_style = tab diff --git a/.github/workflows/REUSABLE_backend.yml b/.github/workflows/REUSABLE_backend.yml index 84dff2467..c45928c09 100644 --- a/.github/workflows/REUSABLE_backend.yml +++ b/.github/workflows/REUSABLE_backend.yml @@ -9,6 +9,12 @@ on: default: true required: false + enable_phpstan: + description: "Enable PHPStan Static Analysis?" + type: boolean + default: false + required: false + backend_directory: description: The directory of the project where backend code is located. This should contain a `composer.json` file, and is generally the root directory of the repo. type: string @@ -130,3 +136,35 @@ jobs: working-directory: ${{ inputs.backend_directory }} env: COMPOSER_PROCESS_TIMEOUT: 600 + + phpstan: + runs-on: ubuntu-latest + + strategy: + matrix: + php: ${{ fromJSON(inputs.php_versions) }} + + name: 'PHPStan PHP ${{ matrix.php }}' + + if: >- + inputs.enable_phpstan && + ((github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) || github.event_name != 'pull_request') + + steps: + - uses: actions/checkout@master + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: xdebug + extensions: curl, dom, gd, json, mbstring, openssl, pdo_mysql, tokenizer, zip + tools: phpunit, composer:v2 + ini-values: ${{ inputs.php_ini_values }} + + - name: Install Composer dependencies + run: composer install + working-directory: ${{ inputs.backend_directory }} + + - name: Run PHPStan + run: composer analyse:phpstan diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml new file mode 100644 index 000000000..e0088cfd2 --- /dev/null +++ b/.github/workflows/phpstan.yml @@ -0,0 +1,12 @@ +name: Framework PHP + +on: [workflow_dispatch, push, pull_request] + +jobs: + run: + uses: ./.github/workflows/REUSABLE_backend.yml + with: + enable_backend_testing: false + enable_phpstan: true + + backend_directory: . diff --git a/composer.json b/composer.json index 0564a66fc..dc3c8ada7 100644 --- a/composer.json +++ b/composer.json @@ -140,8 +140,8 @@ "require-dev": { "mockery/mockery": "^1.4", "phpunit/phpunit": "^9.0", - "phpstan/phpstan-php-parser": "^1.0", - "phpstan/phpstan": "^1.2" + "phpstan/phpstan": "^1.2", + "nunomaduro/larastan": "^1.0" }, "config": { "sort-packages": true @@ -178,5 +178,11 @@ "extension.neon" ] } + }, + "scripts": { + "analyse:phpstan": "phpstan analyse" + }, + "scripts-descriptions": { + "analyse:phpstan": "Run static analysis" } } diff --git a/framework/core/src/Api/Client.php b/framework/core/src/Api/Client.php index 457ec41ac..11e3d45bc 100644 --- a/framework/core/src/Api/Client.php +++ b/framework/core/src/Api/Client.php @@ -11,7 +11,6 @@ namespace Flarum\Api; use Flarum\Http\RequestUtil; use Flarum\User\User; -use Illuminate\Contracts\Container\Container; use Laminas\Diactoros\ServerRequestFactory; use Laminas\Diactoros\Uri; use Laminas\Stratigility\MiddlewarePipeInterface; @@ -26,12 +25,12 @@ class Client protected $pipe; /** - * @var User + * @var User|null */ protected $actor; /** - * @var ServerRequestInterface + * @var ServerRequestInterface|null */ protected $parent; @@ -45,9 +44,6 @@ class Client */ protected $body = []; - /** - * @param Container $container - */ public function __construct(MiddlewarePipeInterface $pipe) { $this->pipe = $pipe; diff --git a/framework/core/src/Api/Controller/AbstractSerializeController.php b/framework/core/src/Api/Controller/AbstractSerializeController.php index ee9e907b1..0c813eabf 100644 --- a/framework/core/src/Api/Controller/AbstractSerializeController.php +++ b/framework/core/src/Api/Controller/AbstractSerializeController.php @@ -88,7 +88,7 @@ abstract class AbstractSerializeController implements RequestHandlerInterface protected static $beforeSerializationCallbacks = []; /** - * @var string[] + * @var string[][] */ protected static $loadRelations = []; diff --git a/framework/core/src/Api/Controller/ListNotificationsController.php b/framework/core/src/Api/Controller/ListNotificationsController.php index aff1f54d6..12fc3b927 100644 --- a/framework/core/src/Api/Controller/ListNotificationsController.php +++ b/framework/core/src/Api/Controller/ListNotificationsController.php @@ -113,15 +113,15 @@ class ListNotificationsController extends AbstractListController $ids = []; foreach ($notifications as $notification) { - if ($notification->subject && $notification->subject->discussion_id) { + if ($notification->subject && isset($notification->subject->discussion_id)) { $ids[] = $notification->subject->discussion_id; } } - $discussions = Discussion::find(array_unique($ids)); + $discussions = Discussion::query()->find(array_unique($ids)); foreach ($notifications as $notification) { - if ($notification->subject && $notification->subject->discussion_id) { + if ($notification->subject && isset($notification->subject->discussion_id)) { $notification->subject->setRelation('discussion', $discussions->find($notification->subject->discussion_id)); } } diff --git a/framework/core/src/Api/Serializer/AbstractSerializer.php b/framework/core/src/Api/Serializer/AbstractSerializer.php index a6892f129..69efef3eb 100644 --- a/framework/core/src/Api/Serializer/AbstractSerializer.php +++ b/framework/core/src/Api/Serializer/AbstractSerializer.php @@ -42,12 +42,12 @@ abstract class AbstractSerializer extends BaseAbstractSerializer protected static $container; /** - * @var callable[] + * @var array */ protected static $attributeMutators = []; /** - * @var array + * @var array> */ protected static $customRelations = []; @@ -189,12 +189,12 @@ abstract class AbstractSerializer extends BaseAbstractSerializer * @param string|Closure|\Tobscure\JsonApi\SerializerInterface $serializer * @param string|null $relation * @param bool $many - * @return Relationship + * @return Relationship|null */ protected function buildRelationship($model, $serializer, $relation = null, $many = false) { if (is_null($relation)) { - list(, , $caller) = debug_backtrace(false, 3); + list(, , $caller) = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 3); $relation = $caller['function']; } @@ -210,6 +210,8 @@ abstract class AbstractSerializer extends BaseAbstractSerializer return new Relationship($element); } + + return null; } /** diff --git a/framework/core/src/Api/Serializer/ExtensionReadmeSerializer.php b/framework/core/src/Api/Serializer/ExtensionReadmeSerializer.php index e59e4f74f..7f40eebef 100644 --- a/framework/core/src/Api/Serializer/ExtensionReadmeSerializer.php +++ b/framework/core/src/Api/Serializer/ExtensionReadmeSerializer.php @@ -12,7 +12,8 @@ namespace Flarum\Api\Serializer; class ExtensionReadmeSerializer extends AbstractSerializer { /** - * {@inheritdoc} + * @param \Flarum\Extension\Extension $extension + * @return array */ protected function getDefaultAttributes($extension) { diff --git a/framework/core/src/Api/Serializer/ForumSerializer.php b/framework/core/src/Api/Serializer/ForumSerializer.php index ec1bbb73d..44e89d26a 100644 --- a/framework/core/src/Api/Serializer/ForumSerializer.php +++ b/framework/core/src/Api/Serializer/ForumSerializer.php @@ -62,7 +62,7 @@ class ForumSerializer extends AbstractSerializer */ public function getId($model) { - return 1; + return '1'; } /** diff --git a/framework/core/src/Console/Schedule.php b/framework/core/src/Console/Schedule.php index 6deba8eb0..e59e57169 100644 --- a/framework/core/src/Console/Schedule.php +++ b/framework/core/src/Console/Schedule.php @@ -18,17 +18,20 @@ class Schedule extends LaravelSchedule public function dueEvents($container) { return (new Collection($this->events))->filter->isDue(new class($container) { + /** @var Config */ + protected $config; + public function __construct($container) { $this->config = $container->make(Config::class); } - public function isDownForMaintenance() + public function isDownForMaintenance(): bool { return $this->config->inMaintenanceMode(); } - public function environment() + public function environment(): string { return ''; } diff --git a/framework/core/src/Database/AbstractModel.php b/framework/core/src/Database/AbstractModel.php index 6da46666a..f61c89c87 100644 --- a/framework/core/src/Database/AbstractModel.php +++ b/framework/core/src/Database/AbstractModel.php @@ -20,6 +20,8 @@ use LogicException; * Adds the ability for custom relations to be added to a model during runtime. * These relations behave in the same way that you would expect; they can be * queried, eager loaded, and accessed as an attribute. + * + * @property-read int|null $id */ abstract class AbstractModel extends Eloquent { diff --git a/framework/core/src/Database/Console/GenerateDumpCommand.php b/framework/core/src/Database/Console/GenerateDumpCommand.php index 84bfd5d50..eb958792e 100644 --- a/framework/core/src/Database/Console/GenerateDumpCommand.php +++ b/framework/core/src/Database/Console/GenerateDumpCommand.php @@ -12,6 +12,7 @@ namespace Flarum\Database\Console; use Flarum\Console\AbstractCommand; use Flarum\Foundation\Paths; use Illuminate\Database\Connection; +use Illuminate\Database\MySqlConnection; class GenerateDumpCommand extends AbstractCommand { @@ -53,7 +54,7 @@ class GenerateDumpCommand extends AbstractCommand protected function fire() { $dumpPath = __DIR__.'/../../../migrations/install.dump'; - /** @var Connection */ + /** @var Connection&MySqlConnection */ $connection = resolve('db.connection'); $connection diff --git a/framework/core/src/Database/DatabaseMigrationRepository.php b/framework/core/src/Database/DatabaseMigrationRepository.php index 7b781210b..04f32e5d4 100644 --- a/framework/core/src/Database/DatabaseMigrationRepository.php +++ b/framework/core/src/Database/DatabaseMigrationRepository.php @@ -30,8 +30,8 @@ class DatabaseMigrationRepository implements MigrationRepositoryInterface /** * Create a new database migration repository instance. * - * @param \Illuminate\Database\ConnectionInterface $connection - * @param string $table + * @param ConnectionInterface $connection + * @param string $table */ public function __construct(ConnectionInterface $connection, $table) { diff --git a/framework/core/src/Database/DatabaseServiceProvider.php b/framework/core/src/Database/DatabaseServiceProvider.php index ad66fcbd4..a23295a0a 100644 --- a/framework/core/src/Database/DatabaseServiceProvider.php +++ b/framework/core/src/Database/DatabaseServiceProvider.php @@ -10,6 +10,7 @@ namespace Flarum\Database; use Flarum\Foundation\AbstractServiceProvider; +use Illuminate\Container\Container as ContainerImplementation; use Illuminate\Contracts\Container\Container; use Illuminate\Database\Capsule\Manager; use Illuminate\Database\ConnectionInterface; @@ -22,7 +23,7 @@ class DatabaseServiceProvider extends AbstractServiceProvider */ public function register() { - $this->container->singleton(Manager::class, function (Container $container) { + $this->container->singleton(Manager::class, function (ContainerImplementation $container) { $manager = new Manager($container); $config = $container['flarum']->config('database'); diff --git a/framework/core/src/Database/Migrator.php b/framework/core/src/Database/Migrator.php index 03b0dde1a..1a3119360 100644 --- a/framework/core/src/Database/Migrator.php +++ b/framework/core/src/Database/Migrator.php @@ -39,20 +39,17 @@ class Migrator /** * The output interface implementation. * - * @var OutputInterface + * @var OutputInterface|null */ protected $output; + /** - * @var ConnectionInterface|MySqlConnection + * @var ConnectionInterface */ protected $connection; /** * Create a new migrator instance. - * - * @param MigrationRepositoryInterface $repository - * @param ConnectionInterface $connection - * @param Filesystem $files */ public function __construct( MigrationRepositoryInterface $repository, @@ -76,7 +73,7 @@ class Migrator * Run the outstanding migrations at a given path. * * @param string $path - * @param Extension $extension + * @param Extension|null $extension * @return void */ public function run($path, Extension $extension = null) @@ -95,7 +92,7 @@ class Migrator * * @param string $path * @param array $migrations - * @param Extension $extension + * @param Extension|null $extension * @return void */ public function runMigrationList($path, $migrations, Extension $extension = null) @@ -122,8 +119,7 @@ class Migrator * * @param string $path * @param string $file - * @param string $path - * @param Extension $extension + * @param Extension|null $extension * @return void */ protected function runUp($path, $file, Extension $extension = null) @@ -144,7 +140,7 @@ class Migrator * Rolls all of the currently applied migrations back. * * @param string $path - * @param Extension $extension + * @param Extension|null $extension * @return int */ public function reset($path, Extension $extension = null) @@ -245,6 +241,8 @@ class Migrator if ($this->files->exists($migration)) { return $this->files->getRequire($migration); } + + return []; } /** diff --git a/framework/core/src/Discussion/Access/DiscussionPolicy.php b/framework/core/src/Discussion/Access/DiscussionPolicy.php index 1f9815102..c0124257c 100644 --- a/framework/core/src/Discussion/Access/DiscussionPolicy.php +++ b/framework/core/src/Discussion/Access/DiscussionPolicy.php @@ -13,7 +13,6 @@ use Flarum\Discussion\Discussion; use Flarum\Settings\SettingsRepositoryInterface; use Flarum\User\Access\AbstractPolicy; use Flarum\User\User; -use Illuminate\Contracts\Events\Dispatcher; class DiscussionPolicy extends AbstractPolicy { @@ -22,10 +21,6 @@ class DiscussionPolicy extends AbstractPolicy */ protected $settings; - /** - * @param SettingsRepositoryInterface $settings - * @param Dispatcher $events - */ public function __construct(SettingsRepositoryInterface $settings) { $this->settings = $settings; @@ -34,7 +29,7 @@ class DiscussionPolicy extends AbstractPolicy /** * @param User $actor * @param string $ability - * @return bool|null + * @return string|void */ public function can(User $actor, $ability) { diff --git a/framework/core/src/Discussion/Discussion.php b/framework/core/src/Discussion/Discussion.php index 10b6dfd13..22e602aff 100644 --- a/framework/core/src/Discussion/Discussion.php +++ b/framework/core/src/Discussion/Discussion.php @@ -23,6 +23,7 @@ use Flarum\Post\MergeableInterface; use Flarum\Post\Post; use Flarum\Settings\SettingsRepositoryInterface; use Flarum\User\User; +use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Support\Str; /** @@ -83,7 +84,7 @@ class Discussion extends AbstractModel /** * The user for which the state relationship should be loaded. * - * @var User + * @var User|null */ protected static $stateUser; @@ -224,8 +225,8 @@ class Discussion extends AbstractModel */ public function refreshLastPost() { - /** @var Post $lastPost */ if ($lastPost = $this->comments()->latest()->first()) { + /** @var Post $lastPost */ $this->setLastPost($lastPost); } @@ -264,8 +265,9 @@ class Discussion extends AbstractModel * DiscussionRenamedPost, and delete if the title has been reverted * completely.) * - * @param \Flarum\Post\MergeableInterface $post The post to save. - * @return Post The resulting post. It may or may not be the same post as + * @template T of \Flarum\Post\MergeableInterface + * @param T $post The post to save. + * @return T The resulting post. It may or may not be the same post as * was originally intended to be saved. It also may not exist, if the * merge logic resulted in deletion. */ @@ -301,7 +303,7 @@ class Discussion extends AbstractModel /** * Define the relationship with the discussion's publicly-visible comments. * - * @return \Illuminate\Database\Eloquent\Relations\HasMany + * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function comments() { @@ -394,12 +396,12 @@ class Discussion extends AbstractModel * If no user is passed (i.e. in the case of eager loading the 'state' * relation), then the static `$stateUser` property is used. * - * @see Discussion::setStateUser() - * * @param User|null $user - * @return \Illuminate\Database\Eloquent\Relations\HasOne + * @return HasOne + * + * @see Discussion::setStateUser() */ - public function state(User $user = null) + public function state(User $user = null): HasOne { $user = $user ?: static::$stateUser; @@ -409,12 +411,10 @@ class Discussion extends AbstractModel /** * Get the state model for a user, or instantiate a new one if it does not * exist. - * - * @param User $user - * @return \Flarum\Discussion\UserState */ - public function stateFor(User $user) + public function stateFor(User $user): UserState { + /** @var UserState|null $state */ $state = $this->state($user)->first(); if (! $state) { @@ -428,8 +428,6 @@ class Discussion extends AbstractModel /** * Set the user for which the state relationship should be loaded. - * - * @param User $user */ public static function setStateUser(User $user) { @@ -440,11 +438,8 @@ class Discussion extends AbstractModel * Set the discussion title. * * This automatically creates a matching slug for the discussion. - * - * @todo slug should be set by the slugger, drop slug column entirely? - * @param string $title */ - protected function setTitleAttribute($title) + protected function setTitleAttribute(string $title) { $this->attributes['title'] = $title; $this->slug = Str::slug( diff --git a/framework/core/src/Discussion/DiscussionRepository.php b/framework/core/src/Discussion/DiscussionRepository.php index a50ec5537..87793f5b7 100644 --- a/framework/core/src/Discussion/DiscussionRepository.php +++ b/framework/core/src/Discussion/DiscussionRepository.php @@ -17,7 +17,7 @@ class DiscussionRepository /** * Get a new query builder for the discussions table. * - * @return Builder + * @return Builder */ public function query() { @@ -28,13 +28,13 @@ class DiscussionRepository * Find a discussion by ID, optionally making sure it is visible to a * certain user, or throw an exception. * - * @param int $id - * @param User $user + * @param int|string $id + * @param User|null $user * @return \Flarum\Discussion\Discussion */ public function findOrFail($id, User $user = null) { - $query = Discussion::where('id', $id); + $query = $this->query()->where('id', $id); return $this->scopeVisibleTo($query, $user)->firstOrFail(); } @@ -42,26 +42,25 @@ class DiscussionRepository /** * Get the IDs of discussions which a user has read completely. * - * @deprecated 1.3 Use `getReadIdsQuery` instead - * * @param User $user - * @return array + * @return \Illuminate\Database\Eloquent\Collection + * @deprecated 1.3 Use `getReadIdsQuery` instead */ public function getReadIds(User $user) { - return $this->getReadIdsQuery($user) - ->all(); + return $this->getReadIdsQuery($user)->get(); } /** * Get a query containing the IDs of discussions which a user has read completely. * * @param User $user - * @return Builder + * @return Builder */ public function getReadIdsQuery(User $user): Builder { - return Discussion::leftJoin('discussion_user', 'discussion_user.discussion_id', '=', 'discussions.id') + return $this->query() + ->leftJoin('discussion_user', 'discussion_user.discussion_id', '=', 'discussions.id') ->where('discussion_user.user_id', $user->id) ->whereColumn('last_read_post_number', '>=', 'last_post_number') ->select('id'); @@ -70,9 +69,9 @@ class DiscussionRepository /** * Scope a query to only include records that are visible to a user. * - * @param Builder $query - * @param User $user - * @return Builder + * @param Builder $query + * @param User|null $user + * @return Builder */ protected function scopeVisibleTo(Builder $query, User $user = null) { diff --git a/framework/core/src/Discussion/IdWithTransliteratedSlugDriver.php b/framework/core/src/Discussion/IdWithTransliteratedSlugDriver.php index 3a1cb58ef..2f55220f7 100644 --- a/framework/core/src/Discussion/IdWithTransliteratedSlugDriver.php +++ b/framework/core/src/Discussion/IdWithTransliteratedSlugDriver.php @@ -13,6 +13,9 @@ use Flarum\Database\AbstractModel; use Flarum\Http\SlugDriverInterface; use Flarum\User\User; +/** + * @implements SlugDriverInterface + */ class IdWithTransliteratedSlugDriver implements SlugDriverInterface { /** @@ -25,6 +28,9 @@ class IdWithTransliteratedSlugDriver implements SlugDriverInterface $this->discussions = $discussions; } + /** + * @param Discussion $instance + */ public function toSlug(AbstractModel $instance): string { return $instance->id.(trim($instance->slug) ? '-'.$instance->slug : ''); diff --git a/framework/core/src/Discussion/Search/Gambit/FulltextGambit.php b/framework/core/src/Discussion/Search/Gambit/FulltextGambit.php index ed0b16f2a..20cd7227e 100644 --- a/framework/core/src/Discussion/Search/Gambit/FulltextGambit.php +++ b/framework/core/src/Discussion/Search/Gambit/FulltextGambit.php @@ -65,5 +65,7 @@ class FulltextGambit implements GambitInterface $query->orderByRaw('MATCH('.$grammar->wrap('discussions.title').') AGAINST (?) desc', [$bit]); $query->orderBy('posts_ft.score', 'desc'); }); + + return true; } } diff --git a/framework/core/src/Discussion/Utf8SlugDriver.php b/framework/core/src/Discussion/Utf8SlugDriver.php index b84facbbe..d0467df49 100644 --- a/framework/core/src/Discussion/Utf8SlugDriver.php +++ b/framework/core/src/Discussion/Utf8SlugDriver.php @@ -13,6 +13,9 @@ use Flarum\Database\AbstractModel; use Flarum\Http\SlugDriverInterface; use Flarum\User\User; +/** + * @implements SlugDriverInterface + */ class Utf8SlugDriver implements SlugDriverInterface { /** @@ -25,6 +28,10 @@ class Utf8SlugDriver implements SlugDriverInterface $this->discussions = $discussions; } + /** + * @param Discussion $instance + * @return string + */ public function toSlug(AbstractModel $instance): string { $slug = preg_replace('/[-\s]+/u', '-', $instance->title); @@ -34,6 +41,11 @@ class Utf8SlugDriver implements SlugDriverInterface return $instance->id.(trim($slug) ? '-'.$slug : ''); } + /** + * @param string $slug + * @param User $actor + * @return Discussion + */ public function fromSlug(string $slug, User $actor): AbstractModel { if (strpos($slug, '-')) { diff --git a/framework/core/src/Extend/ErrorHandling.php b/framework/core/src/Extend/ErrorHandling.php index 7d75465d4..135c795e5 100644 --- a/framework/core/src/Extend/ErrorHandling.php +++ b/framework/core/src/Extend/ErrorHandling.php @@ -76,7 +76,7 @@ class ErrorHandling implements ExtenderInterface * contain "details" - arbitrary data with more context for to the error. * * @param string $exceptionClass: The ::class attribute of the exception class. - * @param string $errorType: The ::class attribute of the handler class. + * @param string $handlerClass: The ::class attribute of the handler class. * @return self */ public function handler(string $exceptionClass, string $handlerClass): self diff --git a/framework/core/src/Extend/Frontend.php b/framework/core/src/Extend/Frontend.php index f44d2ee43..1bab3522d 100644 --- a/framework/core/src/Extend/Frontend.php +++ b/framework/core/src/Extend/Frontend.php @@ -110,7 +110,7 @@ class Frontend implements ExtenderInterface /** * Modify the content of the frontend. * - * @param callable|string|null $content + * @param callable|string|null $callback * * The content can be a closure or an invokable class, and should accept: * - \Flarum\Frontend\Document $document diff --git a/framework/core/src/Extend/LanguagePack.php b/framework/core/src/Extend/LanguagePack.php index 9807ce978..96cc87503 100644 --- a/framework/core/src/Extend/LanguagePack.php +++ b/framework/core/src/Extend/LanguagePack.php @@ -31,7 +31,7 @@ class LanguagePack implements ExtenderInterface, LifecycleInterface /** * LanguagePack constructor. * - * @param string|null $path: Path to yaml language files. + * @param string $path: Path to yaml language files. */ public function __construct(string $path = '/locale') { @@ -115,7 +115,7 @@ class LanguagePack implements ExtenderInterface, LifecycleInterface return true; } - /** @var ExtensionManager $extensions */ + /** @var ExtensionManager|null $extensions */ static $extensions; $extensions = $extensions ?? $container->make(ExtensionManager::class); diff --git a/framework/core/src/Extend/Middleware.php b/framework/core/src/Extend/Middleware.php index e7fe119be..e22f3e458 100644 --- a/framework/core/src/Extend/Middleware.php +++ b/framework/core/src/Extend/Middleware.php @@ -48,7 +48,7 @@ class Middleware implements ExtenderInterface * * @param string $originalMiddleware: ::class attribute of the original middleware class. * Or container binding name. - * @param string $middleware: ::class attribute of the middleware class. + * @param string $newMiddleware: ::class attribute of the middleware class. * Must implement \Psr\Http\Server\MiddlewareInterface. * @return self */ @@ -77,7 +77,7 @@ class Middleware implements ExtenderInterface * * @param string $originalMiddleware: ::class attribute of the original middleware class. * Or container binding name. - * @param string $middleware: ::class attribute of the middleware class. + * @param string $newMiddleware: ::class attribute of the middleware class. * Must implement \Psr\Http\Server\MiddlewareInterface. * @return self */ @@ -93,7 +93,7 @@ class Middleware implements ExtenderInterface * * @param string $originalMiddleware: ::class attribute of the original middleware class. * Or container binding name. - * @param string $middleware: ::class attribute of the middleware class. + * @param string $newMiddleware: ::class attribute of the middleware class. * Must implement \Psr\Http\Server\MiddlewareInterface. * @return self */ diff --git a/framework/core/src/Extend/View.php b/framework/core/src/Extend/View.php index b40b41075..1c0d39c8e 100644 --- a/framework/core/src/Extend/View.php +++ b/framework/core/src/Extend/View.php @@ -13,6 +13,7 @@ use Flarum\Extension\Extension; use Flarum\Foundation\Paths; use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\View\Factory; +use Illuminate\View\Factory as FactoryImplementation; /** * Views are PHP files that use the Laravel Blade syntax for creation of server-side generated HTML. @@ -65,7 +66,7 @@ class View implements ExtenderInterface, LifecycleInterface public function extend(Container $container, Extension $extension = null) { - $container->resolving(Factory::class, function (Factory $view) { + $container->resolving(Factory::class, function (FactoryImplementation $view) { foreach ($this->namespaces as $namespace => $hints) { $view->addNamespace($namespace, $hints); } diff --git a/framework/core/src/Extension/Exception/ExtensionBootError.php b/framework/core/src/Extension/Exception/ExtensionBootError.php index 881b98230..e015bf34b 100644 --- a/framework/core/src/Extension/Exception/ExtensionBootError.php +++ b/framework/core/src/Extension/Exception/ExtensionBootError.php @@ -25,6 +25,6 @@ class ExtensionBootError extends Exception $extenderClass = get_class($extender); - parent::__construct("Experienced an error while booting extension: {$extension->getTitle()}.\n\nError occurred while applying an extender of type: $extenderClass.", null, $previous); + parent::__construct("Experienced an error while booting extension: {$extension->getTitle()}.\n\nError occurred while applying an extender of type: $extenderClass.", 0, $previous); } } diff --git a/framework/core/src/Extension/Extension.php b/framework/core/src/Extension/Extension.php index d841a2f3e..dfe664d22 100644 --- a/framework/core/src/Extension/Extension.php +++ b/framework/core/src/Extension/Extension.php @@ -214,9 +214,6 @@ class Extension implements Arrayable * @param array $extensionSet: An associative array where keys are the composer package names * of installed extensions. Used to figure out which dependencies * are flarum extensions. - * @param array $enabledIds: An associative array where keys are the composer package names - * of enabled extensions. Used to figure out optional dependencies. - * * @internal */ public function calculateDependencies($extensionSet) @@ -489,6 +486,7 @@ class Extension implements Arrayable } /** + * @return int|void * @internal */ public function migrate(Migrator $migrator, $direction = 'up') @@ -498,7 +496,7 @@ class Extension implements Arrayable } if ($direction == 'up') { - return $migrator->run($this->getPath().'/migrations', $this); + $migrator->run($this->getPath().'/migrations', $this); } else { return $migrator->reset($this->getPath().'/migrations', $this); } diff --git a/framework/core/src/Extension/ExtensionManager.php b/framework/core/src/Extension/ExtensionManager.php index d958e9d17..d4ecefed1 100644 --- a/framework/core/src/Extension/ExtensionManager.php +++ b/framework/core/src/Extension/ExtensionManager.php @@ -316,7 +316,7 @@ class ExtensionManager * * @param Extension $extension * @param string $direction - * @return void + * @return int * * @internal */ @@ -326,20 +326,20 @@ class ExtensionManager return $container->make(ConnectionInterface::class)->getSchemaBuilder(); }); - $extension->migrate($this->migrator, $direction); + return $extension->migrate($this->migrator, $direction); } /** * Runs the database migrations to reset the database to its old state. * * @param Extension $extension - * @return array Notes from the migrator. + * @return void * * @internal */ public function migrateDown(Extension $extension) { - return $this->migrate($extension, 'down'); + $this->migrate($extension, 'down'); } /** diff --git a/framework/core/src/Filter/AbstractFilterer.php b/framework/core/src/Filter/AbstractFilterer.php index 7e216f468..db18b21ec 100644 --- a/framework/core/src/Filter/AbstractFilterer.php +++ b/framework/core/src/Filter/AbstractFilterer.php @@ -39,7 +39,7 @@ abstract class AbstractFilterer /** * @param QueryCriteria $criteria - * @param mixed|null $limit + * @param int|null $limit * @param int $offset * * @return QueryResults diff --git a/framework/core/src/Filter/FilterInterface.php b/framework/core/src/Filter/FilterInterface.php index a5853c4bd..edfdf5ce8 100644 --- a/framework/core/src/Filter/FilterInterface.php +++ b/framework/core/src/Filter/FilterInterface.php @@ -18,9 +18,6 @@ interface FilterInterface /** * Filters a query. - * - * @param FilterState $filter - * @param string $value The value of the requested filter */ public function filter(FilterState $filterState, string $filterValue, bool $negate); } diff --git a/framework/core/src/Formatter/Formatter.php b/framework/core/src/Formatter/Formatter.php index 7cd872401..46958d0e9 100644 --- a/framework/core/src/Formatter/Formatter.php +++ b/framework/core/src/Formatter/Formatter.php @@ -9,8 +9,6 @@ namespace Flarum\Formatter; -use DOMDocument; -use DOMElement; use Illuminate\Contracts\Cache\Repository; use Psr\Http\Message\ServerRequestInterface; use s9e\TextFormatter\Configurator; @@ -152,8 +150,8 @@ class Formatter $configurator->rootRules->enableAutoLineBreaks(); - $configurator->rendering->engine = 'PHP'; - $configurator->rendering->engine->cacheDir = $this->cacheDir; + $configurator->rendering->setEngine('PHP'); + $configurator->rendering->getEngine()->cacheDir = $this->cacheDir; // @phpstan-ignore-line $configurator->enableJavaScript(); $configurator->javascript->exports = ['preview']; @@ -161,9 +159,9 @@ class Formatter $configurator->javascript->setMinifier('MatthiasMullieMinify') ->keepGoing = true; - $configurator->Escaper; - $configurator->Autoemail; - $configurator->Autolink; + $configurator->Escaper; /** @phpstan-ignore-line */ + $configurator->Autoemail; /** @phpstan-ignore-line */ + $configurator->Autolink; /** @phpstan-ignore-line */ $configurator->tags->onDuplicate('replace'); foreach ($this->configurationCallbacks as $callback) { @@ -180,11 +178,13 @@ class Formatter */ protected function configureExternalLinks(Configurator $configurator) { - /** @var DOMDocument $dom */ + /** + * @var Configurator\Items\TemplateDocument $dom + */ $dom = $configurator->tags['URL']->template->asDOM(); - /** @var DOMElement $a */ foreach ($dom->getElementsByTagName('a') as $a) { + /** @var \s9e\SweetDOM\Element $a */ $a->prependXslCopyOf('@target'); $a->prependXslCopyOf('@rel'); } diff --git a/framework/core/src/Foundation/Application.php b/framework/core/src/Foundation/Application.php index 0f38486f4..bce9dbbfd 100644 --- a/framework/core/src/Foundation/Application.php +++ b/framework/core/src/Foundation/Application.php @@ -140,10 +140,10 @@ class Application * Use container inside flarum instead. */ $this->container->instance('app', $this->container); - $this->container->alias('app', \Illluminate\Container\Container::class); + $this->container->alias('app', \Illuminate\Container\Container::class); $this->container->instance('container', $this->container); - $this->container->alias('container', \Illluminate\Container\Container::class); + $this->container->alias('container', \Illuminate\Container\Container::class); $this->container->instance('flarum', $this); $this->container->alias('flarum', self::class); @@ -170,7 +170,7 @@ class Application */ public function register($provider, $options = [], $force = false) { - if ($registered = $this->getProvider($provider) && ! $force) { + if (($registered = $this->getProvider($provider)) && ! $force) { return $registered; } diff --git a/framework/core/src/Foundation/Console/InfoCommand.php b/framework/core/src/Foundation/Console/InfoCommand.php index 52a49502c..383710bd5 100644 --- a/framework/core/src/Foundation/Console/InfoCommand.php +++ b/framework/core/src/Foundation/Console/InfoCommand.php @@ -42,6 +42,7 @@ class InfoCommand extends AbstractCommand * @var ConnectionInterface */ protected $db; + /** * @var Queue */ diff --git a/framework/core/src/Foundation/InstalledSite.php b/framework/core/src/Foundation/InstalledSite.php index 790066a7c..6ccc248f1 100644 --- a/framework/core/src/Foundation/InstalledSite.php +++ b/framework/core/src/Foundation/InstalledSite.php @@ -104,7 +104,7 @@ class InstalledSite implements SiteInterface $container->instance('flarum.config', $this->config); $container->alias('flarum.config', Config::class); $container->instance('flarum.debug', $this->config->inDebugMode()); - $container->instance('config', $config = $this->getIlluminateConfig($laravel)); + $container->instance('config', $config = $this->getIlluminateConfig()); $container->instance('flarum.maintenance.handler', new MaintenanceModeHandler); $this->registerLogger($container); diff --git a/framework/core/src/Foundation/Paths.php b/framework/core/src/Foundation/Paths.php index b527cd50b..a873123f8 100644 --- a/framework/core/src/Foundation/Paths.php +++ b/framework/core/src/Foundation/Paths.php @@ -12,10 +12,10 @@ namespace Flarum\Foundation; use InvalidArgumentException; /** - * @property-read string base - * @property-read string public - * @property-read string storage - * @property-read string vendor + * @property-read string $base + * @property-read string $public + * @property-read string $storage + * @property-read string $vendor */ class Paths { diff --git a/framework/core/src/Frontend/Assets.php b/framework/core/src/Frontend/Assets.php index 2bb53507e..6750b7a6c 100644 --- a/framework/core/src/Frontend/Assets.php +++ b/framework/core/src/Frontend/Assets.php @@ -13,7 +13,7 @@ use Flarum\Frontend\Compiler\CompilerInterface; use Flarum\Frontend\Compiler\JsCompiler; use Flarum\Frontend\Compiler\LessCompiler; use Flarum\Frontend\Compiler\Source\SourceCollector; -use Illuminate\Contracts\Filesystem\Filesystem; +use Illuminate\Contracts\Filesystem\Cloud; /** * A factory class for creating frontend asset compilers. @@ -38,7 +38,7 @@ class Assets protected $name; /** - * @var Filesystem + * @var Cloud */ protected $assetsDir; @@ -67,7 +67,7 @@ class Assets */ protected $customFunctions = []; - public function __construct(string $name, Filesystem $assetsDir, string $cacheDir = null, array $lessImportDirs = null, array $customFunctions = []) + public function __construct(string $name, Cloud $assetsDir, string $cacheDir = null, array $lessImportDirs = null, array $customFunctions = []) { $this->name = $name; $this->assetsDir = $assetsDir; @@ -200,12 +200,12 @@ class Assets $this->name = $name; } - public function getAssetsDir(): Filesystem + public function getAssetsDir(): Cloud { return $this->assetsDir; } - public function setAssetsDir(Filesystem $assetsDir) + public function setAssetsDir(Cloud $assetsDir) { $this->assetsDir = $assetsDir; } diff --git a/framework/core/src/Frontend/Compiler/FileVersioner.php b/framework/core/src/Frontend/Compiler/FileVersioner.php index de2766c20..7c03df2c2 100644 --- a/framework/core/src/Frontend/Compiler/FileVersioner.php +++ b/framework/core/src/Frontend/Compiler/FileVersioner.php @@ -27,8 +27,8 @@ class FileVersioner implements VersionerInterface public function putRevision(string $file, ?string $revision) { - if ($this->filesystem->has(static::REV_MANIFEST)) { - $manifest = json_decode($this->filesystem->read(static::REV_MANIFEST), true); + if ($this->filesystem->exists(static::REV_MANIFEST)) { + $manifest = json_decode($this->filesystem->get(static::REV_MANIFEST), true); } else { $manifest = []; } @@ -44,8 +44,8 @@ class FileVersioner implements VersionerInterface public function getRevision(string $file): ?string { - if ($this->filesystem->has(static::REV_MANIFEST)) { - $manifest = json_decode($this->filesystem->read(static::REV_MANIFEST), true); + if ($this->filesystem->exists(static::REV_MANIFEST)) { + $manifest = json_decode($this->filesystem->get(static::REV_MANIFEST), true); return Arr::get($manifest, $file); } diff --git a/framework/core/src/Frontend/Compiler/JsCompiler.php b/framework/core/src/Frontend/Compiler/JsCompiler.php index a092f6af0..c9c4510a7 100644 --- a/framework/core/src/Frontend/Compiler/JsCompiler.php +++ b/framework/core/src/Frontend/Compiler/JsCompiler.php @@ -72,7 +72,7 @@ class JsCompiler extends RevisionCompiler { parent::delete($file); - if ($this->assetsDir->has($mapFile = $file.'.map')) { + if ($this->assetsDir->exists($mapFile = $file.'.map')) { $this->assetsDir->delete($mapFile); } } diff --git a/framework/core/src/Frontend/Compiler/LessCompiler.php b/framework/core/src/Frontend/Compiler/LessCompiler.php index e6c92c928..3825215c7 100644 --- a/framework/core/src/Frontend/Compiler/LessCompiler.php +++ b/framework/core/src/Frontend/Compiler/LessCompiler.php @@ -35,12 +35,12 @@ class LessCompiler extends RevisionCompiler protected $customFunctions = []; /** - * @var Collection + * @var Collection|null */ protected $lessImportOverrides; /** - * @var Collection + * @var Collection|null */ protected $fileSourceOverrides; @@ -88,7 +88,7 @@ class LessCompiler extends RevisionCompiler return ''; } - ini_set('xdebug.max_nesting_level', 200); + ini_set('xdebug.max_nesting_level', '200'); $parser = new Less_Parser([ 'compress' => true, diff --git a/framework/core/src/Frontend/Compiler/RevisionCompiler.php b/framework/core/src/Frontend/Compiler/RevisionCompiler.php index edb88bafc..adf2e9305 100644 --- a/framework/core/src/Frontend/Compiler/RevisionCompiler.php +++ b/framework/core/src/Frontend/Compiler/RevisionCompiler.php @@ -11,7 +11,7 @@ namespace Flarum\Frontend\Compiler; use Flarum\Frontend\Compiler\Source\SourceCollector; use Flarum\Frontend\Compiler\Source\SourceInterface; -use Illuminate\Contracts\Filesystem\Filesystem; +use Illuminate\Contracts\Filesystem\Cloud; /** * @internal @@ -21,9 +21,10 @@ class RevisionCompiler implements CompilerInterface const EMPTY_REVISION = 'empty'; /** - * @var Filesystem + * @var Cloud */ protected $assetsDir; + /** * @var VersionerInterface */ @@ -40,11 +41,11 @@ class RevisionCompiler implements CompilerInterface protected $sourcesCallbacks = []; /** - * @param Filesystem $assetsDir + * @param Cloud $assetsDir * @param string $filename * @param VersionerInterface|null $versioner @deprecated nullable will be removed at v2.0 */ - public function __construct(Filesystem $assetsDir, string $filename, VersionerInterface $versioner = null) + public function __construct(Cloud $assetsDir, string $filename, VersionerInterface $versioner = null) { $this->assetsDir = $assetsDir; $this->filename = $filename; @@ -71,7 +72,7 @@ class RevisionCompiler implements CompilerInterface // In case the previous and current revisions do not match // Or no file was written yet, let's save the file to disk. - if ($force || $oldRevision !== $newRevision || ! $this->assetsDir->has($this->filename)) { + if ($force || $oldRevision !== $newRevision || ! $this->assetsDir->exists($this->filename)) { if (! $this->save($this->filename, $sources)) { // If no file was written (because the sources were empty), we // will set the revision to a special value so that we can tell @@ -145,7 +146,6 @@ class RevisionCompiler implements CompilerInterface /** * @param SourceInterface[] $sources - * @return string */ protected function compile(array $sources): string { @@ -158,10 +158,6 @@ class RevisionCompiler implements CompilerInterface return $output; } - /** - * @param string $string - * @return string - */ protected function format(string $string): string { return $string; @@ -169,7 +165,6 @@ class RevisionCompiler implements CompilerInterface /** * @param SourceInterface[] $sources - * @return string */ protected function calculateRevision(array $sources): string { @@ -196,12 +191,9 @@ class RevisionCompiler implements CompilerInterface } } - /** - * @param string $file - */ protected function delete(string $file) { - if ($this->assetsDir->has($file)) { + if ($this->assetsDir->exists($file)) { $this->assetsDir->delete($file); } } diff --git a/framework/core/src/Frontend/Document.php b/framework/core/src/Frontend/Document.php index b839fca19..4b947059c 100644 --- a/framework/core/src/Frontend/Document.php +++ b/framework/core/src/Frontend/Document.php @@ -221,14 +221,13 @@ class Document implements Renderable return resolve(TitleDriverInterface::class)->makeTitle($this, $this->request, $this->forumApiDocument); } - /** - * @return View - */ - protected function makeLayout(): View + protected function makeLayout(): ?View { if ($this->layoutView) { return $this->view->make($this->layoutView)->with('content', $this->makeContent()); } + + return null; } /** diff --git a/framework/core/src/Group/GroupRepository.php b/framework/core/src/Group/GroupRepository.php index 769e0d606..50aa2708d 100644 --- a/framework/core/src/Group/GroupRepository.php +++ b/framework/core/src/Group/GroupRepository.php @@ -17,7 +17,7 @@ class GroupRepository /** * Get a new query builder for the groups table. * - * @return Builder + * @return Builder */ public function query() { @@ -29,14 +29,14 @@ class GroupRepository * user, or throw an exception. * * @param int $id - * @param User $actor - * @return \Flarum\Group\Group + * @param User|null $actor + * @return Group * * @throws \Illuminate\Database\Eloquent\ModelNotFoundException */ public function findOrFail($id, User $actor = null) { - $query = Group::where('id', $id); + $query = $this->query()->where('id', $id); return $this->scopeVisibleTo($query, $actor)->firstOrFail(); } @@ -44,9 +44,9 @@ class GroupRepository /** * Scope a query to only include records that are visible to a user. * - * @param Builder $query - * @param User $actor - * @return Builder + * @param Builder $query + * @param User|null $actor + * @return Builder */ protected function scopeVisibleTo(Builder $query, User $actor = null) { diff --git a/framework/core/src/Http/AccessToken.php b/framework/core/src/Http/AccessToken.php index 40357838b..41b3e60bf 100644 --- a/framework/core/src/Http/AccessToken.php +++ b/framework/core/src/Http/AccessToken.php @@ -25,8 +25,8 @@ use Psr\Http\Message\ServerRequestInterface; * @property Carbon|null $last_activity_at * @property string $type * @property string $title - * @property string $last_ip_address - * @property string $last_user_agent + * @property string|null $last_ip_address + * @property string|null $last_user_agent * @property \Flarum\User\User|null $user */ class AccessToken extends AbstractModel diff --git a/framework/core/src/Http/CookieFactory.php b/framework/core/src/Http/CookieFactory.php index b0ee9fd60..fb5f72a69 100644 --- a/framework/core/src/Http/CookieFactory.php +++ b/framework/core/src/Http/CookieFactory.php @@ -46,7 +46,7 @@ class CookieFactory /** * Same Site cookie value. * - * @var string + * @var string|null */ protected $samesite; diff --git a/framework/core/src/Http/Middleware/ResolveRoute.php b/framework/core/src/Http/Middleware/ResolveRoute.php index cc203a0b7..dc27027fd 100644 --- a/framework/core/src/Http/Middleware/ResolveRoute.php +++ b/framework/core/src/Http/Middleware/ResolveRoute.php @@ -26,7 +26,7 @@ class ResolveRoute implements Middleware protected $routes; /** - * @var Dispatcher + * @var Dispatcher|null */ protected $dispatcher; @@ -43,6 +43,8 @@ class ResolveRoute implements Middleware /** * Resolve the given request from our route collection. * + * @return Response + * * @throws MethodNotAllowedException * @throws RouteNotFoundException */ @@ -58,7 +60,7 @@ class ResolveRoute implements Middleware throw new RouteNotFoundException($uri); case Dispatcher::METHOD_NOT_ALLOWED: throw new MethodNotAllowedException($method); - case Dispatcher::FOUND: + default: $request = $request ->withAttribute('routeName', $routeInfo[1]['name']) ->withAttribute('routeHandler', $routeInfo[1]['handler']) diff --git a/framework/core/src/Http/Server.php b/framework/core/src/Http/Server.php index e7faf3b17..278caba66 100644 --- a/framework/core/src/Http/Server.php +++ b/framework/core/src/Http/Server.php @@ -11,6 +11,7 @@ namespace Flarum\Http; use Flarum\Foundation\ErrorHandling\LogReporter; use Flarum\Foundation\SiteInterface; +use Illuminate\Contracts\Container\Container; use Laminas\Diactoros\Response; use Laminas\Diactoros\ServerRequest; use Laminas\Diactoros\ServerRequestFactory; @@ -50,7 +51,7 @@ class Server * We catch all exceptions happening during this process and format them to * prevent exposure of sensitive information. * - * @return \Psr\Http\Server\RequestHandlerInterface + * @return \Psr\Http\Server\RequestHandlerInterface|void */ private function safelyBootAndGetHandler() { @@ -80,7 +81,9 @@ class Server */ private function cleanBootExceptionLog(Throwable $error) { - if (app()->has('flarum.config') && app('flarum.config')->inDebugMode()) { + $container = resolve(Container::class); + + if ($container->has('flarum.config') && resolve('flarum.config')->inDebugMode()) { // If the application booted far enough for the config to be available, we will check for debug mode // Since the config is loaded very early, it is very likely to be available from the container $message = $error->getMessage(); @@ -96,12 +99,12 @@ class Server
$error
ERROR; exit(1); - } elseif (app()->has(LoggerInterface::class)) { + } elseif ($container->has(LoggerInterface::class)) { // If the application booted far enough for the logger to be available, we will log the error there // Considering most boot errors are related to database or extensions, the logger should already be loaded // We check for LoggerInterface binding because it's a constructor dependency of LogReporter, // then instantiate LogReporter through the container for automatic dependency injection - app(LogReporter::class)->report($error); + resolve(LogReporter::class)->report($error); echo 'Flarum encountered a boot error. Details have been logged to the Flarum log file.'; exit(1); diff --git a/framework/core/src/Http/SlugDriverInterface.php b/framework/core/src/Http/SlugDriverInterface.php index 84d3a621e..40c3a277d 100644 --- a/framework/core/src/Http/SlugDriverInterface.php +++ b/framework/core/src/Http/SlugDriverInterface.php @@ -12,9 +12,18 @@ namespace Flarum\Http; use Flarum\Database\AbstractModel; use Flarum\User\User; +/** + * @template T of AbstractModel + */ interface SlugDriverInterface { + /** + * @param T $instance + */ public function toSlug(AbstractModel $instance): string; + /** + * @return T + */ public function fromSlug(string $slug, User $actor): AbstractModel; } diff --git a/framework/core/src/Http/SlugManager.php b/framework/core/src/Http/SlugManager.php index 71ec28a85..3aa510e3d 100644 --- a/framework/core/src/Http/SlugManager.php +++ b/framework/core/src/Http/SlugManager.php @@ -20,6 +20,11 @@ class SlugManager $this->drivers = $drivers; } + /** + * @template T of \Flarum\Database\AbstractModel + * @param class-string $resourceName + * @return SlugDriverInterface + */ public function forResource(string $resourceName): SlugDriverInterface { return Arr::get($this->drivers, $resourceName, null); diff --git a/framework/core/src/Install/Console/InstallCommand.php b/framework/core/src/Install/Console/InstallCommand.php index d6b464054..e74d2cd0f 100644 --- a/framework/core/src/Install/Console/InstallCommand.php +++ b/framework/core/src/Install/Console/InstallCommand.php @@ -13,6 +13,7 @@ use Flarum\Console\AbstractCommand; use Flarum\Install\Installation; use Flarum\Install\Pipeline; use Flarum\Install\Step; +use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Input\InputOption; class InstallCommand extends AbstractCommand @@ -83,7 +84,9 @@ class InstallCommand extends AbstractCommand if ($this->input->getOption('file')) { $this->dataSource = new FileDataProvider($this->input); } else { - $this->dataSource = new UserDataProvider($this->input, $this->output, $this->getHelperSet()->get('question')); + /** @var QuestionHelper $questionHelper */ + $questionHelper = $this->getHelperSet()->get('question'); + $this->dataSource = new UserDataProvider($this->input, $this->output, $questionHelper); } } diff --git a/framework/core/src/Install/Controller/IndexController.php b/framework/core/src/Install/Controller/IndexController.php index 886e7a52a..642264291 100644 --- a/framework/core/src/Install/Controller/IndexController.php +++ b/framework/core/src/Install/Controller/IndexController.php @@ -26,10 +26,6 @@ class IndexController extends AbstractHtmlController */ protected $installation; - /** - * @param Factory $view - * @param Installation $installation - */ public function __construct(Factory $view, Installation $installation) { $this->view = $view; @@ -37,7 +33,6 @@ class IndexController extends AbstractHtmlController } /** - * @param Request $request * @return \Illuminate\Contracts\Support\Renderable */ public function render(Request $request) diff --git a/framework/core/src/Install/ReversibleStep.php b/framework/core/src/Install/ReversibleStep.php index da239f2c2..0189bbf3e 100644 --- a/framework/core/src/Install/ReversibleStep.php +++ b/framework/core/src/Install/ReversibleStep.php @@ -9,7 +9,7 @@ namespace Flarum\Install; -interface ReversibleStep +interface ReversibleStep extends Step { public function revert(); } diff --git a/framework/core/src/Install/Steps/EnableBundledExtensions.php b/framework/core/src/Install/Steps/EnableBundledExtensions.php index d77a6109f..5abcdf14e 100644 --- a/framework/core/src/Install/Steps/EnableBundledExtensions.php +++ b/framework/core/src/Install/Steps/EnableBundledExtensions.php @@ -60,6 +60,11 @@ class EnableBundledExtensions implements Step */ private $enabledExtensions; + /** + * @var Migrator|null + */ + private $migrator; + public function __construct(ConnectionInterface $database, $vendorPath, $assetPath, $enabledExtensions = null) { $this->database = $database; @@ -124,7 +129,7 @@ class EnableBundledExtensions implements Step }); } - private function getMigrator() + private function getMigrator(): Migrator { return $this->migrator = $this->migrator ?? new Migrator( new DatabaseMigrationRepository($this->database, 'migrations'), diff --git a/framework/core/src/Install/Steps/PublishAssets.php b/framework/core/src/Install/Steps/PublishAssets.php index f601831c6..4b321a1a0 100644 --- a/framework/core/src/Install/Steps/PublishAssets.php +++ b/framework/core/src/Install/Steps/PublishAssets.php @@ -10,10 +10,9 @@ namespace Flarum\Install\Steps; use Flarum\Install\ReversibleStep; -use Flarum\Install\Step; use Illuminate\Filesystem\Filesystem; -class PublishAssets implements Step, ReversibleStep +class PublishAssets implements ReversibleStep { /** * @var string diff --git a/framework/core/src/Install/Steps/StoreConfig.php b/framework/core/src/Install/Steps/StoreConfig.php index 63fa75ad6..e878e6013 100644 --- a/framework/core/src/Install/Steps/StoreConfig.php +++ b/framework/core/src/Install/Steps/StoreConfig.php @@ -12,9 +12,8 @@ namespace Flarum\Install\Steps; use Flarum\Install\BaseUrl; use Flarum\Install\DatabaseConfig; use Flarum\Install\ReversibleStep; -use Flarum\Install\Step; -class StoreConfig implements Step, ReversibleStep +class StoreConfig implements ReversibleStep { private $debugMode; diff --git a/framework/core/src/Notification/Driver/EmailNotificationDriver.php b/framework/core/src/Notification/Driver/EmailNotificationDriver.php index 1a4870380..d25620953 100644 --- a/framework/core/src/Notification/Driver/EmailNotificationDriver.php +++ b/framework/core/src/Notification/Driver/EmailNotificationDriver.php @@ -41,7 +41,7 @@ class EmailNotificationDriver implements NotificationDriverInterface /** * Mail a notification to a list of users. * - * @param MailableInterface $blueprint + * @param MailableInterface&BlueprintInterface $blueprint * @param User[] $recipients */ protected function mailNotifications(MailableInterface $blueprint, array $recipients) diff --git a/framework/core/src/Notification/Event/DeletedAll.php b/framework/core/src/Notification/Event/DeletedAll.php index 8d202eb7c..84eb20fdc 100644 --- a/framework/core/src/Notification/Event/DeletedAll.php +++ b/framework/core/src/Notification/Event/DeletedAll.php @@ -26,7 +26,7 @@ class DeletedAll public function __construct(User $user, DateTime $timestamp) { - $this->user = $user; + $this->actor = $user; $this->timestamp = $timestamp; } } diff --git a/framework/core/src/Notification/Event/Read.php b/framework/core/src/Notification/Event/Read.php index eb0510f59..00618e4cd 100644 --- a/framework/core/src/Notification/Event/Read.php +++ b/framework/core/src/Notification/Event/Read.php @@ -32,7 +32,7 @@ class Read public function __construct(User $user, Notification $notification, DateTime $timestamp) { - $this->user = $user; + $this->actor = $user; $this->notification = $notification; $this->timestamp = $timestamp; } diff --git a/framework/core/src/Notification/Event/ReadAll.php b/framework/core/src/Notification/Event/ReadAll.php index e2bfa72fe..6cb7b5fe2 100644 --- a/framework/core/src/Notification/Event/ReadAll.php +++ b/framework/core/src/Notification/Event/ReadAll.php @@ -26,7 +26,7 @@ class ReadAll public function __construct(User $user, DateTime $timestamp) { - $this->user = $user; + $this->actor = $user; $this->timestamp = $timestamp; } } diff --git a/framework/core/src/Notification/Notification.php b/framework/core/src/Notification/Notification.php index 368eb0f91..91da2c6c8 100644 --- a/framework/core/src/Notification/Notification.php +++ b/framework/core/src/Notification/Notification.php @@ -41,7 +41,7 @@ use Illuminate\Support\Arr; * @property \Carbon\Carbon $deleted_at * @property \Flarum\User\User|null $user * @property \Flarum\User\User|null $fromUser - * @property \Flarum\Database\AbstractModel|null $subject + * @property \Flarum\Database\AbstractModel|\Flarum\Post\Post|\Flarum\Discussion\Discussion|null $subject */ class Notification extends AbstractModel { @@ -76,7 +76,7 @@ class Notification extends AbstractModel * When getting the data attribute, unserialize the JSON stored in the * database into a plain array. * - * @param string $value + * @param string|null $value * @return mixed */ public function getDataAttribute($value) @@ -258,7 +258,7 @@ class Notification extends AbstractModel static::$subjectModels[$type] = $subjectModel; } - private static function getBlueprintAttributes(BlueprintInterface $blueprint): array + protected static function getBlueprintAttributes(BlueprintInterface $blueprint): array { return [ 'type' => $blueprint::getType(), diff --git a/framework/core/src/Notification/NotificationMailer.php b/framework/core/src/Notification/NotificationMailer.php index 5bdcbca6c..7b5a1ee62 100644 --- a/framework/core/src/Notification/NotificationMailer.php +++ b/framework/core/src/Notification/NotificationMailer.php @@ -12,6 +12,7 @@ namespace Flarum\Notification; use Flarum\Settings\SettingsRepositoryInterface; use Flarum\User\User; use Illuminate\Contracts\Mail\Mailer; +use Illuminate\Contracts\Translation\Translator; use Illuminate\Mail\Message; use Symfony\Contracts\Translation\TranslatorInterface; @@ -23,7 +24,7 @@ class NotificationMailer protected $mailer; /** - * @var TranslatorInterface + * @var TranslatorInterface&Translator */ protected $translator; @@ -33,9 +34,7 @@ class NotificationMailer protected $settings; /** - * @param Mailer $mailer - * @param TranslatorInterface $translator - * @param SettingsRepositoryInterface $settings + * @param TranslatorInterface&Translator $translator */ public function __construct(Mailer $mailer, TranslatorInterface $translator, SettingsRepositoryInterface $settings) { diff --git a/framework/core/src/Notification/NotificationRepository.php b/framework/core/src/Notification/NotificationRepository.php index 7f6b29da1..d34941e65 100644 --- a/framework/core/src/Notification/NotificationRepository.php +++ b/framework/core/src/Notification/NotificationRepository.php @@ -24,7 +24,8 @@ class NotificationRepository */ public function findByUser(User $user, $limit = null, $offset = 0) { - $primaries = Notification::selectRaw('MAX(id) AS id') + $primaries = Notification::query() + ->selectRaw('MAX(id) AS id') ->selectRaw('SUM(read_at IS NULL) AS unread_count') ->where('user_id', $user->id) ->whereIn('type', $user->getAlertableNotificationTypes()) @@ -35,7 +36,8 @@ class NotificationRepository ->skip($offset) ->take($limit); - return Notification::select('notifications.*', 'p.unread_count') + return Notification::query() + ->select('notifications.*', 'p.unread_count') ->joinSub($primaries, 'p', 'notifications.id', '=', 'p.id') ->latest() ->get(); diff --git a/framework/core/src/Post/MergeableInterface.php b/framework/core/src/Post/MergeableInterface.php index 6472cc993..71260c6da 100644 --- a/framework/core/src/Post/MergeableInterface.php +++ b/framework/core/src/Post/MergeableInterface.php @@ -23,7 +23,7 @@ interface MergeableInterface * passed model. * * @param \Flarum\Post\Post|null $previous - * @return Post The model resulting after the merge. If the merge is + * @return static The model resulting after the merge. If the merge is * unsuccessful, this should be the current model instance. Otherwise, * it should be the model that was merged into. */ diff --git a/framework/core/src/Post/Post.php b/framework/core/src/Post/Post.php index 8a0ba4ab5..bdabe071e 100644 --- a/framework/core/src/Post/Post.php +++ b/framework/core/src/Post/Post.php @@ -16,14 +16,13 @@ use Flarum\Foundation\EventGeneratorTrait; use Flarum\Notification\Notification; use Flarum\Post\Event\Deleted; use Flarum\User\User; -use Illuminate\Database\ConnectionInterface; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Query\Expression; /** * @property int $id * @property int $discussion_id - * @property int $number + * @property int|Expression $number * @property \Carbon\Carbon $created_at * @property int|null $user_id * @property string|null $type @@ -94,8 +93,8 @@ class Post extends AbstractModel static::creating(function (self $post) { $post->type = $post::$type; - /** @var ConnectionInterface $db */ - $db = static::getConnectionResolver(); + $db = static::getConnectionResolver()->connection(); + $post->number = new Expression('('. $db->table('posts', 'pn') ->whereRaw($db->getTablePrefix().'pn.discussion_id = '.intval($post->discussion_id)) diff --git a/framework/core/src/Post/PostRepository.php b/framework/core/src/Post/PostRepository.php index 2b8f7829b..96ccba0b5 100644 --- a/framework/core/src/Post/PostRepository.php +++ b/framework/core/src/Post/PostRepository.php @@ -18,7 +18,7 @@ class PostRepository /** * Get a new query builder for the posts table. * - * @return Builder + * @return Builder */ public function query() { @@ -27,7 +27,7 @@ class PostRepository /** * @param User|null $user - * @return Builder + * @return Builder */ protected function queryVisibleTo(User $user = null) { @@ -45,8 +45,8 @@ class PostRepository * user, or throw an exception. * * @param int $id - * @param \Flarum\User\User $actor - * @return \Flarum\Post\Post + * @param \Flarum\User\User|null $actor + * @return Post * * @throws \Illuminate\Database\Eloquent\ModelNotFoundException */ @@ -126,7 +126,7 @@ class PostRepository /** * @param array $ids * @param User|null $actor - * @return Builder + * @return Builder */ protected function queryIds(array $ids, User $actor = null) { diff --git a/framework/core/src/Queue/ExceptionHandler.php b/framework/core/src/Queue/ExceptionHandler.php index d311370b1..2870ac942 100644 --- a/framework/core/src/Queue/ExceptionHandler.php +++ b/framework/core/src/Queue/ExceptionHandler.php @@ -42,9 +42,9 @@ class ExceptionHandler implements ExceptionHandling * * @param \Illuminate\Http\Request $request * @param Throwable $e - * @return \Symfony\Component\HttpFoundation\Response + * @return void */ - public function render($request, Throwable $e) + public function render($request, Throwable $e) /** @phpstan-ignore-line */ { // TODO: Implement render() method. } diff --git a/framework/core/src/Queue/QueueFactory.php b/framework/core/src/Queue/QueueFactory.php index d975f4477..cb6ae9c50 100644 --- a/framework/core/src/Queue/QueueFactory.php +++ b/framework/core/src/Queue/QueueFactory.php @@ -21,7 +21,7 @@ class QueueFactory implements Factory /** * The cached queue instance. * - * @var \Illuminate\Contracts\Queue\Queue + * @var \Illuminate\Contracts\Queue\Queue|null */ private $queue; diff --git a/framework/core/src/Queue/QueueServiceProvider.php b/framework/core/src/Queue/QueueServiceProvider.php index bfa824c67..b813b62d7 100644 --- a/framework/core/src/Queue/QueueServiceProvider.php +++ b/framework/core/src/Queue/QueueServiceProvider.php @@ -14,6 +14,7 @@ use Flarum\Foundation\Config; use Flarum\Foundation\ErrorHandling\Registry; use Flarum\Foundation\ErrorHandling\Reporter; use Flarum\Foundation\Paths; +use Illuminate\Container\Container as ContainerImplementation; use Illuminate\Contracts\Cache\Factory as CacheFactory; use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Debug\ExceptionHandler as ExceptionHandling; @@ -52,7 +53,7 @@ class QueueServiceProvider extends AbstractServiceProvider // Extensions can override this binding if they want to make Flarum use // a different queuing backend. - $this->container->singleton('flarum.queue.connection', function (Container $container) { + $this->container->singleton('flarum.queue.connection', function (ContainerImplementation $container) { $queue = new SyncQueue; $queue->setContainer($container); @@ -90,7 +91,12 @@ class QueueServiceProvider extends AbstractServiceProvider // Bind a simple cache manager that returns the cache store. $this->container->singleton('cache', function (Container $container) { return new class($container) implements CacheFactory { - public function __construct($container) + /** + * @var Container + */ + private $container; + + public function __construct(Container $container) { $this->container = $container; } diff --git a/framework/core/src/Search/AbstractRegexGambit.php b/framework/core/src/Search/AbstractRegexGambit.php index 5787a02c8..fa5fae5e8 100644 --- a/framework/core/src/Search/AbstractRegexGambit.php +++ b/framework/core/src/Search/AbstractRegexGambit.php @@ -34,13 +34,15 @@ abstract class AbstractRegexGambit implements GambitInterface * Match the bit against this gambit. * * @param string $bit - * @return array + * @return array|null */ protected function match($bit) { if (preg_match('/^(-?)'.$this->getGambitPattern().'$/i', $bit, $matches)) { return $matches; } + + return null; } /** diff --git a/framework/core/src/Search/AbstractSearcher.php b/framework/core/src/Search/AbstractSearcher.php index 49978975e..a5fbb244b 100644 --- a/framework/core/src/Search/AbstractSearcher.php +++ b/framework/core/src/Search/AbstractSearcher.php @@ -43,7 +43,6 @@ abstract class AbstractSearcher * @param int $offset * * @return QueryResults - * @throws InvalidArgumentException */ public function search(QueryCriteria $criteria, $limit = null, $offset = 0): QueryResults { diff --git a/framework/core/src/Search/GambitManager.php b/framework/core/src/Search/GambitManager.php index 928bd1257..9429d03c1 100644 --- a/framework/core/src/Search/GambitManager.php +++ b/framework/core/src/Search/GambitManager.php @@ -26,9 +26,6 @@ class GambitManager */ protected $fulltextGambit; - /** - * @param GambitInterface $gambit - */ public function __construct(GambitInterface $fulltextGambit) { $this->fulltextGambit = $fulltextGambit; diff --git a/framework/core/src/Update/Controller/IndexController.php b/framework/core/src/Update/Controller/IndexController.php index f8fe1edf2..d499e2c22 100644 --- a/framework/core/src/Update/Controller/IndexController.php +++ b/framework/core/src/Update/Controller/IndexController.php @@ -28,10 +28,6 @@ class IndexController extends AbstractHtmlController $this->view = $view; } - /** - * @param Request $request - * @return \Psr\Http\Message\ResponseInterface - */ public function render(Request $request) { $view = $this->view->make('flarum.update::app')->with('title', 'Update Flarum'); diff --git a/framework/core/src/User/Access/AbstractPolicy.php b/framework/core/src/User/Access/AbstractPolicy.php index 3b4579d74..c9d188085 100644 --- a/framework/core/src/User/Access/AbstractPolicy.php +++ b/framework/core/src/User/Access/AbstractPolicy.php @@ -40,13 +40,11 @@ abstract class AbstractPolicy } /** - * @param User $user - * @param string $ability - * @param $instance * @return string|void */ public function checkAbility(User $actor, string $ability, $instance) - { // If a specific method for this ability is defined, + { + // If a specific method for this ability is defined, // call that and return any non-null results if (method_exists($this, $ability)) { $result = $this->sanitizeResult(call_user_func_array([$this, $ability], [$actor, $instance])); @@ -73,7 +71,7 @@ abstract class AbstractPolicy * `return SOME_BOOLEAN_LOGIC; * * @param mixed $result - * @return string|void + * @return string|void|null */ public function sanitizeResult($result) { diff --git a/framework/core/src/User/Command/RegisterUserHandler.php b/framework/core/src/User/Command/RegisterUserHandler.php index a9c9a872b..bde2e4490 100644 --- a/framework/core/src/User/Command/RegisterUserHandler.php +++ b/framework/core/src/User/Command/RegisterUserHandler.php @@ -54,12 +54,6 @@ class RegisterUserHandler */ protected $imageManager; - /** - * @param Dispatcher $events - * @param SettingsRepositoryInterface $settings - * @param UserValidator $validator - * @param AvatarUploader $avatarUploader - */ public function __construct(Dispatcher $events, SettingsRepositoryInterface $settings, UserValidator $userValidator, AvatarUploader $avatarUploader, Factory $validator, ImageManager $imageManager) { $this->events = $events; @@ -91,6 +85,7 @@ class RegisterUserHandler // If a valid authentication token was provided as an attribute, // then we won't require the user to choose a password. if (isset($data['attributes']['token'])) { + /** @var RegistrationToken $token */ $token = RegistrationToken::validOrFail($data['attributes']['token']); $password = $password ?: Str::random(20); diff --git a/framework/core/src/User/EmailToken.php b/framework/core/src/User/EmailToken.php index f11862189..39313cb09 100644 --- a/framework/core/src/User/EmailToken.php +++ b/framework/core/src/User/EmailToken.php @@ -81,7 +81,7 @@ class EmailToken extends AbstractModel */ public function scopeValidOrFail($query, $id) { - /** @var EmailToken $token */ + /** @var static|null $token */ $token = $query->find($id); if (! $token || $token->created_at->diffInDays() >= 1) { diff --git a/framework/core/src/User/IdSlugDriver.php b/framework/core/src/User/IdSlugDriver.php index 2a71a508c..59fa73857 100644 --- a/framework/core/src/User/IdSlugDriver.php +++ b/framework/core/src/User/IdSlugDriver.php @@ -12,6 +12,9 @@ namespace Flarum\User; use Flarum\Database\AbstractModel; use Flarum\Http\SlugDriverInterface; +/** + * @implements SlugDriverInterface + */ class IdSlugDriver implements SlugDriverInterface { /** @@ -24,11 +27,17 @@ class IdSlugDriver implements SlugDriverInterface $this->users = $users; } + /** + * @param User $instance + */ public function toSlug(AbstractModel $instance): string { - return $instance->id; + return (string) $instance->id; } + /** + * @return User + */ public function fromSlug(string $slug, User $actor): AbstractModel { return $this->users->findOrFail($slug, $actor); diff --git a/framework/core/src/User/RegistrationToken.php b/framework/core/src/User/RegistrationToken.php index fdb696abc..adf3ade9c 100644 --- a/framework/core/src/User/RegistrationToken.php +++ b/framework/core/src/User/RegistrationToken.php @@ -21,6 +21,8 @@ use Illuminate\Support\Str; * @property array $user_attributes * @property array $payload * @property \Carbon\Carbon $created_at + * + * @method static self validOrFail(string $token) */ class RegistrationToken extends AbstractModel { @@ -74,7 +76,7 @@ class RegistrationToken extends AbstractModel /** * Find the token with the given ID, and assert that it has not expired. * - * @param \Illuminate\Database\Eloquent\Builder $query + * @param \Illuminate\Database\Eloquent\Builder $query * @param string $token * * @throws InvalidConfirmationTokenException @@ -83,7 +85,7 @@ class RegistrationToken extends AbstractModel */ public function scopeValidOrFail($query, string $token) { - /** @var RegistrationToken $token */ + /** @var RegistrationToken|null $token */ $token = $query->find($token); if (! $token || $token->created_at->lessThan(Carbon::now()->subDay())) { diff --git a/framework/core/src/User/Search/Gambit/FulltextGambit.php b/framework/core/src/User/Search/Gambit/FulltextGambit.php index 0522e76d2..47180a043 100644 --- a/framework/core/src/User/Search/Gambit/FulltextGambit.php +++ b/framework/core/src/User/Search/Gambit/FulltextGambit.php @@ -50,5 +50,7 @@ class FulltextGambit implements GambitInterface 'id', $this->getUserSearchSubQuery($searchValue) ); + + return true; } } diff --git a/framework/core/src/User/User.php b/framework/core/src/User/User.php index 50725ef5b..4231328b6 100644 --- a/framework/core/src/User/User.php +++ b/framework/core/src/User/User.php @@ -109,7 +109,7 @@ class User extends AbstractModel /** * The access gate. * - * @var Gate + * @var Access\Gate */ protected static $gate; @@ -172,7 +172,7 @@ class User extends AbstractModel } /** - * @param Gate $gate + * @param Access\Gate $gate */ public static function setGate($gate) { @@ -296,7 +296,7 @@ class User extends AbstractModel /** * Change the path of the user avatar. * - * @param string $path + * @param string|null $path * @return $this */ public function changeAvatarPath($path) @@ -311,7 +311,6 @@ class User extends AbstractModel /** * Get the URL of the user's avatar. * - * @todo Allow different storage locations to be used * @param string|null $value * @return string */ @@ -410,15 +409,6 @@ class User extends AbstractModel return false; } - private function checkForDeprecatedPermissions($permission) - { - foreach (['viewDiscussions', 'viewUserList'] as $deprecated) { - if (strpos($permission, $deprecated) !== false) { - trigger_error('The `viewDiscussions` and `viewUserList` permissions have been renamed to `viewForum` and `searchUsers` respectively. Please use those instead.', E_USER_DEPRECATED); - } - } - } - /** * Get the notification types that should be alerted to this user, according * to their preferences. @@ -482,7 +472,7 @@ class User extends AbstractModel * Get the values of all registered preferences for this user, by * transforming their stored preferences and merging them with the defaults. * - * @param string $value + * @param string|null $value * @return array */ public function getPreferencesAttribute($value) @@ -679,7 +669,7 @@ class User extends AbstractModel /** * Define the relationship with the user's read discussions. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function read() { @@ -838,7 +828,7 @@ class User extends AbstractModel * Register a callback that processes a user's list of groups. * * @param callable $callback - * @return array $groupIds + * @return void * * @internal */ diff --git a/framework/core/src/User/UserRepository.php b/framework/core/src/User/UserRepository.php index eb828e37a..46df8ecf6 100644 --- a/framework/core/src/User/UserRepository.php +++ b/framework/core/src/User/UserRepository.php @@ -16,7 +16,7 @@ class UserRepository /** * Get a new query builder for the users table. * - * @return \Illuminate\Database\Eloquent\Builder + * @return Builder */ public function query() { @@ -27,15 +27,15 @@ class UserRepository * Find a user by ID, optionally making sure it is visible to a certain * user, or throw an exception. * - * @param int $id - * @param User $actor + * @param int|string $id + * @param User|null $actor * @return User * * @throws \Illuminate\Database\Eloquent\ModelNotFoundException */ public function findOrFail($id, User $actor = null) { - $query = User::where('id', $id); + $query = $this->query()->where('id', $id); return $this->scopeVisibleTo($query, $actor)->firstOrFail(); } @@ -44,15 +44,15 @@ class UserRepository * Find a user by username, optionally making sure it is visible to a certain * user, or throw an exception. * - * @param int $id - * @param User $actor + * @param string $username + * @param User|null $actor * @return User * * @throws \Illuminate\Database\Eloquent\ModelNotFoundException */ public function findOrFailByUsername($username, User $actor = null) { - $query = User::where('username', $username); + $query = $this->query()->where('username', $username); return $this->scopeVisibleTo($query, $actor)->firstOrFail(); } @@ -67,7 +67,7 @@ class UserRepository { $field = filter_var($identification, FILTER_VALIDATE_EMAIL) ? 'email' : 'username'; - return User::where($field, $identification)->first(); + return $this->query()->where($field, $identification)->first(); } /** @@ -78,7 +78,7 @@ class UserRepository */ public function findByEmail($email) { - return User::where('email', $email)->first(); + return $this->query()->where('email', $email)->first(); } /** @@ -90,7 +90,7 @@ class UserRepository */ public function getIdForUsername($username, User $actor = null) { - $query = User::where('username', $username); + $query = $this->query()->where('username', $username); return $this->scopeVisibleTo($query, $actor)->value('id'); } @@ -107,7 +107,7 @@ class UserRepository { $string = $this->escapeLikeString($string); - $query = User::where('username', 'like', '%'.$string.'%') + $query = $this->query()->where('username', 'like', '%'.$string.'%') ->orderByRaw('username = ? desc', [$string]) ->orderByRaw('username like ? desc', [$string.'%']); @@ -117,9 +117,9 @@ class UserRepository /** * Scope a query to only include records that are visible to a user. * - * @param Builder $query - * @param User $actor - * @return Builder + * @param Builder $query + * @param User|null $actor + * @return Builder */ protected function scopeVisibleTo(Builder $query, User $actor = null) { diff --git a/framework/core/src/User/UserServiceProvider.php b/framework/core/src/User/UserServiceProvider.php index 242e6e480..9898e2c35 100644 --- a/framework/core/src/User/UserServiceProvider.php +++ b/framework/core/src/User/UserServiceProvider.php @@ -109,6 +109,9 @@ class UserServiceProvider extends AbstractServiceProvider User::addGroupProcessor(ContainerUtil::wrapCallback($callback, $container)); } + /** + * @var \Illuminate\Container\Container $container + */ User::setHasher($container->make('hash')); User::setPasswordCheckers($container->make('flarum.user.password_checkers')); User::setGate($container->makeWith(Access\Gate::class, ['policyClasses' => $container->make('flarum.policies')])); diff --git a/framework/core/src/User/UserValidator.php b/framework/core/src/User/UserValidator.php index ea9624cbc..bd24ec34d 100644 --- a/framework/core/src/User/UserValidator.php +++ b/framework/core/src/User/UserValidator.php @@ -14,7 +14,7 @@ use Flarum\Foundation\AbstractValidator; class UserValidator extends AbstractValidator { /** - * @var User + * @var User|null */ protected $user; diff --git a/framework/core/src/User/UsernameSlugDriver.php b/framework/core/src/User/UsernameSlugDriver.php index 9bacf3740..ad18a1118 100644 --- a/framework/core/src/User/UsernameSlugDriver.php +++ b/framework/core/src/User/UsernameSlugDriver.php @@ -12,6 +12,9 @@ namespace Flarum\User; use Flarum\Database\AbstractModel; use Flarum\Http\SlugDriverInterface; +/** + * @implements SlugDriverInterface + */ class UsernameSlugDriver implements SlugDriverInterface { /** @@ -24,11 +27,17 @@ class UsernameSlugDriver implements SlugDriverInterface $this->users = $users; } + /** + * @param User $instance + */ public function toSlug(AbstractModel $instance): string { return $instance->username; } + /** + * @return User + */ public function fromSlug(string $slug, User $actor): AbstractModel { return $this->users->findOrFailByUsername($slug, $actor); diff --git a/framework/core/src/helpers.php b/framework/core/src/helpers.php index 9033587ca..b97f16616 100644 --- a/framework/core/src/helpers.php +++ b/framework/core/src/helpers.php @@ -16,11 +16,11 @@ if (! function_exists('resolve')) { * Resolve a service from the container. * * @template T - * @param class-string|string $name - * @param array $parameters + * @param string|class-string $name + * @param array $parameters * @return T|mixed */ - function resolve($name, $parameters = []) + function resolve(string $name, array $parameters = []) { return Container::getInstance()->make($name, $parameters); } diff --git a/php-packages/phpstan/composer.json b/php-packages/phpstan/composer.json index 225023e2f..a5bbee220 100644 --- a/php-packages/phpstan/composer.json +++ b/php-packages/phpstan/composer.json @@ -4,8 +4,8 @@ "minimum-stability": "dev", "license": "MIT", "require": { - "phpstan/phpstan-php-parser": "^1.0", - "phpstan/phpstan": "^1.2" + "phpstan/phpstan": "^1.2", + "nunomaduro/larastan": "^1.0" }, "autoload": { "psr-4": { diff --git a/php-packages/phpstan/extension.neon b/php-packages/phpstan/extension.neon index 7ff796157..c8950dbae 100644 --- a/php-packages/phpstan/extension.neon +++ b/php-packages/phpstan/extension.neon @@ -1,291 +1,17 @@ includes: - - vendor/phpstan/phpstan-php-parser/extension.neon + - larastan-extension.neon + - phpstan-baseline.neon + parameters: - stubFiles: - - stubs/Illuminate/Enumerable.stub - - stubs/Illuminate/Database/EloquentBuilder.stub - - stubs/Illuminate/Collection.stub - - stubs/Illuminate/Database/EloquentCollection.stub - - stubs/Illuminate/Database/Factory.stub - - stubs/Illuminate/Database/Model.stub - - stubs/Illuminate/Database/Gate.stub - - stubs/Illuminate/Database/Relation.stub - - stubs/Illuminate/Database/BelongsTo.stub - - stubs/Illuminate/Database/BelongsToMany.stub - - stubs/Illuminate/Database/HasOneOrMany.stub - - stubs/Illuminate/Database/HasMany.stub - - stubs/Illuminate/Database/HasOne.stub - - stubs/Illuminate/Database/HasOneThrough.stub - - stubs/Illuminate/Database/HasManyThrough.stub - - stubs/Illuminate/Database/MorphTo.stub - - stubs/Illuminate/Database/MorphToMany.stub - - stubs/Illuminate/Database/MorphMany.stub - - stubs/Illuminate/Database/MorphOne.stub - - stubs/Illuminate/Database/MorphOneOrMany.stub - - stubs/Illuminate/HigherOrderProxies.stub - - stubs/Illuminate/Database/QueryBuilder.stub - - stubs/Illuminate/EnumeratesValues.stub - - stubs/Contracts/Support.stub - universalObjectCratesClasses: - - Illuminate\Http\Request - mixinExcludeClasses: - - Eloquent - earlyTerminatingFunctionCalls: - - abort - - dd - excludePaths: - - *.blade.php - checkGenericClassInNonGenericObjectType: false - checkModelProperties: false - databaseMigrationsPath: [] + stubFiles: + - stubs/Illuminate/Contracts/Container/Container.stub + - stubs/Illuminate/Queue/ListenerOptions.stub + - stubs/Illuminate/Support/ServiceProvider.stub + - stubs/Illuminate/Filesystem/Filesystem.stub + - stubs/Illuminate/Filesystem/FilesystemManager.stub -parametersSchema: - databaseMigrationsPath: listOf(string()) - checkModelProperties: bool() - -services: - - - class: Flarum\PHPStan\Methods\RelationForwardsCallsExtension - tags: - - phpstan.broker.methodsClassReflectionExtension - - - - class: Flarum\PHPStan\Methods\ModelForwardsCallsExtension - tags: - - phpstan.broker.methodsClassReflectionExtension - - - - class: Flarum\PHPStan\Methods\EloquentBuilderForwardsCallsExtension - tags: - - phpstan.broker.methodsClassReflectionExtension - - - - class: Flarum\PHPStan\Methods\HigherOrderTapProxyExtension - tags: - - phpstan.broker.methodsClassReflectionExtension - - - - class: Flarum\PHPStan\Methods\HigherOrderCollectionProxyExtension - tags: - - phpstan.broker.methodsClassReflectionExtension - - - - class: Flarum\PHPStan\Methods\StorageMethodsClassReflectionExtension - tags: - - phpstan.broker.methodsClassReflectionExtension - - - - class: Flarum\PHPStan\Methods\Extension - tags: - - phpstan.broker.methodsClassReflectionExtension - - - class: Flarum\PHPStan\Methods\ModelFactoryMethodsClassReflectionExtension - tags: - - phpstan.broker.methodsClassReflectionExtension - - - - class: Flarum\PHPStan\Properties\ModelAccessorExtension - tags: - - phpstan.broker.propertiesClassReflectionExtension - - - - class: Flarum\PHPStan\Properties\ModelPropertyExtension - tags: - - phpstan.broker.propertiesClassReflectionExtension - - - - class: Flarum\PHPStan\Properties\HigherOrderCollectionProxyPropertyExtension - tags: - - phpstan.broker.propertiesClassReflectionExtension - - - - class: Flarum\PHPStan\Types\RelationDynamicMethodReturnTypeExtension - tags: - - phpstan.broker.dynamicMethodReturnTypeExtension - - - - class: Flarum\PHPStan\Types\ModelRelationsDynamicMethodReturnTypeExtension - tags: - - phpstan.broker.dynamicMethodReturnTypeExtension - - - - class: Flarum\PHPStan\ReturnTypes\HigherOrderTapProxyExtension - tags: - - phpstan.broker.dynamicMethodReturnTypeExtension - - - class: Flarum\PHPStan\ReturnTypes\ContainerArrayAccessDynamicMethodReturnTypeExtension - tags: - - phpstan.broker.dynamicMethodReturnTypeExtension - arguments: - className: Illuminate\Contracts\Container\Container - - - class: Flarum\PHPStan\ReturnTypes\ContainerArrayAccessDynamicMethodReturnTypeExtension - tags: - - phpstan.broker.dynamicMethodReturnTypeExtension - arguments: - className: Illuminate\Container\Container - - - class: Flarum\PHPStan\ReturnTypes\ContainerArrayAccessDynamicMethodReturnTypeExtension - tags: - - phpstan.broker.dynamicMethodReturnTypeExtension - arguments: - className: Illuminate\Foundation\Application - - - class: Flarum\PHPStan\ReturnTypes\ContainerArrayAccessDynamicMethodReturnTypeExtension - tags: - - phpstan.broker.dynamicMethodReturnTypeExtension - arguments: - className: Illuminate\Contracts\Foundation\Application - - - - class: Flarum\PHPStan\Properties\ModelRelationsExtension - tags: - - phpstan.broker.propertiesClassReflectionExtension - - - - class: Flarum\PHPStan\ReturnTypes\ModelFactoryDynamicStaticMethodReturnTypeExtension - tags: - - phpstan.broker.dynamicStaticMethodReturnTypeExtension - - - - class: Flarum\PHPStan\ReturnTypes\ModelExtension - tags: - - phpstan.broker.dynamicStaticMethodReturnTypeExtension - - - - class: Flarum\PHPStan\ReturnTypes\RequestExtension - tags: - - phpstan.broker.dynamicMethodReturnTypeExtension - - - - class: Flarum\PHPStan\ReturnTypes\EloquentBuilderExtension - tags: - - phpstan.broker.dynamicMethodReturnTypeExtension - - - - class: Flarum\PHPStan\ReturnTypes\RelationFindExtension - tags: - - phpstan.broker.dynamicMethodReturnTypeExtension - - - - class: Flarum\PHPStan\ReturnTypes\RelationCollectionExtension - tags: - - phpstan.broker.dynamicMethodReturnTypeExtension - - - - class: Flarum\PHPStan\ReturnTypes\ModelFindExtension - tags: - - phpstan.broker.dynamicStaticMethodReturnTypeExtension - - - - class: Flarum\PHPStan\ReturnTypes\BuilderModelFindExtension - tags: - - phpstan.broker.dynamicMethodReturnTypeExtension - - - - class: Flarum\PHPStan\ReturnTypes\TestCaseExtension - tags: - - phpstan.broker.dynamicMethodReturnTypeExtension - - - - class: Flarum\PHPStan\ReturnTypes\CollectionMakeDynamicStaticMethodReturnTypeExtension - tags: - - phpstan.broker.dynamicStaticMethodReturnTypeExtension - - - - class: Flarum\PHPStan\Support\CollectionHelper - - - - class: Flarum\PHPStan\ReturnTypes\Helpers\CollectExtension - tags: - - phpstan.broker.dynamicFunctionReturnTypeExtension - - - - class: Flarum\PHPStan\ReturnTypes\Helpers\TransExtension - tags: - - phpstan.broker.dynamicFunctionReturnTypeExtension - - - - class: Flarum\PHPStan\ReturnTypes\Helpers\ValidatorExtension - tags: - - phpstan.broker.dynamicFunctionReturnTypeExtension - - - - class: Flarum\PHPStan\ReturnTypes\CollectionFilterDynamicReturnTypeExtension - tags: - - phpstan.broker.dynamicMethodReturnTypeExtension - - - - class: Flarum\PHPStan\Types\AbortIfFunctionTypeSpecifyingExtension - tags: - - phpstan.typeSpecifier.functionTypeSpecifyingExtension - arguments: - methodName: 'abort' - negate: false - - - - class: Flarum\PHPStan\Types\AbortIfFunctionTypeSpecifyingExtension - tags: - - phpstan.typeSpecifier.functionTypeSpecifyingExtension - arguments: - methodName: 'abort' - negate: true - - - - class: Flarum\PHPStan\Types\AbortIfFunctionTypeSpecifyingExtension - tags: - - phpstan.typeSpecifier.functionTypeSpecifyingExtension - arguments: - methodName: throw - negate: false - - - - class: Flarum\PHPStan\Types\AbortIfFunctionTypeSpecifyingExtension - tags: - - phpstan.typeSpecifier.functionTypeSpecifyingExtension - arguments: - methodName: throw - negate: true - - - - class: Flarum\PHPStan\ReturnTypes\Helpers\AppExtension - tags: - - phpstan.broker.dynamicFunctionReturnTypeExtension - - - - class: Flarum\PHPStan\ReturnTypes\Helpers\ValueExtension - tags: - - phpstan.broker.dynamicFunctionReturnTypeExtension - - - - class: Flarum\PHPStan\ReturnTypes\Helpers\TapExtension - tags: - - phpstan.broker.dynamicFunctionReturnTypeExtension - - - - class: Flarum\PHPStan\ReturnTypes\StorageDynamicStaticMethodReturnTypeExtension - tags: - - phpstan.broker.dynamicStaticMethodReturnTypeExtension - - - - class: Flarum\PHPStan\Types\GenericEloquentCollectionTypeNodeResolverExtension - tags: - - phpstan.phpDoc.typeNodeResolverExtension - - - - class: Flarum\PHPStan\Types\ViewStringTypeNodeResolverExtension - tags: - - phpstan.phpDoc.typeNodeResolverExtension - - - class: Flarum\PHPStan\Methods\BuilderHelper - arguments: - checkProperties: %checkModelProperties% - - - class: Flarum\PHPStan\Properties\MigrationHelper - arguments: - databaseMigrationPath: %databaseMigrationsPath% - parser: @currentPhpVersionSimpleDirectParser - - - class: Flarum\PHPStan\Types\RelationParserHelper - arguments: - parser: @currentPhpVersionSimpleDirectParser + # We're changing the disk return type from Filesystem to Cloud, + # rather than hacking every bit of the codebase with a phpdoc @var. + - stubs/Illuminate/Contracts/Filesystem/Factory.stub + - stubs/Illuminate/Contracts/Filesystem/Cloud.stub + - stubs/Illuminate/Contracts/Filesystem/Filesystem.stub diff --git a/php-packages/phpstan/larastan-extension.neon b/php-packages/phpstan/larastan-extension.neon new file mode 100644 index 000000000..bf75e3c98 --- /dev/null +++ b/php-packages/phpstan/larastan-extension.neon @@ -0,0 +1,439 @@ +parameters: + stubFiles: + - ../../vendor/nunomaduro/larastan/stubs/Enumerable.stub + - ../../vendor/nunomaduro/larastan/stubs/EloquentBuilder.stub + - ../../vendor/nunomaduro/larastan/stubs/Collection.stub + - ../../vendor/nunomaduro/larastan/stubs/EloquentCollection.stub + - ../../vendor/nunomaduro/larastan/stubs/Factory.stub + - ../../vendor/nunomaduro/larastan/stubs/Model.stub + - ../../vendor/nunomaduro/larastan/stubs/Gate.stub + - ../../vendor/nunomaduro/larastan/stubs/Relation.stub + - ../../vendor/nunomaduro/larastan/stubs/BelongsTo.stub + - ../../vendor/nunomaduro/larastan/stubs/BelongsToMany.stub + - ../../vendor/nunomaduro/larastan/stubs/HasOneOrMany.stub + - ../../vendor/nunomaduro/larastan/stubs/HasMany.stub + - ../../vendor/nunomaduro/larastan/stubs/HasOne.stub + - ../../vendor/nunomaduro/larastan/stubs/HasOneThrough.stub + - ../../vendor/nunomaduro/larastan/stubs/HasManyThrough.stub + - ../../vendor/nunomaduro/larastan/stubs/Mailable.stub + - ../../vendor/nunomaduro/larastan/stubs/MorphOne.stub + - ../../vendor/nunomaduro/larastan/stubs/MorphOneOrMany.stub + - ../../vendor/nunomaduro/larastan/stubs/MorphTo.stub + - ../../vendor/nunomaduro/larastan/stubs/MorphToMany.stub + - ../../vendor/nunomaduro/larastan/stubs/MorphMany.stub + - ../../vendor/nunomaduro/larastan/stubs/Helpers.stub + - ../../vendor/nunomaduro/larastan/stubs/HigherOrderProxies.stub + - ../../vendor/nunomaduro/larastan/stubs/QueryBuilder.stub + - ../../vendor/nunomaduro/larastan/stubs/Facades.stub + - ../../vendor/nunomaduro/larastan/stubs/Pagination.stub + - ../../vendor/nunomaduro/larastan/stubs/Contracts/Pagination.stub + - ../../vendor/nunomaduro/larastan/stubs/Contracts/Support.stub + - ../../vendor/nunomaduro/larastan/stubs/Redis/Connection.stub + - ../../vendor/nunomaduro/larastan/stubs/Logger.stub + - ../../vendor/nunomaduro/larastan/stubs/EnumeratesValues.stub + universalObjectCratesClasses: + - Illuminate\Http\Request + earlyTerminatingFunctionCalls: + - abort + - dd + excludePaths: + - *.blade.php + mixinExcludeClasses: + - Eloquent +# bootstrapFiles: +# - bootstrap.php + checkGenericClassInNonGenericObjectType: false + checkOctaneCompatibility: false + noModelMake: true + noUnnecessaryCollectionCall: true + noUnnecessaryCollectionCallOnly: [] + noUnnecessaryCollectionCallExcept: [] + databaseMigrationsPath: [] + checkModelProperties: false + checkPhpDocMissingReturn: false + +parametersSchema: + checkOctaneCompatibility: bool() + noModelMake: bool() + noUnnecessaryCollectionCall: bool() + noUnnecessaryCollectionCallOnly: listOf(string()) + noUnnecessaryCollectionCallExcept: listOf(string()) + databaseMigrationsPath: listOf(string()) + checkModelProperties: bool() + +conditionalTags: + NunoMaduro\Larastan\Rules\NoModelMakeRule: + phpstan.rules.rule: %noModelMake% + NunoMaduro\Larastan\Rules\NoUnnecessaryCollectionCallRule: + phpstan.rules.rule: %noUnnecessaryCollectionCall% + NunoMaduro\Larastan\Rules\OctaneCompatibilityRule: + phpstan.rules.rule: %checkOctaneCompatibility% + NunoMaduro\Larastan\Rules\ModelProperties\ModelPropertyRule: + phpstan.rules.rule: %checkModelProperties% + NunoMaduro\Larastan\Rules\ModelProperties\ModelPropertyStaticCallRule: + phpstan.rules.rule: %checkModelProperties% + +services: + - + class: NunoMaduro\Larastan\Methods\RelationForwardsCallsExtension + tags: + - phpstan.broker.methodsClassReflectionExtension + + - + class: NunoMaduro\Larastan\Methods\ModelForwardsCallsExtension + tags: + - phpstan.broker.methodsClassReflectionExtension + + - + class: NunoMaduro\Larastan\Methods\EloquentBuilderForwardsCallsExtension + tags: + - phpstan.broker.methodsClassReflectionExtension + + - + class: NunoMaduro\Larastan\Methods\HigherOrderTapProxyExtension + tags: + - phpstan.broker.methodsClassReflectionExtension + + - + class: NunoMaduro\Larastan\Methods\HigherOrderCollectionProxyExtension + tags: + - phpstan.broker.methodsClassReflectionExtension + + - + class: NunoMaduro\Larastan\Methods\StorageMethodsClassReflectionExtension + tags: + - phpstan.broker.methodsClassReflectionExtension + + - + class: NunoMaduro\Larastan\Methods\Extension + tags: + - phpstan.broker.methodsClassReflectionExtension + - + class: NunoMaduro\Larastan\Methods\ModelFactoryMethodsClassReflectionExtension + tags: + - phpstan.broker.methodsClassReflectionExtension + - + class: NunoMaduro\Larastan\Methods\RedirectResponseMethodsClassReflectionExtension + tags: + - phpstan.broker.methodsClassReflectionExtension + + - + class: NunoMaduro\Larastan\Properties\ModelAccessorExtension + tags: + - phpstan.broker.propertiesClassReflectionExtension + + - + class: NunoMaduro\Larastan\Properties\ModelPropertyExtension + tags: + - phpstan.broker.propertiesClassReflectionExtension + + - + class: NunoMaduro\Larastan\Properties\HigherOrderCollectionProxyPropertyExtension + tags: + - phpstan.broker.propertiesClassReflectionExtension + + - + class: NunoMaduro\Larastan\Types\RelationDynamicMethodReturnTypeExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\Types\ModelRelationsDynamicMethodReturnTypeExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\HigherOrderTapProxyExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension + - + class: NunoMaduro\Larastan\ReturnTypes\ContainerArrayAccessDynamicMethodReturnTypeExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension + arguments: + className: Illuminate\Contracts\Container\Container + - + class: NunoMaduro\Larastan\ReturnTypes\ContainerArrayAccessDynamicMethodReturnTypeExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension + arguments: + className: Illuminate\Container\Container + - + class: NunoMaduro\Larastan\ReturnTypes\ContainerArrayAccessDynamicMethodReturnTypeExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension + arguments: + className: Illuminate\Foundation\Application + - + class: NunoMaduro\Larastan\ReturnTypes\ContainerArrayAccessDynamicMethodReturnTypeExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension + arguments: + className: Illuminate\Contracts\Foundation\Application + + - + class: NunoMaduro\Larastan\Properties\ModelRelationsExtension + tags: + - phpstan.broker.propertiesClassReflectionExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\ModelFactoryDynamicStaticMethodReturnTypeExtension + tags: + - phpstan.broker.dynamicStaticMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\ModelExtension + tags: + - phpstan.broker.dynamicStaticMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\AuthExtension + tags: + - phpstan.broker.dynamicStaticMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\GuardDynamicStaticMethodReturnTypeExtension + tags: + - phpstan.broker.dynamicStaticMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\AuthManagerExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\GuardExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\RequestExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\EloquentBuilderExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\RelationFindExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\RelationCollectionExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\ModelFindExtension + tags: + - phpstan.broker.dynamicStaticMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\BuilderModelFindExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\TestCaseExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\CollectionMakeDynamicStaticMethodReturnTypeExtension + tags: + - phpstan.broker.dynamicStaticMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\Support\CollectionHelper + + - + class: NunoMaduro\Larastan\ReturnTypes\Helpers\AuthExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\Helpers\CollectExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\Helpers\CookieExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\Helpers\ResponseExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\Helpers\RequestExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\Helpers\RedirectExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\Helpers\UrlExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\Helpers\ViewExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\Helpers\TransExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\Helpers\ValidatorExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\CollectionFilterDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\Types\AbortIfFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + arguments: + methodName: 'abort' + negate: false + + - + class: NunoMaduro\Larastan\Types\AbortIfFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + arguments: + methodName: 'abort' + negate: true + + - + class: NunoMaduro\Larastan\Types\AbortIfFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + arguments: + methodName: throw + negate: false + + - + class: NunoMaduro\Larastan\Types\AbortIfFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + arguments: + methodName: throw + negate: true + + - + class: NunoMaduro\Larastan\ReturnTypes\Helpers\AppExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\Helpers\ValueExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\Helpers\TapExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: NunoMaduro\Larastan\ReturnTypes\StorageDynamicStaticMethodReturnTypeExtension + tags: + - phpstan.broker.dynamicStaticMethodReturnTypeExtension + + - + class: NunoMaduro\Larastan\Types\GenericEloquentCollectionTypeNodeResolverExtension + tags: + - phpstan.phpDoc.typeNodeResolverExtension + + - + class: NunoMaduro\Larastan\Types\ViewStringTypeNodeResolverExtension + tags: + - phpstan.phpDoc.typeNodeResolverExtension + + - + class: NunoMaduro\Larastan\Rules\OctaneCompatibilityRule + + - + class: NunoMaduro\Larastan\Rules\NoModelMakeRule + + - + class: NunoMaduro\Larastan\Rules\NoUnnecessaryCollectionCallRule + arguments: + onlyMethods: %noUnnecessaryCollectionCallOnly% + excludeMethods: %noUnnecessaryCollectionCallExcept% + + - + class: NunoMaduro\Larastan\Rules\ModelProperties\ModelPropertyRule + + - + class: NunoMaduro\Larastan\Rules\ModelProperties\ModelPropertyStaticCallRule + + - + class: NunoMaduro\Larastan\Types\GenericEloquentBuilderTypeNodeResolverExtension + tags: + - phpstan.phpDoc.typeNodeResolverExtension + + - + class: NunoMaduro\Larastan\Types\ModelProperty\ModelPropertyTypeNodeResolverExtension + tags: + - phpstan.phpDoc.typeNodeResolverExtension + arguments: + active: %checkModelProperties% + + - + class: NunoMaduro\Larastan\Types\RelationParserHelper + arguments: + parser: @currentPhpVersionSimpleDirectParser + + - + class: NunoMaduro\Larastan\Properties\MigrationHelper + arguments: + databaseMigrationPath: %databaseMigrationsPath% + parser: @currentPhpVersionSimpleDirectParser + + - + class: NunoMaduro\Larastan\Rules\ModelProperties\ModelPropertiesRuleHelper + + - + class: NunoMaduro\Larastan\Rules\ModelRuleHelper + + - + class: NunoMaduro\Larastan\Methods\BuilderHelper + arguments: + checkProperties: %checkModelProperties% + + - + class: NunoMaduro\Larastan\Rules\RelationExistenceRule + tags: + - phpstan.rule + + - + class: NunoMaduro\Larastan\Rules\CheckDispatchArgumentTypesCompatibleWithClassConstructorRule + arguments: + dispatchableClass: Illuminate\Foundation\Bus\Dispatchable + tags: + - phpstan.rules.rule + - + class: NunoMaduro\Larastan\Rules\CheckDispatchArgumentTypesCompatibleWithClassConstructorRule + arguments: + dispatchableClass: Illuminate\Foundation\Events\Dispatchable + tags: + - phpstan.rules.rule +rules: + - NunoMaduro\Larastan\Rules\RelationExistenceRule diff --git a/php-packages/phpstan/phpstan-baseline.neon b/php-packages/phpstan/phpstan-baseline.neon new file mode 100644 index 000000000..6a0b13882 --- /dev/null +++ b/php-packages/phpstan/phpstan-baseline.neon @@ -0,0 +1,17 @@ +parameters: + ignoreErrors: + # Remove this group below with larastan 2.0 (i.e Flarum 2.0) + - "#Relation '[A-z_-]+' is not found in [A-z\_]+ model.#" + - '#^Parameter \#1 \$query of method [A-z_<>\\]+\:\:union\(\) expects [A-z_<> .,|\\]+ given\.$#' + - '#^Parameter \#1 \$query of method [A-z_<>\\]+\:\:joinSub\(\) expects [A-z_<> .,|\\]+ given\.$#' + + # We ignore this because resolve can either take a class name as the generic return type or just a binding name. + - "#Template type T of function resolve[()]{2} is not referenced in a parameter.#" + + # We ignore new static errors because we want extensibility. + # @TODO: needs discussion. + - "#^Unsafe usage of new static[()]{2}.$#" + + # ConnectionInterface lacks methods that exist in the implementation, + # yet we don't want to inject the implementation. + - '#^Call to an undefined method Illuminate\\Database\\ConnectionInterface\:\:[A-z0-9_]+\(\)\.$#' diff --git a/php-packages/phpstan/src/Concerns/HasContainer.php b/php-packages/phpstan/src/Concerns/HasContainer.php deleted file mode 100644 index 8625b638c..000000000 --- a/php-packages/phpstan/src/Concerns/HasContainer.php +++ /dev/null @@ -1,72 +0,0 @@ -container = $container; - } - - /** - * Returns the current broker. - * - * @return \Illuminate\Contracts\Container\Container - */ - public function getContainer(): ContainerContract - { - return $this->container ?? Container::getInstance(); - } - - /** - * Resolve the given type from the container. - * - * @param string $abstract - * @return mixed - */ - public function resolve(string $abstract) - { - $concrete = null; - - try { - $concrete = $this->getContainer() - ->make($abstract); - } catch (ReflectionException $exception) { - // .. - } catch (BindingResolutionException $exception) { - // .. - } catch (NotFoundExceptionInterface $exception) { - // .. - } - - return $concrete; - } -} diff --git a/php-packages/phpstan/src/Concerns/LoadsAuthModel.php b/php-packages/phpstan/src/Concerns/LoadsAuthModel.php deleted file mode 100644 index 300f5c161..000000000 --- a/php-packages/phpstan/src/Concerns/LoadsAuthModel.php +++ /dev/null @@ -1,31 +0,0 @@ -get('auth.defaults.guard'))) || - ! ($provider = $config->get('auth.guards.'.$guard.'.provider')) || - ! ($authModel = $config->get('auth.providers.'.$provider.'.model')) - ) { - return null; - } - - return $authModel; - } -} diff --git a/php-packages/phpstan/src/Contracts/Methods/PassableContract.php b/php-packages/phpstan/src/Contracts/Methods/PassableContract.php deleted file mode 100644 index 4a71387cf..000000000 --- a/php-packages/phpstan/src/Contracts/Methods/PassableContract.php +++ /dev/null @@ -1,96 +0,0 @@ -reflectionProvider = $reflectionProvider; - $this->checkProperties = $checkProperties; - } - - public function dynamicWhere( - string $methodName, - Type $returnObject - ): ?EloquentBuilderMethodReflection { - if (! Str::startsWith($methodName, 'where')) { - return null; - } - - if ($returnObject instanceof GenericObjectType && $this->checkProperties) { - $returnClassReflection = $returnObject->getClassReflection(); - - if ($returnClassReflection !== null) { - $modelType = $returnClassReflection->getActiveTemplateTypeMap()->getType('TModelClass'); - - if ($modelType === null) { - $modelType = $returnClassReflection->getActiveTemplateTypeMap()->getType('TRelatedModel'); - } - - if ($modelType !== null) { - $finder = substr($methodName, 5); - - $segments = preg_split( - '/(And|Or)(?=[A-Z])/', - $finder, - -1, - PREG_SPLIT_DELIM_CAPTURE - ); - - if ($segments !== false) { - $trinaryLogic = TrinaryLogic::createYes(); - - foreach ($segments as $segment) { - if ($segment !== 'And' && $segment !== 'Or') { - $trinaryLogic = $trinaryLogic->and($modelType->hasProperty(Str::snake($segment))); - } - } - - if (! $trinaryLogic->yes()) { - return null; - } - } - } - } - } - - $classReflection = $this->reflectionProvider->getClass(QueryBuilder::class); - - $methodReflection = $classReflection->getNativeMethod('dynamicWhere'); - - return new EloquentBuilderMethodReflection( - $methodName, - $classReflection, - $methodReflection, - [new DynamicWhereParameterReflection], - $returnObject, - true - ); - } - - /** - * This method mimics the `EloquentBuilder::__call` method. - * Does not handle the case where $methodName exists in `EloquentBuilder`, - * that should be checked by caller before calling this method. - * - * @param ClassReflection $eloquentBuilder Can be `EloquentBuilder` or a custom builder extending it. - * @param string $methodName - * @param ClassReflection $model - * @return MethodReflection|null - * - * @throws MissingMethodFromReflectionException - * @throws ShouldNotHappenException - */ - public function searchOnEloquentBuilder(ClassReflection $eloquentBuilder, string $methodName, ClassReflection $model): ?MethodReflection - { - // Check for local query scopes - if (array_key_exists('scope'.ucfirst($methodName), $model->getMethodTags())) { - $methodTag = $model->getMethodTags()['scope'.ucfirst($methodName)]; - - $parameters = []; - foreach ($methodTag->getParameters() as $parameterName => $parameterTag) { - $parameters[] = new AnnotationScopeMethodParameterReflection($parameterName, $parameterTag->getType(), $parameterTag->passedByReference(), $parameterTag->isOptional(), $parameterTag->isVariadic(), $parameterTag->getDefaultValue()); - } - - // We shift the parameters, - // because first parameter is the Builder - array_shift($parameters); - - return new EloquentBuilderMethodReflection( - 'scope'.ucfirst($methodName), - $model, - new AnnotationScopeMethodReflection('scope'.ucfirst($methodName), $model, $methodTag->getReturnType(), $parameters, $methodTag->isStatic(), false), - $parameters, - $methodTag->getReturnType() - ); - } - - if ($model->hasNativeMethod('scope'.ucfirst($methodName))) { - $methodReflection = $model->getNativeMethod('scope'.ucfirst($methodName)); - $parametersAcceptor = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants()); - - $parameters = $parametersAcceptor->getParameters(); - // We shift the parameters, - // because first parameter is the Builder - array_shift($parameters); - - $returnType = $parametersAcceptor->getReturnType(); - - return new EloquentBuilderMethodReflection( - 'scope'.ucfirst($methodName), - $methodReflection->getDeclaringClass(), - $methodReflection, - $parameters, - $returnType, - $parametersAcceptor->isVariadic() - ); - } - - $queryBuilderReflection = $this->reflectionProvider->getClass(QueryBuilder::class); - - if (in_array($methodName, $this->passthru, true)) { - return $queryBuilderReflection->getNativeMethod($methodName); - } - - if ($queryBuilderReflection->hasNativeMethod($methodName)) { - return $queryBuilderReflection->getNativeMethod($methodName); - } - - return $this->dynamicWhere($methodName, new GenericObjectType($eloquentBuilder->getName(), [new ObjectType($model->getName())])); - } - - /** - * @param string $modelClassName - * @return string - * - * @throws MissingMethodFromReflectionException - * @throws ShouldNotHappenException - */ - public function determineBuilderName(string $modelClassName): string - { - $method = $this->reflectionProvider->getClass($modelClassName)->getNativeMethod('newEloquentBuilder'); - - $returnType = ParametersAcceptorSelector::selectSingle($method->getVariants())->getReturnType(); - - if (in_array(EloquentBuilder::class, $returnType->getReferencedClasses(), true)) { - return EloquentBuilder::class; - } - - if ($returnType instanceof ObjectType) { - return $returnType->getClassName(); - } - - return $returnType->describe(VerbosityLevel::value()); - } - - /** - * @throws MissingMethodFromReflectionException - * @throws ShouldNotHappenException - */ - public function determineCollectionClassName(string $modelClassName): string - { - $newCollectionMethod = $this->reflectionProvider->getClass($modelClassName)->getNativeMethod('newCollection'); - - $returnType = ParametersAcceptorSelector::selectSingle($newCollectionMethod->getVariants())->getReturnType(); - - if ($returnType instanceof ObjectType) { - return $returnType->getClassName(); - } - - return $returnType->describe(VerbosityLevel::value()); - } -} diff --git a/php-packages/phpstan/src/Methods/EloquentBuilderForwardsCallsExtension.php b/php-packages/phpstan/src/Methods/EloquentBuilderForwardsCallsExtension.php deleted file mode 100644 index 6e532269f..000000000 --- a/php-packages/phpstan/src/Methods/EloquentBuilderForwardsCallsExtension.php +++ /dev/null @@ -1,161 +0,0 @@ - */ - private $cache = []; - - /** @var BuilderHelper */ - private $builderHelper; - - /** @var ReflectionProvider */ - private $reflectionProvider; - - public function __construct(BuilderHelper $builderHelper, ReflectionProvider $reflectionProvider) - { - $this->builderHelper = $builderHelper; - $this->reflectionProvider = $reflectionProvider; - } - - /** - * @throws ShouldNotHappenException - * @throws MissingMethodFromReflectionException - */ - public function hasMethod(ClassReflection $classReflection, string $methodName): bool - { - if (array_key_exists($classReflection->getCacheKey().'-'.$methodName, $this->cache)) { - return true; - } - - $methodReflection = $this->findMethod($classReflection, $methodName); - - if ($methodReflection !== null && $classReflection->isGeneric()) { - $this->cache[$classReflection->getCacheKey().'-'.$methodName] = $methodReflection; - - return true; - } - - return false; - } - - public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection - { - return $this->cache[$classReflection->getCacheKey().'-'.$methodName]; - } - - /** - * @throws MissingMethodFromReflectionException - * @throws ShouldNotHappenException - */ - private function findMethod(ClassReflection $classReflection, string $methodName): ?MethodReflection - { - if ($classReflection->getName() !== EloquentBuilder::class && ! $classReflection->isSubclassOf(EloquentBuilder::class)) { - return null; - } - - /** @var Type|TemplateMixedType|null $modelType */ - $modelType = $classReflection->getActiveTemplateTypeMap()->getType('TModelClass'); - - // Generic type is not specified - if ($modelType === null) { - return null; - } - - if ($modelType instanceof TemplateObjectType) { - $modelType = $modelType->getBound(); - - if ($modelType->equals(new ObjectType(Model::class))) { - return null; - } - } - - if ($modelType instanceof TypeWithClassName) { - $modelReflection = $modelType->getClassReflection(); - } else { - $modelReflection = $this->reflectionProvider->getClass(Model::class); - } - - if ($modelReflection === null) { - return null; - } - - $ref = $this->builderHelper->searchOnEloquentBuilder($classReflection, $methodName, $modelReflection); - - if ($ref === null) { - // Special case for `SoftDeletes` trait - if ( - in_array($methodName, ['withTrashed', 'onlyTrashed', 'withoutTrashed'], true) && - in_array(SoftDeletes::class, array_keys($modelReflection->getTraits(true))) - ) { - $ref = $this->reflectionProvider->getClass(SoftDeletes::class)->getMethod($methodName, new OutOfClassScope()); - - return new EloquentBuilderMethodReflection( - $methodName, - $classReflection, - $ref, - ParametersAcceptorSelector::selectSingle($ref->getVariants())->getParameters(), - new GenericObjectType($classReflection->getName(), [$modelType]), - ParametersAcceptorSelector::selectSingle($ref->getVariants())->isVariadic() - ); - } - - return null; - } - - $parametersAcceptor = ParametersAcceptorSelector::selectSingle($ref->getVariants()); - - if (in_array($methodName, $this->builderHelper->passthru, true)) { - $returnType = $parametersAcceptor->getReturnType(); - - return new EloquentBuilderMethodReflection( - $methodName, - $classReflection, - $ref, - $parametersAcceptor->getParameters(), - $returnType, - $parametersAcceptor->isVariadic() - ); - } - - // Returning custom reflection - // to ensure return type is always `EloquentBuilder` - return new EloquentBuilderMethodReflection( - $methodName, - $classReflection, - $ref, - $parametersAcceptor->getParameters(), - new GenericObjectType($classReflection->getName(), [$modelType]), - $parametersAcceptor->isVariadic() - ); - } -} diff --git a/php-packages/phpstan/src/Methods/Extension.php b/php-packages/phpstan/src/Methods/Extension.php deleted file mode 100644 index cb6ff82d1..000000000 --- a/php-packages/phpstan/src/Methods/Extension.php +++ /dev/null @@ -1,64 +0,0 @@ -kernel = $kernel ?? new Kernel($methodReflectionFactory, $reflectionProvider); - } - - public function hasMethod(ClassReflection $classReflection, string $methodName): bool - { - if ($classReflection->getName() === Model::class) { - return false; - } - - if (array_key_exists($methodName.'-'.$classReflection->getName(), $this->methodReflections)) { - return true; - } - - $passable = $this->kernel->handle($classReflection, $methodName); - - $found = $passable->hasFound(); - - if ($found) { - $this->methodReflections[$methodName.'-'.$classReflection->getName()] = $passable->getMethodReflection(); - } - - return $found; - } - - public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection - { - return $this->methodReflections[$methodName.'-'.$classReflection->getName()]; - } -} diff --git a/php-packages/phpstan/src/Methods/HigherOrderCollectionProxyExtension.php b/php-packages/phpstan/src/Methods/HigherOrderCollectionProxyExtension.php deleted file mode 100644 index 9663764a8..000000000 --- a/php-packages/phpstan/src/Methods/HigherOrderCollectionProxyExtension.php +++ /dev/null @@ -1,149 +0,0 @@ -getActiveTemplateTypeMap(); - - /** @var Type\Constant\ConstantStringType $methodType */ - $methodType = $activeTemplateTypeMap->getType('T'); - - /** @var Type\ObjectType $valueType */ - $valueType = $activeTemplateTypeMap->getType('TValue'); - - $modelMethodReflection = $valueType->getMethod($methodName, new OutOfClassScope()); - - $modelMethodReturnType = ParametersAcceptorSelector::selectSingle($modelMethodReflection->getVariants())->getReturnType(); - - $returnType = HigherOrderCollectionProxyHelper::determineReturnType($methodType->getValue(), $valueType, $modelMethodReturnType); - - return new class($classReflection, $methodName, $modelMethodReflection, $returnType) implements MethodReflection { - /** @var ClassReflection */ - private $classReflection; - - /** @var string */ - private $methodName; - - /** @var MethodReflection */ - private $modelMethodReflection; - - /** @var Type\Type */ - private $returnType; - - public function __construct(ClassReflection $classReflection, string $methodName, MethodReflection $modelMethodReflection, Type\Type $returnType) - { - $this->classReflection = $classReflection; - $this->methodName = $methodName; - $this->modelMethodReflection = $modelMethodReflection; - $this->returnType = $returnType; - } - - public function getDeclaringClass(): \PHPStan\Reflection\ClassReflection - { - return $this->classReflection; - } - - public function isStatic(): bool - { - return false; - } - - public function isPrivate(): bool - { - return false; - } - - public function isPublic(): bool - { - return true; - } - - public function getDocComment(): ?string - { - return null; - } - - public function getName(): string - { - return $this->methodName; - } - - public function getPrototype(): \PHPStan\Reflection\ClassMemberReflection - { - return $this; - } - - public function getVariants(): array - { - return [ - new FunctionVariant( - ParametersAcceptorSelector::selectSingle($this->modelMethodReflection->getVariants())->getTemplateTypeMap(), - ParametersAcceptorSelector::selectSingle($this->modelMethodReflection->getVariants())->getResolvedTemplateTypeMap(), - ParametersAcceptorSelector::selectSingle($this->modelMethodReflection->getVariants())->getParameters(), - ParametersAcceptorSelector::selectSingle($this->modelMethodReflection->getVariants())->isVariadic(), - $this->returnType - ), - ]; - } - - public function isDeprecated(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function getDeprecatedDescription(): ?string - { - return null; - } - - public function isFinal(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function isInternal(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function getThrowType(): ?\PHPStan\Type\Type - { - return null; - } - - public function hasSideEffects(): TrinaryLogic - { - return TrinaryLogic::createMaybe(); - } - }; - } -} diff --git a/php-packages/phpstan/src/Methods/HigherOrderTapProxyExtension.php b/php-packages/phpstan/src/Methods/HigherOrderTapProxyExtension.php deleted file mode 100644 index a356235a0..000000000 --- a/php-packages/phpstan/src/Methods/HigherOrderTapProxyExtension.php +++ /dev/null @@ -1,56 +0,0 @@ -getName() !== HigherOrderTapProxy::class) { - return false; - } - - $templateTypeMap = $classReflection->getActiveTemplateTypeMap(); - - $templateType = $templateTypeMap->getType('TClass'); - - if (! $templateType instanceof ObjectType) { - return false; - } - - if ($templateType->getClassReflection() === null) { - return false; - } - - return $templateType->hasMethod($methodName)->yes(); - } - - public function getMethod( - ClassReflection $classReflection, - string $methodName - ): MethodReflection { - /** @var ObjectType $templateType */ - $templateType = $classReflection->getActiveTemplateTypeMap()->getType('TClass'); - - /** @var ClassReflection $reflection */ - $reflection = $templateType->getClassReflection(); - - return $reflection->getMethod($methodName, new OutOfClassScope()); - } -} diff --git a/php-packages/phpstan/src/Methods/Kernel.php b/php-packages/phpstan/src/Methods/Kernel.php deleted file mode 100644 index b10d79330..000000000 --- a/php-packages/phpstan/src/Methods/Kernel.php +++ /dev/null @@ -1,79 +0,0 @@ -methodReflectionFactory = $methodReflectionFactory; - $this->reflectionProvider = $reflectionProvider; - } - - /** - * @param ClassReflection $classReflection - * @param string $methodName - * @return PassableContract - */ - public function handle(ClassReflection $classReflection, string $methodName): PassableContract - { - $pipeline = new Pipeline($this->getContainer()); - - $passable = new Passable($this->methodReflectionFactory, $this->reflectionProvider, $pipeline, $classReflection, $methodName); - - $pipeline->send($passable) - ->through( - [ - Pipes\SelfClass::class, - Pipes\Macros::class, - Pipes\Contracts::class, - Pipes\Facades::class, - Pipes\Managers::class, - Pipes\Auths::class, - ] - ) - ->then( - function ($method) { - } - ); - - return $passable; - } -} diff --git a/php-packages/phpstan/src/Methods/Macro.php b/php-packages/phpstan/src/Methods/Macro.php deleted file mode 100644 index deff8ace4..000000000 --- a/php-packages/phpstan/src/Methods/Macro.php +++ /dev/null @@ -1,265 +0,0 @@ - ValidationException::class, - 'validateWithBag' => ValidationException::class, - ]; - - public function __construct(ClassReflection $classReflection, string $methodName, ReflectionFunction $reflectionFunction) - { - $this->classReflection = $classReflection; - $this->methodName = $methodName; - $this->reflectionFunction = $reflectionFunction; - $this->parameters = $this->reflectionFunction->getParameters(); - - if ($this->reflectionFunction->isClosure()) { - try { - /** @var Closure $closure */ - $closure = $this->reflectionFunction->getClosure(); - Closure::bind($closure, new stdClass); - // The closure can be bound so it was not explicitly marked as static - } catch (ErrorException $e) { - // The closure was explicitly marked as static - $this->isStatic = true; - } - } - } - - public function getDeclaringClass(): ClassReflection - { - return $this->classReflection; - } - - public function isPrivate(): bool - { - return false; - } - - public function isPublic(): bool - { - return true; - } - - public function isFinal(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function isInternal(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function isStatic(): bool - { - return $this->isStatic; - } - - /** - * Set the is static value. - * - * @param bool $isStatic - * @return void - */ - public function setIsStatic(bool $isStatic): void - { - $this->isStatic = $isStatic; - } - - /** - * {@inheritdoc} - */ - public function getDocComment(): ?string - { - return $this->reflectionFunction->getDocComment() ?: null; - } - - /** - * {@inheritdoc} - */ - public function getName(): string - { - return $this->methodName; - } - - /** @return ParameterReflection[] */ - public function getParameters(): array - { - return array_map(function (ReflectionParameter $reflection): ParameterReflection { - return new class($reflection) implements ParameterReflection { - /** - * @var ReflectionParameter - */ - private $reflection; - - public function __construct(ReflectionParameter $reflection) - { - $this->reflection = $reflection; - } - - public function getName(): string - { - return $this->reflection->getName(); - } - - public function isOptional(): bool - { - return $this->reflection->isOptional(); - } - - public function getType(): Type - { - $type = $this->reflection->getType(); - - if ($type === null) { - return new MixedType(); - } - - return TypehintHelper::decideTypeFromReflection($this->reflection->getType()); - } - - public function passedByReference(): PassedByReference - { - return PassedByReference::createNo(); - } - - public function isVariadic(): bool - { - return $this->reflection->isVariadic(); - } - - public function getDefaultValue(): ?Type - { - return null; - } - }; - }, $this->parameters); - } - - /** - * Set the parameters value. - * - * @param ReflectionParameter[] $parameters - * @return void - */ - public function setParameters(array $parameters): void - { - $this->parameters = $parameters; - } - - public function getReturnType(): ?ReflectionType - { - return $this->reflectionFunction->getReturnType(); - } - - public function isDeprecated(): TrinaryLogic - { - return TrinaryLogic::createFromBoolean($this->reflectionFunction->isDeprecated()); - } - - public function getPrototype(): ClassMemberReflection - { - return $this; - } - - /** - * @inheritDoc - */ - public function getVariants(): array - { - return [ - new FunctionVariant(TemplateTypeMap::createEmpty(), null, $this->getParameters(), $this->reflectionFunction->isVariadic(), TypehintHelper::decideTypeFromReflection($this->getReturnType())), - ]; - } - - public function getDeprecatedDescription(): ?string - { - return null; - } - - public function getThrowType(): ?Type - { - if (array_key_exists($this->methodName, $this->methodThrowTypeMap)) { - return new ObjectType($this->methodThrowTypeMap[$this->methodName]); - } - - return null; - } - - public function hasSideEffects(): TrinaryLogic - { - return TrinaryLogic::createMaybe(); - } -} diff --git a/php-packages/phpstan/src/Methods/ModelFactoryMethodsClassReflectionExtension.php b/php-packages/phpstan/src/Methods/ModelFactoryMethodsClassReflectionExtension.php deleted file mode 100644 index 8ed0ca124..000000000 --- a/php-packages/phpstan/src/Methods/ModelFactoryMethodsClassReflectionExtension.php +++ /dev/null @@ -1,166 +0,0 @@ -isSubclassOf(Factory::class)) { - return false; - } - - if (! Str::startsWith($methodName, ['for', 'has'])) { - return false; - } - - $relationship = Str::camel(Str::substr($methodName, 3)); - - $parent = $classReflection->getParentClass(); - - if ($parent === null) { - return false; - } - - $modelType = $parent->getActiveTemplateTypeMap()->getType('TModel'); - - if ($modelType === null) { - return false; - } - - return $modelType->hasMethod($relationship)->yes(); - } - - public function getMethod( - ClassReflection $classReflection, - string $methodName - ): MethodReflection { - return new class($classReflection, $methodName) implements MethodReflection { - /** @var ClassReflection */ - private $classReflection; - - /** @var string */ - private $methodName; - - public function __construct(ClassReflection $classReflection, string $methodName) - { - $this->classReflection = $classReflection; - $this->methodName = $methodName; - } - - public function getDeclaringClass(): ClassReflection - { - return $this->classReflection; - } - - public function isStatic(): bool - { - return false; - } - - public function isPrivate(): bool - { - return false; - } - - public function isPublic(): bool - { - return true; - } - - public function getDocComment(): ?string - { - return null; - } - - public function getName(): string - { - return $this->methodName; - } - - public function getPrototype(): ClassMemberReflection - { - return $this; - } - - public function getVariants(): array - { - $returnType = new ObjectType($this->classReflection->getName()); - $stateParameter = ParametersAcceptorSelector::selectSingle($this->classReflection->getMethod('state', new OutOfClassScope())->getVariants())->getParameters()[0]; - $countParameter = ParametersAcceptorSelector::selectSingle($this->classReflection->getMethod('count', new OutOfClassScope())->getVariants())->getParameters()[0]; - - $variants = [ - new FunctionVariant(TemplateTypeMap::createEmpty(), null, [], false, $returnType), - ]; - - if (Str::startsWith($this->methodName, 'for')) { - $variants[] = new FunctionVariant(TemplateTypeMap::createEmpty(), null, [$stateParameter], false, $returnType); - } else { - $variants[] = new FunctionVariant(TemplateTypeMap::createEmpty(), null, [$countParameter], false, $returnType); - $variants[] = new FunctionVariant(TemplateTypeMap::createEmpty(), null, [$stateParameter], false, $returnType); - $variants[] = new FunctionVariant(TemplateTypeMap::createEmpty(), null, [$countParameter, $stateParameter], false, $returnType); - } - - return $variants; - } - - public function isDeprecated(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function getDeprecatedDescription(): ?string - { - return null; - } - - public function isFinal(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function isInternal(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function getThrowType(): ?Type - { - return null; - } - - public function hasSideEffects(): TrinaryLogic - { - return TrinaryLogic::createMaybe(); - } - }; - } -} diff --git a/php-packages/phpstan/src/Methods/ModelForwardsCallsExtension.php b/php-packages/phpstan/src/Methods/ModelForwardsCallsExtension.php deleted file mode 100644 index a9d60885e..000000000 --- a/php-packages/phpstan/src/Methods/ModelForwardsCallsExtension.php +++ /dev/null @@ -1,219 +0,0 @@ - */ - private $cache = []; - - public function __construct(BuilderHelper $builderHelper, ReflectionProvider $reflectionProvider, EloquentBuilderForwardsCallsExtension $eloquentBuilderForwardsCallsExtension) - { - $this->builderHelper = $builderHelper; - $this->reflectionProvider = $reflectionProvider; - $this->eloquentBuilderForwardsCallsExtension = $eloquentBuilderForwardsCallsExtension; - } - - /** - * @throws MissingMethodFromReflectionException - * @throws ShouldNotHappenException - */ - public function hasMethod(ClassReflection $classReflection, string $methodName): bool - { - if (array_key_exists($classReflection->getCacheKey().'-'.$methodName, $this->cache)) { - return true; - } - - $methodReflection = $this->findMethod($classReflection, $methodName); - - if ($methodReflection !== null) { - $this->cache[$classReflection->getCacheKey().'-'.$methodName] = $methodReflection; - - return true; - } - - return false; - } - - /** - * @param ClassReflection $classReflection - * @param string $methodName - * @return MethodReflection - */ - public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection - { - return $this->cache[$classReflection->getCacheKey().'-'.$methodName]; - } - - /** - * @throws ShouldNotHappenException - * @throws MissingMethodFromReflectionException - */ - private function findMethod(ClassReflection $classReflection, string $methodName): ?MethodReflection - { - if ($classReflection->getName() !== Model::class && ! $classReflection->isSubclassOf(Model::class)) { - return null; - } - - $builderName = $this->builderHelper->determineBuilderName($classReflection->getName()); - - if (in_array($methodName, ['increment', 'decrement'], true)) { - $methodReflection = $classReflection->getNativeMethod($methodName); - - return new class($classReflection, $methodName, $methodReflection) implements MethodReflection { - /** @var ClassReflection */ - private $classReflection; - - /** @var string */ - private $methodName; - - /** @var MethodReflection */ - private $methodReflection; - - public function __construct(ClassReflection $classReflection, string $methodName, MethodReflection $methodReflection) - { - $this->classReflection = $classReflection; - $this->methodName = $methodName; - $this->methodReflection = $methodReflection; - } - - public function getDeclaringClass(): \PHPStan\Reflection\ClassReflection - { - return $this->classReflection; - } - - public function isStatic(): bool - { - return false; - } - - public function isPrivate(): bool - { - return false; - } - - public function isPublic(): bool - { - return true; - } - - public function getDocComment(): ?string - { - return null; - } - - public function getName(): string - { - return $this->methodName; - } - - public function getPrototype(): \PHPStan\Reflection\ClassMemberReflection - { - return $this; - } - - public function getVariants(): array - { - return $this->methodReflection->getVariants(); - } - - public function isDeprecated(): \PHPStan\TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function getDeprecatedDescription(): ?string - { - return null; - } - - public function isFinal(): \PHPStan\TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function isInternal(): \PHPStan\TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function getThrowType(): ?\PHPStan\Type\Type - { - return null; - } - - public function hasSideEffects(): \PHPStan\TrinaryLogic - { - return TrinaryLogic::createYes(); - } - }; - } - - $builderReflection = $this->reflectionProvider->getClass($builderName)->withTypes([new ObjectType($classReflection->getName())]); - $genericBuilderAndModelType = new GenericObjectType($builderName, [new ObjectType($classReflection->getName())]); - - if ($builderReflection->hasNativeMethod($methodName)) { - $reflection = $builderReflection->getNativeMethod($methodName); - - $parametersAcceptor = ParametersAcceptorSelector::selectSingle($reflection->getVariants()); - - $returnType = TypeTraverser::map($parametersAcceptor->getReturnType(), static function (Type $type, callable $traverse) use ($genericBuilderAndModelType) { - if ($type instanceof TypeWithClassName && $type->getClassName() === Builder::class) { - return $genericBuilderAndModelType; - } - - return $traverse($type); - }); - - return new EloquentBuilderMethodReflection( - $methodName, - $classReflection, - $reflection, - $parametersAcceptor->getParameters(), - $returnType, - $parametersAcceptor->isVariadic() - ); - } - - if ($this->eloquentBuilderForwardsCallsExtension->hasMethod($builderReflection, $methodName)) { - return $this->eloquentBuilderForwardsCallsExtension->getMethod($builderReflection, $methodName); - } - - return null; - } -} diff --git a/php-packages/phpstan/src/Methods/ModelTypeHelper.php b/php-packages/phpstan/src/Methods/ModelTypeHelper.php deleted file mode 100644 index 8b122dbd6..000000000 --- a/php-packages/phpstan/src/Methods/ModelTypeHelper.php +++ /dev/null @@ -1,38 +0,0 @@ -getClassName() === Model::class) { - return new ObjectType($modelClass); - } - - return $traverse($type); - }); - } -} diff --git a/php-packages/phpstan/src/Methods/Passable.php b/php-packages/phpstan/src/Methods/Passable.php deleted file mode 100644 index 503dd6009..000000000 --- a/php-packages/phpstan/src/Methods/Passable.php +++ /dev/null @@ -1,224 +0,0 @@ -methodReflectionFactory = $methodReflectionFactory; - $this->reflectionProvider = $reflectionProvider; - $this->pipeline = $pipeline; - $this->classReflection = $classReflection; - $this->methodName = $methodName; - } - - /** - * {@inheritdoc} - */ - public function getClassReflection(): ClassReflection - { - return $this->classReflection; - } - - /** - * {@inheritdoc} - */ - public function setClassReflection(ClassReflection $classReflection): PassableContract - { - $this->classReflection = $classReflection; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getMethodName(): string - { - return $this->methodName; - } - - /** - * {@inheritdoc} - */ - public function hasFound(): bool - { - return $this->methodReflection !== null; - } - - /** - * {@inheritdoc} - */ - public function searchOn(string $class): bool - { - $classReflection = $this->reflectionProvider->getClass($class); - - $found = $classReflection->hasNativeMethod($this->methodName); - - if ($found) { - $this->setMethodReflection($classReflection->getNativeMethod($this->methodName)); - } - - return $found; - } - - /** - * {@inheritdoc} - */ - public function getMethodReflection(): MethodReflection - { - if ($this->methodReflection === null) { - throw new LogicException("MethodReflection doesn't exist"); - } - - return $this->methodReflection; - } - - /** - * {@inheritdoc} - */ - public function setMethodReflection(MethodReflection $methodReflection): void - { - $this->methodReflection = $methodReflection; - } - - /** - * {@inheritdoc} - */ - public function setStaticAllowed(bool $staticAllowed): void - { - $this->staticAllowed = $staticAllowed; - } - - /** - * {@inheritdoc} - */ - public function isStaticAllowed(): bool - { - return $this->staticAllowed; - } - - /** - * {@inheritdoc} - */ - public function sendToPipeline(string $class, $staticAllowed = false): bool - { - $classReflection = $this->reflectionProvider->getClass($class); - - $this->setStaticAllowed($this->staticAllowed ?: $staticAllowed); - - $originalClassReflection = $this->classReflection; - $this->pipeline->send($this->setClassReflection($classReflection)) - ->then( - function (PassableContract $passable) use ($originalClassReflection) { - if ($passable->hasFound()) { - $this->setMethodReflection($passable->getMethodReflection()); - $this->setStaticAllowed($passable->isStaticAllowed()); - } - - $this->setClassReflection($originalClassReflection); - } - ); - - if ($result = $this->hasFound()) { - $methodReflection = $this->getMethodReflection(); - if (get_class($methodReflection) === PhpMethodReflection::class) { - $methodReflection = Mockery::mock($methodReflection); - $methodReflection->shouldReceive('isStatic') - ->andReturn($this->isStaticAllowed()); - } - - $this->setMethodReflection($methodReflection); - } - - return $result; - } - - public function getReflectionProvider(): ReflectionProvider - { - return $this->reflectionProvider; - } - - /** - * {@inheritdoc} - */ - public function getMethodReflectionFactory(): PhpMethodReflectionFactory - { - return $this->methodReflectionFactory; - } -} diff --git a/php-packages/phpstan/src/Methods/Pipes/Auths.php b/php-packages/phpstan/src/Methods/Pipes/Auths.php deleted file mode 100644 index 3176ad5ee..000000000 --- a/php-packages/phpstan/src/Methods/Pipes/Auths.php +++ /dev/null @@ -1,68 +0,0 @@ -getClassReflection() - ->getName(); - - $found = false; - - $config = $this->resolve('config'); - - if ($config !== null && in_array($classReflectionName, $this->classes, true)) { - $authModel = $this->getAuthModel($config); - - if ($authModel !== null) { - $found = $passable->sendToPipeline($authModel); - } - } elseif ($classReflectionName === \Illuminate\Contracts\Auth\Factory::class || $classReflectionName === \Illuminate\Auth\AuthManager::class) { - $found = $passable->sendToPipeline( - \Illuminate\Contracts\Auth\Guard::class - ); - } - - if (! $found) { - $next($passable); - } - } -} diff --git a/php-packages/phpstan/src/Methods/Pipes/Contracts.php b/php-packages/phpstan/src/Methods/Pipes/Contracts.php deleted file mode 100644 index a82ce20ba..000000000 --- a/php-packages/phpstan/src/Methods/Pipes/Contracts.php +++ /dev/null @@ -1,67 +0,0 @@ -concretes($passable->getClassReflection()) as $concrete) { - if ($found = $passable->sendToPipeline($concrete)) { - break; - } - } - - if (! $found) { - $next($passable); - } - } - - /** - * @param \PHPStan\Reflection\ClassReflection $classReflection - * @return class-string[] - */ - private function concretes(ClassReflection $classReflection): array - { - if ($classReflection->isInterface() && Str::startsWith($classReflection->getName(), 'Illuminate\Contracts')) { - $concrete = $this->resolve($classReflection->getName()); - - if ($concrete !== null) { - $class = get_class($concrete); - - if ($class) { - return [$class]; - } - } - } - - return []; - } -} diff --git a/php-packages/phpstan/src/Methods/Pipes/Facades.php b/php-packages/phpstan/src/Methods/Pipes/Facades.php deleted file mode 100644 index c98987bc9..000000000 --- a/php-packages/phpstan/src/Methods/Pipes/Facades.php +++ /dev/null @@ -1,66 +0,0 @@ -getClassReflection(); - - $found = false; - - if ($classReflection->isSubclassOf(Facade::class)) { - $facadeClass = $classReflection->getName(); - - if ($concrete = $facadeClass::getFacadeRoot()) { - $class = get_class($concrete); - - if ($class) { - $found = $passable->sendToPipeline($class, true); - } - } - - if (! $found && Str::startsWith($passable->getMethodName(), 'assert')) { - $fakeFacadeClass = $this->getFake($facadeClass); - - if ($passable->getReflectionProvider()->hasClass($fakeFacadeClass)) { - assert(class_exists($fakeFacadeClass)); - $found = $passable->sendToPipeline($fakeFacadeClass, true); - } - } - } - - if (! $found) { - $next($passable); - } - } - - private function getFake(string $facade): string - { - $shortClassName = substr($facade, strrpos($facade, '\\') + 1); - - return sprintf('\\Illuminate\\Support\\Testing\\Fakes\\%sFake', $shortClassName); - } -} diff --git a/php-packages/phpstan/src/Methods/Pipes/Macros.php b/php-packages/phpstan/src/Methods/Pipes/Macros.php deleted file mode 100644 index 8dbabd83b..000000000 --- a/php-packages/phpstan/src/Methods/Pipes/Macros.php +++ /dev/null @@ -1,105 +0,0 @@ -getTraits() as $trait) { - if ($this->hasIndirectTraitUse($trait, $traitName)) { - return true; - } - } - - return $class->hasTraitUse($traitName); - } - - /** - * {@inheritdoc} - */ - public function handle(PassableContract $passable, Closure $next): void - { - $classReflection = $passable->getClassReflection(); - - /** @var class-string $className */ - $className = null; - $found = false; - $macroTraitProperty = null; - - if ($classReflection->isInterface() && Str::startsWith($classReflection->getName(), 'Illuminate\Contracts')) { - /** @var object|null $concrete */ - $concrete = $this->resolve($classReflection->getName()); - - if ($concrete !== null) { - $className = get_class($concrete); - - if ($className && $passable->getReflectionProvider() - ->getClass($className) - ->hasTraitUse(Macroable::class)) { - $macroTraitProperty = 'macros'; - } - } - } elseif ($classReflection->hasTraitUse(Macroable::class) || $classReflection->getName() === Builder::class) { - $className = $classReflection->getName(); - $macroTraitProperty = 'macros'; - } elseif ($this->hasIndirectTraitUse($classReflection, CarbonMacro::class)) { - $className = $classReflection->getName(); - $macroTraitProperty = 'globalMacros'; - } - - if ($className !== null && $macroTraitProperty) { - $classReflection = $passable->getReflectionProvider()->getClass($className); - $refObject = new \ReflectionClass($className); - $refProperty = $refObject->getProperty($macroTraitProperty); - $refProperty->setAccessible(true); - - $found = $className === Builder::class - ? $className::hasGlobalMacro($passable->getMethodName()) - : $className::hasMacro($passable->getMethodName()); - - if ($found) { - $reflectionFunction = new \ReflectionFunction($refProperty->getValue()[$passable->getMethodName()]); - - $methodReflection = new Macro( - $classReflection, - $passable->getMethodName(), - $reflectionFunction - ); - - $methodReflection->setIsStatic(true); - - $passable->setMethodReflection($methodReflection); - } - } - - if (! $found) { - $next($passable); - } - } -} diff --git a/php-packages/phpstan/src/Methods/Pipes/Managers.php b/php-packages/phpstan/src/Methods/Pipes/Managers.php deleted file mode 100644 index 6e66e66fa..000000000 --- a/php-packages/phpstan/src/Methods/Pipes/Managers.php +++ /dev/null @@ -1,63 +0,0 @@ -getClassReflection(); - - $found = false; - - if ($classReflection->isSubclassOf(Manager::class)) { - $driver = null; - - $concrete = $this->resolve( - $classReflection->getName() - ); - - try { - $driver = $concrete->driver(); - } catch (InvalidArgumentException $exception) { - // .. - } - - if ($driver !== null) { - $class = get_class($driver); - - if ($class) { - $found = $passable->sendToPipeline($class); - } - } - } - - if (! $found) { - $next($passable); - } - } -} diff --git a/php-packages/phpstan/src/Methods/Pipes/SelfClass.php b/php-packages/phpstan/src/Methods/Pipes/SelfClass.php deleted file mode 100644 index ccff37108..000000000 --- a/php-packages/phpstan/src/Methods/Pipes/SelfClass.php +++ /dev/null @@ -1,35 +0,0 @@ -getClassReflection() - ->getName(); - - if (! $passable->searchOn($className)) { - $next($passable); - } - } -} diff --git a/php-packages/phpstan/src/Methods/RelationForwardsCallsExtension.php b/php-packages/phpstan/src/Methods/RelationForwardsCallsExtension.php deleted file mode 100644 index 61aee24f2..000000000 --- a/php-packages/phpstan/src/Methods/RelationForwardsCallsExtension.php +++ /dev/null @@ -1,150 +0,0 @@ - */ - private $cache = []; - - /** @var ReflectionProvider */ - private $reflectionProvider; - - /** @var EloquentBuilderForwardsCallsExtension */ - private $eloquentBuilderForwardsCallsExtension; - - public function __construct(BuilderHelper $builderHelper, ReflectionProvider $reflectionProvider, EloquentBuilderForwardsCallsExtension $eloquentBuilderForwardsCallsExtension) - { - $this->builderHelper = $builderHelper; - $this->reflectionProvider = $reflectionProvider; - $this->eloquentBuilderForwardsCallsExtension = $eloquentBuilderForwardsCallsExtension; - } - - public function hasMethod(ClassReflection $classReflection, string $methodName): bool - { - if (array_key_exists($classReflection->getCacheKey().'-'.$methodName, $this->cache)) { - return true; - } - - $methodReflection = $this->findMethod($classReflection, $methodName); - - if ($methodReflection !== null) { - $this->cache[$classReflection->getCacheKey().'-'.$methodName] = $methodReflection; - - return true; - } - - return false; - } - - public function getMethod( - ClassReflection $classReflection, - string $methodName - ): MethodReflection { - return $this->cache[$classReflection->getCacheKey().'-'.$methodName]; - } - - /** - * @throws MissingMethodFromReflectionException - * @throws ShouldNotHappenException - */ - private function findMethod(ClassReflection $classReflection, string $methodName): ?MethodReflection - { - if (! $classReflection->isSubclassOf(Relation::class)) { - return null; - } - - /** @var Type|TemplateMixedType|null $relatedModel */ - $relatedModel = $classReflection->getActiveTemplateTypeMap()->getType('TRelatedModel'); - - if ($relatedModel === null) { - return null; - } - - if ($relatedModel instanceof TypeWithClassName) { - $modelReflection = $relatedModel->getClassReflection(); - } else { - $modelReflection = $this->reflectionProvider->getClass(Model::class); - } - - if ($modelReflection === null) { - return null; - } - - $builderName = $this->builderHelper->determineBuilderName($modelReflection->getName()); - - $builderReflection = $this->reflectionProvider->getClass($builderName)->withTypes([$relatedModel]); - - if ($builderReflection->hasNativeMethod($methodName)) { - $reflection = $builderReflection->getNativeMethod($methodName); - } elseif ($this->eloquentBuilderForwardsCallsExtension->hasMethod($builderReflection, $methodName)) { - $reflection = $this->eloquentBuilderForwardsCallsExtension->getMethod($builderReflection, $methodName); - } else { - return null; - } - - $parametersAcceptor = ParametersAcceptorSelector::selectSingle($reflection->getVariants()); - $returnType = $parametersAcceptor->getReturnType(); - - $types = [$relatedModel]; - - // BelongsTo relation needs second generic type - if ($classReflection->getName() === BelongsTo::class) { - $childType = $classReflection->getActiveTemplateTypeMap()->getType('TChildModel'); - - if ($childType !== null) { - $types[] = $childType; - } - } - - if ((new ObjectType(Builder::class))->isSuperTypeOf($returnType)->yes()) { - return new EloquentBuilderMethodReflection( - $methodName, - $classReflection, - $reflection, - $parametersAcceptor->getParameters(), - new GenericObjectType($classReflection->getName(), $types), - $parametersAcceptor->isVariadic() - ); - } - - return new EloquentBuilderMethodReflection( - $methodName, - $classReflection, - $reflection, - $parametersAcceptor->getParameters(), - $returnType, - $parametersAcceptor->isVariadic() - ); - } -} diff --git a/php-packages/phpstan/src/Methods/StorageMethodsClassReflectionExtension.php b/php-packages/phpstan/src/Methods/StorageMethodsClassReflectionExtension.php deleted file mode 100644 index b46979d97..000000000 --- a/php-packages/phpstan/src/Methods/StorageMethodsClassReflectionExtension.php +++ /dev/null @@ -1,67 +0,0 @@ -reflectionProvider = $reflectionProvider; - } - - public function hasMethod(ClassReflection $classReflection, string $methodName): bool - { - if ($classReflection->getName() !== Storage::class) { - return false; - } - - if ($this->reflectionProvider->getClass(FilesystemManager::class)->hasMethod($methodName)) { - return true; - } - - if ($this->reflectionProvider->getClass(FilesystemAdapter::class)->hasMethod($methodName)) { - return true; - } - - return false; - } - - public function getMethod( - ClassReflection $classReflection, - string $methodName - ): MethodReflection { - if ($this->reflectionProvider->getClass(FilesystemManager::class)->hasMethod($methodName)) { - return new StaticMethodReflection( - $this->reflectionProvider->getClass(FilesystemManager::class)->getMethod($methodName, new OutOfClassScope()) - ); - } - - return new StaticMethodReflection( - $this->reflectionProvider->getClass(FilesystemAdapter::class)->getMethod($methodName, new OutOfClassScope()) - ); - } -} diff --git a/php-packages/phpstan/src/Properties/HigherOrderCollectionProxyPropertyExtension.php b/php-packages/phpstan/src/Properties/HigherOrderCollectionProxyPropertyExtension.php deleted file mode 100644 index 2d9d8670c..000000000 --- a/php-packages/phpstan/src/Properties/HigherOrderCollectionProxyPropertyExtension.php +++ /dev/null @@ -1,124 +0,0 @@ -getActiveTemplateTypeMap(); - - /** @var Type\Constant\ConstantStringType $methodType */ - $methodType = $activeTemplateTypeMap->getType('T'); - - /** @var Type\ObjectType $modelType */ - $modelType = $activeTemplateTypeMap->getType('TValue'); - - $propertyType = $modelType->getProperty($propertyName, new OutOfClassScope())->getReadableType(); - - $returnType = HigherOrderCollectionProxyHelper::determineReturnType($methodType->getValue(), $modelType, $propertyType); - - return new class($classReflection, $returnType) implements PropertyReflection { - /** @var ClassReflection */ - private $classReflection; - - /** @var Type\Type */ - private $returnType; - - public function __construct(ClassReflection $classReflection, Type\Type $returnType) - { - $this->classReflection = $classReflection; - $this->returnType = $returnType; - } - - public function getDeclaringClass(): \PHPStan\Reflection\ClassReflection - { - return $this->classReflection; - } - - public function isStatic(): bool - { - return false; - } - - public function isPrivate(): bool - { - return false; - } - - public function isPublic(): bool - { - return true; - } - - public function getDocComment(): ?string - { - return null; - } - - public function getReadableType(): Type\Type - { - return $this->returnType; - } - - public function getWritableType(): Type\Type - { - return $this->returnType; - } - - public function canChangeTypeAfterAssignment(): bool - { - return false; - } - - public function isReadable(): bool - { - return true; - } - - public function isWritable(): bool - { - return false; - } - - public function isDeprecated(): \PHPStan\TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function getDeprecatedDescription(): ?string - { - return null; - } - - public function isInternal(): \PHPStan\TrinaryLogic - { - return TrinaryLogic::createNo(); - } - }; - } -} diff --git a/php-packages/phpstan/src/Properties/MigrationHelper.php b/php-packages/phpstan/src/Properties/MigrationHelper.php deleted file mode 100644 index 870053a7a..000000000 --- a/php-packages/phpstan/src/Properties/MigrationHelper.php +++ /dev/null @@ -1,102 +0,0 @@ -parser = $parser; - $this->databaseMigrationPath = $databaseMigrationPath; - $this->fileHelper = $fileHelper; - } - - /** - * @return array - */ - public function initializeTables(): array - { - if (empty($this->databaseMigrationPath)) { - $this->databaseMigrationPath = [database_path('migrations')]; - } - - $schemaAggregator = new SchemaAggregator(); - $filesArray = $this->getMigrationFiles(); - - if (empty($filesArray)) { - return []; - } - - ksort($filesArray); - - $this->requireFiles($filesArray); - - foreach ($filesArray as $file) { - $schemaAggregator->addStatements($this->parser->parseFile($file->getPathname())); - } - - return $schemaAggregator->tables; - } - - /** - * @return SplFileInfo[] - */ - private function getMigrationFiles(): array - { - /** @var SplFileInfo[] $migrationFiles */ - $migrationFiles = []; - - foreach ($this->databaseMigrationPath as $additionalPath) { - $absolutePath = $this->fileHelper->absolutizePath($additionalPath); - - if (is_dir($absolutePath)) { - $migrationFiles += iterator_to_array( - new RegexIterator( - new RecursiveIteratorIterator(new RecursiveDirectoryIterator($absolutePath)), - '/\.php$/i' - ) - ); - } - } - - return $migrationFiles; - } - - /** - * @param SplFileInfo[] $files - */ - private function requireFiles(array $files): void - { - foreach ($files as $file) { - require_once $file; - } - } -} diff --git a/php-packages/phpstan/src/Properties/ModelAccessorExtension.php b/php-packages/phpstan/src/Properties/ModelAccessorExtension.php deleted file mode 100644 index c889972a7..000000000 --- a/php-packages/phpstan/src/Properties/ModelAccessorExtension.php +++ /dev/null @@ -1,46 +0,0 @@ -isSubclassOf(Model::class)) { - return false; - } - - return $classReflection->hasNativeMethod('get'.Str::studly($propertyName).'Attribute'); - } - - public function getProperty( - ClassReflection $classReflection, - string $propertyName - ): PropertyReflection { - $method = $classReflection->getNativeMethod('get'.Str::studly($propertyName).'Attribute'); - - return new ModelProperty( - $classReflection, - $method->getVariants()[0]->getReturnType(), - $method->getVariants()[0]->getReturnType() - ); - } -} diff --git a/php-packages/phpstan/src/Properties/ModelProperty.php b/php-packages/phpstan/src/Properties/ModelProperty.php deleted file mode 100644 index e6515478b..000000000 --- a/php-packages/phpstan/src/Properties/ModelProperty.php +++ /dev/null @@ -1,105 +0,0 @@ -declaringClass = $declaringClass; - $this->readableType = $readableType; - $this->writableType = $writableType; - $this->writeable = $writeable; - } - - public function getDeclaringClass(): ClassReflection - { - return $this->declaringClass; - } - - public function isStatic(): bool - { - return false; - } - - public function isPrivate(): bool - { - return false; - } - - public function isPublic(): bool - { - return true; - } - - public function isReadable(): bool - { - return true; - } - - public function isWritable(): bool - { - return $this->writeable; - } - - public function getDocComment(): ?string - { - return null; - } - - public function getReadableType(): Type - { - return $this->readableType; - } - - public function getWritableType(): Type - { - return $this->writableType; - } - - public function canChangeTypeAfterAssignment(): bool - { - return false; - } - - public function isDeprecated(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function getDeprecatedDescription(): ?string - { - return null; - } - - public function isInternal(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } -} diff --git a/php-packages/phpstan/src/Properties/ModelPropertyExtension.php b/php-packages/phpstan/src/Properties/ModelPropertyExtension.php deleted file mode 100644 index 55fd433c9..000000000 --- a/php-packages/phpstan/src/Properties/ModelPropertyExtension.php +++ /dev/null @@ -1,274 +0,0 @@ - */ - private $tables = []; - - /** @var TypeStringResolver */ - private $stringResolver; - - /** @var string */ - private $dateClass; - - /** @var MigrationHelper */ - private $migrationHelper; - - public function __construct(TypeStringResolver $stringResolver, MigrationHelper $migrationHelper) - { - $this->stringResolver = $stringResolver; - $this->migrationHelper = $migrationHelper; - } - - public function hasProperty(ClassReflection $classReflection, string $propertyName): bool - { - if (! $classReflection->isSubclassOf(Model::class)) { - return false; - } - - if ($classReflection->isAbstract()) { - return false; - } - - if ($classReflection->hasNativeMethod('get'.Str::studly($propertyName).'Attribute')) { - return false; - } - - if (ReflectionHelper::hasPropertyTag($classReflection, $propertyName)) { - return false; - } - - if (count($this->tables) === 0) { - $this->tables = $this->migrationHelper->initializeTables(); - } - - if ($propertyName === 'id') { - return true; - } - - $modelName = $classReflection->getNativeReflection()->getName(); - - try { - $reflect = new \ReflectionClass($modelName); - - /** @var Model $modelInstance */ - $modelInstance = $reflect->newInstanceWithoutConstructor(); - - $tableName = $modelInstance->getTable(); - } catch (\ReflectionException $e) { - return false; - } - - if (! array_key_exists($tableName, $this->tables)) { - return false; - } - - if (! array_key_exists($propertyName, $this->tables[$tableName]->columns)) { - return false; - } - - $this->castPropertiesType($modelInstance); - - $column = $this->tables[$tableName]->columns[$propertyName]; - - [$readableType, $writableType] = $this->getReadableAndWritableTypes($column, $modelInstance); - - $column->readableType = $readableType; - $column->writeableType = $writableType; - - $this->tables[$tableName]->columns[$propertyName] = $column; - - return true; - } - - public function getProperty( - ClassReflection $classReflection, - string $propertyName - ): PropertyReflection { - $modelName = $classReflection->getNativeReflection()->getName(); - - try { - $reflect = new \ReflectionClass($modelName); - - /** @var Model $modelInstance */ - $modelInstance = $reflect->newInstanceWithoutConstructor(); - - $tableName = $modelInstance->getTable(); - } catch (\ReflectionException $e) { - // `hasProperty` should return false if there was a reflection exception. - // so this should never happen - throw new ShouldNotHappenException(); - } - - if ( - ( - ! array_key_exists($tableName, $this->tables) - || ! array_key_exists($propertyName, $this->tables[$tableName]->columns) - ) - && $propertyName === 'id' - ) { - return new ModelProperty( - $classReflection, - new IntegerType(), - new IntegerType() - ); - } - - $column = $this->tables[$tableName]->columns[$propertyName]; - - return new ModelProperty( - $classReflection, - $this->stringResolver->resolve($column->readableType), - $this->stringResolver->resolve($column->writeableType) - ); - } - - private function getDateClass(): string - { - if (! $this->dateClass) { - $this->dateClass = class_exists(\Illuminate\Support\Facades\Date::class) - ? '\\'.get_class(\Illuminate\Support\Facades\Date::now()) - : '\Illuminate\Support\Carbon'; - - $this->dateClass .= '|\Carbon\Carbon'; - } - - return $this->dateClass; - } - - /** - * @param SchemaColumn $column - * @param Model $modelInstance - * @return string[] - * @phpstan-return array - */ - private function getReadableAndWritableTypes(SchemaColumn $column, Model $modelInstance): array - { - $readableType = $column->readableType; - $writableType = $column->writeableType; - - if (in_array($column->name, $modelInstance->getDates(), true)) { - return [$this->getDateClass().($column->nullable ? '|null' : ''), $this->getDateClass().'|string'.($column->nullable ? '|null' : '')]; - } - - switch ($column->readableType) { - case 'string': - case 'int': - case 'float': - $readableType = $writableType = $column->readableType.($column->nullable ? '|null' : ''); - break; - - case 'boolean': - case 'bool': - switch ((string) config('database.default')) { - case 'sqlite': - case 'mysql': - $writableType = '0|1|bool'; - $readableType = 'bool'; - break; - default: - $readableType = $writableType = 'bool'; - break; - } - break; - case 'enum': - if (! $column->options) { - $readableType = $writableType = 'string'; - } else { - $readableType = $writableType = '\''.implode('\'|\'', $column->options).'\''; - } - - break; - - default: - break; - } - - return [$readableType, $writableType]; - } - - private function castPropertiesType(Model $modelInstance): void - { - $casts = $modelInstance->getCasts(); - foreach ($casts as $name => $type) { - if (! array_key_exists($name, $this->tables[$modelInstance->getTable()]->columns)) { - continue; - } - - switch ($type) { - case 'boolean': - case 'bool': - $realType = 'boolean'; - break; - case 'string': - $realType = 'string'; - break; - case 'array': - case 'json': - $realType = 'array'; - break; - case 'object': - $realType = 'object'; - break; - case 'int': - case 'integer': - case 'timestamp': - $realType = 'integer'; - break; - case 'real': - case 'double': - case 'float': - $realType = 'float'; - break; - case 'date': - case 'datetime': - $realType = $this->getDateClass(); - break; - case 'collection': - $realType = '\Illuminate\Support\Collection'; - break; - case 'Illuminate\Database\Eloquent\Casts\AsArrayObject': - $realType = ArrayObject::class; - break; - case 'Illuminate\Database\Eloquent\Casts\AsCollection': - $realType = '\Illuminate\Support\Collection'; - break; - default: - $realType = class_exists($type) ? ('\\'.$type) : 'mixed'; - break; - } - - if ($this->tables[$modelInstance->getTable()]->columns[$name]->nullable) { - $realType .= '|null'; - } - - $this->tables[$modelInstance->getTable()]->columns[$name]->readableType = $realType; - $this->tables[$modelInstance->getTable()]->columns[$name]->writeableType = $realType; - } - } -} diff --git a/php-packages/phpstan/src/Properties/ModelRelationsExtension.php b/php-packages/phpstan/src/Properties/ModelRelationsExtension.php deleted file mode 100644 index 9364860c8..000000000 --- a/php-packages/phpstan/src/Properties/ModelRelationsExtension.php +++ /dev/null @@ -1,124 +0,0 @@ -relationParserHelper = $relationParserHelper; - $this->builderHelper = $builderHelper; - } - - public function hasProperty(ClassReflection $classReflection, string $propertyName): bool - { - if (! $classReflection->isSubclassOf(Model::class)) { - return false; - } - - if (ReflectionHelper::hasPropertyTag($classReflection, $propertyName)) { - return false; - } - - $hasNativeMethod = $classReflection->hasNativeMethod($propertyName); - - if (! $hasNativeMethod) { - return false; - } - - $returnType = ParametersAcceptorSelector::selectSingle($classReflection->getNativeMethod($propertyName)->getVariants())->getReturnType(); - - if (! (new ObjectType(Relation::class))->isSuperTypeOf($returnType)->yes()) { - return false; - } - - return true; - } - - public function getProperty(ClassReflection $classReflection, string $propertyName): PropertyReflection - { - $method = $classReflection->getMethod($propertyName, new OutOfClassScope()); - - /** @var ObjectType $returnType */ - $returnType = ParametersAcceptorSelector::selectSingle($method->getVariants())->getReturnType(); - - if ($returnType instanceof GenericObjectType) { - /** @var ObjectType $relatedModelType */ - $relatedModelType = $returnType->getTypes()[0]; - $relatedModelClassName = $relatedModelType->getClassName(); - } else { - $relatedModelClassName = $this - ->relationParserHelper - ->findRelatedModelInRelationMethod($method); - } - - if ($relatedModelClassName === null) { - $relatedModelClassName = Model::class; - } - - $relatedModel = new ObjectType($relatedModelClassName); - $collectionClass = $this->builderHelper->determineCollectionClassName($relatedModelClassName); - - if (Str::contains($returnType->getClassName(), 'Many')) { - return new ModelProperty( - $classReflection, - new GenericObjectType($collectionClass, [$relatedModel]), - new NeverType(), - false - ); - } - - if (Str::endsWith($returnType->getClassName(), 'MorphTo')) { - return new ModelProperty($classReflection, new UnionType([ - new ObjectType(Model::class), - new MixedType(), - ]), new NeverType(), false); - } - - return new ModelProperty($classReflection, new UnionType([ - $relatedModel, - new NullType(), - ]), new NeverType(), false); - } -} diff --git a/php-packages/phpstan/src/Properties/ReflectionTypeContainer.php b/php-packages/phpstan/src/Properties/ReflectionTypeContainer.php deleted file mode 100644 index f4b7daea8..000000000 --- a/php-packages/phpstan/src/Properties/ReflectionTypeContainer.php +++ /dev/null @@ -1,67 +0,0 @@ -type = $type; - } - - /** - * {@inheritdoc} - */ - public function allowsNull(): bool - { - return false; - } - - /** - * {@inheritdoc} - */ - public function isBuiltin(): bool - { - return false; - } - - /** - * {@inheritdoc} - */ - public function __toString(): string - { - return $this->getName(); - } - - /** - * {@inheritdoc} - */ - public function getName(): string - { - return $this->type; - } -} diff --git a/php-packages/phpstan/src/Properties/SchemaAggregator.php b/php-packages/phpstan/src/Properties/SchemaAggregator.php deleted file mode 100644 index 0d9a5ee75..000000000 --- a/php-packages/phpstan/src/Properties/SchemaAggregator.php +++ /dev/null @@ -1,439 +0,0 @@ - */ - public $tables = []; - - /** - * @param array $stmts - */ - public function addStatements(array $stmts): void - { - $nodeFinder = new NodeFinder(); - - /** @var PhpParser\Node\Stmt\Class_[] $classes */ - $classes = $nodeFinder->findInstanceOf($stmts, PhpParser\Node\Stmt\Class_::class); - - foreach ($classes as $stmt) { - $this->addClassStatements($stmt->stmts); - } - } - - /** - * @param array $stmts - */ - private function addClassStatements(array $stmts): void - { - foreach ($stmts as $stmt) { - if ($stmt instanceof PhpParser\Node\Stmt\ClassMethod - && $stmt->name->name !== 'down' - && $stmt->stmts - ) { - $this->addUpMethodStatements($stmt->stmts); - } - } - } - - /** - * @param PhpParser\Node\Stmt[] $stmts - */ - private function addUpMethodStatements(array $stmts): void - { - $nodeFinder = new NodeFinder(); - $methods = $nodeFinder->findInstanceOf($stmts, PhpParser\Node\Stmt\Expression::class); - - foreach ($methods as $stmt) { - if ($stmt instanceof PhpParser\Node\Stmt\Expression - && $stmt->expr instanceof PhpParser\Node\Expr\StaticCall - && ($stmt->expr->class instanceof PhpParser\Node\Name) - && $stmt->expr->name instanceof PhpParser\Node\Identifier - && ($stmt->expr->class->toCodeString() === '\Illuminate\Support\Facades\Schema' || $stmt->expr->class->toCodeString() === '\Schema') - ) { - switch ($stmt->expr->name->name) { - case 'create': - $this->alterTable($stmt->expr, true); - break; - - case 'table': - $this->alterTable($stmt->expr, false); - break; - - case 'drop': - case 'dropIfExists': - $this->dropTable($stmt->expr); - break; - - case 'rename': - $this->renameTable($stmt->expr); - } - } - } - } - - private function alterTable(PhpParser\Node\Expr\StaticCall $call, bool $creating): void - { - if (! isset($call->args[0]) - || ! $call->getArgs()[0]->value instanceof PhpParser\Node\Scalar\String_ - ) { - return; - } - - $tableName = $call->getArgs()[0]->value->value; - - if ($creating) { - $this->tables[$tableName] = new SchemaTable($tableName); - } - - if (! isset($call->args[1]) - || ! $call->getArgs()[1]->value instanceof PhpParser\Node\Expr\Closure - || count($call->getArgs()[1]->value->params) < 1 - || ($call->getArgs()[1]->value->params[0]->type instanceof PhpParser\Node\Name - && $call->getArgs()[1]->value->params[0]->type->toCodeString() - !== '\\Illuminate\Database\Schema\Blueprint') - ) { - return; - } - - $updateClosure = $call->getArgs()[1]->value; - - if ($call->getArgs()[1]->value->params[0]->var instanceof PhpParser\Node\Expr\Variable - && is_string($call->getArgs()[1]->value->params[0]->var->name) - ) { - $argName = $call->getArgs()[1]->value->params[0]->var->name; - - $this->processColumnUpdates($tableName, $argName, $updateClosure->stmts); - } - } - - /** - * @param string $tableName - * @param string $argName - * @param PhpParser\Node\Stmt[] $stmts - * - * @throws \Exception - */ - private function processColumnUpdates(string $tableName, string $argName, array $stmts): void - { - if (! isset($this->tables[$tableName])) { - return; - } - - $table = $this->tables[$tableName]; - - foreach ($stmts as $stmt) { - if ($stmt instanceof PhpParser\Node\Stmt\Expression - && $stmt->expr instanceof PhpParser\Node\Expr\MethodCall - && $stmt->expr->name instanceof PhpParser\Node\Identifier - ) { - $rootVar = $stmt->expr; - - $firstMethodCall = $rootVar; - - $nullable = false; - - while ($rootVar instanceof PhpParser\Node\Expr\MethodCall) { - if ($rootVar->name instanceof PhpParser\Node\Identifier - && $rootVar->name->name === 'nullable' - ) { - $nullable = true; - } - - $firstMethodCall = $rootVar; - $rootVar = $rootVar->var; - } - - if ($rootVar instanceof PhpParser\Node\Expr\Variable - && $rootVar->name === $argName - && $firstMethodCall->name instanceof PhpParser\Node\Identifier - ) { - $firstArg = $firstMethodCall->getArgs()[0]->value ?? null; - $secondArg = $firstMethodCall->getArgs()[1]->value ?? null; - - if ($firstMethodCall->name->name === 'foreignIdFor') { - if ($firstArg instanceof PhpParser\Node\Expr\ClassConstFetch - && $firstArg->class instanceof PhpParser\Node\Name - ) { - $modelClass = $firstArg->class->toCodeString(); - } elseif ($firstArg instanceof PhpParser\Node\Scalar\String_) { - $modelClass = $firstArg->value; - } else { - continue; - } - - $columnName = Str::snake(class_basename($modelClass)).'_id'; - if ($secondArg instanceof PhpParser\Node\Scalar\String_) { - $columnName = $secondArg->value; - } - - $table->setColumn(new SchemaColumn($columnName, 'int', $nullable)); - - continue; - } - - if (! $firstArg instanceof PhpParser\Node\Scalar\String_) { - if ($firstMethodCall->name->name === 'timestamps' - || $firstMethodCall->name->name === 'timestampsTz' - || $firstMethodCall->name->name === 'nullableTimestamps' - || $firstMethodCall->name->name === 'nullableTimestampsTz' - || $firstMethodCall->name->name === 'rememberToken' - ) { - switch (strtolower($firstMethodCall->name->name)) { - case 'droptimestamps': - case 'droptimestampstz': - $table->dropColumn('created_at'); - $table->dropColumn('updated_at'); - break; - - case 'remembertoken': - $table->setColumn(new SchemaColumn('remember_token', 'string', $nullable)); - break; - - case 'dropremembertoken': - $table->dropColumn('remember_token'); - break; - - case 'timestamps': - case 'timestampstz': - case 'nullabletimestamps': - $table->setColumn(new SchemaColumn('created_at', 'string', true)); - $table->setColumn(new SchemaColumn('updated_at', 'string', true)); - break; - } - - continue; - } - - if ($firstMethodCall->name->name === 'softDeletes' - || $firstMethodCall->name->name === 'softDeletesTz' - || $firstMethodCall->name->name === 'dropSoftDeletes' - || $firstMethodCall->name->name === 'dropSoftDeletesTz' - ) { - $columnName = 'deleted_at'; - } else { - continue; - } - } else { - $columnName = $firstArg->value; - } - - $secondArgArray = null; - - if ($secondArg instanceof PhpParser\Node\Expr\Array_) { - $secondArgArray = []; - - foreach ($secondArg->items as $array_item) { - if ($array_item !== null && $array_item->value instanceof PhpParser\Node\Scalar\String_) { - $secondArgArray[] = $array_item->value->value; - } - } - } - - switch (strtolower($firstMethodCall->name->name)) { - case 'biginteger': - case 'increments': - case 'integer': - case 'integerincrements': - case 'mediumincrements': - case 'mediuminteger': - case 'smallincrements': - case 'smallinteger': - case 'tinyincrements': - case 'tinyinteger': - case 'unsignedbiginteger': - case 'unsignedinteger': - case 'unsignedmediuminteger': - case 'unsignedsmallinteger': - case 'unsignedtinyinteger': - case 'bigincrements': - $table->setColumn(new SchemaColumn($columnName, 'int', $nullable)); - break; - - case 'char': - case 'datetimetz': - case 'date': - case 'datetime': - case 'ipaddress': - case 'json': - case 'jsonb': - case 'linestring': - case 'longtext': - case 'macaddress': - case 'mediumtext': - case 'multilinestring': - case 'string': - case 'text': - case 'time': - case 'timestamp': - case 'uuid': - case 'binary': - $table->setColumn(new SchemaColumn($columnName, 'string', $nullable)); - break; - - case 'boolean': - $table->setColumn(new SchemaColumn($columnName, 'bool', $nullable)); - break; - - case 'geometry': - case 'geometrycollection': - case 'multipoint': - case 'multipolygon': - case 'multipolygonz': - case 'point': - case 'polygon': - case 'computed': - $table->setColumn(new SchemaColumn($columnName, 'mixed', $nullable)); - break; - - case 'double': - case 'float': - case 'unsigneddecimal': - case 'decimal': - $table->setColumn(new SchemaColumn($columnName, 'float', $nullable)); - break; - - case 'after': - if ($secondArg instanceof PhpParser\Node\Expr\Closure - && $secondArg->params[0]->var instanceof PhpParser\Node\Expr\Variable - && ! ($secondArg->params[0]->var->name instanceof PhpParser\Node\Expr)) { - $argName = $secondArg->params[0]->var->name; - $this->processColumnUpdates($tableName, $argName, $secondArg->stmts); - } - break; - - case 'dropcolumn': - case 'dropifexists': - case 'dropsoftdeletes': - case 'dropsoftdeletestz': - case 'removecolumn': - case 'drop': - $table->dropColumn($columnName); - break; - - case 'dropforeign': - case 'dropindex': - case 'dropprimary': - case 'dropunique': - case 'foreign': - case 'index': - case 'primary': - case 'renameindex': - case 'spatialIndex': - case 'unique': - case 'dropspatialindex': - break; - - case 'dropmorphs': - $table->dropColumn($columnName.'_type'); - $table->dropColumn($columnName.'_id'); - break; - - case 'enum': - $table->setColumn(new SchemaColumn($columnName, 'enum', $nullable, $secondArgArray)); - break; - - case 'morphs': - $table->setColumn(new SchemaColumn($columnName.'_type', 'string', $nullable)); - $table->setColumn(new SchemaColumn($columnName.'_id', 'int', $nullable)); - break; - - case 'nullablemorphs': - $table->setColumn(new SchemaColumn($columnName.'_type', 'string', true)); - $table->setColumn(new SchemaColumn($columnName.'_id', 'int', true)); - break; - - case 'nullableuuidmorphs': - $table->setColumn(new SchemaColumn($columnName.'_type', 'string', true)); - $table->setColumn(new SchemaColumn($columnName.'_id', 'string', true)); - break; - - case 'rename': - case 'renamecolumn': - if ($secondArg instanceof PhpParser\Node\Scalar\String_) { - $table->renameColumn($columnName, $secondArg->value); - } - break; - - case 'set': - $table->setColumn(new SchemaColumn($columnName, 'set', $nullable, $secondArgArray)); - break; - - case 'softdeletestz': - case 'timestamptz': - case 'timetz': - case 'year': - case 'softdeletes': - $table->setColumn(new SchemaColumn($columnName, 'string', true)); - break; - - case 'uuidmorphs': - $table->setColumn(new SchemaColumn($columnName.'_type', 'string', $nullable)); - $table->setColumn(new SchemaColumn($columnName.'_id', 'string', $nullable)); - break; - - default: - // We know a property exists with a name, we just don't know its type. - $table->setColumn(new SchemaColumn($columnName, 'mixed', $nullable)); - break; - } - } - } - } - } - - private function dropTable(PhpParser\Node\Expr\StaticCall $call): void - { - if (! isset($call->args[0]) - || ! $call->getArgs()[0]->value instanceof PhpParser\Node\Scalar\String_ - ) { - return; - } - - $tableName = $call->getArgs()[0]->value->value; - - unset($this->tables[$tableName]); - } - - private function renameTable(PhpParser\Node\Expr\StaticCall $call): void - { - if (! isset($call->args[0], $call->args[1]) - || ! $call->getArgs()[0]->value instanceof PhpParser\Node\Scalar\String_ - || ! $call->getArgs()[1]->value instanceof PhpParser\Node\Scalar\String_ - ) { - return; - } - - $oldTableName = $call->getArgs()[0]->value->value; - $newTableName = $call->getArgs()[1]->value->value; - - if (! isset($this->tables[$oldTableName])) { - return; - } - - $table = $this->tables[$oldTableName]; - - unset($this->tables[$oldTableName]); - - $table->name = $newTableName; - - $this->tables[$newTableName] = $table; - } -} diff --git a/php-packages/phpstan/src/Properties/SchemaColumn.php b/php-packages/phpstan/src/Properties/SchemaColumn.php deleted file mode 100644 index 8cba2c2cd..000000000 --- a/php-packages/phpstan/src/Properties/SchemaColumn.php +++ /dev/null @@ -1,52 +0,0 @@ - */ - public $options; - - /** - * @param string $name - * @param string $readableType - * @param bool $nullable - * @param string[]|null $options - */ - public function __construct( - string $name, - string $readableType, - bool $nullable = false, - ?array $options = null - ) { - $this->name = $name; - $this->readableType = $readableType; - $this->writeableType = $readableType; - $this->nullable = $nullable; - $this->options = $options; - } -} diff --git a/php-packages/phpstan/src/Properties/SchemaTable.php b/php-packages/phpstan/src/Properties/SchemaTable.php deleted file mode 100644 index 703338189..000000000 --- a/php-packages/phpstan/src/Properties/SchemaTable.php +++ /dev/null @@ -1,54 +0,0 @@ -name = $name; - } - - public function setColumn(SchemaColumn $column): void - { - $this->columns[$column->name] = $column; - } - - public function renameColumn(string $oldName, string $newName): void - { - if (! isset($this->columns[$oldName])) { - return; - } - - $oldColumn = $this->columns[$oldName]; - - unset($this->columns[$oldName]); - - $oldColumn->name = $newName; - - $this->columns[$newName] = $oldColumn; - } - - public function dropColumn(string $columnName): void - { - unset($this->columns[$columnName]); - } -} diff --git a/php-packages/phpstan/src/Reflection/AnnotationScopeMethodParameterReflection.php b/php-packages/phpstan/src/Reflection/AnnotationScopeMethodParameterReflection.php deleted file mode 100644 index 6c1154593..000000000 --- a/php-packages/phpstan/src/Reflection/AnnotationScopeMethodParameterReflection.php +++ /dev/null @@ -1,77 +0,0 @@ -name = $name; - $this->type = $type; - $this->passedByReference = $passedByReference; - $this->isOptional = $isOptional; - $this->isVariadic = $isVariadic; - $this->defaultValue = $defaultValue; - } - - public function getName(): string - { - return $this->name; - } - - public function isOptional(): bool - { - return $this->isOptional; - } - - public function getType(): Type - { - return $this->type; - } - - public function passedByReference(): PassedByReference - { - return $this->passedByReference; - } - - public function isVariadic(): bool - { - return $this->isVariadic; - } - - public function getDefaultValue(): ?Type - { - return $this->defaultValue; - } -} diff --git a/php-packages/phpstan/src/Reflection/AnnotationScopeMethodReflection.php b/php-packages/phpstan/src/Reflection/AnnotationScopeMethodReflection.php deleted file mode 100644 index 604c7f4a2..000000000 --- a/php-packages/phpstan/src/Reflection/AnnotationScopeMethodReflection.php +++ /dev/null @@ -1,140 +0,0 @@ -name = $name; - $this->declaringClass = $declaringClass; - $this->returnType = $returnType; - $this->parameters = $parameters; - $this->isStatic = $isStatic; - $this->isVariadic = $isVariadic; - } - - public function getDeclaringClass(): ClassReflection - { - return $this->declaringClass; - } - - public function getPrototype(): ClassMemberReflection - { - return $this; - } - - public function isStatic(): bool - { - return $this->isStatic; - } - - public function isPrivate(): bool - { - return false; - } - - public function isPublic(): bool - { - return true; - } - - public function getName(): string - { - return $this->name; - } - - /** - * @return ParametersAcceptor[] - */ - public function getVariants(): array - { - if ($this->variants === null) { - $this->variants = [new FunctionVariant(TemplateTypeMap::createEmpty(), null, $this->parameters, $this->isVariadic, $this->returnType)]; - } - - return $this->variants; - } - - public function isDeprecated(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function getDeprecatedDescription(): ?string - { - return null; - } - - public function isFinal(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function isInternal(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function getThrowType(): ?Type - { - return null; - } - - public function hasSideEffects(): TrinaryLogic - { - return TrinaryLogic::createMaybe(); - } - - public function getDocComment(): ?string - { - return null; - } -} diff --git a/php-packages/phpstan/src/Reflection/DynamicWhereParameterReflection.php b/php-packages/phpstan/src/Reflection/DynamicWhereParameterReflection.php deleted file mode 100644 index f3c77e2bb..000000000 --- a/php-packages/phpstan/src/Reflection/DynamicWhereParameterReflection.php +++ /dev/null @@ -1,50 +0,0 @@ -methodName = $methodName; - $this->classReflection = $classReflection; - $this->originalMethodReflection = $originalMethodReflection; - $this->parameters = $parameters; - $this->returnType = $returnType ?? new ObjectType(Builder::class); - $this->isVariadic = $isVariadic; - } - - public function getDeclaringClass(): ClassReflection - { - return $this->classReflection; - } - - public function isStatic(): bool - { - return true; - } - - public function isPrivate(): bool - { - return false; - } - - public function isPublic(): bool - { - return true; - } - - public function getName(): string - { - return $this->methodName; - } - - public function getPrototype(): ClassMemberReflection - { - return $this; - } - - /** - * {@inheritdoc} - */ - public function getVariants(): array - { - return [ - new FunctionVariant( - TemplateTypeMap::createEmpty(), - null, - $this->parameters, - $this->isVariadic, - $this->returnType - ), - ]; - } - - public function getDocComment(): ?string - { - return null; - } - - public function isDeprecated(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function getDeprecatedDescription(): ?string - { - return null; - } - - public function isFinal(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function isInternal(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function getThrowType(): ?Type - { - return null; - } - - public function hasSideEffects(): TrinaryLogic - { - return TrinaryLogic::createMaybe(); - } - - /** - * @return MethodReflection - */ - public function getOriginalMethodReflection(): MethodReflection - { - return $this->originalMethodReflection; - } -} diff --git a/php-packages/phpstan/src/Reflection/ModelScopeMethodReflection.php b/php-packages/phpstan/src/Reflection/ModelScopeMethodReflection.php deleted file mode 100644 index 45ff9e2f9..000000000 --- a/php-packages/phpstan/src/Reflection/ModelScopeMethodReflection.php +++ /dev/null @@ -1,127 +0,0 @@ -methodName = $methodName; - $this->classReflection = $classReflection; - $this->relation = $relation; - } - - public function getDeclaringClass(): ClassReflection - { - return $this->classReflection; - } - - public function isStatic(): bool - { - return false; - } - - public function isPrivate(): bool - { - return false; - } - - public function isPublic(): bool - { - return true; - } - - public function getName(): string - { - return $this->methodName; - } - - public function getPrototype(): ClassMemberReflection - { - return $this; - } - - /** - * {@inheritdoc} - */ - public function getVariants(): array - { - return [ - new FunctionVariant( - TemplateTypeMap::createEmpty(), - null, - [], - false, - new ObjectType($this->relation->getName()) - ), - ]; - } - - public function getDocComment(): ?string - { - return null; - } - - public function isDeprecated(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function getDeprecatedDescription(): ?string - { - return null; - } - - public function isFinal(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function isInternal(): TrinaryLogic - { - return TrinaryLogic::createNo(); - } - - public function getThrowType(): ?Type - { - return null; - } - - public function hasSideEffects(): TrinaryLogic - { - return TrinaryLogic::createMaybe(); - } -} diff --git a/php-packages/phpstan/src/Reflection/ReflectionHelper.php b/php-packages/phpstan/src/Reflection/ReflectionHelper.php deleted file mode 100644 index a593540a3..000000000 --- a/php-packages/phpstan/src/Reflection/ReflectionHelper.php +++ /dev/null @@ -1,35 +0,0 @@ -getPropertyTags())) { - return true; - } - - foreach ($classReflection->getAncestors() as $ancestor) { - if (array_key_exists($propertyName, $ancestor->getPropertyTags())) { - return true; - } - } - - return false; - } -} diff --git a/php-packages/phpstan/src/Reflection/StaticMethodReflection.php b/php-packages/phpstan/src/Reflection/StaticMethodReflection.php deleted file mode 100644 index dc37f8c88..000000000 --- a/php-packages/phpstan/src/Reflection/StaticMethodReflection.php +++ /dev/null @@ -1,99 +0,0 @@ -methodReflection = $methodReflection; - } - - public function getDeclaringClass(): ClassReflection - { - return $this->methodReflection->getDeclaringClass(); - } - - public function isStatic(): bool - { - return true; - } - - public function isPrivate(): bool - { - return $this->methodReflection->isPrivate(); - } - - public function isPublic(): bool - { - return $this->methodReflection->isPublic(); - } - - public function getDocComment(): ?string - { - return $this->methodReflection->getDocComment(); - } - - public function getName(): string - { - return $this->methodReflection->getName(); - } - - public function getPrototype(): ClassMemberReflection - { - return $this->methodReflection->getPrototype(); - } - - public function getVariants(): array - { - return $this->methodReflection->getVariants(); - } - - public function isDeprecated(): TrinaryLogic - { - return $this->methodReflection->isDeprecated(); - } - - public function getDeprecatedDescription(): ?string - { - return $this->methodReflection->getDeprecatedDescription(); - } - - public function isFinal(): TrinaryLogic - { - return $this->methodReflection->isFinal(); - } - - public function isInternal(): TrinaryLogic - { - return $this->methodReflection->isInternal(); - } - - public function getThrowType(): ?Type - { - return $this->methodReflection->getThrowType(); - } - - public function hasSideEffects(): TrinaryLogic - { - return $this->methodReflection->hasSideEffects(); - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/BuilderModelFindExtension.php b/php-packages/phpstan/src/ReturnTypes/BuilderModelFindExtension.php deleted file mode 100644 index 6caf7eb56..000000000 --- a/php-packages/phpstan/src/ReturnTypes/BuilderModelFindExtension.php +++ /dev/null @@ -1,119 +0,0 @@ -builderHelper = $builderHelper; - $this->reflectionProvider = $reflectionProvider; - } - - /** - * {@inheritdoc} - */ - public function getClass(): string - { - return Builder::class; - } - - /** - * {@inheritdoc} - */ - public function isMethodSupported(MethodReflection $methodReflection): bool - { - $methodName = $methodReflection->getName(); - - if (! Str::startsWith($methodName, 'find')) { - return false; - } - - $model = $methodReflection->getDeclaringClass()->getActiveTemplateTypeMap()->getType('TModelClass'); - - if ($model === null || ! $model instanceof ObjectType) { - return false; - } - - if (! $this->reflectionProvider->getClass(Builder::class)->hasNativeMethod($methodName) && - ! $this->reflectionProvider->getClass(QueryBuilder::class)->hasNativeMethod($methodName)) { - return false; - } - - return true; - } - - /** - * {@inheritdoc} - */ - public function getTypeFromMethodCall( - MethodReflection $methodReflection, - MethodCall $methodCall, - Scope $scope - ): Type { - /** @var ObjectType $model */ - $model = $methodReflection->getDeclaringClass()->getActiveTemplateTypeMap()->getType('TModelClass'); - $returnType = $methodReflection->getVariants()[0]->getReturnType(); - $argType = $scope->getType($methodCall->getArgs()[0]->value); - - $returnType = ModelTypeHelper::replaceStaticTypeWithModel($returnType, $model->getClassName()); - - if ($argType->isIterable()->yes()) { - if (in_array(Collection::class, $returnType->getReferencedClasses(), true)) { - $collectionClassName = $this->builderHelper->determineCollectionClassName($model->getClassName()); - - return new GenericObjectType($collectionClassName, [$model]); - } - - return TypeCombinator::remove($returnType, $model); - } - - if ($argType instanceof MixedType) { - return $returnType; - } - - return TypeCombinator::remove( - TypeCombinator::remove( - $returnType, - new ArrayType(new MixedType(), $model) - ), - new ObjectType(Collection::class) - ); - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/CollectionFilterDynamicReturnTypeExtension.php b/php-packages/phpstan/src/ReturnTypes/CollectionFilterDynamicReturnTypeExtension.php deleted file mode 100644 index b017ef6e6..000000000 --- a/php-packages/phpstan/src/ReturnTypes/CollectionFilterDynamicReturnTypeExtension.php +++ /dev/null @@ -1,119 +0,0 @@ -getName() === 'filter'; - } - - public function getTypeFromMethodCall( - MethodReflection $methodReflection, - MethodCall $methodCall, - Scope $scope - ): Type { - $calledOnType = $scope->getType($methodCall->var); - - if (! $calledOnType instanceof \PHPStan\Type\Generic\GenericObjectType) { - return ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType(); - } - - $keyType = $methodReflection->getDeclaringClass()->getActiveTemplateTypeMap()->getType('TKey'); - $valueType = $methodReflection->getDeclaringClass()->getActiveTemplateTypeMap()->getType('TValue'); - - if ($keyType === null || $valueType === null) { - return ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType(); - } - - if (count($methodCall->getArgs()) < 1) { - $falseyTypes = $this->getFalseyTypes(); - - $nonFalseyTypes = TypeCombinator::remove($valueType, $falseyTypes); - - if ((new ObjectType(Collection::class))->isSuperTypeOf($calledOnType)->yes()) { - return new GenericObjectType($calledOnType->getClassName(), [$nonFalseyTypes]); - } - - return new GenericObjectType($calledOnType->getClassName(), [$keyType, $nonFalseyTypes]); - } - - $callbackArg = $methodCall->getArgs()[0]->value; - - $var = null; - $expr = null; - - if ($callbackArg instanceof Closure && count($callbackArg->stmts) === 1 && count($callbackArg->params) > 0) { - $statement = $callbackArg->stmts[0]; - if ($statement instanceof Return_ && $statement->expr !== null) { - $var = $callbackArg->params[0]->var; - $expr = $statement->expr; - } - } elseif ($callbackArg instanceof ArrowFunction && count($callbackArg->params) > 0) { - $var = $callbackArg->params[0]->var; - $expr = $callbackArg->expr; - } - - if ($var !== null && $expr !== null) { - if (! $var instanceof Variable || ! is_string($var->name)) { - throw new \PHPStan\ShouldNotHappenException(); - } - - $itemVariableName = $var->name; - - // @phpstan-ignore-next-line - $scope = $scope->assignVariable($itemVariableName, $valueType); - $scope = $scope->filterByTruthyValue($expr); - $valueType = $scope->getVariableType($itemVariableName); - } - - if ((new ObjectType(Collection::class))->isSuperTypeOf($calledOnType)->yes()) { - return new GenericObjectType($calledOnType->getClassName(), [$valueType]); - } - - return new GenericObjectType($calledOnType->getClassName(), [$keyType, $valueType]); - } - - private function getFalseyTypes(): UnionType - { - return new UnionType([new NullType(), new ConstantBooleanType(false), new ConstantIntegerType(0), new ConstantFloatType(0.0), new ConstantStringType(''), new ConstantStringType('0'), new ConstantArrayType([], [])]); - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/CollectionMakeDynamicStaticMethodReturnTypeExtension.php b/php-packages/phpstan/src/ReturnTypes/CollectionMakeDynamicStaticMethodReturnTypeExtension.php deleted file mode 100644 index 2cca6a0d9..000000000 --- a/php-packages/phpstan/src/ReturnTypes/CollectionMakeDynamicStaticMethodReturnTypeExtension.php +++ /dev/null @@ -1,58 +0,0 @@ -collectionHelper = $collectionHelper; - } - - public function getClass(): string - { - return Collection::class; - } - - public function isStaticMethodSupported(MethodReflection $methodReflection): bool - { - return $methodReflection->getName() === 'make'; - } - - public function getTypeFromStaticMethodCall( - MethodReflection $methodReflection, - StaticCall $methodCall, - Scope $scope - ): Type { - if (count($methodCall->getArgs()) < 1) { - return ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType(); - } - - $valueType = $scope->getType($methodCall->getArgs()[0]->value); - - return $this->collectionHelper->determineGenericCollectionTypeFromType($valueType); - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/ContainerArrayAccessDynamicMethodReturnTypeExtension.php b/php-packages/phpstan/src/ReturnTypes/ContainerArrayAccessDynamicMethodReturnTypeExtension.php deleted file mode 100644 index 9121ac6f5..000000000 --- a/php-packages/phpstan/src/ReturnTypes/ContainerArrayAccessDynamicMethodReturnTypeExtension.php +++ /dev/null @@ -1,80 +0,0 @@ -className = $className; - } - - public function getClass(): string - { - return $this->className; - } - - public function isMethodSupported(MethodReflection $methodReflection): bool - { - return $methodReflection->getName() === 'offsetGet'; - } - - public function getTypeFromMethodCall( - MethodReflection $methodReflection, - MethodCall $methodCall, - Scope $scope - ): Type { - $args = $methodCall->getArgs(); - - if (count($args) === 0) { - return ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType(); - } - - $argType = $scope->getType($args[0]->value); - - if (! $argType instanceof ConstantStringType) { - return ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType(); - } - - $resolvedValue = $this->resolve($argType->getValue()); - - if ($resolvedValue === null) { - return new ErrorType(); - } - - if (is_object($resolvedValue)) { - $class = get_class($resolvedValue); - - return new ObjectType($class); - } - - return $scope->getTypeFromValue($resolvedValue); - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/EloquentBuilderExtension.php b/php-packages/phpstan/src/ReturnTypes/EloquentBuilderExtension.php deleted file mode 100644 index 902a5ceb2..000000000 --- a/php-packages/phpstan/src/ReturnTypes/EloquentBuilderExtension.php +++ /dev/null @@ -1,93 +0,0 @@ -builderHelper = $builderHelper; - $this->reflectionProvider = $reflectionProvider; - } - - public function getClass(): string - { - return EloquentBuilder::class; - } - - public function isMethodSupported(MethodReflection $methodReflection): bool - { - $builderReflection = $this->reflectionProvider->getClass(EloquentBuilder::class); - - // Don't handle dynamic wheres - if (Str::startsWith($methodReflection->getName(), 'where') && - ! $builderReflection->hasNativeMethod($methodReflection->getName()) - ) { - return false; - } - - if (Str::startsWith($methodReflection->getName(), 'find') && - $builderReflection->hasNativeMethod($methodReflection->getName()) - ) { - return false; - } - - $templateTypeMap = $methodReflection->getDeclaringClass()->getActiveTemplateTypeMap(); - - if (! $templateTypeMap->getType('TModelClass') instanceof ObjectType) { - return false; - } - - return $builderReflection->hasNativeMethod($methodReflection->getName()); - } - - public function getTypeFromMethodCall( - MethodReflection $methodReflection, - MethodCall $methodCall, - Scope $scope - ): Type { - $returnType = ParametersAcceptorSelector::selectFromArgs($scope, $methodCall->getArgs(), $methodReflection->getVariants())->getReturnType(); - $templateTypeMap = $methodReflection->getDeclaringClass()->getActiveTemplateTypeMap(); - - /** @var Type|ObjectType|TemplateMixedType $modelType */ - $modelType = $templateTypeMap->getType('TModelClass'); - - if ($modelType instanceof ObjectType && in_array(Collection::class, $returnType->getReferencedClasses(), true)) { - $collectionClassName = $this->builderHelper->determineCollectionClassName($modelType->getClassName()); - - return new GenericObjectType($collectionClassName, [$modelType]); - } - - return $returnType; - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/Helpers/AppExtension.php b/php-packages/phpstan/src/ReturnTypes/Helpers/AppExtension.php deleted file mode 100644 index 89b659f2e..000000000 --- a/php-packages/phpstan/src/ReturnTypes/Helpers/AppExtension.php +++ /dev/null @@ -1,72 +0,0 @@ -getName() === 'app' || $functionReflection->getName() === 'resolve'; - } - - public function getTypeFromFunctionCall( - FunctionReflection $functionReflection, - FuncCall $functionCall, - Scope $scope - ): Type { - if (count($functionCall->getArgs()) === 0) { - return new ObjectType(Application::class); - } - - /** @var Expr $expr */ - $expr = $functionCall->getArgs()[0]->value; - - if ($expr instanceof String_) { - try { - /** @var object|null $resolved */ - $resolved = $this->resolve($expr->value); - - if ($resolved === null) { - return new ErrorType(); - } - - return new ObjectType(get_class($resolved)); - } catch (Throwable $exception) { - return new ErrorType(); - } - } - - if ($expr instanceof ClassConstFetch && $expr->class instanceof FullyQualified) { - return new ObjectType($expr->class->toString()); - } - - return new NeverType(); - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/Helpers/CollectExtension.php b/php-packages/phpstan/src/ReturnTypes/Helpers/CollectExtension.php deleted file mode 100644 index 499b39487..000000000 --- a/php-packages/phpstan/src/ReturnTypes/Helpers/CollectExtension.php +++ /dev/null @@ -1,52 +0,0 @@ -collectionHelper = $collectionHelper; - } - - public function isFunctionSupported(FunctionReflection $functionReflection): bool - { - return $functionReflection->getName() === 'collect'; - } - - public function getTypeFromFunctionCall( - FunctionReflection $functionReflection, - FuncCall $functionCall, - Scope $scope - ): Type { - if (count($functionCall->getArgs()) < 1) { - return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); - } - - $valueType = $scope->getType($functionCall->getArgs()[0]->value); - - return $this->collectionHelper->determineGenericCollectionTypeFromType($valueType); - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/Helpers/TapExtension.php b/php-packages/phpstan/src/ReturnTypes/Helpers/TapExtension.php deleted file mode 100644 index ad6e59e99..000000000 --- a/php-packages/phpstan/src/ReturnTypes/Helpers/TapExtension.php +++ /dev/null @@ -1,56 +0,0 @@ -getName() === 'tap'; - } - - /** - * {@inheritdoc} - */ - public function getTypeFromFunctionCall( - FunctionReflection $functionReflection, - FuncCall $functionCall, - Scope $scope - ): Type { - if (count($functionCall->getArgs()) === 1) { - $type = $scope->getType($functionCall->getArgs()[0]->value); - - return new GenericObjectType(HigherOrderTapProxy::class, [ - $type instanceof ThisType ? $type->getStaticObjectType() : $type, - ]); - } - - if (count($functionCall->getArgs()) === 2) { - return $scope->getType($functionCall->getArgs()[0]->value); - } - - return new NeverType(); - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/Helpers/TransExtension.php b/php-packages/phpstan/src/ReturnTypes/Helpers/TransExtension.php deleted file mode 100644 index 66bde450b..000000000 --- a/php-packages/phpstan/src/ReturnTypes/Helpers/TransExtension.php +++ /dev/null @@ -1,47 +0,0 @@ -getName() === 'trans'; - } - - /** - * {@inheritdoc} - */ - public function getTypeFromFunctionCall( - FunctionReflection $functionReflection, - FuncCall $functionCall, - Scope $scope - ): Type { - // No path provided, so it returns a Translator instance - if (count($functionCall->getArgs()) === 0) { - return new ObjectType(\Illuminate\Contracts\Translation\Translator::class); - } - - return new MixedType(); - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/Helpers/ValidatorExtension.php b/php-packages/phpstan/src/ReturnTypes/Helpers/ValidatorExtension.php deleted file mode 100644 index 71e7de08f..000000000 --- a/php-packages/phpstan/src/ReturnTypes/Helpers/ValidatorExtension.php +++ /dev/null @@ -1,47 +0,0 @@ -getName() === 'validator'; - } - - public function getTypeFromFunctionCall( - FunctionReflection $functionReflection, - FuncCall $functionCall, - Scope $scope - ): Type { - if (count($functionCall->getArgs()) === 0) { - return new ObjectType(\Illuminate\Contracts\Validation\Factory::class); - } - - return new IntersectionType([ - new ObjectType(\Illuminate\Validation\Validator::class), - new ObjectType(\Illuminate\Contracts\Validation\Validator::class), - ]); - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/Helpers/ValueExtension.php b/php-packages/phpstan/src/ReturnTypes/Helpers/ValueExtension.php deleted file mode 100644 index f4e8e630b..000000000 --- a/php-packages/phpstan/src/ReturnTypes/Helpers/ValueExtension.php +++ /dev/null @@ -1,63 +0,0 @@ -getName() === 'value'; - } - - /** - * {@inheritdoc} - */ - public function getTypeFromFunctionCall( - FunctionReflection $functionReflection, - FuncCall $functionCall, - Scope $scope - ): Type { - if (count($functionCall->getArgs()) === 0) { - return new NeverType(); - } - - $arg = $functionCall->getArgs()[0]->value; - if ($arg instanceof Closure) { - $callbackType = $scope->getType($arg); - $callbackReturnType = ParametersAcceptorSelector::selectFromArgs( - $scope, - $functionCall->getArgs(), - $callbackType->getCallableParametersAcceptors($scope) - )->getReturnType(); - - return $callbackReturnType; - } - - return $scope->getType($arg); - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/HigherOrderTapProxyExtension.php b/php-packages/phpstan/src/ReturnTypes/HigherOrderTapProxyExtension.php deleted file mode 100644 index a60e7a54e..000000000 --- a/php-packages/phpstan/src/ReturnTypes/HigherOrderTapProxyExtension.php +++ /dev/null @@ -1,63 +0,0 @@ -getType($methodCall->var); - if ($type instanceof GenericObjectType) { - $types = $type->getTypes(); - if (count($types) === 1 && $types[0] instanceof ObjectType) { - return $types[0]; - } - } - - return new MixedType(); - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/ModelExtension.php b/php-packages/phpstan/src/ReturnTypes/ModelExtension.php deleted file mode 100644 index 4e1b2dba4..000000000 --- a/php-packages/phpstan/src/ReturnTypes/ModelExtension.php +++ /dev/null @@ -1,111 +0,0 @@ -builderHelper = $builderHelper; - } - - /** - * {@inheritdoc} - */ - public function getClass(): string - { - return Model::class; - } - - /** - * {@inheritdoc} - */ - public function isStaticMethodSupported(MethodReflection $methodReflection): bool - { - $name = $methodReflection->getName(); - if ($name === '__construct') { - return false; - } - - if (in_array($name, ['get', 'hydrate', 'fromQuery'], true)) { - return true; - } - - if (! $methodReflection->getDeclaringClass()->hasNativeMethod($name)) { - return false; - } - - $method = $methodReflection->getDeclaringClass()->getNativeMethod($methodReflection->getName()); - - $returnType = ParametersAcceptorSelector::selectSingle($method->getVariants())->getReturnType(); - - return (count(array_intersect([EloquentBuilder::class, QueryBuilder::class, Collection::class], $returnType->getReferencedClasses()))) > 0; - } - - /** - * {@inheritdoc} - */ - public function getTypeFromStaticMethodCall( - MethodReflection $methodReflection, - StaticCall $methodCall, - Scope $scope - ): Type { - $method = $methodReflection->getDeclaringClass() - ->getMethod($methodReflection->getName(), $scope); - - $returnType = ParametersAcceptorSelector::selectSingle($method->getVariants())->getReturnType(); - - if ((count(array_intersect([EloquentBuilder::class, QueryBuilder::class], $returnType->getReferencedClasses())) > 0) - && $methodCall->class instanceof \PhpParser\Node\Name - ) { - $returnType = new GenericObjectType( - $this->builderHelper->determineBuilderName($scope->resolveName($methodCall->class)), - [new ObjectType($scope->resolveName($methodCall->class))] - ); - } - - if ( - $methodCall->class instanceof \PhpParser\Node\Name - && in_array(Collection::class, $returnType->getReferencedClasses(), true) - && in_array($methodReflection->getName(), ['get', 'hydrate', 'fromQuery', 'all', 'findMany'], true) - ) { - $collectionClassName = $this->builderHelper->determineCollectionClassName($scope->resolveName($methodCall->class)); - - return new GenericObjectType($collectionClassName, [new ObjectType($scope->resolveName($methodCall->class))]); - } - - return $returnType; - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/ModelFactoryDynamicStaticMethodReturnTypeExtension.php b/php-packages/phpstan/src/ReturnTypes/ModelFactoryDynamicStaticMethodReturnTypeExtension.php deleted file mode 100644 index 910731ff1..000000000 --- a/php-packages/phpstan/src/ReturnTypes/ModelFactoryDynamicStaticMethodReturnTypeExtension.php +++ /dev/null @@ -1,64 +0,0 @@ -getName() !== 'factory') { - return false; - } - - // Class only available on Laravel 8 - if (! class_exists('\Illuminate\Database\Eloquent\Factories\Factory')) { - return false; - } - - return true; - } - - public function getTypeFromStaticMethodCall( - MethodReflection $methodReflection, - StaticCall $methodCall, - Scope $scope - ): Type { - $class = $methodCall->class; - - if (! $class instanceof Name) { - return new ErrorType(); - } - - $modelName = basename(str_replace('\\', '/', $class->toCodeString())); - - if (! class_exists('Database\\Factories\\'.$modelName.'Factory')) { - return new ErrorType(); - } - - return new ObjectType('Database\\Factories\\'.$modelName.'Factory'); - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/ModelFindExtension.php b/php-packages/phpstan/src/ReturnTypes/ModelFindExtension.php deleted file mode 100644 index 4a1db41ab..000000000 --- a/php-packages/phpstan/src/ReturnTypes/ModelFindExtension.php +++ /dev/null @@ -1,115 +0,0 @@ -builderHelper = $builderHelper; - $this->reflectionProvider = $reflectionProvider; - } - - /** - * {@inheritdoc} - */ - public function getClass(): string - { - return Model::class; - } - - /** - * {@inheritdoc} - */ - public function isStaticMethodSupported(MethodReflection $methodReflection): bool - { - $methodName = $methodReflection->getName(); - - if (! Str::startsWith($methodName, 'find')) { - return false; - } - - if (! $this->reflectionProvider->getClass(Builder::class)->hasNativeMethod($methodName) && - ! $this->reflectionProvider->getClass(QueryBuilder::class)->hasNativeMethod($methodName)) { - return false; - } - - return true; - } - - /** - * {@inheritdoc} - */ - public function getTypeFromStaticMethodCall( - MethodReflection $methodReflection, - StaticCall $methodCall, - Scope $scope - ): Type { - if (count($methodCall->getArgs()) < 1) { - return new ErrorType(); - } - - $modelName = $methodReflection->getDeclaringClass()->getName(); - $returnType = $methodReflection->getVariants()[0]->getReturnType(); - $argType = $scope->getType($methodCall->getArgs()[0]->value); - - if ($argType->isIterable()->yes()) { - if (in_array(Collection::class, $returnType->getReferencedClasses(), true)) { - $collectionClassName = $this->builderHelper->determineCollectionClassName($modelName); - - return new GenericObjectType($collectionClassName, [new ObjectType($modelName)]); - } - - return TypeCombinator::remove($returnType, new ObjectType($modelName)); - } - - if ($argType instanceof MixedType) { - return $returnType; - } - - return TypeCombinator::remove( - TypeCombinator::remove( - $returnType, - new ArrayType(new MixedType(), new ObjectType($modelName)) - ), - new ObjectType(Collection::class) - ); - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/RelationCollectionExtension.php b/php-packages/phpstan/src/ReturnTypes/RelationCollectionExtension.php deleted file mode 100644 index c9caa3faf..000000000 --- a/php-packages/phpstan/src/ReturnTypes/RelationCollectionExtension.php +++ /dev/null @@ -1,93 +0,0 @@ -builderHelper = $builderHelper; - } - - /** - * {@inheritdoc} - */ - public function getClass(): string - { - return Relation::class; - } - - /** - * {@inheritdoc} - */ - public function isMethodSupported(MethodReflection $methodReflection): bool - { - if (Str::startsWith($methodReflection->getName(), 'find')) { - return false; - } - - $modelType = $methodReflection->getDeclaringClass()->getActiveTemplateTypeMap()->getType('TRelatedModel'); - - if (! $modelType instanceof ObjectType) { - return false; - } - - $returnType = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType(); - - if (! in_array(Collection::class, $returnType->getReferencedClasses(), true)) { - return false; - } - - return $methodReflection->getDeclaringClass()->hasNativeMethod($methodReflection->getName()); - } - - /** - * {@inheritdoc} - */ - public function getTypeFromMethodCall( - MethodReflection $methodReflection, - MethodCall $methodCall, - Scope $scope - ): Type { - /** @var ObjectType $modelType */ - $modelType = $methodReflection->getDeclaringClass()->getActiveTemplateTypeMap()->getType('TRelatedModel'); - - $returnType = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType(); - - if (in_array(Collection::class, $returnType->getReferencedClasses(), true)) { - $collectionClassName = $this->builderHelper->determineCollectionClassName($modelType->getClassname()); - - return new GenericObjectType($collectionClassName, [$modelType]); - } - - return $returnType; - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/RelationFindExtension.php b/php-packages/phpstan/src/ReturnTypes/RelationFindExtension.php deleted file mode 100644 index 9ff1ed7ea..000000000 --- a/php-packages/phpstan/src/ReturnTypes/RelationFindExtension.php +++ /dev/null @@ -1,106 +0,0 @@ -builderHelper = $builderHelper; - $this->reflectionProvider = $reflectionProvider; - } - - /** - * {@inheritdoc} - */ - public function getClass(): string - { - return Relation::class; - } - - /** - * {@inheritdoc} - */ - public function isMethodSupported(MethodReflection $methodReflection): bool - { - if (! Str::startsWith($methodReflection->getName(), 'find')) { - return false; - } - - $modelType = $methodReflection->getDeclaringClass()->getActiveTemplateTypeMap()->getType('TRelatedModel'); - - if (! $modelType instanceof ObjectType) { - return false; - } - - return $methodReflection->getDeclaringClass()->hasNativeMethod($methodReflection->getName()) || - $this->reflectionProvider->getClass(Builder::class)->hasNativeMethod($methodReflection->getName()) || - $this->reflectionProvider->getClass(QueryBuilder::class)->hasNativeMethod($methodReflection->getName()); - } - - /** - * {@inheritdoc} - */ - public function getTypeFromMethodCall( - MethodReflection $methodReflection, - MethodCall $methodCall, - Scope $scope - ): Type { - /** @var ObjectType $modelType */ - $modelType = $methodReflection->getDeclaringClass()->getActiveTemplateTypeMap()->getType('TRelatedModel'); - - $argType = $scope->getType($methodCall->getArgs()[0]->value); - - $returnType = $methodReflection->getVariants()[0]->getReturnType(); - - if (in_array(Collection::class, $returnType->getReferencedClasses(), true)) { - if ($argType->isIterable()->yes()) { - $collectionClassName = $this->builderHelper->determineCollectionClassName($modelType->getClassname()); - - return new GenericObjectType($collectionClassName, [$modelType]); - } - - $returnType = TypeCombinator::remove($returnType, new ObjectType(Collection::class)); - - return TypeCombinator::remove($returnType, new ArrayType(new MixedType(), $modelType)); - } - - return $returnType; - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/RequestExtension.php b/php-packages/phpstan/src/ReturnTypes/RequestExtension.php deleted file mode 100644 index 155b20a7b..000000000 --- a/php-packages/phpstan/src/ReturnTypes/RequestExtension.php +++ /dev/null @@ -1,68 +0,0 @@ -getName() === 'file'; - } - - /** - * {@inheritdoc} - */ - public function getTypeFromMethodCall( - MethodReflection $methodReflection, - MethodCall $methodCall, - Scope $scope - ): Type { - $uploadedFileType = new ObjectType(UploadedFile::class); - $uploadedFileArrayType = new ArrayType(new IntegerType(), $uploadedFileType); - - if (count($methodCall->getArgs()) === 0) { - return new ArrayType(new IntegerType(), $uploadedFileType); - } - - if (count($methodCall->getArgs()) === 1) { - return TypeCombinator::union($uploadedFileArrayType, TypeCombinator::addNull($uploadedFileType)); - } - - return TypeCombinator::union(TypeCombinator::union($uploadedFileArrayType, $uploadedFileType), $scope->getType($methodCall->getArgs()[1]->value)); - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/StorageDynamicStaticMethodReturnTypeExtension.php b/php-packages/phpstan/src/ReturnTypes/StorageDynamicStaticMethodReturnTypeExtension.php deleted file mode 100644 index 8ed27c8d3..000000000 --- a/php-packages/phpstan/src/ReturnTypes/StorageDynamicStaticMethodReturnTypeExtension.php +++ /dev/null @@ -1,45 +0,0 @@ -getName() === 'disk'; - } - - public function getTypeFromStaticMethodCall( - MethodReflection $methodReflection, - StaticCall $methodCall, - Scope $scope - ): Type { - return new ObjectType(FilesystemAdapter::class); - } -} diff --git a/php-packages/phpstan/src/ReturnTypes/TestCaseExtension.php b/php-packages/phpstan/src/ReturnTypes/TestCaseExtension.php deleted file mode 100644 index c80ad7898..000000000 --- a/php-packages/phpstan/src/ReturnTypes/TestCaseExtension.php +++ /dev/null @@ -1,60 +0,0 @@ -getName(), [ - 'mock', - 'partialMock', - 'spy', - ], true); - } - - public function getTypeFromMethodCall( - MethodReflection $methodReflection, - MethodCall $methodCall, - Scope $scope - ): Type { - $defaultReturnType = new ObjectType('Mockery\\MockInterface'); - - $classType = $scope->getType($methodCall->getArgs()[0]->value); - - if (! $classType instanceof ConstantStringType) { - return $defaultReturnType; - } - - $objectType = new ObjectType($classType->getValue()); - - return TypeCombinator::intersect($defaultReturnType, $objectType); - } -} diff --git a/php-packages/phpstan/src/Support/CollectionHelper.php b/php-packages/phpstan/src/Support/CollectionHelper.php deleted file mode 100644 index 1b6061ca5..000000000 --- a/php-packages/phpstan/src/Support/CollectionHelper.php +++ /dev/null @@ -1,106 +0,0 @@ -isSuperTypeOf($type)->yes()) { - return $this->getTypeFromEloquentCollection($type); - } - - if ( - (new ObjectType(Traversable::class))->isSuperTypeOf($type)->yes() || - (new ObjectType(IteratorAggregate::class))->isSuperTypeOf($type)->yes() || - (new ObjectType(Iterator::class))->isSuperTypeOf($type)->yes() - ) { - return $this->getTypeFromIterator($type); - } - } - - if (! $type->isArray()->yes()) { - return new GenericObjectType(Collection::class, [$type->toArray()->getIterableKeyType(), $type->toArray()->getIterableValueType()]); - } - - if ($type->isIterableAtLeastOnce()->no()) { - return new GenericObjectType(Collection::class, [$keyType, new MixedType()]); - } - - return new GenericObjectType(Collection::class, [ - TypeUtils::generalizeType($type->getIterableKeyType(), GeneralizePrecision::lessSpecific()), - TypeUtils::generalizeType($type->getIterableValueType(), GeneralizePrecision::lessSpecific()), - ]); - } - - private function getTypeFromEloquentCollection(TypeWithClassName $valueType): GenericObjectType - { - $keyType = TypeCombinator::union(new IntegerType(), new StringType()); - - $classReflection = $valueType->getClassReflection(); - - if ($classReflection === null) { - return new GenericObjectType(Collection::class, [$keyType, new MixedType()]); - } - - $innerValueType = $classReflection->getActiveTemplateTypeMap()->getType('TValue'); - - if ($classReflection->getName() === EloquentCollection::class || $classReflection->isSubclassOf(EloquentCollection::class)) { - $keyType = new IntegerType(); - } - - if ($innerValueType !== null) { - return new GenericObjectType(Collection::class, [$keyType, $innerValueType]); - } - - return new GenericObjectType(Collection::class, [$keyType, new MixedType()]); - } - - private function getTypeFromIterator(TypeWithClassName $valueType): GenericObjectType - { - $keyType = TypeCombinator::union(new IntegerType(), new StringType()); - - $classReflection = $valueType->getClassReflection(); - - if ($classReflection === null) { - return new GenericObjectType(Collection::class, [$keyType, new MixedType()]); - } - - $templateTypes = array_values($classReflection->getActiveTemplateTypeMap()->getTypes()); - - if (count($templateTypes) === 1) { - return new GenericObjectType(Collection::class, [$keyType, $templateTypes[0]]); - } - - return new GenericObjectType(Collection::class, $templateTypes); - } -} diff --git a/php-packages/phpstan/src/Support/HigherOrderCollectionProxyHelper.php b/php-packages/phpstan/src/Support/HigherOrderCollectionProxyHelper.php deleted file mode 100644 index 99a6cb086..000000000 --- a/php-packages/phpstan/src/Support/HigherOrderCollectionProxyHelper.php +++ /dev/null @@ -1,141 +0,0 @@ -getName() !== HigherOrderCollectionProxy::class) { - return false; - } - - $activeTemplateTypeMap = $classReflection->getActiveTemplateTypeMap(); - - if ($activeTemplateTypeMap->count() !== 2) { - return false; - } - - $methodType = $activeTemplateTypeMap->getType('T'); - $valueType = $activeTemplateTypeMap->getType('TValue'); - - if (($methodType === null) || ($valueType === null)) { - return false; - } - - if (! $methodType instanceof Type\Constant\ConstantStringType) { - return false; - } - - if (! $valueType->canCallMethods()->yes()) { - return false; - } - - if ($propertyOrMethod === 'method') { - return $valueType->hasMethod($name)->yes(); - } - - return $valueType->hasProperty($name)->yes(); - } - - public static function determineReturnType(string $name, Type\Type $valueType, Type\Type $methodOrPropertyReturnType): Type\Type - { - if ((new Type\ObjectType(Model::class))->isSuperTypeOf($valueType)->yes()) { - $collectionType = Collection::class; - $types = [$valueType]; - } else { - $collectionType = SupportCollection::class; - $types = [new Type\IntegerType(), $valueType]; - } - switch ($name) { - case 'average': - case 'avg': - $returnType = new Type\FloatType(); - break; - case 'contains': - case 'every': - case 'some': - $returnType = new Type\BooleanType(); - break; - case 'each': - case 'filter': - case 'reject': - case 'skipUntil': - case 'skipWhile': - case 'sortBy': - case 'sortByDesc': - case 'takeUntil': - case 'takeWhile': - case 'unique': - $returnType = new Type\Generic\GenericObjectType($collectionType, $types); - break; - case 'keyBy': - if ($collectionType === SupportCollection::class) { - $returnType = new Type\Generic\GenericObjectType($collectionType, [$methodOrPropertyReturnType, $valueType]); - } else { - $returnType = new Type\Generic\GenericObjectType($collectionType, $types); - } - break; - case 'first': - $returnType = Type\TypeCombinator::addNull($valueType); - break; - case 'flatMap': - $returnType = new Type\Generic\GenericObjectType(SupportCollection::class, [new Type\IntegerType(), new Type\MixedType()]); - break; - case 'groupBy': - case 'partition': - $innerTypes = [ - new Type\Generic\GenericObjectType($collectionType, $types), - ]; - - if ($collectionType === SupportCollection::class) { - array_unshift($innerTypes, new Type\IntegerType()); - } - - $returnType = new Type\Generic\GenericObjectType($collectionType, $innerTypes); - break; - case 'map': - $returnType = new Type\Generic\GenericObjectType(SupportCollection::class, [ - new Type\IntegerType(), - $methodOrPropertyReturnType, - ]); - break; - case 'max': - case 'min': - $returnType = $methodOrPropertyReturnType; - break; - case 'sum': - if ($methodOrPropertyReturnType->accepts(new Type\IntegerType(), true)->yes()) { - $returnType = new Type\IntegerType(); - } else { - $returnType = new Type\ErrorType(); - } - - break; - default: - $returnType = new Type\ErrorType(); - break; - } - - return $returnType; - } -} diff --git a/php-packages/phpstan/src/Types/AbortIfFunctionTypeSpecifyingExtension.php b/php-packages/phpstan/src/Types/AbortIfFunctionTypeSpecifyingExtension.php deleted file mode 100644 index 075d854cd..000000000 --- a/php-packages/phpstan/src/Types/AbortIfFunctionTypeSpecifyingExtension.php +++ /dev/null @@ -1,67 +0,0 @@ -negate = $negate; - $this->methodName = $methodName.'_'.($negate === false ? 'if' : 'unless'); - } - - public function isFunctionSupported( - FunctionReflection $functionReflection, - FuncCall $node, - TypeSpecifierContext $context - ): bool { - return $functionReflection->getName() === $this->methodName && $context->null(); - } - - public function specifyTypes( - FunctionReflection $functionReflection, - FuncCall $node, - Scope $scope, - TypeSpecifierContext $context - ): SpecifiedTypes { - if (count($node->args) < 2) { - return new SpecifiedTypes(); - } - - $context = $this->negate === false ? TypeSpecifierContext::createFalsey() : TypeSpecifierContext::createTruthy(); - - return $this->typeSpecifier->specifyTypesInCondition($scope, $node->getArgs()[0]->value, $context); - } - - public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void - { - $this->typeSpecifier = $typeSpecifier; - } -} diff --git a/php-packages/phpstan/src/Types/GenericEloquentBuilderTypeNodeResolverExtension.php b/php-packages/phpstan/src/Types/GenericEloquentBuilderTypeNodeResolverExtension.php deleted file mode 100644 index 5fc7f202f..000000000 --- a/php-packages/phpstan/src/Types/GenericEloquentBuilderTypeNodeResolverExtension.php +++ /dev/null @@ -1,63 +0,0 @@ -types) !== 2) { - return null; - } - - $modelTypeNode = null; - $builderTypeNode = null; - foreach ($typeNode->types as $innerTypeNode) { - if ($innerTypeNode instanceof IdentifierTypeNode - && is_subclass_of($nameScope->resolveStringName($innerTypeNode->name), Model::class) - ) { - $modelTypeNode = $innerTypeNode; - continue; - } - - if ( - $innerTypeNode instanceof IdentifierTypeNode - && ($nameScope->resolveStringName($innerTypeNode->name) === Builder::class || is_subclass_of($nameScope->resolveStringName($innerTypeNode->name), Builder::class)) - ) { - $builderTypeNode = $innerTypeNode; - } - } - - if ($modelTypeNode === null || $builderTypeNode === null) { - return null; - } - - $builderTypeName = $nameScope->resolveStringName($builderTypeNode->name); - $modelTypeName = $nameScope->resolveStringName($modelTypeNode->name); - - return new GenericObjectType($builderTypeName, [ - new ObjectType($modelTypeName), - ]); - } -} diff --git a/php-packages/phpstan/src/Types/GenericEloquentCollectionTypeNodeResolverExtension.php b/php-packages/phpstan/src/Types/GenericEloquentCollectionTypeNodeResolverExtension.php deleted file mode 100644 index 0108eab48..000000000 --- a/php-packages/phpstan/src/Types/GenericEloquentCollectionTypeNodeResolverExtension.php +++ /dev/null @@ -1,91 +0,0 @@ - $accounts - * - * Now IDE's can benefit from auto-completion, and we can benefit from the correct type passed to the generic collection - */ -class GenericEloquentCollectionTypeNodeResolverExtension implements TypeNodeResolverExtension -{ - /** - * @var TypeNodeResolver - */ - private $typeNodeResolver; - - public function __construct(TypeNodeResolver $typeNodeResolver) - { - $this->typeNodeResolver = $typeNodeResolver; - } - - public function resolve(TypeNode $typeNode, NameScope $nameScope): ?Type - { - if (! $typeNode instanceof UnionTypeNode || count($typeNode->types) !== 2) { - return null; - } - - $arrayTypeNode = null; - $identifierTypeNode = null; - foreach ($typeNode->types as $innerTypeNode) { - if ($innerTypeNode instanceof ArrayTypeNode) { - $arrayTypeNode = $innerTypeNode; - continue; - } - - if ($innerTypeNode instanceof IdentifierTypeNode) { - $identifierTypeNode = $innerTypeNode; - } - } - - if ($arrayTypeNode === null || $identifierTypeNode === null) { - return null; - } - - $identifierTypeName = $nameScope->resolveStringName($identifierTypeNode->name); - if ($identifierTypeName !== Collection::class) { - return null; - } - - $innerArrayTypeNode = $arrayTypeNode->type; - if (! $innerArrayTypeNode instanceof IdentifierTypeNode) { - return null; - } - - $resolvedInnerArrayType = $this->typeNodeResolver->resolve($innerArrayTypeNode, $nameScope); - - return new GenericObjectType($identifierTypeName, [ - $resolvedInnerArrayType, - ]); - } -} diff --git a/php-packages/phpstan/src/Types/ModelProperty/GenericModelPropertyType.php b/php-packages/phpstan/src/Types/ModelProperty/GenericModelPropertyType.php deleted file mode 100644 index 6018b1212..000000000 --- a/php-packages/phpstan/src/Types/ModelProperty/GenericModelPropertyType.php +++ /dev/null @@ -1,126 +0,0 @@ -type = $type; - } - - public function getReferencedClasses(): array - { - return $this->getGenericType()->getReferencedClasses(); - } - - public function getGenericType(): Type - { - return $this->type; - } - - public function isSuperTypeOf(Type $type): TrinaryLogic - { - if ($type instanceof ConstantStringType) { - return $this->getGenericType()->hasProperty($type->getValue()); - } - - if ($type instanceof self) { - return TrinaryLogic::createYes(); - } - - if ($type instanceof parent) { - return TrinaryLogic::createMaybe(); - } - - if ($type instanceof CompoundType) { - return $type->isSubTypeOf($this); - } - - return TrinaryLogic::createNo(); - } - - public function traverse(callable $cb): Type - { - $newType = $cb($this->getGenericType()); - - if ($newType === $this->getGenericType()) { - return $this; - } - - return new self($newType); - } - - public function inferTemplateTypes(Type $receivedType): TemplateTypeMap - { - if ($receivedType instanceof UnionType || $receivedType instanceof IntersectionType) { - return $receivedType->inferTemplateTypesOn($this); - } - - if ($receivedType instanceof ConstantStringType) { - $typeToInfer = new ObjectType($receivedType->getValue()); - } elseif ($receivedType instanceof self) { - $typeToInfer = $receivedType->type; - } elseif ($receivedType instanceof ClassStringType) { - $typeToInfer = $this->getGenericType(); - - if ($typeToInfer instanceof TemplateType) { - $typeToInfer = $typeToInfer->getBound(); - } - - $typeToInfer = TypeCombinator::intersect($typeToInfer, new ObjectWithoutClassType()); - } else { - return TemplateTypeMap::createEmpty(); - } - - if (! $this->getGenericType()->isSuperTypeOf($typeToInfer)->no()) { - return $this->getGenericType()->inferTemplateTypes($typeToInfer); - } - - return TemplateTypeMap::createEmpty(); - } - - public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance): array - { - $variance = $positionVariance->compose(TemplateTypeVariance::createCovariant()); - - return $this->getGenericType()->getReferencedTemplateTypes($variance); - } - - /** - * @param mixed[] $properties - * @return Type - */ - public static function __set_state(array $properties): Type - { - return new self($properties['type']); - } -} diff --git a/php-packages/phpstan/src/Types/ModelProperty/ModelPropertyType.php b/php-packages/phpstan/src/Types/ModelProperty/ModelPropertyType.php deleted file mode 100644 index 7da7bb300..000000000 --- a/php-packages/phpstan/src/Types/ModelProperty/ModelPropertyType.php +++ /dev/null @@ -1,27 +0,0 @@ -baseResolver = $baseResolver; - $this->active = $active; - } - - public function resolve(TypeNode $typeNode, NameScope $nameScope): ?Type - { - if ($typeNode instanceof IdentifierTypeNode && $typeNode->name === 'model-property') { - return $this->active ? new ModelPropertyType() : new StringType(); - } - - if ($typeNode instanceof GenericTypeNode && $typeNode->type->name === 'model-property') { - if (! $this->active) { - return new StringType(); - } - - if (count($typeNode->genericTypes) !== 1) { - return new ErrorType(); - } - - $genericType = $this->baseResolver->resolve($typeNode->genericTypes[0], $nameScope); - - if ((new ObjectType(Model::class))->isSuperTypeOf($genericType)->no()) { - return new ErrorType(); - } - - if ($genericType instanceof NeverType) { - return new ErrorType(); - } - - return new GenericModelPropertyType($genericType); - } - - return null; - } -} diff --git a/php-packages/phpstan/src/Types/ModelRelationsDynamicMethodReturnTypeExtension.php b/php-packages/phpstan/src/Types/ModelRelationsDynamicMethodReturnTypeExtension.php deleted file mode 100644 index 3c18af086..000000000 --- a/php-packages/phpstan/src/Types/ModelRelationsDynamicMethodReturnTypeExtension.php +++ /dev/null @@ -1,115 +0,0 @@ -relationParserHelper = $relationParserHelper; - } - - public function getClass(): string - { - return Model::class; - } - - public function isMethodSupported(MethodReflection $methodReflection): bool - { - $variants = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants()); - - $returnType = $variants->getReturnType(); - - if (! $returnType instanceof ObjectType) { - return false; - } - - if (! (new ObjectType(Relation::class))->isSuperTypeOf($returnType)->yes()) { - return false; - } - - if (! $methodReflection->getDeclaringClass()->hasNativeMethod($methodReflection->getName())) { - return false; - } - - if (count($variants->getParameters()) !== 0) { - return false; - } - - if (in_array($methodReflection->getName(), [ - 'hasOne', 'hasOneThrough', 'morphOne', - 'belongsTo', 'morphTo', - 'hasMany', 'hasManyThrough', 'morphMany', - 'belongsToMany', 'morphToMany', 'morphedByMany', - ], true)) { - return false; - } - - $relatedModel = $this - ->relationParserHelper - ->findRelatedModelInRelationMethod($methodReflection); - - return $relatedModel !== null; - } - - /** - * @param MethodReflection $methodReflection - * @param MethodCall $methodCall - * @param Scope $scope - * @return Type - * - * @throws ShouldNotHappenException - */ - public function getTypeFromMethodCall( - MethodReflection $methodReflection, - MethodCall $methodCall, - Scope $scope - ): Type { - /** @var ObjectType $returnType */ - $returnType = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType(); - - /** @var string $relatedModelClassName */ - $relatedModelClassName = $this - ->relationParserHelper - ->findRelatedModelInRelationMethod($methodReflection); - - $classReflection = $methodReflection->getDeclaringClass(); - - if ($returnType->isInstanceOf(BelongsTo::class)->yes()) { - return new GenericObjectType($returnType->getClassName(), [ - new ObjectType($relatedModelClassName), - new ObjectType($classReflection->getName()), - ]); - } - - return new GenericObjectType($returnType->getClassName(), [new ObjectType($relatedModelClassName)]); - } -} diff --git a/php-packages/phpstan/src/Types/Passable.php b/php-packages/phpstan/src/Types/Passable.php deleted file mode 100644 index 47cab20a0..000000000 --- a/php-packages/phpstan/src/Types/Passable.php +++ /dev/null @@ -1,52 +0,0 @@ -type = $type; - } - - /** - * @return \PHPStan\Type\Type - */ - public function getType(): Type - { - return $this->type; - } - - /** - * @param \PHPStan\Type\Type $type - */ - public function setType(Type $type): void - { - $this->type = $type; - } -} diff --git a/php-packages/phpstan/src/Types/RelationDynamicMethodReturnTypeExtension.php b/php-packages/phpstan/src/Types/RelationDynamicMethodReturnTypeExtension.php deleted file mode 100644 index 054bafbe7..000000000 --- a/php-packages/phpstan/src/Types/RelationDynamicMethodReturnTypeExtension.php +++ /dev/null @@ -1,72 +0,0 @@ -getName(), [ - 'hasOne', 'hasOneThrough', 'morphOne', - 'belongsTo', 'morphTo', - 'hasMany', 'hasManyThrough', 'morphMany', - 'belongsToMany', 'morphToMany', 'morphedByMany', - ], true); - } - - /** - * @throws ShouldNotHappenException - */ - public function getTypeFromMethodCall( - MethodReflection $methodReflection, - MethodCall $methodCall, - Scope $scope - ): Type { - /** @var FunctionVariant $functionVariant */ - $functionVariant = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants()); - $returnType = $functionVariant->getReturnType(); - - if (count($methodCall->getArgs()) === 0) { - return $returnType; - } - - $argType = $scope->getType($methodCall->getArgs()[0]->value); - - if (! $argType instanceof ConstantStringType) { - return $returnType; - } - - if (! $returnType instanceof ObjectType) { - return $returnType; - } - - return new GenericObjectType($returnType->getClassName(), [new ObjectType($argType->getValue())]); - } -} diff --git a/php-packages/phpstan/src/Types/RelationParserHelper.php b/php-packages/phpstan/src/Types/RelationParserHelper.php deleted file mode 100644 index f059f8afe..000000000 --- a/php-packages/phpstan/src/Types/RelationParserHelper.php +++ /dev/null @@ -1,139 +0,0 @@ -parser = $parser; - $this->scopeFactory = $scopeFactory; - $this->reflectionProvider = $reflectionProvider; - } - - public function findRelatedModelInRelationMethod( - MethodReflection $methodReflection - ): ?string { - $fileName = $methodReflection - ->getDeclaringClass() - ->getNativeReflection() - ->getMethod($methodReflection->getName()) - ->getFileName(); - - if ($fileName === false) { - return null; - } - - $fileStmts = $this->parser->parseFile($fileName); - - /** @var Node\Stmt\ClassMethod|null $relationMethod */ - $relationMethod = $this->findMethod($methodReflection->getName(), $fileStmts); - - if ($relationMethod === null) { - return null; - } - - /** @var Node\Stmt\Return_|null $returnStmt */ - $returnStmt = $this->findReturn($relationMethod); - - if ($returnStmt === null || ! $returnStmt->expr instanceof MethodCall) { - return null; - } - - $methodCall = $returnStmt->expr; - - while ($methodCall->var instanceof MethodCall) { - $methodCall = $methodCall->var; - } - - if (count($methodCall->getArgs()) < 1) { - return null; - } - - $scope = $this->scopeFactory->create( - ScopeContext::create($fileName), - false, - [], - $methodReflection - ); - - $methodScope = $scope - ->enterClass($methodReflection->getDeclaringClass()) - ->enterClassMethod($relationMethod, TemplateTypeMap::createEmpty(), [], null, null, null, false, false, false); - - $argType = $methodScope->getType($methodCall->getArgs()[0]->value); - $returnClass = null; - - if ($argType instanceof ConstantStringType) { - $returnClass = $argType->getValue(); - } - - if ($argType instanceof GenericClassStringType) { - $modelType = $argType->getGenericType(); - - if (! $modelType instanceof ObjectType) { - return null; - } - - $returnClass = $modelType->getClassName(); - } - - if ($returnClass === null) { - return null; - } - - return $this->reflectionProvider->hasClass($returnClass) ? $returnClass : null; - } - - /** - * @param string $method - * @param mixed $statements - * @return Node|null - */ - private function findMethod(string $method, $statements): ?Node - { - return (new NodeFinder)->findFirst($statements, static function (Node $node) use ($method) { - return $node instanceof Node\Stmt\ClassMethod - && $node->name->toString() === $method; - }); - } - - private function findReturn(Node\Stmt\ClassMethod $relationMethod): ?Node - { - /** @var Node[] $statements */ - $statements = $relationMethod->stmts; - - return (new NodeFinder)->findFirstInstanceOf($statements, Node\Stmt\Return_::class); - } -} diff --git a/php-packages/phpstan/src/Types/ViewStringType.php b/php-packages/phpstan/src/Types/ViewStringType.php deleted file mode 100644 index 0b84a916d..000000000 --- a/php-packages/phpstan/src/Types/ViewStringType.php +++ /dev/null @@ -1,87 +0,0 @@ -exists($string) test is a valid view-string type. - */ -class ViewStringType extends StringType -{ - public function describe(\PHPStan\Type\VerbosityLevel $level): string - { - return 'view-string'; - } - - public function accepts(Type $type, bool $strictTypes): TrinaryLogic - { - if ($type instanceof CompoundType) { - return $type->isAcceptedBy($this, $strictTypes); - } - - if ($type instanceof ConstantStringType) { - /** @var \Illuminate\View\Factory $view */ - $view = view(); - - return TrinaryLogic::createFromBoolean($view->exists($type->getValue())); - } - - if ($type instanceof self) { - return TrinaryLogic::createYes(); - } - - if ($type instanceof StringType) { - return TrinaryLogic::createMaybe(); - } - - return TrinaryLogic::createNo(); - } - - public function isSuperTypeOf(Type $type): TrinaryLogic - { - if ($type instanceof ConstantStringType) { - /** @var \Illuminate\View\Factory $view */ - $view = view(); - - return TrinaryLogic::createFromBoolean($view->exists($type->getValue())); - } - - if ($type instanceof self) { - return TrinaryLogic::createYes(); - } - - if ($type instanceof parent) { - return TrinaryLogic::createMaybe(); - } - - if ($type instanceof CompoundType) { - return $type->isSubTypeOf($this); - } - - return TrinaryLogic::createNo(); - } - - /** - * @param mixed[] $properties - * @return Type - */ - public static function __set_state(array $properties): Type - { - return new self(); - } -} diff --git a/php-packages/phpstan/src/Types/ViewStringTypeNodeResolverExtension.php b/php-packages/phpstan/src/Types/ViewStringTypeNodeResolverExtension.php deleted file mode 100644 index eff6526ad..000000000 --- a/php-packages/phpstan/src/Types/ViewStringTypeNodeResolverExtension.php +++ /dev/null @@ -1,33 +0,0 @@ -__toString() === 'view-string') { - return new ViewStringType(); - } - - return null; - } -} diff --git a/php-packages/phpstan/stubs/Contracts/Container.stub b/php-packages/phpstan/stubs/Contracts/Container.stub deleted file mode 100644 index 78ed9c632..000000000 --- a/php-packages/phpstan/stubs/Contracts/Container.stub +++ /dev/null @@ -1,16 +0,0 @@ - */ -interface Container extends \ArrayAccess -{ - -} - -namespace Illuminate\Contracts\Foundation; - -interface Application extends \Illuminate\Contracts\Container\Container -{ - -} diff --git a/php-packages/phpstan/stubs/Contracts/Pagination.stub b/php-packages/phpstan/stubs/Contracts/Pagination.stub deleted file mode 100644 index f23beab12..000000000 --- a/php-packages/phpstan/stubs/Contracts/Pagination.stub +++ /dev/null @@ -1,17 +0,0 @@ - - */ - public function toArray(); -} - -interface Jsonable -{} diff --git a/php-packages/phpstan/stubs/Flarum/User.stub b/php-packages/phpstan/stubs/Flarum/User.stub deleted file mode 100644 index 4ce9aecb5..000000000 --- a/php-packages/phpstan/stubs/Flarum/User.stub +++ /dev/null @@ -1,31 +0,0 @@ - - * @implements Enumerable - */ -class Collection implements \ArrayAccess, Enumerable -{ - /** - * @param callable|null $callback - * @param mixed $default - * @return TValue|null - */ - public function first(callable $callback = null, $default = null){} - - /** - * @param callable|null $callback - * @param mixed $default - * @return TValue|null - */ - public function last(callable $callback = null, $default = null){} - - - /** - * @param mixed $key - * @param mixed $default - * @return TValue|null - */ - public function get($key, $default = null) {} - - /** - * @return TValue|null - */ - public function pop() {} - - /** - * @param mixed $key - * @param mixed $default - * @return TValue|null - */ - public function pull($key, $default = null) {} - - /** - * @param mixed $value - * @param bool $strict - * @return TKey|false - */ - public function search($value, $strict = false) {} - - /** - * @return TValue|null - */ - public function shift() {} - - /** - * @param callable(TValue, TKey): (void|bool) $callable - * @return static - */ - public function each($callable) {} - - /** - * @template TReturn - * @param callable(TValue, TKey): TReturn $callable - * @return static - */ - public function map($callable) {} - - /** - * Run a grouping map over the items. - * - * The callback should return an associative array with a single key/value pair. - * - * @template TMapToGroupsKey of array-key - * @template TMapToGroupsValue - * - * @param callable(TValue, TKey): array $callback - * @return static> - */ - public function mapToGroups(callable $callback) {} - - /** - * @param array|string|callable(TValue, TKey): mixed $groupBy - * @param bool $preserveKeys - * @return static> - */ - public function groupBy($groupBy, $preserveKeys = false); - - /** - * @template TClass - * @param class-string $class - * @return static - */ - public function mapInto($class); - - /** - * @template TReturn - * @param callable(TValue, TKey): (array|\Illuminate\Support\Enumerable) $callback - * @return static - */ - public function flatMap(callable $callback) {} - - /** - * @template TReturn - * @param callable(TValue ...$values): TReturn $callback - * @return static - */ - public function mapSpread(callable $callback) {} - - /** - * @param int $number - * @param null|callable(int, int): mixed $callback - * @return static - */ - public static function times($number, callable $callback = null) {} - - /** - * @param string|array $value - * @param string|null $key - * @return static - */ - public function pluck($value, $key = null) {} - - /** - * @return TValue - */ - public function pop() {} - - /** - * Push one or more items onto the end of the collection. - * - * @param TValue ...$values - * @return static - */ - public function push(...$values) {} - - /** - * Put an item in the collection by key. - * - * @param TKey $key - * @param TValue $value - * @return static - */ - public function put($key, $value) {} -} diff --git a/php-packages/phpstan/stubs/Illuminate/Contracts/Container/Container.stub b/php-packages/phpstan/stubs/Illuminate/Contracts/Container/Container.stub new file mode 100644 index 000000000..6e07ef116 --- /dev/null +++ b/php-packages/phpstan/stubs/Illuminate/Contracts/Container/Container.stub @@ -0,0 +1,7 @@ + - */ -class BelongsTo extends Relation -{ - /** @phpstan-return TChildModel */ - public function associate(); - - /** @phpstan-return TChildModel */ - public function dissociate(); - - /** @phpstan-return TChildModel */ - public function getChild(); - - /** - * Get the results of the relationship. - * - * @phpstan-return ?TRelatedModel - */ - public function getResults(); -} diff --git a/php-packages/phpstan/stubs/Illuminate/Database/BelongsToMany.stub b/php-packages/phpstan/stubs/Illuminate/Database/BelongsToMany.stub deleted file mode 100644 index 22484d0ba..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Database/BelongsToMany.stub +++ /dev/null @@ -1,112 +0,0 @@ - - */ -class BelongsToMany extends Relation -{ - /** - * Find a related model by its primary key or return new instance of the related model. - * - * @param mixed $id - * @param array $columns - * @return \Illuminate\Support\Collection|TRelatedModel - */ - public function findOrNew($id, $columns = ['*']); - - /** - * Get the first related model record matching the attributes or instantiate it. - * - * @param array $attributes - * @return TRelatedModel - */ - public function firstOrNew(array $attributes); - - /** - * Get the first related record matching the attributes or create it. - * - * @param array $attributes - * @param array $joining - * @param bool $touch - * @return TRelatedModel - */ - public function firstOrCreate(array $attributes, array $joining = [], $touch = true); - - /** - * Create or update a related record matching the attributes, and fill it with values. - * - * @param array $attributes - * @param array $values - * @param array $joining - * @param bool $touch - * @return TRelatedModel - */ - public function updateOrCreate(array $attributes, array $values = [], array $joining = [], $touch = true); - - /** - * Find a related model by its primary key. - * - * @param mixed $id - * @param array $columns - * @return TRelatedModel|\Illuminate\Database\Eloquent\Collection|null - */ - public function find($id, $columns = ['*']); - - /** - * Find multiple related models by their primary keys. - * - * @param \Illuminate\Contracts\Support\Arrayable|int[] $ids - * @param array $columns - * @return \Illuminate\Database\Eloquent\Collection - */ - public function findMany($ids, $columns = ['*']); - - /** - * Find a related model by its primary key or throw an exception. - * - * @param mixed $id - * @param array $columns - * @return TRelatedModel|\Illuminate\Database\Eloquent\Collection - * - * @throws \Illuminate\Database\Eloquent\ModelNotFoundException - */ - public function findOrFail($id, $columns = ['*']); - - /** - * Execute the query and get the first result. - * - * @param array $columns - * @return TRelatedModel|null - */ - public function first($columns = ['*']); - - /** - * Execute the query and get the first result or throw an exception. - * - * @param array $columns - * @return TRelatedModel - * - * @throws \Illuminate\Database\Eloquent\ModelNotFoundException - */ - public function firstOrFail($columns = ['*']); - - /** - * Create a new instance of the related model. - * - * @param array, mixed> $attributes - * @param mixed[] $joining - * @param bool $touch - * @return TRelatedModel - */ - public function create(array $attributes = [], array $joining = [], $touch = true); - - /** - * Get the results of the relationship. - * - * @phpstan-return \Illuminate\Database\Eloquent\Collection - */ - public function getResults(); -} diff --git a/php-packages/phpstan/stubs/Illuminate/Database/EloquentBuilder.stub b/php-packages/phpstan/stubs/Illuminate/Database/EloquentBuilder.stub deleted file mode 100644 index 039dd8e3c..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Database/EloquentBuilder.stub +++ /dev/null @@ -1,454 +0,0 @@ - $orWhere - */ -class Builder -{ - /** - * Create and return an un-saved model instance. - * - * @phpstan-param array, mixed> $attributes - * @phpstan-return TModelClass - */ - public function make(array $attributes = []); - - /** - * Register a new global scope. - * - * @param string $identifier - * @param \Illuminate\Database\Eloquent\Scope|\Closure $scope - * @return static - */ - public function withGlobalScope($identifier, $scope); - - /** - * Remove a registered global scope. - * - * @param \Illuminate\Database\Eloquent\Scope|string $scope - * @return static - */ - public function withoutGlobalScope($scope); - - /** @phpstan-return TModelClass */ - public function getModel(); - - /** - * @phpstan-param array, mixed> $attributes - * @phpstan-return TModelClass - */ - public function create(array $attributes = []); - - /** - * Create a collection of models from plain arrays. - * - * @param array $items - * @phpstan-return \Illuminate\Database\Eloquent\Collection - */ - public function hydrate(array $items); - - /** - * Create a collection of models from a raw query. - * - * @param string $query - * @param array $bindings - * @phpstan-return \Illuminate\Database\Eloquent\Collection - */ - public function fromQuery($query, $bindings = []); - - /** - * Find a model by its primary key. - * - * @param mixed $id - * @param array|'*')>|model-property|'*' $columns - * @phpstan-return TModelClass|\Illuminate\Database\Eloquent\Collection|null - */ - public function find($id, $columns = ['*']); - - /** - * Find multiple models by their primary keys. - * - * @param \Illuminate\Contracts\Support\Arrayable|array $ids - * @param array|'*')>|model-property|'*' $columns - * @phpstan-return \Illuminate\Database\Eloquent\Collection - */ - public function findMany($ids, $columns = ['*']); - - /** - * Find a model by its primary key or throw an exception. - * - * @param mixed $id - * @param array|'*')>|model-property|'*' $columns - * @phpstan-return TModelClass|\Illuminate\Database\Eloquent\Collection - * - * @throws \Illuminate\Database\Eloquent\ModelNotFoundException - */ - public function findOrFail($id, $columns = ['*']); - - /** - * Find a model by its primary key or return fresh model instance. - * - * @param mixed $id - * @param array|'*')>|model-property|'*' $columns - * @phpstan-return TModelClass - */ - public function findOrNew($id, $columns = ['*']); - - /** - * Execute the query and get the first result. - * - * @param array|int, mixed>|string $columns - * @return TModelClass|null - */ - public function first($columns = ['*']); - - /** - * Get the first record matching the attributes or instantiate it. - * - * @param array, mixed> $attributes - * @param array, mixed> $values - * @phpstan-return TModelClass - */ - public function firstOrNew(array $attributes = [], array $values = []); - - /** - * Get the first record matching the attributes or create it. - * - * @param array, mixed> $attributes - * @param array, mixed> $values - * @phpstan-return TModelClass - */ - public function firstOrCreate(array $attributes, array $values = []); - - /** - * Create or update a record matching the attributes, and fill it with values. - * - * @param array, mixed> $attributes - * @param array, mixed> $values - * @phpstan-return TModelClass - */ - public function updateOrCreate(array $attributes, array $values = []); - - /** - * @param array, mixed> $attributes - * @phpstan-return TModelClass - */ - public function forceCreate(array $attributes); - - /** - * @param array, mixed> $values - * @return int - */ - public function update(array $values); - - /** - * Execute the query and get the first result or throw an exception. - * - * @param array|'*')>|model-property|'*' $columns - * @phpstan-return TModelClass - * - * @throws \Illuminate\Database\Eloquent\ModelNotFoundException - */ - public function firstOrFail($columns = ['*']); - - /** - * Execute the query and get the first result if it's the sole matching record. - * - * @param array|'*')>|model-property|'*' $columns - * @phpstan-return TModelClass - */ - public function sole($columns = ['*']); - - /** - * Execute the query and get the first result or call a callback. - * - * @param \Closure|array|'*')> $columns - * @param \Closure|null $callback - * @phpstan-return TModelClass|mixed - */ - public function firstOr($columns = ['*'], \Closure $callback = null); - - /** - * Add a basic where clause to the query. - * - * @param \Closure|model-property|array|int, mixed>|\Illuminate\Database\Query\Expression $column - * @param mixed $operator - * @param mixed $value - * @param string $boolean - * @return static - */ - public function where($column, $operator = null, $value = null, $boolean = 'and'); - - /** - * Add an "or where" clause to the query. - * - * @param \Closure|model-property|array|int, mixed>|\Illuminate\Database\Query\Expression $column - * @param mixed $operator - * @param mixed $value - * @return static - */ - public function orWhere($column, $operator = null, $value = null); - - /** - * Add a relationship count / exists condition to the query. - * - * @template TRelatedModel of Model - * @param \Illuminate\Database\Eloquent\Relations\Relation|string $relation - * @param string $operator - * @param int $count - * @param string $boolean - * @param \Closure|null $callback - * @return static - * - * @throws \RuntimeException - */ - public function has($relation, $operator = '>=', $count = 1, $boolean = 'and', \Closure $callback = null); - - /** - * Add a relationship count / exists condition to the query with an "or". - * - * @param string $relation - * @param string $operator - * @param int $count - * @return static - */ - public function orHas($relation, $operator = '>=', $count = 1); - - /** - * Add a relationship count / exists condition to the query. - * - * @param string $relation - * @param string $boolean - * @param \Closure|null $callback - * @return static - */ - public function doesntHave($relation, $boolean = 'and', \Closure $callback = null); - - /** - * Add a relationship count / exists condition to the query with an "or". - * - * @param string $relation - * @return static - */ - public function orDoesntHave($relation); - - /** - * Add a relationship count / exists condition to the query with where clauses. - * - * @param string $relation - * @param \Closure|null $callback - * @param string $operator - * @param int $count - * @return static - */ - public function whereHas($relation, \Closure $callback = null, $operator = '>=', $count = 1); - - /** - * Add a relationship count / exists condition to the query with where clauses and an "or". - * - * @param string $relation - * @param \Closure|null $callback - * @param string $operator - * @param int $count - * @return static - */ - public function orWhereHas($relation, \Closure $callback = null, $operator = '>=', $count = 1); - - /** - * Add a polymorphic relationship count / exists condition to the query. - * - * @template TRelatedModel of Model - * @template TChildModel of Model - * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation - * @param string|array $types - * @param string $operator - * @param int $count - * @param string $boolean - * @param \Closure|null $callback - * @return static - */ - public function hasMorph($relation, $types, $operator = '>=', $count = 1, $boolean = 'and', \Closure $callback = null); - - /** - * Add a polymorphic relationship count / exists condition to the query with an "or". - * - * @template TRelatedModel of Model - * @template TChildModel of Model - * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation - * @param string|array $types - * @param string $operator - * @param int $count - * @return static - */ - public function orHasMorph($relation, $types, $operator = '>=', $count = 1); - - /** - * Add a polymorphic relationship count / exists condition to the query. - * - * @template TRelatedModel of Model - * @template TChildModel of Model - * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation - * @param string|array $types - * @param string $boolean - * @param \Closure|null $callback - * @return static - */ - public function doesntHaveMorph($relation, $types, $boolean = 'and', \Closure $callback = null); - - /** - * Add a polymorphic relationship count / exists condition to the query with an "or". - * - * @template TRelatedModel of Model - * @template TChildModel of Model - * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation - * @param string|array $types - * @return static - */ - public function orDoesntHaveMorph($relation, $types); - - /** - * Add a polymorphic relationship count / exists condition to the query with where clauses. - * - * @template TRelatedModel of Model - * @template TChildModel of Model - * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation - * @param string|array $types - * @param \Closure|null $callback - * @param string $operator - * @param int $count - * @return static - */ - public function whereHasMorph($relation, $types, \Closure $callback = null, $operator = '>=', $count = 1); - - /** - * Add a polymorphic relationship count / exists condition to the query with where clauses and an "or". - * - * @template TRelatedModel of Model - * @template TChildModel of Model - * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation - * @param string|array $types - * @param \Closure|null $callback - * @param string $operator - * @param int $count - * @return static - */ - public function orWhereHasMorph($relation, $types, \Closure $callback = null, $operator = '>=', $count = 1); - - /** - * Add a polymorphic relationship count / exists condition to the query with where clauses. - * - * @template TRelatedModel of Model - * @template TChildModel of Model - * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation - * @param string|array $types - * @param \Closure|null $callback - * @return static - */ - public function whereDoesntHaveMorph($relation, $types, \Closure $callback = null); - - /** - * Add a polymorphic relationship count / exists condition to the query with where clauses and an "or". - * - * @template TRelatedModel of Model - * @template TChildModel of Model - * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation - * @param string|array $types - * @param \Closure|null $callback - * @return static - */ - public function orWhereDoesntHaveMorph($relation, $types, \Closure $callback = null); - - /** - * Merge the where constraints from another query to the current query. - * - * @param \Illuminate\Database\Eloquent\Builder $from - * @return static - */ - public function mergeConstraintsFrom(\Illuminate\Database\Eloquent\Builder $from); - - /** - * Add a relationship count / exists condition to the query with where clauses and an "or". - * - * @param string $relation - * @param \Closure|null $callback - * @return static - */ - public function orWhereDoesntHave($relation, \Closure $callback = null); - - /** - * Add a relationship count / exists condition to the query with where clauses. - * - * @param string $relation - * @param \Closure|null $callback - * @return static - */ - public function whereDoesntHave($relation, \Closure $callback = null); - - /** - * Add a basic where clause to the query, and return the first result. - * - * @param \Closure|model-property|array|int, mixed>|\Illuminate\Database\Query\Expression $column - * @param mixed $operator - * @param mixed $value - * @param string $boolean - * @phpstan-return TModelClass|null - */ - public function firstWhere($column, $operator = null, $value = null, $boolean = 'and'); - - /** - * Execute the query as a "select" statement. - * - * @param array|'*')>|model-property|'*' $columns - * @phpstan-return \Illuminate\Database\Eloquent\Collection - */ - public function get($columns = ['*']); - - /** - * Get the hydrated models without eager loading. - * - * @param array|'*')>|model-property|'*' $columns - * @phpstan-return TModelClass[] - */ - public function getModels($columns = ['*']); - - /** - * Get a single column's value from the first result of a query. - * - * @param model-property|\Illuminate\Database\Query\Expression $column - * @return mixed - */ - public function value($column); - - /** - * Apply the callback's query changes if the given "value" is true. - * - * @param mixed $value - * @param callable($this, mixed): (void|Builder) $callback - * @param callable($this, mixed): (null|Builder)|null $default - * @return mixed|$this - */ - public function when($value, $callback, $default = null); - - /** - * Apply the callback's query changes if the given "value" is false. - * - * @param mixed $value - * @param callable($this, mixed): (void|Builder) $callback - * @param callable($this, mixed): (null|Builder)|null $default - * @return mixed|$this - */ - public function unless($value, $callback, $default = null); -} - -class Scope {} - -/** - * @method static \Illuminate\Database\Eloquent\Builder withTrashed(bool $withTrashed = true) - * @method static \Illuminate\Database\Eloquent\Builder onlyTrashed() - * @method static \Illuminate\Database\Eloquent\Builder withoutTrashed() - * @method static bool restore() - */ -trait SoftDeletes {} diff --git a/php-packages/phpstan/stubs/Illuminate/Database/EloquentCollection.stub b/php-packages/phpstan/stubs/Illuminate/Database/EloquentCollection.stub deleted file mode 100644 index 02da6d683..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Database/EloquentCollection.stub +++ /dev/null @@ -1,43 +0,0 @@ - - */ -class Collection extends \Illuminate\Support\Collection -{ - - /** @phpstan-use EnumeratesValues */ - use EnumeratesValues; - - /** - * @param mixed $key - * @param mixed $default - * @phpstan-return TValue|null - */ - public function find($key, $default = null) {} - - /** - * @template TReturn - * @param callable(TValue, int): TReturn $callable - * @return static|\Illuminate\Support\Collection - */ - public function map($callable) {} - - /** - * @param callable(TValue, int): mixed $callback - * @return \Illuminate\Support\Collection - */ - public function flatMap(callable $callback) {} - - /** - * @template TReturn - * @param callable(TValue ...$values): TReturn $callback - * @return static|\Illuminate\Support\Collection - */ - public function mapSpread(callable $callback) {} -} diff --git a/php-packages/phpstan/stubs/Illuminate/Database/Factory.stub b/php-packages/phpstan/stubs/Illuminate/Database/Factory.stub deleted file mode 100644 index dc6add1a0..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Database/Factory.stub +++ /dev/null @@ -1,81 +0,0 @@ - - */ - protected $model; - - /** - * Get a new factory instance for the given attributes. - * - * @param callable|array, mixed> $attributes - * @return static - */ - public static function new($attributes = []) {} - - /** - * Create a single model and persist it to the database. - * - * @param array, mixed> $attributes - * @return TModel - */ - public function createOne($attributes = []) {} - - /** - * Create a collection of models and persist them to the database. - * - * @param iterable, mixed>> $records - * @return \Illuminate\Database\Eloquent\Collection - */ - public function createMany(iterable $records) {} - - /** - * Create a collection of models and persist them to the database. - * - * @param array, mixed> $attributes - * @param \Illuminate\Database\Eloquent\Model|null $parent - * @return \Illuminate\Database\Eloquent\Collection|TModel - */ - public function create($attributes = [], ?\Illuminate\Database\Eloquent\Model $parent = null) {} - - /** - * Make a single instance of the model. - * - * @param callable|array, mixed> $attributes - * @return TModel - */ - public function makeOne($attributes = []) {} - - /** - * Create a collection of models. - * - * @param array, mixed> $attributes - * @param \Illuminate\Database\Eloquent\Model|null $parent - * @return \Illuminate\Database\Eloquent\Collection|TModel - */ - public function make($attributes = [], ?\Illuminate\Database\Eloquent\Model $parent = null) {} - - /** - * Make an instance of the model with the given attributes. - * - * @param \Illuminate\Database\Eloquent\Model|null $parent - * @return TModel - */ - protected function makeInstance(?\Illuminate\Database\Eloquent\Model $parent) {} - - /** - * Define the model's default state. - * - * @return array, mixed> - */ - abstract public function definition(); -} diff --git a/php-packages/phpstan/stubs/Illuminate/Database/Gate.stub b/php-packages/phpstan/stubs/Illuminate/Database/Gate.stub deleted file mode 100644 index ed57dd695..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Database/Gate.stub +++ /dev/null @@ -1,31 +0,0 @@ - - */ -class HasMany extends HasOneOrMany -{ - /** - * Get the results of the relationship. - * - * @phpstan-return \Illuminate\Database\Eloquent\Collection - */ - public function getResults(); -} diff --git a/php-packages/phpstan/stubs/Illuminate/Database/HasManyThrough.stub b/php-packages/phpstan/stubs/Illuminate/Database/HasManyThrough.stub deleted file mode 100644 index e4537e015..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Database/HasManyThrough.stub +++ /dev/null @@ -1,17 +0,0 @@ - - */ -class HasManyThrough extends Relation -{ - /** - * Get the results of the relationship. - * - * @phpstan-return \Illuminate\Database\Eloquent\Collection - */ - public function getResults(); -} diff --git a/php-packages/phpstan/stubs/Illuminate/Database/HasOne.stub b/php-packages/phpstan/stubs/Illuminate/Database/HasOne.stub deleted file mode 100644 index 336dd2d6d..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Database/HasOne.stub +++ /dev/null @@ -1,17 +0,0 @@ - - */ -class HasOne extends HasOneOrMany -{ - /** - * Get the results of the relationship. - * - * @phpstan-return ?TRelatedModel - */ - public function getResults(); -} diff --git a/php-packages/phpstan/stubs/Illuminate/Database/HasOneOrMany.stub b/php-packages/phpstan/stubs/Illuminate/Database/HasOneOrMany.stub deleted file mode 100644 index 75c04a1f9..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Database/HasOneOrMany.stub +++ /dev/null @@ -1,86 +0,0 @@ - - */ -abstract class HasOneOrMany extends Relation -{ - /** - * Create a new has one or many relationship instance. - * - * @param \Illuminate\Database\Eloquent\Builder $query - * @param TRelatedModel $parent - * @param non-empty-string $foreignKey - * @param non-empty-string $localKey - * @return void - */ - public function __construct(\Illuminate\Database\Eloquent\Builder $query, \Illuminate\Database\Eloquent\Model $parent, $foreignKey, $localKey); - - /** - * @param array, mixed> $attributes - * @phpstan-return TRelatedModel - */ - public function make(array $attributes = []); - - /** - * Find a model by its primary key or return new instance of the related model. - * - * @param mixed $id - * @param array $columns - * @return \Illuminate\Support\Collection|TRelatedModel - */ - public function findOrNew($id, $columns = ['*']); - - /** - * Get the first related model record matching the attributes or instantiate it. - * - * @param array, mixed> $attributes - * @param array $values - * @return TRelatedModel - */ - public function firstOrNew(array $attributes, array $values = []); - - /** - * Get the first related record matching the attributes or create it. - * - * @param array, mixed> $attributes - * @param array $values - * @return TRelatedModel - */ - public function firstOrCreate(array $attributes, array $values = []); - - /** - * Create or update a related record matching the attributes, and fill it with values. - * - * @param array, mixed> $attributes - * @param array $values - * @return TRelatedModel - */ - public function updateOrCreate(array $attributes, array $values = []); - - /** - * Attach a model instance to the parent model. - * - * @param \Illuminate\Database\Eloquent\Model $model - * @return TRelatedModel|false - */ - public function save(\Illuminate\Database\Eloquent\Model $model); - - /** - * @phpstan-param array, mixed> $attributes - * - * @phpstan-return TRelatedModel - */ - public function create(array $attributes = []); - - /** - * Create a Collection of new instances of the related model. - * - * @param iterable $records - * @return \Illuminate\Database\Eloquent\Collection - */ - public function createMany(iterable $records); -} diff --git a/php-packages/phpstan/stubs/Illuminate/Database/HasOneThrough.stub b/php-packages/phpstan/stubs/Illuminate/Database/HasOneThrough.stub deleted file mode 100644 index 222878f9e..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Database/HasOneThrough.stub +++ /dev/null @@ -1,24 +0,0 @@ - - */ -class HasOneThrough extends HasManyThrough -{ - /** - * @param array, mixed> $attributes - * - * @phpstan-return TRelatedModel - */ - public function create(array $attributes = []); - - /** - * Get the results of the relationship. - * - * @phpstan-return \Illuminate\Database\Eloquent\Collection - */ - public function getResults(); -} diff --git a/php-packages/phpstan/stubs/Illuminate/Database/Model.stub b/php-packages/phpstan/stubs/Illuminate/Database/Model.stub deleted file mode 100644 index a71b3a027..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Database/Model.stub +++ /dev/null @@ -1,28 +0,0 @@ - - */ -abstract class Model implements \JsonSerializable, \ArrayAccess -{ - /** - * Update the model in the database. - * - * @param array, mixed> $attributes - * @param array $options - * @return bool - */ - public function update(array $attributes = [], array $options = []); - - /** - * Begin querying a model with eager loading. - * - * @param non-empty-string|array $relations - * @return \Illuminate\Database\Eloquent\Builder - */ - public static function with($relations); -} - -class ModelNotFoundException extends \RuntimeException {} diff --git a/php-packages/phpstan/stubs/Illuminate/Database/MorphMany.stub b/php-packages/phpstan/stubs/Illuminate/Database/MorphMany.stub deleted file mode 100644 index 4543315c0..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Database/MorphMany.stub +++ /dev/null @@ -1,24 +0,0 @@ - - */ -class MorphMany extends MorphOneOrMany -{ - /** - * @param array, mixed> $attributes - * - * @phpstan-return TRelatedModel - */ - public function create(array $attributes = []); - - /** - * Get the results of the relationship. - * - * @phpstan-return \Illuminate\Database\Eloquent\Collection - */ - public function getResults(); -} diff --git a/php-packages/phpstan/stubs/Illuminate/Database/MorphOne.stub b/php-packages/phpstan/stubs/Illuminate/Database/MorphOne.stub deleted file mode 100644 index bf5e437fa..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Database/MorphOne.stub +++ /dev/null @@ -1,17 +0,0 @@ - - */ -class MorphOne extends MorphOneOrMany -{ - /** - * Get the results of the relationship. - * - * @phpstan-return ?TRelatedModel - */ - public function getResults(); -} diff --git a/php-packages/phpstan/stubs/Illuminate/Database/MorphOneOrMany.stub b/php-packages/phpstan/stubs/Illuminate/Database/MorphOneOrMany.stub deleted file mode 100644 index c3b775b79..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Database/MorphOneOrMany.stub +++ /dev/null @@ -1,17 +0,0 @@ - - */ -abstract class MorphOneOrMany extends HasOneOrMany -{ - /** - * @param array, mixed> $attributes - * - * @phpstan-return TRelatedModel - */ - public function create(array $attributes = []); -} diff --git a/php-packages/phpstan/stubs/Illuminate/Database/MorphTo.stub b/php-packages/phpstan/stubs/Illuminate/Database/MorphTo.stub deleted file mode 100644 index 2904af2ce..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Database/MorphTo.stub +++ /dev/null @@ -1,11 +0,0 @@ - - */ -class MorphTo extends BelongsTo -{} diff --git a/php-packages/phpstan/stubs/Illuminate/Database/MorphToMany.stub b/php-packages/phpstan/stubs/Illuminate/Database/MorphToMany.stub deleted file mode 100644 index 65d0ec38c..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Database/MorphToMany.stub +++ /dev/null @@ -1,11 +0,0 @@ - - */ -class MorphToMany extends BelongsToMany -{ -} diff --git a/php-packages/phpstan/stubs/Illuminate/Database/QueryBuilder.stub b/php-packages/phpstan/stubs/Illuminate/Database/QueryBuilder.stub deleted file mode 100644 index 5641034e4..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Database/QueryBuilder.stub +++ /dev/null @@ -1,1440 +0,0 @@ -|mixed $columns - * @return $this - */ - public function select($columns = ['*']) - {} - - /** - * Add a subselect expression to the query. - * - * @param \Closure|$this|non-empty-string $query - * @param non-empty-string $as - * @return $this - * - * @throws \InvalidArgumentException - */ - public function selectSub($query, $as) - {} - - /** - * Add a new "raw" select expression to the query. - * - * @param non-empty-string $expression - * @param array $bindings - * @return $this - */ - public function selectRaw($expression, array $bindings = []) - {} - - /** - * Makes "from" fetch from a subquery. - * - * @param \Closure|\Illuminate\Database\Query\Builder|non-empty-string $query - * @param non-empty-string $as - * @return $this - * - * @throws \InvalidArgumentException - */ - public function fromSub($query, $as) - {} - - /** - * Add a raw from clause to the query. - * - * @param non-empty-string $expression - * @param mixed $bindings - * @return $this - */ - public function fromRaw($expression, $bindings = []) - {} - - /** - * Creates a subquery and parse it. - * - * @param \Closure|\Illuminate\Database\Query\Builder|non-empty-string $query - * @return array - */ - protected function createSub($query) - {} - - /** - * Parse the subquery into SQL and bindings. - * - * @param mixed $query - * @return array - * - * @throws \InvalidArgumentException - */ - protected function parseSub($query) - {} - - /** - * Add a new select column to the query. - * - * @param array|mixed $column - * @return $this - */ - public function addSelect($column) - {} - - /** - * Force the query to only return distinct results. - * - * @return $this - */ - public function distinct() - {} - - /** - * Set the table which the query is targeting. - * - * @param \Closure|\Illuminate\Database\Query\Builder|non-empty-string $table - * @param non-empty-string|null $as - * @return $this - */ - public function from($table, $as = null) - {} - - /** - * Add a join clause to the query. - * - * @param non-empty-string $table - * @param \Closure|non-empty-string $first - * @param non-empty-string|null $operator - * @param non-empty-string|null $second - * @param non-empty-string $type - * @param bool $where - * @return $this - */ - public function join($table, $first, $operator = null, $second = null, $type = 'inner', $where = false) - {} - - /** - * Add a "join where" clause to the query. - * - * @param non-empty-string $table - * @param \Closure|non-empty-string $first - * @param non-empty-string $operator - * @param non-empty-string $second - * @param non-empty-string $type - * @return $this - */ - public function joinWhere($table, $first, $operator, $second, $type = 'inner') - {} - - /** - * Add a subquery join clause to the query. - * - * @param \Closure|\Illuminate\Database\Query\Builder|non-empty-string $query - * @param non-empty-string $as - * @param \Closure|non-empty-string $first - * @param non-empty-string|null $operator - * @param non-empty-string|null $second - * @param non-empty-string $type - * @param bool $where - * @return $this - * - * @throws \InvalidArgumentException - */ - public function joinSub($query, $as, $first, $operator = null, $second = null, $type = 'inner', $where = false) - {} - - /** - * Add a left join to the query. - * - * @param non-empty-string $table - * @param \Closure|non-empty-string $first - * @param non-empty-string|null $operator - * @param non-empty-string|null $second - * @return $this - */ - public function leftJoin($table, $first, $operator = null, $second = null) - {} - - /** - * Add a "join where" clause to the query. - * - * @param non-empty-string $table - * @param \Closure|non-empty-string $first - * @param non-empty-string $operator - * @param non-empty-string $second - * @return $this - */ - public function leftJoinWhere($table, $first, $operator, $second) - {} - - /** - * Add a subquery left join to the query. - * - * @param \Closure|\Illuminate\Database\Query\Builder|non-empty-string $query - * @param non-empty-string $as - * @param \Closure|non-empty-string $first - * @param non-empty-string|null $operator - * @param non-empty-string|null $second - * @return $this - */ - public function leftJoinSub($query, $as, $first, $operator = null, $second = null) - {} - - /** - * Add a right join to the query. - * - * @param non-empty-string $table - * @param \Closure|non-empty-string $first - * @param non-empty-string|null $operator - * @param non-empty-string|null $second - * @return $this - */ - public function rightJoin($table, $first, $operator = null, $second = null) - {} - - /** - * Add a "right join where" clause to the query. - * - * @param non-empty-string $table - * @param \Closure|non-empty-string $first - * @param non-empty-string $operator - * @param non-empty-string $second - * @return $this - */ - public function rightJoinWhere($table, $first, $operator, $second) - {} - - /** - * Add a subquery right join to the query. - * - * @param \Closure|\Illuminate\Database\Query\Builder|non-empty-string $query - * @param non-empty-string $as - * @param \Closure|non-empty-string $first - * @param non-empty-string|null $operator - * @param non-empty-string|null $second - * @return $this - */ - public function rightJoinSub($query, $as, $first, $operator = null, $second = null) - {} - - /** - * Add a "cross join" clause to the query. - * - * @param non-empty-string $table - * @param \Closure|string|null $first - * @param non-empty-string|null $operator - * @param non-empty-string|null $second - * @return $this - */ - public function crossJoin($table, $first = null, $operator = null, $second = null) - {} - - /** - * Add a basic where clause to the query. - * - * @param \Closure|string|array $column - * @param mixed $operator - * @param mixed $value - * @param non-empty-string $boolean - * @return $this - */ - public function where($column, $operator = null, $value = null, $boolean = 'and') - {} - - /** - * Add an array of where clauses to the query. - * - * @param array $column - * @param non-empty-string $boolean - * @param non-empty-string $method - * @return $this - */ - protected function addArrayOfWheres($column, $boolean, $method = 'where') - {} - - /** - * Prepare the value and operator for a where clause. - * - * @param non-empty-string $value - * @param non-empty-string $operator - * @param bool $useDefault - * @return array - * - * @throws \InvalidArgumentException - */ - public function prepareValueAndOperator($value, $operator, $useDefault = false) - {} - - /** - * Determine if the given operator and value combination is legal. - * - * Prevents using Null values with invalid operators. - * - * @param non-empty-string $operator - * @param mixed $value - * @return bool - */ - protected function invalidOperatorAndValue($operator, $value) - {} - - /** - * Determine if the given operator is supported. - * - * @param non-empty-string $operator - * @return bool - */ - protected function invalidOperator($operator) - {} - - /** - * Add an "or where" clause to the query. - * - * @param \Closure|array $column - * @param mixed $operator - * @param mixed $value - * @return $this - */ - public function orWhere($column, $operator = null, $value = null) - {} - - /** - * Add a "where" clause comparing two columns to the query. - * - * @param array $first - * @param non-empty-string|null $operator - * @param non-empty-string|null $second - * @param non-empty-string|null $boolean - * @return $this - */ - public function whereColumn($first, $operator = null, $second = null, $boolean = 'and') - {} - - /** - * Add an "or where" clause comparing two columns to the query. - * - * @param non-empty-string|array $first - * @param non-empty-string|null $operator - * @param non-empty-string|null $second - * @return $this - */ - public function orWhereColumn($first, $operator = null, $second = null) - {} - - /** - * Add a raw where clause to the query. - * - * @param non-empty-string $sql - * @param mixed $bindings - * @param non-empty-string $boolean - * @return $this - */ - public function whereRaw($sql, $bindings = [], $boolean = 'and') - {} - - /** - * Add a raw or where clause to the query. - * - * @param non-empty-string $sql - * @param mixed $bindings - * @return $this - */ - public function orWhereRaw($sql, $bindings = []) - {} - - /** - * Add a "where in" clause to the query. - * - * @param non-empty-string $column - * @param mixed $values - * @param non-empty-string $boolean - * @param bool $not - * @return $this - */ - public function whereIn($column, $values, $boolean = 'and', $not = false) - {} - - /** - * Add an "or where in" clause to the query. - * - * @param non-empty-string $column - * @param mixed $values - * @return $this - */ - public function orWhereIn($column, $values) - {} - - /** - * Add a "where not in" clause to the query. - * - * @param non-empty-string $column - * @param mixed $values - * @param non-empty-string $boolean - * @return $this - */ - public function whereNotIn($column, $values, $boolean = 'and') - {} - - /** - * Add an "or where not in" clause to the query. - * - * @param non-empty-string $column - * @param mixed $values - * @return $this - */ - public function orWhereNotIn($column, $values) - {} - - /** - * Add a "where in raw" clause for integer values to the query. - * - * @param non-empty-string $column - * @param \Illuminate\Contracts\Support\Arrayable|array $values - * @param non-empty-string $boolean - * @param bool $not - * @return $this - */ - public function whereIntegerInRaw($column, $values, $boolean = 'and', $not = false) - {} - - /** - * Add an "or where in raw" clause for integer values to the query. - * - * @param non-empty-string $column - * @param \Illuminate\Contracts\Support\Arrayable|array $values - * @return $this - */ - public function orWhereIntegerInRaw($column, $values) - {} - - /** - * Add a "where not in raw" clause for integer values to the query. - * - * @param non-empty-string $column - * @param \Illuminate\Contracts\Support\Arrayable|array $values - * @param non-empty-string $boolean - * @return $this - */ - public function whereIntegerNotInRaw($column, $values, $boolean = 'and') - {} - - /** - * Add an "or where not in raw" clause for integer values to the query. - * - * @param non-empty-string $column - * @param \Illuminate\Contracts\Support\Arrayable|array $values - * @return $this - */ - public function orWhereIntegerNotInRaw($column, $values) - {} - - /** - * Add a "where null" clause to the query. - * - * @param non-empty-string|array $columns - * @param non-empty-string $boolean - * @param bool $not - * @return $this - */ - public function whereNull($columns, $boolean = 'and', $not = false) - {} - - /** - * Add an "or where null" clause to the query. - * - * @param non-empty-string $column - * @return $this - */ - public function orWhereNull($column) - {} - - /** - * Add a "where not null" clause to the query. - * - * @param non-empty-string|array $columns - * @param non-empty-string $boolean - * @return $this - */ - public function whereNotNull($columns, $boolean = 'and') - {} - - /** - * Add a where between statement to the query. - * - * @param non-empty-string $column - * @param array $values - * @param non-empty-string $boolean - * @param bool $not - * @return $this - */ - public function whereBetween($column, array $values, $boolean = 'and', $not = false) - {} - - /** - * Add an or where between statement to the query. - * - * @param non-empty-string $column - * @param array $values - * @return $this - */ - public function orWhereBetween($column, array $values) - {} - - /** - * Add a where not between statement to the query. - * - * @param non-empty-string $column - * @param array $values - * @param non-empty-string $boolean - * @return $this - */ - public function whereNotBetween($column, array $values, $boolean = 'and') - {} - - /** - * Add an or where not between statement to the query. - * - * @param non-empty-string $column - * @param array $values - * @return $this - */ - public function orWhereNotBetween($column, array $values) - {} - - /** - * Add an "or where not null" clause to the query. - * - * @param non-empty-string $column - * @return $this - */ - public function orWhereNotNull($column) - {} - - /** - * Add a "where date" statement to the query. - * - * @param non-empty-string $column - * @param non-empty-string $operator - * @param \DateTimeInterface|string|null $value - * @param non-empty-string $boolean - * @return $this - */ - public function whereDate($column, $operator, $value = null, $boolean = 'and') - {} - - /** - * Add an "or where date" statement to the query. - * - * @param non-empty-string $column - * @param non-empty-string $operator - * @param \DateTimeInterface|string|null $value - * @return $this - */ - public function orWhereDate($column, $operator, $value = null) - {} - - /** - * Add a "where time" statement to the query. - * - * @param non-empty-string $column - * @param non-empty-string $operator - * @param \DateTimeInterface|string|null $value - * @param non-empty-string $boolean - * @return $this - */ - public function whereTime($column, $operator, $value = null, $boolean = 'and') - {} - - /** - * Add an "or where time" statement to the query. - * - * @param non-empty-string $column - * @param non-empty-string $operator - * @param \DateTimeInterface|string|null $value - * @return $this - */ - public function orWhereTime($column, $operator, $value = null) - {} - - /** - * Add a "where day" statement to the query. - * - * @param non-empty-string $column - * @param non-empty-string $operator - * @param \DateTimeInterface|string|null $value - * @param non-empty-string $boolean - * @return $this - */ - public function whereDay($column, $operator, $value = null, $boolean = 'and') - {} - - /** - * Add an "or where day" statement to the query. - * - * @param non-empty-string $column - * @param non-empty-string $operator - * @param \DateTimeInterface|string|null $value - * @return $this - */ - public function orWhereDay($column, $operator, $value = null) - {} - - /** - * Add a "where month" statement to the query. - * - * @param non-empty-string $column - * @param non-empty-string $operator - * @param \DateTimeInterface|string|null $value - * @param non-empty-string $boolean - * @return $this - */ - public function whereMonth($column, $operator, $value = null, $boolean = 'and') - {} - - /** - * Add an "or where month" statement to the query. - * - * @param non-empty-string $column - * @param non-empty-string $operator - * @param \DateTimeInterface|string|null $value - * @return $this - */ - public function orWhereMonth($column, $operator, $value = null) - {} - - /** - * Add a "where year" statement to the query. - * - * @param non-empty-string $column - * @param non-empty-string $operator - * @param \DateTimeInterface|string|int|null $value - * @param non-empty-string $boolean - * @return $this - */ - public function whereYear($column, $operator, $value = null, $boolean = 'and') - {} - - /** - * Add an "or where year" statement to the query. - * - * @param non-empty-string $column - * @param non-empty-string $operator - * @param \DateTimeInterface|string|int|null $value - * @return $this - */ - public function orWhereYear($column, $operator, $value = null) - {} - - /** - * Add a date based (year, month, day, time) statement to the query. - * - * @param non-empty-string $type - * @param non-empty-string $column - * @param non-empty-string $operator - * @param mixed $value - * @param non-empty-string $boolean - * @return $this - */ - protected function addDateBasedWhere($type, $column, $operator, $value, $boolean = 'and') - {} - - /** - * Add a nested where statement to the query. - * - * @param \Closure $callback - * @param non-empty-string $boolean - * @return $this - */ - public function whereNested(\Closure $callback, $boolean = 'and') - {} - - /** - * Create a new query instance for nested where condition. - * - * @return $this - */ - public function forNestedWhere() - {} - - /** - * Add another query builder as a nested where to the query builder. - * - * @param $this $query - * @param non-empty-string $boolean - * @return $this - */ - public function addNestedWhereQuery($query, $boolean = 'and') - {} - - /** - * Add a full sub-select to the query. - * - * @param non-empty-string $column - * @param non-empty-string $operator - * @param \Closure $callback - * @param non-empty-string $boolean - * @return $this - */ - protected function whereSub($column, $operator, \Closure $callback, $boolean) - {} - - /** - * Add an exists clause to the query. - * - * @param \Closure $callback - * @param non-empty-string $boolean - * @param bool $not - * @return $this - */ - public function whereExists(\Closure $callback, $boolean = 'and', $not = false) - {} - - /** - * Add an or exists clause to the query. - * - * @param \Closure $callback - * @param bool $not - * @return $this - */ - public function orWhereExists(\Closure $callback, $not = false) - {} - - /** - * Add a where not exists clause to the query. - * - * @param \Closure $callback - * @param non-empty-string $boolean - * @return $this - */ - public function whereNotExists(\Closure $callback, $boolean = 'and') - {} - - /** - * Add a where not exists clause to the query. - * - * @param \Closure $callback - * @return $this - */ - public function orWhereNotExists(\Closure $callback) - {} - - /** - * Add an exists clause to the query. - * - * @param \Illuminate\Database\Query\Builder $query - * @param non-empty-string $boolean - * @param bool $not - * @return $this - */ - public function addWhereExistsQuery(self $query, $boolean = 'and', $not = false) - {} - - /** - * Adds a where condition using row values. - * - * @param array $columns - * @param non-empty-string $operator - * @param array $values - * @param non-empty-string $boolean - * @return $this - * - * @throws \InvalidArgumentException - */ - public function whereRowValues($columns, $operator, $values, $boolean = 'and') - {} - - /** - * Adds a or where condition using row values. - * - * @param array $columns - * @param non-empty-string $operator - * @param array $values - * @return $this - */ - public function orWhereRowValues($columns, $operator, $values) - {} - - /** - * Add a "where JSON contains" clause to the query. - * - * @param non-empty-string $column - * @param mixed $value - * @param non-empty-string $boolean - * @param bool $not - * @return $this - */ - public function whereJsonContains($column, $value, $boolean = 'and', $not = false) - {} - - /** - * Add a "or where JSON contains" clause to the query. - * - * @param non-empty-string $column - * @param mixed $value - * @return $this - */ - public function orWhereJsonContains($column, $value) - {} - - /** - * Add a "where JSON not contains" clause to the query. - * - * @param non-empty-string $column - * @param mixed $value - * @param non-empty-string $boolean - * @return $this - */ - public function whereJsonDoesntContain($column, $value, $boolean = 'and') - {} - - /** - * Add a "or where JSON not contains" clause to the query. - * - * @param non-empty-string $column - * @param mixed $value - * @return $this - */ - public function orWhereJsonDoesntContain($column, $value) - {} - - /** - * Add a "where JSON length" clause to the query. - * - * @param non-empty-string $column - * @param mixed $operator - * @param mixed $value - * @param non-empty-string $boolean - * @return $this - */ - public function whereJsonLength($column, $operator, $value = null, $boolean = 'and') - {} - - /** - * Add a "or where JSON length" clause to the query. - * - * @param non-empty-string $column - * @param mixed $operator - * @param mixed $value - * @return $this - */ - public function orWhereJsonLength($column, $operator, $value = null) - {} - - /** - * Handles dynamic "where" clauses to the query. - * - * @param non-empty-string $method - * @param array $parameters - * @return $this - */ - public function dynamicWhere($method, $parameters) - {} - - /** - * Add a single dynamic where clause statement to the query. - * - * @param non-empty-string $segment - * @param non-empty-string $connector - * @param array $parameters - * @param int $index - * @return void - */ - protected function addDynamic($segment, $connector, $parameters, $index) - {} - - /** - * Add a "group by" clause to the query. - * - * @param array|non-empty-string ...$groups - * @return $this - */ - public function groupBy(...$groups) - {} - - /** - * Add a raw groupBy clause to the query. - * - * @param non-empty-string $sql - * @param array $bindings - * @return $this - */ - public function groupByRaw($sql, array $bindings = []) - {} - - /** - * Add a "having" clause to the query. - * - * @param non-empty-string $column - * @param non-empty-string|null $operator - * @param non-empty-string|null $value - * @param non-empty-string $boolean - * @return $this - */ - public function having($column, $operator = null, $value = null, $boolean = 'and') - {} - - /** - * Add a "or having" clause to the query. - * - * @param non-empty-string $column - * @param non-empty-string|null $operator - * @param non-empty-string|null $value - * @return $this - */ - public function orHaving($column, $operator = null, $value = null) - {} - - /** - * Add a "having between " clause to the query. - * - * @param non-empty-string $column - * @param array $values - * @param non-empty-string $boolean - * @param bool $not - * @return $this - */ - public function havingBetween($column, array $values, $boolean = 'and', $not = false) - {} - - /** - * Add a raw having clause to the query. - * - * @param non-empty-string $sql - * @param array $bindings - * @param non-empty-string $boolean - * @return $this - */ - public function havingRaw($sql, array $bindings = [], $boolean = 'and') - {} - - /** - * Add a raw or having clause to the query. - * - * @param non-empty-string $sql - * @param array $bindings - * @return $this - */ - public function orHavingRaw($sql, array $bindings = []) - {} - - /** - * Add an "order by" clause to the query. - * - * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Query\Expression|non-empty-string $column - * @param non-empty-string $direction - * @return $this - * - * @throws \InvalidArgumentException - */ - public function orderBy($column, $direction = 'asc') - {} - - /** - * Add a descending "order by" clause to the query. - * - * @param non-empty-string $column - * @return $this - */ - public function orderByDesc($column) - {} - - /** - * Add an "order by" clause for a timestamp to the query. - * - * @param non-empty-string|\Illuminate\Database\Query\Expression $column - * @return $this - */ - public function latest($column = 'created_at') - {} - - /** - * Add an "order by" clause for a timestamp to the query. - * - * @param non-empty-string|\Illuminate\Database\Query\Expression $column - * @return $this - */ - public function oldest($column = 'created_at') - {} - - /** - * Put the query's results in random order. - * - * @param non-empty-string $seed - * @return $this - */ - public function inRandomOrder($seed = '') - {} - - /** - * Add a raw "order by" clause to the query. - * - * @param non-empty-string $sql - * @param array $bindings - * @return $this - */ - public function orderByRaw($sql, $bindings = []) - {} - - /** - * Alias to set the "offset" value of the query. - * - * @param int $value - * @return $this - */ - public function skip($value) - {} - - /** - * Set the "offset" value of the query. - * - * @param int $value - * @return $this - */ - public function offset($value) - {} - - /** - * Alias to set the "limit" value of the query. - * - * @param int $value - * @return $this - */ - public function take($value) - {} - - /** - * Set the "limit" value of the query. - * - * @param int $value - * @return $this - */ - public function limit($value) - {} - - /** - * Set the limit and offset for a given page. - * - * @param int $page - * @param int $perPage - * @return $this - */ - public function forPage($page, $perPage = 15) - {} - - /** - * Constrain the query to the previous "page" of results before a given ID. - * - * @param int $perPage - * @param int|null $lastId - * @param non-empty-string $column - * @return $this - */ - public function forPageBeforeId($perPage = 15, $lastId = 0, $column = 'id') - {} - - /** - * Constrain the query to the next "page" of results after a given ID. - * - * @param int $perPage - * @param int|null $lastId - * @param non-empty-string $column - * @return $this - */ - public function forPageAfterId($perPage = 15, $lastId = 0, $column = 'id') - {} - - /** - * Remove all existing orders and optionally add a new order. - * - * @param non-empty-string|null $column - * @param non-empty-string $direction - * @return $this - */ - public function reorder($column = null, $direction = 'asc') - {} - - /** - * Get an array with all orders with a given column removed. - * - * @param non-empty-string $column - * @return array - */ - protected function removeExistingOrdersFor($column) - {} - - /** - * Add a union statement to the query. - * - * @param \Illuminate\Database\Query\Builder|\Closure $query - * @param bool $all - * @return $this - */ - public function union($query, $all = false) - {} - - /** - * Add a union all statement to the query. - * - * @param \Illuminate\Database\Query\Builder|\Closure $query - * @return $this - */ - public function unionAll($query) - {} - - /** - * Lock the selected rows in the table. - * - * @param non-empty-string|bool $value - * @return $this - */ - public function lock($value = true) - {} - - /** - * Lock the selected rows in the table for updating. - * - * @return static - */ - public function lockForUpdate() - {} - - /** - * Share lock the selected rows in the table. - * - * @return $this - */ - public function sharedLock() - {} - - /** - * Execute a query for a single record by ID. - * - * @param int|non-empty-string $id - * @param array $columns - * @return mixed|static - */ - public function find($id, $columns = ['*']) - {} - - /** - * Throw an exception if the query doesn't have an orderBy clause. - * - * @return void - * - * @throws \RuntimeException - */ - protected function enforceOrderBy() - {} - - /** - * Get an array with the values of a given column. - * - * @param non-empty-string|\Illuminate\Database\Query\Expression $column - * @param non-empty-string|null $key - * @return \Illuminate\Support\Collection - */ - public function pluck($column, $key = null) - {} - - /** - * Concatenate values of a given column as a string. - * - * @param non-empty-string $column - * @param non-empty-string $glue - * @return string - */ - public function implode($column, $glue = '') - {} - - /** - * Determine if any rows exist for the current query. - * - * @return bool - */ - public function exists() - {} - - /** - * Determine if no rows exist for the current query. - * - * @return bool - */ - public function doesntExist() - {} - - /** - * Execute the given callback if no rows exist for the current query. - * - * @param \Closure $callback - * @return mixed - */ - public function existsOr(\Closure $callback) - {} - - /** - * Execute the given callback if rows exist for the current query. - * - * @param \Closure $callback - * @return mixed - */ - public function doesntExistOr(\Closure $callback) - {} - - /** - * Retrieve the "count" result of the query. - * - * @param non-empty-string $columns - * @return int - */ - public function count($columns = '*') - {} - - /** - * Retrieve the minimum value of a given column. - * - * @param non-empty-string $column - * @return mixed - */ - public function min($column) - {} - - /** - * Retrieve the maximum value of a given column. - * - * @param non-empty-string $column - * @return mixed - */ - public function max($column) - {} - - /** - * Retrieve the sum of the values of a given column. - * - * @param non-empty-string $column - * @return mixed - */ - public function sum($column) - {} - - /** - * Retrieve the average of the values of a given column. - * - * @param non-empty-string $column - * @return mixed - */ - public function avg($column) - {} - - /** - * Alias for the "avg" method. - * - * @param non-empty-string $column - * @return mixed - */ - public function average($column) - {} - - /** - * Execute an aggregate function on the database. - * - * @param non-empty-string $function - * @param array $columns - * @return mixed - */ - public function aggregate($function, $columns = ['*']) - {} - - /** - * Execute a numeric aggregate function on the database. - * - * @param non-empty-string $function - * @param array $columns - * @return float|int - */ - public function numericAggregate($function, $columns = ['*']) - {} - - /** - * Set the aggregate property without running the query. - * - * @param non-empty-string $function - * @param array $columns - * @return $this - */ - protected function setAggregate($function, $columns) - {} - - /** - * Execute the given callback while selecting the given columns. - * - * After running the callback, the columns are reset to the original value. - * - * @param array $columns - * @param callable $callback - * @return mixed - */ - protected function onceWithColumns($columns, $callback) - {} - - /** - * Insert a new record into the database. - * - * @param array $values - * @return bool - */ - public function insert(array $values) - {} - - /** - * Insert a new record into the database while ignoring errors. - * - * @param array $values - * @return int - */ - public function insertOrIgnore(array $values) - {} - - /** - * Insert a new record and get the value of the primary key. - * - * @param array $values - * @param non-empty-string|null $sequence - * @return int - */ - public function insertGetId(array $values, $sequence = null) - {} - - /** - * Insert new records into the table using a subquery. - * - * @param array $columns - * @param \Closure|\Illuminate\Database\Query\Builder|non-empty-string $query - * @return int - */ - public function insertUsing(array $columns, $query) - {} - - /** - * Update a record in the database. - * - * @param array $values - * @return int - */ - public function update(array $values) - {} - - /** - * Insert or update a record matching the attributes, and fill it with values. - * - * @param array $attributes - * @param array $values - * @return bool - */ - public function updateOrInsert(array $attributes, array $values = []) - {} - - /** - * Increment a column's value by a given amount. - * - * @param non-empty-string|\Illuminate\Database\Query\Expression $column - * @param float|int $amount - * @param array $extra - * @return int - * - * @throws \InvalidArgumentException - */ - public function increment($column, $amount = 1, array $extra = []) - {} - - /** - * Decrement a column's value by a given amount. - * - * @param non-empty-string|\Illuminate\Database\Query\Expression $column - * @param float|int $amount - * @param array $extra - * @return int - * - * @throws \InvalidArgumentException - */ - public function decrement($column, $amount = 1, array $extra = []) - {} - - /** - * Delete a record from the database. - * - * @param mixed $id - * @return int - */ - public function delete($id = null) - {} - - /** - * Run a truncate statement on the table. - * - * @return void - */ - public function truncate() - {} - - /** - * Get a new instance of the query builder. - * - * @return $this - */ - public function newQuery() - {} - - /** - * Get the current query value bindings in a flattened array. - * - * @return array - */ - public function getBindings() - {} - - /** - * Get the raw array of bindings. - * - * @return array - */ - public function getRawBindings() - {} - - /** - * Set the bindings on the query builder. - * - * @param array $bindings - * @param non-empty-string $type - * @return $this - * - * @throws \InvalidArgumentException - */ - public function setBindings(array $bindings, $type = 'where') - {} - - /** - * Add a binding to the query. - * - * @param mixed $value - * @param non-empty-string $type - * @return $this - * - * @throws \InvalidArgumentException - */ - public function addBinding($value, $type = 'where') - {} - - /** - * Merge an array of bindings into our bindings. - * - * @param \Illuminate\Database\Query\Builder $query - * @return $this - */ - public function mergeBindings(self $query) - {} -} diff --git a/php-packages/phpstan/stubs/Illuminate/Database/Relation.stub b/php-packages/phpstan/stubs/Illuminate/Database/Relation.stub deleted file mode 100644 index dff906308..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Database/Relation.stub +++ /dev/null @@ -1,24 +0,0 @@ - $columns - * @phpstan-return \Illuminate\Database\Eloquent\Collection - */ - public function get($columns = ['*']); - - - /** - * @param array, mixed> $attributes - * @phpstan-return TRelatedModel - */ - public function make(array $attributes = []); -} diff --git a/php-packages/phpstan/stubs/Illuminate/Enumerable.stub b/php-packages/phpstan/stubs/Illuminate/Enumerable.stub deleted file mode 100644 index 7fd2c1ea5..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Enumerable.stub +++ /dev/null @@ -1,58 +0,0 @@ - - */ -interface Enumerable extends \Countable, \IteratorAggregate, \JsonSerializable -{ - /** - * @param string|callable(TValue, TKey): bool $key - * @param mixed $operator - * @param mixed $value - * @return static - */ - public function partition($key, $operator = null, $value = null); - - /** - * @param string|callable(TValue, TKey): mixed $keyBy - * @return static - */ - public function keyBy($keyBy); - - /** - * @param callable(TValue, TKey): array $callback - * @return static - */ - public function mapWithKeys(callable $callback); - - /** - * @param callable(TValue, TKey): array $callback - * @return static> - */ - public function mapToDictionary(callable $callback); - - /** - * @param string|callable(TValue, TKey): bool $key - * @param mixed $operator - * @param mixed $value - * @return bool - */ - public function every($key, $operator = null, $value = null); - - /** - * @param int $size - * @return static - */ - public function chunk($size); - - /** - * @param callable(static): void $callable - * @return static - */ - public function tap($callable); -} diff --git a/php-packages/phpstan/stubs/Illuminate/EnumeratesValues.stub b/php-packages/phpstan/stubs/Illuminate/EnumeratesValues.stub deleted file mode 100644 index 6cc58f849..000000000 --- a/php-packages/phpstan/stubs/Illuminate/EnumeratesValues.stub +++ /dev/null @@ -1,36 +0,0 @@ - $average - * @property-read HigherOrderCollectionProxy<'avg', TValue> $avg - * @property-read HigherOrderCollectionProxy<'contains', TValue> $contains - * @property-read HigherOrderCollectionProxy<'each', TValue> $each - * @property-read HigherOrderCollectionProxy<'every', TValue> $every - * @property-read HigherOrderCollectionProxy<'filter', TValue> $filter - * @property-read HigherOrderCollectionProxy<'first', TValue> $first - * @property-read HigherOrderCollectionProxy<'flatMap', TValue> $flatMap - * @property-read HigherOrderCollectionProxy<'groupBy', TValue> $groupBy - * @property-read HigherOrderCollectionProxy<'keyBy', TValue> $keyBy - * @property-read HigherOrderCollectionProxy<'map', TValue> $map - * @property-read HigherOrderCollectionProxy<'max', TValue> $max - * @property-read HigherOrderCollectionProxy<'min', TValue> $min - * @property-read HigherOrderCollectionProxy<'partition', TValue> $partition - * @property-read HigherOrderCollectionProxy<'reject', TValue> $reject - * @property-read HigherOrderCollectionProxy<'some', TValue> $some - * @property-read HigherOrderCollectionProxy<'sortBy', TValue> $sortBy - * @property-read HigherOrderCollectionProxy<'sortByDesc', TValue> $sortByDesc - * @property-read HigherOrderCollectionProxy<'skipUntil', TValue> $skipUntil - * @property-read HigherOrderCollectionProxy<'skipWhile', TValue> $skipWhile - * @property-read HigherOrderCollectionProxy<'sum', TValue> $sum - * @property-read HigherOrderCollectionProxy<'takeUntil', TValue> $takeUntil - * @property-read HigherOrderCollectionProxy<'takeWhile', TValue> $takeWhile - * @property-read HigherOrderCollectionProxy<'unique', TValue> $unique - * @property-read HigherOrderCollectionProxy<'until', TValue> $until - */ -trait EnumeratesValues -{} diff --git a/php-packages/phpstan/stubs/Illuminate/Facades.stub b/php-packages/phpstan/stubs/Illuminate/Facades.stub deleted file mode 100644 index 30f2089af..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Facades.stub +++ /dev/null @@ -1,30 +0,0 @@ -app = $app; + } +} diff --git a/php-packages/phpstan/stubs/Illuminate/Helpers.stub b/php-packages/phpstan/stubs/Illuminate/Helpers.stub deleted file mode 100644 index f0fa8bd40..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Helpers.stub +++ /dev/null @@ -1,48 +0,0 @@ - $data - * @param array $mergeData - * @return mixed - */ -function view($view = null, $data = [], $mergeData = []) -{ -} diff --git a/php-packages/phpstan/stubs/Illuminate/HigherOrderProxies.stub b/php-packages/phpstan/stubs/Illuminate/HigherOrderProxies.stub deleted file mode 100644 index b3cf0f30a..000000000 --- a/php-packages/phpstan/stubs/Illuminate/HigherOrderProxies.stub +++ /dev/null @@ -1,24 +0,0 @@ - $data - * @return $this - */ - public function markdown($view, array $data = []) - {} - - /** - * @param view-string $view - * @param array $data - * @return $this - */ - public function view($view, array $data = []) - {} -} diff --git a/php-packages/phpstan/stubs/Illuminate/Pagination.stub b/php-packages/phpstan/stubs/Illuminate/Pagination.stub deleted file mode 100644 index 8c57cd079..000000000 --- a/php-packages/phpstan/stubs/Illuminate/Pagination.stub +++ /dev/null @@ -1,23 +0,0 @@ - - * @implements \IteratorAggregate - */ -class Paginator extends AbstractPaginator implements \Illuminate\Contracts\Support\Arrayable, \ArrayAccess, \Countable, \IteratorAggregate, \Illuminate\Contracts\Support\Jsonable, \JsonSerializable, \Illuminate\Contracts\Pagination\Paginator -{} - -/** - * @implements \ArrayAccess - * @implements \IteratorAggregate - */ -class LengthAwarePaginator extends AbstractPaginator implements \Illuminate\Contracts\Support\Arrayable, \ArrayAccess, \Countable, \IteratorAggregate, \Illuminate\Contracts\Support\Jsonable, \JsonSerializable, \Illuminate\Contracts\Pagination\LengthAwarePaginator -{} diff --git a/php-packages/phpstan/stubs/Illuminate/Queue/ListenerOptions.stub b/php-packages/phpstan/stubs/Illuminate/Queue/ListenerOptions.stub new file mode 100644 index 000000000..c77b7600d --- /dev/null +++ b/php-packages/phpstan/stubs/Illuminate/Queue/ListenerOptions.stub @@ -0,0 +1,13 @@ +