From 8f756f995f8eb2423c4c3d664b6e21aa2eb8fa06 Mon Sep 17 00:00:00 2001 From: Julien Roche Date: Mon, 7 Jul 2025 16:12:59 +0200 Subject: [PATCH] Add larastan extension for trans helper --- composer.json | 145 +++++++++--------- larastan/TransHelperReturnTypeExtension.php | 78 ++++++++++ .../TransHelperReturnTypeExtension.php | 15 ++ tests/Features/bootstrap.php | 11 ++ tests/Features/phpstan-tests.neon | 8 + 5 files changed, 188 insertions(+), 69 deletions(-) create mode 100644 larastan/TransHelperReturnTypeExtension.php create mode 100644 tests/Features/Default/TransHelperReturnTypeExtension.php create mode 100644 tests/Features/bootstrap.php diff --git a/composer.json b/composer.json index 27f0548..db31079 100644 --- a/composer.json +++ b/composer.json @@ -1,72 +1,79 @@ { - "name": "soyhuce/phpstan-extension", - "description": "Extra rules for phpstan analysis", - "keywords": [ - "soyhuce", - "laravel", - "phpstan" - ], - "homepage": "https://github.com/soyhuce/phpstan-extension", - "license": "MIT", - "authors": [ - { - "name": "Bastien Philippe", - "email": "bastien.philippe@soyhuce.fr", - "role": "Developer" - } - ], - "require": { - "php": "^8.3", - "illuminate/support": "^11.0|^12.0", - "nesbot/carbon": "^3.0", - "phpstan/phpstan": "^2.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.7", - "larastan/larastan": "^3.0", - "nunomaduro/collision": "^8.0", - "orchestra/testbench": "^9.0|^10.0", - "pestphp/pest": "^3.0", - "pestphp/pest-plugin-laravel": "^3.0", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan-deprecation-rules": "^2.0", - "phpstan/phpstan-phpunit": "^2.0" - }, - "autoload": { - "psr-4": { - "Soyhuce\\PhpstanExtension\\": "src" - } - }, - "autoload-dev": { - "psr-4": { - "Soyhuce\\PhpstanExtension\\Tests\\": "tests" - } + "name": "soyhuce/phpstan-extension", + "description": "Extra rules for phpstan analysis", + "keywords": [ + "soyhuce", + "laravel", + "phpstan" + ], + "homepage": "https://github.com/soyhuce/phpstan-extension", + "license": "MIT", + "authors": [ + { + "name": "Bastien Philippe", + "email": "bastien.philippe@soyhuce.fr", + "role": "Developer" + } + ], + "require": { + "php": "^8.3", + "illuminate/support": "^11.0|^12.0", + "nesbot/carbon": "^3.0", + "phpstan/phpstan": "^2.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.7", + "larastan/larastan": "^3.0", + "nunomaduro/collision": "^8.0", + "orchestra/testbench": "^9.0|^10.0", + "pestphp/pest": "^3.0", + "pestphp/pest-plugin-laravel": "^3.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0" + }, + "autoload": { + "psr-4": { + "Soyhuce\\PhpstanExtension\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Soyhuce\\PhpstanExtension\\Tests\\": "tests", + "Larastan\\Larastan\\ReturnTypes\\": "larastan" }, - "scripts": { - "cs": "vendor/bin/php-cs-fixer fix", - "analyse": "vendor/bin/phpstan analyse", - "test": "vendor/bin/pest", - "test-coverage": "vendor/bin/pest --coverage", - "all": [ - "@cs", - "@test", - "@analyse" - ] - }, - "config": { - "sort-packages": true, - "allow-plugins": { - "pestphp/pest-plugin": true, - "phpstan/extension-installer": true - } - }, - "extra": { - "phpstan": { - "includes": [ - "extension.neon" - ] - } - }, - "minimum-stability": "dev", - "prefer-stable": true + "exclude-from-classmap": [ + "Larastan\\Larastan\\ReturnTypes\\TransHelperReturnTypeExtension" + ], + "files": [ + "larastan/TransHelperReturnTypeExtension.php" + ] + }, + "scripts": { + "cs": "vendor/bin/php-cs-fixer fix", + "analyse": "vendor/bin/phpstan analyse", + "test": "vendor/bin/pest", + "test-coverage": "vendor/bin/pest --coverage", + "all": [ + "@cs", + "@test", + "@analyse" + ] + }, + "config": { + "sort-packages": true, + "allow-plugins": { + "pestphp/pest-plugin": true, + "phpstan/extension-installer": true + } + }, + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "minimum-stability": "dev", + "prefer-stable": true } diff --git a/larastan/TransHelperReturnTypeExtension.php b/larastan/TransHelperReturnTypeExtension.php new file mode 100644 index 0000000..74d8f0d --- /dev/null +++ b/larastan/TransHelperReturnTypeExtension.php @@ -0,0 +1,78 @@ +getName() === 'trans'; + } + + public function getTypeFromFunctionCall( + FunctionReflection $functionReflection, + FuncCall $functionCall, + Scope $scope, + ): Type { + if (count($functionCall->args) === 0) { + return new ObjectType(Translator::class); + } + + $firstArg = $functionCall->args[0]->value; + $type = $scope->getType($firstArg); + + if (!$type instanceof ConstantStringType) { + return new BenevolentUnionType([ + new ArrayType(new MixedType(), new MixedType()), + new StringType(), + ]); + } + + $key = $type->getValue(); + + $translatedValue = app(Translator::class)->get($key); + + return $this->getTypeFromValue($translatedValue); + } + + private function getTypeFromValue(mixed $value): Type + { + if (is_array($value)) { + return new ArrayType(new MixedType(), new MixedType()); + } + + if (is_string($value)) { + return new StringType(); + } + + if (is_int($value)) { + return new IntegerType(); + } + + if (is_float($value)) { + return new FloatType(); + } + + if (is_bool($value)) { + return new BooleanType(); + } + + return new MixedType(); + } +} diff --git a/tests/Features/Default/TransHelperReturnTypeExtension.php b/tests/Features/Default/TransHelperReturnTypeExtension.php new file mode 100644 index 0000000..a896d62 --- /dev/null +++ b/tests/Features/Default/TransHelperReturnTypeExtension.php @@ -0,0 +1,15 @@ +addLines( + [ + 'example.array' => ['foo', 'bar'], + 'example.string' => 'Hello, World!', + ], + 'en' +); diff --git a/tests/Features/phpstan-tests.neon b/tests/Features/phpstan-tests.neon index c35e4c5..34bf0d8 100644 --- a/tests/Features/phpstan-tests.neon +++ b/tests/Features/phpstan-tests.neon @@ -5,3 +5,11 @@ services: - class: Soyhuce\PhpstanExtension\ReturnTypes\RequestDateExtension tags: - phpstan.broker.dynamicMethodReturnTypeExtension + + - class: Larastan\Larastan\ReturnTypes\TransHelperReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + +parameters: + bootstrapFiles: + - bootstrap.php