Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
],
"require": {
"php": ">=7.1",
"vimeo/psalm": "^4.8",
"vimeo/psalm": "^4.8 || ^5.12",
"yiisoft/yii2": "^2.0"
},
"require-dev": {
Expand Down
11 changes: 6 additions & 5 deletions src/Handlers/BaseObjectPropertyAccessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ public static function getPropertyType(PropertyTypeProviderEvent $event): ?Union
return Type::getMixed();
}

foreach ($type->getAtomicTypes() as $atomic_type) {
$mutableType = method_exists($type, 'getBuilder') ? $type->getBuilder() : $type;
foreach ($mutableType->getAtomicTypes() as $atomic_type) {
if ($atomic_type instanceof TGenericObject) {
if ($atomic_type->value === ActiveQuery::class
|| $codebase->classExtendsOrImplements($atomic_type->value, ActiveQueryInterface::class)
Expand All @@ -151,19 +152,19 @@ public static function getPropertyType(PropertyTypeProviderEvent $event): ?Union
$isArray = true;
}

$type->removeType($atomic_type->getKey());
$mutableType->removeType($atomic_type->getKey());
if ($isArray) {
$type->addType(new TArray([Type::getArrayKey(), $atomic_type->type_params[0]]));
$mutableType->addType(new TArray([Type::getArrayKey(), $atomic_type->type_params[0]]));
} else {
foreach ($atomic_type->type_params[0]->getAtomicTypes() as $type_to_add) {
$type->addType($type_to_add);
$mutableType->addType($type_to_add);
}
}
}
}
}

return $type;
return method_exists($mutableType, 'freeze') ? $mutableType->freeze() : $mutableType;
}

if (self::doesSetterExist($codebase, $fq_classlike_name, $property_name)) {
Expand Down
4 changes: 3 additions & 1 deletion stubs/BaseActiveRecord.phpstub
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ declare(strict_types=1);

namespace yii\db;

class BaseActiveRecord
use yii\base\Model;

class BaseActiveRecord extends Model implements ActiveRecordInterface
{
/**
* @template T
Expand Down
3 changes: 2 additions & 1 deletion stubs/BaseObject.phpstub
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ namespace yii\base;
* BaseObject stub to force the class to be loaded. If we dont add this stub
* then psalm will not be able to find the class storage for this class
*/
class BaseObject {}
class BaseObject implements Configurable
{}
5 changes: 4 additions & 1 deletion stubs/Query.phpstub
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ declare(strict_types=1);

namespace yii\db;

use yii\base\Component;

/**
* @template TModel
* @template TMultiple
* @method iterable<mixed, TModel> each(int $batchSize = 100, ?Connection $db = null)
* @method TModel|null one()
* @method array<mixed, TModel> all()
*/
class Query {}
class Query extends Component implements QueryInterface, ExpressionInterface
{}
7 changes: 6 additions & 1 deletion tests/acceptance/Query.feature
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,17 @@ Feature: Query::class;
declare(strict_types=1);

namespace Practically\PsalmPluginYii2\Tests\Sandbox;

use yii\db\ActiveQuery;
"""
Scenario: You can create a instance of a model and its typed
Given I have the following code
"""
/**
* @template TModel
* @template TMultiple
* @extends ActiveQuery<TModel, TMultiple>
*/
class MyQuery extends ActiveQuery
{
public function active(): self
Expand Down