psalm / psalm-plugin-laravel Goto Github PK
View Code? Open in Web Editor NEWA Psalm plugin for Laravel
License: MIT License
A Psalm plugin for Laravel
License: MIT License
Describe the bug
ERROR: InvalidReturnStatement - app/Http/Controllers/Api/V1/UserController.php:58:16 - The inferred type 'Illuminate\Contracts\Routing\ResponseFactory|Illuminate\Http\Response' does not match the declared return type 'Illuminate\Http\Response' for App\Http\Controllers\Api\V1\UserController::storeCoupon (see https://psalm.dev/128)
return response('OK');
Impacted Versions
barryvdh/laravel-ide-helper dev-master a233d5b Laravel IDE Helper, generates
laravel/framework v5.8.37 The Laravel Framework.
psalm/plugin-laravel dev-eloquent-collection c2e30af A Laravel plugin for Psalm
vimeo/psalm 3.11.2 A static analysis tool for finding er...
Additional context
We just need to write a simple stub for the response helper
Describe the bug
Initial installation on Laravel 6.0 is not possible due to dependencies conflict.
Impacted Versions
barryvdh/laravel-debugbar v3.2.9 PHP Debugbar integration for Laravel
fruitcake/laravel-cors v1.0.4 Adds CORS (Cross-Origin Resource Sharing) headers support in y...
laravel/framework v6.0.0 The Laravel Framework.
laravel/tinker v1.0.10 Powerful REPL for the Laravel framework.
vimeo/psalm 3.12.0 A static analysis tool for finding errors in PHP applications
Additional context
Using version ^1.3 for psalm/plugin-laravel
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Installation request for composer/semver (locked at 3.0.0) -> satisfiable by composer/semver[3.0.0].
- psalm/plugin-laravel 1.x-dev requires barryvdh/laravel-ide-helper ^2.7 -> satisfiable by barryvdh/laravel-ide-helper[v2.7.0].
- psalm/plugin-laravel v1.3.0 requires barryvdh/laravel-ide-helper ^2.7 -> satisfiable by barryvdh/laravel-ide-helper[v2.7.0].
- Conclusion: don't install barryvdh/laravel-ide-helper v2.7.0
- Installation request for psalm/plugin-laravel ^1.3 -> satisfiable by psalm/plugin-laravel[1.x-dev, v1.3.0].
I'm getting these kinds of errors when running psalm in a github action:
ERROR: UndefinedMagicPropertyFetch - app/Context/Balance/Projectors/BalanceProjector.php:35:9 - Magic instance property Illuminate\Database\Eloquent\Model::$amount is not defined (see https://psalm.dev/218)
$balance->amount += $event->amount;
Running psalm locally doesn't yield these errors. I'm sure _ide_helper_models.php
is available within the github action, since it's committed in the repository.
Is your feature request related to a problem? Please describe.
Let's clone our supported laravel releases during our CI pipeline and run this plugin and an accompanying baseline file on them. That will help to ensure that we don't have any regressions.
Describe the solution you'd like
Larastan and psalm itself both do something similar -- let's use them for inspiration
Describe the bug
the first
method of BelongsToMany has wrong return type. It can return model or null, but described only model. Also the method has some code in body.
And on checking I get that error:
INFO: RedundantConditionGivenDocblockType - app\User.php:83:16 - Docblock-defined type TRelatedModel can never contain null (see https://psalm.dev/156)
&& null !== $this->roles()->where('name', $role)->first();
Impacted Versions
barryvdh/laravel-ide-helper v2.8.0 Laravel IDE Helper, generates correct PHPDocs for all Facad...
laravel/framework v5.8.38 The Laravel Framework.
laravel/tinker v1.0.10 Powerful REPL for the Laravel framework.
matt-allan/laravel-code-style 0.5.1 Code formatting for Laravel projects
psalm/plugin-laravel v1.4.0 A Laravel plugin for Psalm
vimeo/psalm 3.17.2 A static analysis tool for finding errors in PHP applications
Additional context
I think problem is here:
* @psalm-return TRelatedModel|null
Is your feature request related to a problem? Please describe.
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
/**
* @psalm-return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\User>
*/
public function users()
{
return $this->hasMany(User::class);
}
public function something()
{
return $this->users()->first();
}
}
The return type of something()
type should be known and it should be \App\Models\User|null
.
Describe the solution you'd like
The solution would be to support template in all of the relationship calls like in the above example.
ERROR: MixedMethodCall - app/Http/Middleware/RedirectIfAuthenticated.php:21:34 - Cannot determine the type of the object on the left hand side of this expression (see https://psalm.dev/015)
if (Auth::guard($guard)->check()) {
on a fresh laravel install
we need to add support for the likes of
app()
and resolve()
global helpers to return instances of Application
with no args, or else proxy the method call to Container::make
Container::make
needs support to take a classname as first parameter, and returns an instance of that classnameCurrently, the likes of base_path()
emits an UnresolvableInclude
.
These are all of the path helpers to add support for
/**
* Get the base path of the Laravel installation.
*
* @return string
*/
public function basePath();
/**
* Get the path to the bootstrap directory.
*
* @param string $path Optionally, a path to append to the bootstrap path
* @return string
*/
public function bootstrapPath($path = '');
/**
* Get the path to the application configuration files.
*
* @param string $path Optionally, a path to append to the config path
* @return string
*/
public function configPath($path = '');
/**
* Get the path to the database directory.
*
* @param string $path Optionally, a path to append to the database path
* @return string
*/
public function databasePath($path = '');
/**
* Get the path to the environment file directory.
*
* @return string
*/
public function environmentPath();
/**
* Get the path to the resources directory.
*
* @param string $path
* @return string
*/
public function resourcePath($path = '');
/**
* Get the path to the storage directory.
*
* @return string
*/
public function storagePath();
Hi, I'm trying to use this plugin in conjunction with Psalm on Laravel v5.8.19 but after following the instructions I receive the following error when running Psalm:
ErrorException : Undefined property: Psalm\Type\Atomic\TNonEmptyList::$type_params
at /home/me/project/vendor/vimeo/psalm/src/Psalm/Internal/Scanner/PhpStormMetaScanner.php:345
341| if ($array_atomic_type instanceof Type\Atomic\ObjectLike) {
342| return $array_atomic_type->getGenericValueType();
343| }
344|
> 345| return clone $array_atomic_type->type_params[1];
346| }
347| }
348|
349| if (!$statements_analyzer instanceof StatementsAnalyzer) {
Exception trace:
1 Illuminate\Foundation\Bootstrap\HandleExceptions::handleError("Undefined property: Psalm\Type\Atomic\TNonEmptyList::$type_params", "/home/me/project/vendor/vimeo/psalm/src/Psalm/Internal/Scanner/PhpStormMetaScanner.php")
/home/me/project/vendor/vimeo/psalm/src/Psalm/Internal/Scanner/PhpStormMetaScanner.php:345
2 Psalm\Internal\Scanner\PhpStormMetaScanner::Psalm\Internal\Scanner\{closure}(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), "last", Object(Psalm\Context), Object(Psalm\CodeLocation))
/home/me/project/vendor/vimeo/psalm/src/Psalm/Internal/Provider/FunctionReturnTypeProvider.php:114
We need to template model factories and create a return type provider to decide if a collection or model instance will be returned
This is mainly a reference to this, but more broadly for the whole of Laravel: vimeo/psalm#2489
List of issues to handle: vimeo/psalm#2489 (comment)
Currently getting 695 extra errors when I add --find-unused-code
😬 (on a different code base than above)
One of these days I'll put aside some time to fix this.
Even though it doesn't extend ArrayAccess
.
Illuminate\Container\Container::make
is the underlying method called - there should be some sort of shortcut that allows Psalm to invoke that method and get the return type.
Since Laravel collections are quite popular and I'm not sure that it will be typed (I mean template annotations in Laravel code; see this laravel/framework#31486 (comment)), I would like to suggest adding stubs for Collection.
Problem:
I am implementing an interface but psalm is not recognizing that it is an instance of that interface.
Example:
# User.php
<?php
namespace App\Models\Acl;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable;
class User extends Model implements Authenticable {
/** stuff */
}
# Controller.php
<?php
namespace App\Http\Controllers;
use Auth;
use App\Models\Acl\User;
class SomeController {
public function login()
{
$user = User::first();
Auth::login($user); // **Psalm Error**
}
}
/*
**Psalm Error:**
Argument 1 of Auth::login expects Illuminate\Contracts\Auth\Authenticatable, App\Models\Acl\User provided
So that was pretty weird,
then I looked into vendor/psalm/plugin-laravel/src/cache/models.php
namespace App\Models\Acl{
/**
* App\Models\Acl\User
*
* @property int $id
* @property string $name
* @property string $email
* @property string $password
* @property string $remember_token
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property int|null $role_id
* @property \Illuminate\Support\Carbon|null $last_active
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property string|null $surname
* @property string|null $telephone
* @property int|null $reference_id
* @property bool $login_allowed
* @property int|null $salutation_id
* @method static bool|null forceDelete()
* @method static \Illuminate\Database\Query\Builder|\App\Models\Acl\User onlyTrashed()
* @method static bool|null restore()
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Acl\User whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Acl\User whereDeletedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Acl\User whereEmail($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Acl\User whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Acl\User whereLastActive($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Acl\User whereLoginAllowed($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Acl\User whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Acl\User wherePassword($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Acl\User whereReferenceId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Acl\User whereRememberToken($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Acl\User whereRoleId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Acl\User whereSalutationId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Acl\User whereSurname($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Acl\User whereTelephone($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Acl\User whereUpdatedAt($value)
* @method static \Illuminate\Database\Query\Builder|\App\Models\Acl\User withTrashed()
* @method static \Illuminate\Database\Query\Builder|\App\Models\Acl\User withoutTrashed()
*/
class User extends \Eloquent {}
}
so I changed the following line:
class User extends \Eloquent {}
to
class User extends \Eloquent implements \Illuminate\Contracts\Auth\Authenticatable {}
So I think that when we generate the stub we will also need to include the interfaces for these models.
Also note that if I disable the laravel plugin psalm doesn't find any errors with the file in question :/
If someone could give me a rough idea of what the solution could look like I don't mind diving into it,
If you'd like me to setup a demo repo I also don't mind doing that- let me know how I can help!
Is your feature request related to a problem? Please describe.
$disk = Storage::disk('resources');
$path = 'definitions/features/';
foreach ($disk->files($path) as $file) {
//
}
Describe the bug
After updating to 1.4.0 version, psalm was crashed by following error
░░░░░░[2020-08-21 19:05:05] development.ERROR: Could not get class storage for
Stack trace in the forked worker:
#0 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.php(340): Psalm\Internal\Provider\ClassLikeStorageProvider->get()
#1 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/MethodCallAnalyzer.php(173): Psalm\Internal\Analyzer\Statements\Expression\Call\Method\AtomicMethodCallAnalyzer::analyze()
#2 /myproject/vendor/psalm/plugin-laravel/src/ReturnTypeProvider/ModelReturnTypeProvider.php(86): Psalm\Internal\Analyzer\Statements\Expression\Call\MethodCallAnalyzer::analyze()
#3 /myproject/vendor/psalm/plugin-laravel/src/ReturnTypeProvider/ModelReturnTypeProvider.php(49): Psalm\LaravelPlugin\ReturnTypeProvider\ModelReturnTypeProvider::executeFakeCall()
#4 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Provider/MethodReturnTypeProvider.php(108): Psalm\LaravelPlugin\ReturnTypeProvider\ModelReturnTypeProvider::getMethodReturnType()
#5 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticCallAnalyzer.php(985): Psalm\Internal\Provider\MethodReturnTypeProvider->getReturnType()
#6 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(154): Psalm\Internal\Analyzer\Statements\Expression\Call\StaticCallAnalyzer::analyze()
#7 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(45): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::handleExpression()
#8 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/MethodCallAnalyzer.php(50): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze()
#9 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(150): Psalm\Internal\Analyzer\Statements\Expression\Call\MethodCallAnalyzer::analyze()
#10 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(45): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::handleExpression()
#11 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php(164): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze()
#12 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(131): Psalm\Internal\Analyzer\Statements\Expression\AssignmentAnalyzer::analyze()
#13 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(45): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::handleExpression()
#14 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php(500): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze()
#15 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php(169): Psalm\Internal\Analyzer\StatementsAnalyzer::analyzeStatement()
#16 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php(570): Psalm\Internal\Analyzer\StatementsAnalyzer->analyze()
#17 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ClassAnalyzer.php(1921): Psalm\Internal\Analyzer\FunctionLikeAnalyzer->analyze()
#18 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ClassAnalyzer.php(748): Psalm\Internal\Analyzer\ClassAnalyzer->analyzeClassMethod()
#19 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FileAnalyzer.php(221): Psalm\Internal\Analyzer\ClassAnalyzer->analyze()
#20 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(349): Psalm\Internal\Analyzer\FileAnalyzer->analyze()
#21 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Fork/Pool.php(184): Psalm\Internal\Codebase\Analyzer->Psalm\Internal\Codebase\{closure}()
#22 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(415): Psalm\Internal\Fork\Pool->__construct()
#23 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(275): Psalm\Internal\Codebase\Analyzer->doAnalysis()
#24 /myproject/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php(632): Psalm\Internal\Codebase\Analyzer->analyzeFiles()
#25 /myproject/vendor/vimeo/psalm/src/psalm.php(680): Psalm\Internal\Analyzer\ProjectAnalyzer->check()
#26 /myproject/vendor/vimeo/psalm/psalm(2): require_once('/home/user/mypr...')
#27 {main}
at vendor/vimeo/psalm/src/Psalm/Internal/Fork/Pool.php:348
344| if ($this->task_done_closure !== null) {
345| ($this->task_done_closure)($message->data);
346| }
347| } elseif ($message instanceof ForkProcessErrorMessage) {
> 348| throw new \Exception($message->message);
349| } else {
350| error_log('Child should return ForkMessage - response type=' . gettype($message));
351| $this->did_have_error = true;
352| }
Impacted Versions
barryvdh/laravel-ide-helper v2.8.0
laravel/framework v7.25.0
vimeo/psalm 3.14.1
psalm/plugin-laravel v1.4.0
I have Psalm 3.7 installed. When I run
composer require --dev psalm/plugin-laravel
Composer tells me:
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Installation request for psalm/plugin-laravel ^0.7.0 -> satisfiable by psalm/plugin-laravel[0.7].
- psalm/plugin-laravel 0.7 requires vimeo/psalm 3.2.|3.3.|3.4.|3.5.|3.6.* -> satisfiable by vimeo/psalm[3.2, 3.2.10, 3.2.11, 3.2.12, 3.2.2, 3.2.3, 3.2.4, 3.2.5, 3.2.6, 3.2.7, 3.2.8, 3.2.9, 3.3.0, 3.3.1, 3.3.2, 3.4.0, 3.4.1, 3.4.10, 3.4.11, 3.4.12, 3.4.2, 3.4.3, 3.4.4, 3.4.5, 3.4.6, 3.4.7, 3.4.8, 3.4.9, 3.5.0, 3.5.1, 3.5.2, 3.5.3, 3.6.0, 3.6.1, 3.6.2, 3.6.3, 3.6.4, 3.6.5, 3.6.6] but these conflict with your requirements or minimum-stability.
After installing psalm, the Laravel plug-in and enabling the plug-in, I get the following error message:
PHP Fatal error: Declaration of Psalm\LaravelPlugin\AppInterfaceProvider::getMethodReturnType(Psalm\StatementsSource $statements_source, string $fq_classlike_name, string $method_name_lowercase, array $call_args, Psalm\Context $context, ?Psalm\CodeLocation $code_location = NULL, ?array $template_type_parameters = NULL) must be compatible with Psalm\Plugin\Hook\MethodReturnTypeProviderInterface::getMethodReturnType(Psalm\StatementsSource $source, string $fq_classlike_name, string $method_name_lowercase, array $call_args, Psalm\Context $context, Psalm\CodeLocation $code_location, ?array $template_type_parameters = NULL, ?string $called_fq_classlike_name = NULL, ?string $called_method_name_lowercase = NULL) in /Users/wgriffioen/project/vendor/psalm/plugin-laravel/src/AppInterfaceProvider.php on line 11
After I've altered the method to be compatible with the interface, I've been able to run Psalm successfully.
cc @weirdan in case this interest you at all
Describe the bug
ERROR: TooManyTemplateParams - app/Context/Product/Models/FieldOfStudy.php:26:16 - Illuminate\Database\Eloquent\Relations\MorphToMany<App\Context\Product\Types\Event\Models\Event> has too many template params, expecting 0 (see https://psalm.dev/184)
return $this->morphedByMany(Event::class, 'product');
ERROR: TooManyTemplateParams - app/Context/Product/Models/ProductAttribute.php:23:16 - Illuminate\Database\Eloquent\Relations\MorphToMany<App\Context\Product\Types\Event\Models\Event> has too many template params, expecting 0 (see https://psalm.dev/184)
return $this->morphedByMany(
Event::class,
'assigned_attribute',
'product_assigned_attributes'
);
ERROR: TooManyTemplateParams - app/Context/Product/Types/Event/Models/Event.php:107:16 - Illuminate\Database\Eloquent\Relations\MorphToMany<App\Context\Product\Models\FieldOfStudy> has too many template params, expecting 0 (see https://psalm.dev/184)
return $this->morphToMany(
FieldOfStudy::class,
'product',
'product_field_of_study',
'product_uuid'
)->withPivot('credit_hours');
Impacted Versions
dev-master
Additional context
@brendt reported here: #62 (comment)
Describe the bug
facade/ignition#292 (comment)
ala
app('log)`
Impacted Versions
all
Additional context
Laravel-ide-helper already determines the type for each of these aliases by resolving them from the container. We can probably reuse that logic somehow, or else apply the same technique
Describe the bug
As of Laravel 8.3.0 (this commit), the RouteServiceProvider
uses the helper optional()
, which causes the following errors:
ERROR: MixedPropertyFetch - app/Providers/RouteServiceProvider.php:60:45 - Cannot fetch property on mixed var (see https://psalm.dev/034)
return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
ERROR: MixedArgument - app/Providers/RouteServiceProvider.php:60:45 - Argument 1 of Illuminate\Cache\RateLimiting\Limit::by cannot be non-empty-mixed|null|string, expecting string (see https://psalm.dev/030)
return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
ERROR: PossiblyNullArgument - app/Providers/RouteServiceProvider.php:60:45 - Argument 1 of Illuminate\Cache\RateLimiting\Limit::by cannot be null, possibly null value provided (see https://psalm.dev/078)
return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
Impacted Versions
Affects Laravel 8.3.0 and later.
Additional context
I guess this could be fixed by adding stubs for both the optional()
function and the Optional
class:
optional()
returns an Optional
object if it's second $callback
parameter is omitted.Optional::__get()
returns null
unless the optional value is an object.However, I'm not sure if it is possible to declare that Optional::__get()
returns the value of the corresponding property (magic or not) on the value.
As for the PossiblyNullArgument
, this would probably require to update the Limit::by()
signature to accept string|null
, since Request::ip()
can return null
.
PS: A workaround is to modify RouteServiceProvider::configureRateLimiting()
as follows:
/**
* Configure the rate limiters for the application.
*
* @return void
*/
protected function configureRateLimiting()
{
RateLimiter::for('api', function (Request $request) {
/** @var User|null $user */
$user = $request->user();
/** @var \Illuminate\Support\Optional $optional */
$optional = optional($user);
/** @var string $key */
$key = $optional->id ?: $request->ip();
return Limit::perMinute(60)->by($key);
});
}
Is your feature request related to a problem? Please describe.
https://github.com/facade/ignition/pull/292/files#r455046472
Describe the bug
I have some code that Psalm okays when psalm/plugin-laravel
is disabled. When psalm/plugin-laravel
is enabled, I get an Undefined index: wrap
error. Full repro at https://github.com/AlbinoDrought/repro-psalm-laravel-undefined-index
I have this resource:
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
/**
* @property-read \App\User $resource
*/
class User extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->resource->id,
'name' => $this->resource->name,
];
}
}
I have this controller:
<?php
namespace App\Http\Controllers;
use App\Http\Resources\User as UserResource;
use App\User;
class UserController extends Controller
{
public function __construct()
{
UserResource::$wrap = 'items';
}
public function show(User $user)
{
return new UserResource($user);
}
}
I see
Getting /app/app/Http/Controllers/UserController.php
Analyzing /app/app/Http/Controllers/UserController.php
ErrorException
Undefined index: wrap
at vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php:318
314| }
315| }
316|
317| $class_storage = $codebase->classlike_storage_provider->get($declaring_property_class);
> 318| $property = $class_storage->properties[$prop_name];
319|
320| if ($var_id) {
321| if ($property->type) {
322| $context->vars_in_scope[$var_id] = \Psalm\Internal\Type\TypeExpander::expandUnion(
The Undefined index: $wrap
error is triggered by UserResource::$wrap = 'items';
.
I have a full repro repository at https://github.com/AlbinoDrought/repro-psalm-laravel-undefined-index
Impacted Versions
barryvdh/laravel-ide-helper v2.7.0 Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.
fruitcake/laravel-cors v1.0.6 Adds CORS (Cross-Origin Resource Sharing) headers support in your Laravel application
laravel/framework v7.19.1 The Laravel Framework.
laravel/tinker v2.4.1 Powerful REPL for the Laravel framework.
psalm/plugin-laravel v1.3.1 A Laravel plugin for Psalm
vimeo/psalm 3.12.2 A static analysis tool for finding errors in PHP applications
Additional context
For what it's worth, PHPStorm detects the $wrap
property:
EDIT: Still occurs with psalm/plugin-laravel:1.4.2
and vimeo/psalm:4.4.1
, updated repro and added Github Actions https://github.com/AlbinoDrought/repro-psalm-laravel-undefined-index/actions
Describe the bug
Context: vimeo/psalm#3449
It seems psalm crashes on the first run when \Eloquent
is referenced. If this is the case, we will want to provide better messaging in Psalm, as well as documentation here around how to resolve.
Impacted Versions
Unknown.
Since we are generating ide-helper files, phpstorm complains about multiple class definitions.
Perhaps we should consider moving ide-helper to a suggested peer dependency, as I assume a lot of laravel developers will already have it installed and the files generated. Then the developer can configure the path to their phpstorm stubs file if they would like.
Laravel makes use of the variadic function pattern quite a bit. (func_get_args is used 110 times in the Framework code.) Even a Laravel skeleton project starts out with this error:
ERROR: TooManyArguments - app/Http/Controllers/Auth/VerificationController.php:34:44 - Too many arguments for method Illuminate\Routing\ControllerMiddlewareOptions::only - expecting 1 but saw 2
$this->middleware('throttle:6,1')->only('verify', 'resend');
vimeo/psalm#605 suggested plugin-based stubbing, which seems like it might be appropriate here.
Seems like the latest version on packagist is 0.7. Can we get this updated?
Model scope:
public function scopeAuthoredBy($query, User $user)
{
return $query->whereHas('author', function ($subQuery) use ($user) {
$subQuery->where('id', $user->id);
});
}
Implementation:
/**
* @return \Illuminate\Http\JsonResponse
*/
public function recentlyAuthored()
{
$reports = Report::with('categories', 'customer')
->authoredBy(Auth::user())
->latest()
->get()
->take(5);
return response()->json(ReportResource::collection($reports));
}
Psalm's result:
ERROR: UndefinedMagicMethod - app\Http\Controllers\AdminDashboardController.php:18:15 - Magic method Illuminate\Database\Eloquent\Builder::authoredby does not exist
->authoredBy(Auth::user())
vimeo/psalm: 3.9.3
psalm/plugin-laravel: 1.1.0
laravel/framework: 5.6.39
Illuminate\Support\Facades\Date
seems to have only been introduced in laravel 6
Describe the bug
When running psalm, an error occurs with the message: Could not get class storage for
. This is happening in the ClassLikeStorageProvider
, here: https://github.com/vimeo/psalm/blob/master/src/Psalm/Internal/Provider/ClassLikeStorageProvider.php#L41-L48. This method is getting called from here: https://github.com/vimeo/psalm/blob/master/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.php#L339-L341
It seems that the $fq_classlike_name
parameter of the get
method is null
. I've dumped $class_storage
and it represents \Illuminate\Database\Eloquent\Builder
, that's why I'm creating the issue here and not in the main psalm repository.
When running vendor/bin/psalm --debug-by-line
this piece of code, especially the query
bit pops up:
return Cart::query()
->where('user_uuid', $this->user->getUuid())
->where('uuid', $this->session->get('cart_uuid'))
->exists();
Cart is just a regular Laravel model nothin special there.
Impacted Versions
barryvdh/laravel-debugbar v3.4.1 PHP Debugbar int...
barryvdh/laravel-ide-helper v2.8.0 Laravel IDE Help...
beyondcode/laravel-dump-server 1.4.0 Symfony Var-Dump...
fruitcake/laravel-cors v1.0.6 Adds CORS (Cross...
inertiajs/inertia-laravel v0.2.5 The Laravel adap...
laravel/framework v7.25.0 The Laravel Fram...
laravel/horizon v4.3.3 Dashboard and co...
laravel/scout v8.2.1 Laravel Scout pr...
laravel/tinker v2.4.2 Powerful REPL fo...
propaganistas/laravel-phone 4.2.4 Adds phone numbe...
psalm/plugin-laravel dev-master 95761f9 A Laravel plugin...
spatie/laravel-backup 6.11.1 A Laravel packag...
spatie/laravel-db-snapshots 1.6.1 Quickly dump and...
spatie/laravel-event-sourcing 4.2.0 The easiest way ...
spatie/laravel-log-dumper 1.3.1 A function to du...
spatie/laravel-model-states 1.6.3
spatie/laravel-multitenancy 1.6.4 Make your Larave...
spatie/laravel-navigation dev-master 90dc440 Manage menus, br...
spatie/laravel-query-builder 2.8.2 Easily build Elo...
spatie/laravel-schemaless-attributes 1.7.1 Add schemaless a...
spatie/laravel-settings dev-master 1725356 Store your appli...
spatie/laravel-sluggable 2.5.0 Generate slugs w...
spatie/laravel-stubs 1.1.0 Opinionated Lara...
spatie/laravel-tail 4.2.1 Easily tail appl...
spatie/laravel-typescript-transformer dev-master 7a73107 Transform your P...
spatie/laravel-view-models 1.3.0 View models in L...
vimeo/psalm dev-master 9822043 A static analysi...
Any idea what the issue could be?
Describe the bug
if (app()->environment('production')) {
// do something
}
Impacted Versions
barryvdh/laravel-ide-helper v2.7.0 Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.
bugsnag/bugsnag-laravel v2.19.0 Official Bugsnag notifier for Laravel applications.
laravel/dusk v5.11.0 Laravel Dusk provides simple end-to-end testing and browser automation.
laravel/framework v7.19.1 The Laravel Framework.
laravel/helpers v1.2.0 Provides backwards compatibility for helpers in the latest Laravel release.
laravel/tinker v2.4.0 Powerful REPL for the Laravel framework.
laravel/ui v2.0.3 Laravel UI utilities and presets.
psalm/plugin-laravel v1.3.1 A Laravel plugin for Psalm
spatie/laravel-newsletter 4.8.0 Manage newsletters in Laravel
vimeo/psalm 3.12.2 A static analysis tool for finding errors in PHP applications
Additional context
N/A
There are small differences between a project generated models file, compared to psalm cached version:
This is an excerpt from models.stubphp
* @method static \Illuminate\Database\Eloquent\Builder|\App\Context\Product\Models\EventSession whereEndsAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Context\Product\Models\EventSession whereEventUuid($value)
While this is the project-level equivalent:
* @method static \Illuminate\Database\Eloquent\Builder|\App\Context\Product\Models\EventSession whereEndsAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Context\Product\Models\EventSession whereEvent(\App\Context\Product\Models\Event $event)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Context\Product\Models\EventSession whereEventUuid($value)
You can see that whereEvent
misses from the psalm version. The scope certainly exists btw. I've regenerated both the cached psalm file and the project file, they stay out of sync.
As a sidenote: how can I tell psalm to use my project-level ide helper file, instead of generating a new one?
Describe the bug
Adding this plugin to psalm v4.0.0 or v4.0.1 triggers "ErrorException : Undefined index: unguarded"
It wouldn't surprise me if there is some kind of clash with this class inheriting from our class named 'Model', which does a lot of Eloquent-y stuff. If I prune enough code it also seems to inhibit loading this plugin for some reason.
Memory usage was also to the order of 24GB 😅 when analyzing code it doesn't crash on. Instead of ~870MB without this plugin.
$ vendor/bin/psalm --debug --alter --issues="InvalidFalsableReturnType" Product/Module/Models/Group.php
[..]
Getting Product/Module/Models/Group.php
Analyzing Product/Module/Models/Group.php
ErrorException : Undefined index: unguarded
at vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php:317
313| }
314| }
315|
316| $class_storage = $codebase->classlike_storage_provider->get($declaring_property_class);
> 317| $property = $class_storage->properties[$prop_name];
318|
319| if ($var_id) {
320| if ($property->type) {
321| $context->vars_in_scope[$var_id] = \Psalm\Internal\Type\TypeExpander::expandUnion(
Exception trace:
1 Illuminate\Foundation\Bootstrap\HandleExceptions::handleError("Undefined index: unguarded", "vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php")
vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php:317
2 Psalm\Internal\Analyzer\Statements\Expression\Fetch\StaticPropertyFetchAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\StaticPropertyFetch), Object(Psalm\Context))
vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php:212
Please use the argument -v to see more details.
Impacted Versions
$ composer show | grep -E 'psalm|laravel'
barryvdh/laravel-ide-helper v2.8.1 Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.
cviebrock/laravel-elasticsearch 4.2.2 An easy way to use the official PHP ElasticSearch client in your Laravel applications.
laravel/framework v6.19.1 The Laravel Framework.
laravel/passport v9.3.2 Laravel Passport provides OAuth2 server support to Laravel.
laravel/tinker v2.4.2 Powerful REPL for the Laravel framework.
psalm/plugin-laravel v1.4.1 A Laravel plugin for Psalm
supliu/laravel-query-monitor 1.0.1 Laravel Query Monitor
vimeo/psalm 4.0.1 A static analysis tool for finding errors in PHP applications
Additional context
Minimized Product/Module/Models/Group.php:
<?php
namespace Apnvpn\Models;
use Product\Ldap\Model;
class Group extends Model
{
}
$ vendor/bin/psalm --version
Psalm 4.0.1@b1e2e30026936ef8d5bf6a354d1c3959b6231f44
I'm getting the following error after having upgraded to Laravel 7:
$ composer info | grep -P "(laravel|psalm)"
barryvdh/laravel-ide-helper v2.6.7 Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.
beyondcode/laravel-dump-server 1.4.0 Symfony Var-Dump Server for Laravel
laravel/framework v7.5.2 The Laravel Framework.
laravel/tinker v2.4.0 Powerful REPL for the Laravel framework.
psalm/plugin-laravel 1.1.1 A Laravel plugin for Psalm
vimeo/psalm 3.10.1 A static analysis tool for finding errors in PHP applications
$ vendor/bin/psalm
Scanning files...
Psalm\Exception\ConfigException
Failed to load plugin Psalm\LaravelPlugin\Plugin
at D:\path\to\project\vendor\vimeo\psalm\src\Psalm\Config.php:1173
1169| */
1170| $plugin_object = new $plugin_class_name;
1171| $plugin_object($socket, $plugin_config);
1172| } catch (\Throwable $e) {
> 1173| throw new ConfigException('Failed to load plugin ' . $plugin_class_name, 0, $e);
1174| }
1175|
1176| $project_analyzer->progress->debug('Loaded plugin ' . $plugin_class_name . ' successfully'. PHP_EOL);
1177| }
1 D:\path\to\project\vendor\laravel\framework\src\Illuminate\Auth\SessionGuard.php:105
TypeError::("Argument 2 passed to Illuminate\Auth\SessionGuard::__construct() must be an instance of Illuminate\Contracts\Auth\UserProvider, null given, called in D:\path\to\project\vendor\laravel\framework\src\Illuminate\Auth\AuthManager.php on line 125")
2 D:\path\to\project\vendor\laravel\framework\src\Illuminate\Auth\AuthManager.php:125
Illuminate\Auth\SessionGuard::__construct("web", Object(Illuminate\Session\Store))
I'm getting the following unexpected error on the RouteServiceProvider
that comes with Laravel and hasn't been modified by me:
ERROR: InvalidStaticInvocation - app\Providers\RouteServiceProvider.php:12:36 - Method Illuminate\Routing\Router::__construct is not static, but is called statically
class RouteServiceProvider extends ServiceProvider
Unfortunately I cannot suppress it using @psalm-suppress InvalidStaticInvocation
on the RouteServiceProvider
class either.
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider
{
/**
* This namespace is applied to your controller routes.
*
* In addition, it is set as the URL generator's root namespace.
*
* @var string
*/
protected $namespace = 'App\Http\Controllers';
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
{
//
parent::boot();
}
/**
* Define the routes for the application.
*
* @return void
*/
public function map()
{
$this->mapApiRoutes();
$this->mapWebRoutes();
//
}
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*
* @return void
*/
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*
* @return void
*/
protected function mapApiRoutes()
{
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
}
> ./vendor/bin/psalm --show-info=false
Scanning files...
Psalm\Exception\ConfigException
Failed to load plugin Psalm\LaravelPlugin\Plugin
at vendor/vimeo/psalm/src/Psalm/Config.php:1216
1212| */
1213| $plugin_object = new $plugin_class_name;
1214| $plugin_object($socket, $plugin_config);
1215| } catch (\Throwable $e) {
> 1216| throw new ConfigException('Failed to load plugin ' . $plugin_class_name, 0, $e);
1217| }
1218|
1219| $project_analyzer->progress->debug('Loaded plugin ' . $plugin_class_name . ' successfully' . PHP_EOL);
1220| }
I'm using these packages:
"php": "7.3.*"
"laravel/framework": "^7.24"
"psalm/plugin-laravel": "1.4.0"
"vimeo/psalm": "3.16"
Describe the bug
Contents of models.stubphp are incomplete. I get errors about missing model class properties. E.g. id. This was not an issue in 1.4.0 version. I don't get this issue with _ide_helper_models.php generated by barryvdh/laravel-ide-helper.
Impacted Versions
1.4.1 and 1.4.2
If I run psalm with a file specified, the following error is thrown:
psalm app/Context/Product/Actions/UpdateProductComplianceCardAction.php
Scanning files...
InvalidArgumentException
Could not get class storage for illuminate\support\facades\broadcast
at vendor/vimeo/psalm/src/Psalm/Internal/Provider/ClassLikeStorageProvider.php:45
41| public function get($fq_classlike_name)
42| {
43| $fq_classlike_name_lc = strtolower($fq_classlike_name);
44| if (!isset(self::$storage[$fq_classlike_name_lc])) {
> 45| throw new \InvalidArgumentException('Could not get class storage for ' . $fq_classlike_name_lc);
46| }
47|
48| return self::$storage[$fq_classlike_name_lc];
49| }
Running psalm on the whole codebase succeeds.
Describe the bug
I have an issue similar to @vladyslavstartsev’s #90.
On the project I currently want to refactor this plugin fails with endless memory consumption on one file every time.
I limited the Psalm config with the directory containing this file only, but this didn’t help.
Without the plugin Psalm runs okay but the results are unusable as they have many Laravel-specific issues.
Impacted Versions
$ composer show | grep -E 'psalm|laravel'
barryvdh/laravel-ide-helper v2.8.1 Laravel IDE Helper, generates correct PHPDocs for all F...
beyondcode/laravel-websockets 1.9.0 An easy to use WebSocket server
emadadly/laravel-uuid v1.3.2 laravel uuid a simple, automatic UUID generator for any...
fruitcake/laravel-cors v1.0.6 Adds CORS (Cross-Origin Resource Sharing) headers suppo...
laravel/framework v8.17.2 The Laravel Framework.
laravel/socialite v5.1.2 Laravel wrapper around OAuth 1 & OAuth 2 libraries.
laravel/tinker v2.5.0 Powerful REPL for the Laravel framework.
laravel/ui v2.3.0 Laravel UI utilities and presets.
laravelcollective/html v6.2.0 HTML and Form Builders for the Laravel Framework
orklah/psalm-insane-comparison v1.0.0 Detects possible insane comparison ("string" == 0) to h...
psalm/plugin-laravel v1.4.1 A Laravel plugin for Psalm
sentry/sentry-laravel 1.9.0 Laravel SDK for Sentry (https://sentry.io)
vimeo/psalm 4.3.1 A static analysis tool for finding errors in PHP applic...
Additional context
I can send you the whole project archive (in private only). Specific file which aborts the analysis is a hell of a mess, but in order to fix this it would be perfect to have some handy Psalm recomendations.
ERROR: UndefinedInterfaceMethod - tests/Feature/Tax/TaxServiceTest.php:1031:30 - Method Illuminate\Contracts\Foundation\Application::makewith does not exist (see https://psalm.dev/181)
$taxService = app()->makeWith(TaxService::class, ['taxVerification' => $taxVerification]);
We can probably figure out the app instance to use and return that, rather than the application interface which is missing some methods.
#57 will be a step in the right direction for helping this
Hi,
This package depends on orchestra/testbench:^3.5
, but none of the releases with that constraint are compatible with Laravel 6.
It looks like orchestra/testbench
needs to be updated to ^4.0
.
Psalm reported following error:
ERROR: InvalidArgument - app/Context/Product/Actions/UpdateEventGeneralCardAction.php:16:41 - Argument 2 of App\Context\Product\Actions\UpdateEventGeneralCardAction::saveProductDetail expects App\Context\Product\Models\ProductDetail, Illuminate\Database\Eloquent\Relations\BelongsTo provided (see https://psalm.dev/004)
$this->saveProductDetail($data, $event->productDetail);
It seems like it didn't recognise productDetail
as the relation.
So I did some digging in _ide_helper_models.php
, where the property seemed to exist:
* @property-read \App\Context\Product\Models\ProductDetail $productDetail
Looking at models.stubphp
in vendor/psalm/plugin-laravel/src/cache/models.stubphp
though, the property wasn't present. It seemed like this file was an outdated version.
I've tried reinstalling psalm/plugin-laravel
, but the same stub file, missing the property gets generated.
Any ideas?
We should have tests run on various versions of our dependencies.
Ie we should be testing on laravel 5.5, laravel 6, and laravel 7
Hi, thanks for this psalm plugin.
I tried this plugin, but failed with the following error
Psalm\Exception\ConfigException : Failed to load plugin Psalm\LaravelPlugin\Plugin
at /home/me/project/vendor/vimeo/psalm/src/Psalm/Config.php:886
882| */
883| $plugin_object = new $plugin_class_name;
884| $plugin_object($socket, $plugin_config);
885| } catch (\Throwable $e) {
> 886| throw new ConfigException('Failed to load plugin ' . $plugin_class_name, 0, $e);
887| }
888| }
889|
890| foreach ($this->filetype_scanner_paths as $extension => $path) {
Exception trace:
1 Error::("Class 'Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory' not found")
/home/me/project/vendor/laravel/framework/src/Illuminate/Routing/RoutingServiceProvider.php:128
2 Illuminate\Routing\RoutingServiceProvider::Illuminate\Routing\{closure}(Object(Illuminate\Foundation\Application), [])
/home/me/project/vendor/laravel/framework/src/Illuminate/Container/Container.php:776
Describe the bug
When I try to execute psalm receiving next error
In ClassLikeStorageProvider.php line 45:
Could not get class storage for eloquent
Impacted Versions
barryvdh/laravel-debugbar v3.3.3 PHP Debugbar integ...
barryvdh/laravel-ide-helper v2.7.0 Laravel IDE Helper...
barryvdh/laravel-snappy v0.4.7 Snappy PDF/Image f...
bugsnag/bugsnag-laravel v2.17.1 Official Bugsnag n...
fruitcake/laravel-cors v0.11.4 Adds CORS (Cross-O...
laravel/browser-kit-testing v5.1.3 Provides backwards...
laravel/framework v5.8.38 The Laravel Framew...
laravel/passport v7.5.1 Laravel Passport p...
laravel/slack-notification-channel v2.0.2 Slack Notification...
laravel/socialite v4.3.2 Laravel wrapper ar...
laravel/telescope v2.1.7 An elegant debug a...
laravel/tinker v1.0.10 Powerful REPL for ...
laravelcollective/html v5.8.1 HTML and Form Buil...
m50/psalm-json-to-junit dev-master 840343b Converts psalm's j...
psalm/plugin-laravel v1.3.0 A Laravel plugin f...
spatie/laravel-webhook-server 1.4.0 Send webhooks in L...
vimeo/psalm 3.12.2 A static analysis ...
Additional context
[2020-07-07 10:58:08] local.ERROR: Could not get class storage for eloquent ["[object] (InvalidArgumentException(code: 0): Could not get class storage for eloquent at /app/vendor/vimeo/psalm/src/Psalm/Internal/Provider/ClassLikeStorageProvider.php:45)\n[stacktrace]\n#0 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticCallAnalyzer.php(93): Psalm\Internal\Provider\ClassLikeStorageProvider->get('Eloquent')\n#1 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(151): Psalm\Internal\Analyzer\Statements\Expression\Call\StaticCallAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\StaticCall), Object(Psalm\Context))\n#2 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(45): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::handleExpression(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\StaticCall), Object(Psalm\Context), false, NULL, false)\n#3 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php(246): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\StaticCall), Object(Psalm\Context))\n#4 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(128): Psalm\Internal\Analyzer\Statements\Expression\AssignmentAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\Variable), Object(PhpParser\Node\Expr\StaticCall), NULL, Object(Psalm\Context), NULL)\n#5 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(45): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::handleExpression(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\Assign), Object(Psalm\Context), false, NULL, true)\n#6 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php(439): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\Assign), Object(Psalm\Context), false, NULL, true)\n#7 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php(163): Psalm\Internal\Analyzer\StatementsAnalyzer::analyzeStatement(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Stmt\Expression), Object(Psalm\Context), NULL)\n#8 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Block/IfAnalyzer.php(795): Psalm\Internal\Analyzer\StatementsAnalyzer->analyze(Array, Object(Psalm\Context))\n#9 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Block/IfAnalyzer.php(348): Psalm\Internal\Analyzer\Statements\Block\IfAnalyzer::analyzeIfBlock(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Stmt\If_), Object(Psalm\Internal\Scope\IfScope), Object(Psalm\Context), Object(Psalm\Context), Object(Psalm\Context), Array)\n#10 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php(387): Psalm\Internal\Analyzer\Statements\Block\IfAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Stmt\If_), Object(Psalm\Context))\n#11 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php(163): Psalm\Internal\Analyzer\StatementsAnalyzer::analyzeStatement(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Stmt\If_), Object(Psalm\Context), Object(Psalm\Context))\n#12 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php(547): Psalm\Internal\Analyzer\StatementsAnalyzer->analyze(Array, Object(Psalm\Context), Object(Psalm\Context), true)\n#13 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ClassAnalyzer.php(1803): Psalm\Internal\Analyzer\FunctionLikeAnalyzer->analyze(Object(Psalm\Context), Object(Psalm\Internal\Provider\NodeDataProvider), Object(Psalm\Context))\n#14 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ClassAnalyzer.php(754): Psalm\Internal\Analyzer\ClassAnalyzer->analyzeClassMethod(Object(PhpParser\Node\Stmt\ClassMethod), Object(Psalm\Storage\ClassLikeStorage), Object(Psalm\Internal\Analyzer\ClassAnalyzer), Object(Psalm\Context), Object(Psalm\Context))\n#15 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FileAnalyzer.php(217): Psalm\Internal\Analyzer\ClassAnalyzer->analyze(Object(Psalm\Context), Object(Psalm\Context))\n#16 /app/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(340): Psalm\Internal\Analyzer\FileAnalyzer->analyze(NULL)\n#17 /app/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(576): Psalm\Internal\Codebase\Analyzer->Psalm\Internal\Codebase\{closure}(2, '/app/app/Models...')\n#18 /app/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(266): Psalm\Internal\Codebase\Analyzer->doAnalysis(Object(Psalm\Internal\Analyzer\ProjectAnalyzer), 1)\n#19 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php(1203): Psalm\Internal\Codebase\Analyzer->analyzeFiles(Object(Psalm\Internal\Analyzer\ProjectAnalyzer), 1, false, false)\n#20 /app/vendor/vimeo/psalm/src/psalm.php(604): Psalm\Internal\Analyzer\ProjectAnalyzer->checkPaths(Array)\n#21 /app/vendor/vimeo/psalm/psalm(2): require_once('/app/vendor/vim...')\n#22 {main}\n"]
Laravel has Form Request classes that can look like the following:
<?php
namespace App\Modules\Accounts\Requests;
use App\Http\Requests\FormRequest;
class SaveAccountRequest extends FormRequest
{
public function rules()
{
return [
'name' => 'string|max:128',
'email' => 'required|string|email',
];
}
public function email(): string
{
return $this->input('email');
}
}
The input()
method has a return signature declared as * @return string|array|null
. For that reason, Psalm end up giving PossiblyInvalidArgument [...] possibly different type array<array-key, mixed>|string|null provided
.
I tried the following:
<issueHandlers>
<PossiblyInvalidArgument>
<errorLevel type="suppress">
<file name="*Request.php" />
</errorLevel>
</PossiblyInvalidArgument>
</issueHandlers>
but that configuration leads to
/app # vendor/bin/psalm
Could not resolve config path to /app//*Request.php
What can I do to suppress this problem but only for Request objects or for any interaction with the input
method of a Form Request class?
Describe the bug
When using psalm
with Laravel plugin I have, as I think, memory leak.
At least, when I run it with plugin, I have
psalm --no-cache
Scanning files...
PHP Fatal error: Allowed memory size of 8589934592 bytes exhausted (tried to allocate 20480 bytes) in /var/www/vendor/laravel/framework/src/Illuminate/Support/Arr.php on line 300
PHP Fatal error: Allowed memory size of 8589934592 bytes exhausted (tried to allocate 65536 bytes) in /var/www/vendor/sentry/sentry/src/Integration/FrameContextifierIntegration.php on line 56
when I run without plugin, it works fine
Impacted Versions
laravel/framework 5.8
vimeo/psalm 3.9
psalm/plugin-laravel 1.2.1
Can't give more info due to NDA.
Additional context
Add any other context about the problem here.
I can provide some other info (logs all dependencies) but only in private DM
Describe the bug
See convo here: psalm/codeception-psalm-module#18
the expected errors are supposed to have table headers
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.