Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to phpstan 2.0 #12

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
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
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
},
"require-dev": {
"maglnet/composer-require-checker": "^4.7",
"phpstan/phpstan-deprecation-rules": "^1.2",
"phpstan/phpstan-phpunit": "^1.0",
"phpunit/phpunit": "^10.2",
"symplify/easy-coding-standard": "^12.1"
Expand Down
2 changes: 2 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ includes:
- extension.neon
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-phpunit/rules.neon
- phar://phpstan.phar/conf/bleedingEdge.neon
- vendor/phpstan/phpstan-deprecation-rules/rules.neon

parameters:
ignoreErrors:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ final class ApplicationPropertiesClassReflectionExtension implements PropertiesC
public function __construct(
private readonly AnnotationsPropertiesClassReflectionExtension $annotationsProperties,
private readonly ReflectionProvider $reflectionProvider,
private readonly ServiceMap $serviceMap
private readonly ServiceMap $serviceMap,
) {}

public function hasProperty(ClassReflection $classReflection, string $propertyName): bool
Expand Down
19 changes: 10 additions & 9 deletions src/Type/ActiveQueryDynamicMethodReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@
*/
public function isMethodSupported(MethodReflection $methodReflection): bool
{
if (
ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())
->getReturnType() instanceof ThisType
) {
/** @phpstan-ignore staticMethod.deprecated */
$returnType = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())
->getReturnType();

Check warning on line 43 in src/Type/ActiveQueryDynamicMethodReturnTypeExtension.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ActiveQueryDynamicMethodReturnTypeExtension.php#L42-L43

Added lines #L42 - L43 were not covered by tests

if ($returnType instanceof ThisType) {

Check warning on line 45 in src/Type/ActiveQueryDynamicMethodReturnTypeExtension.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ActiveQueryDynamicMethodReturnTypeExtension.php#L45

Added line #L45 was not covered by tests
return true;
}

Expand All @@ -54,7 +55,7 @@
public function getTypeFromMethodCall(
MethodReflection $methodReflection,
MethodCall $methodCall,
Scope $scope
Scope $scope,
): Type {
$calledOnType = $scope->getType($methodCall->var);
if (!$calledOnType instanceof ActiveQueryObjectType) {
Expand All @@ -63,7 +64,7 @@
'Unexpected type %s during method call %s at line %d',
get_class($calledOnType),
$methodReflection->getName(),
$methodCall->getLine()
$methodCall->getLine(),

Check warning on line 67 in src/Type/ActiveQueryDynamicMethodReturnTypeExtension.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ActiveQueryDynamicMethodReturnTypeExtension.php#L67

Added line #L67 was not covered by tests
),
);
}
Expand All @@ -72,13 +73,13 @@
if ($methodName === 'asArray') {
$argType = isset($methodCall->args[0]) && $methodCall->args[0] instanceof Arg
? $scope->getType($methodCall->args[0]->value) : new ConstantBooleanType(true);
if (!$argType instanceof ConstantBooleanType) {
if ($argType->isBoolean()->no()) {

Check warning on line 76 in src/Type/ActiveQueryDynamicMethodReturnTypeExtension.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ActiveQueryDynamicMethodReturnTypeExtension.php#L76

Added line #L76 was not covered by tests
throw new ShouldNotHappenException(
sprintf('Invalid argument provided to asArray method at line %d', $methodCall->getLine()),
);
}

return new ActiveQueryObjectType($calledOnType->getModelClass(), $argType->getValue());

Check failure on line 82 in src/Type/ActiveQueryDynamicMethodReturnTypeExtension.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

Call to an undefined method PHPStan\Type\Type::getValue().
}

if (!in_array($methodName, ['one', 'all'], true)) {
Expand All @@ -90,15 +91,15 @@
new NullType(),
$calledOnType->isAsArray()
? new ArrayType(new StringType(), new MixedType())
: new ActiveRecordObjectType($calledOnType->getModelClass())
: new ActiveRecordObjectType($calledOnType->getModelClass()),

Check warning on line 94 in src/Type/ActiveQueryDynamicMethodReturnTypeExtension.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ActiveQueryDynamicMethodReturnTypeExtension.php#L94

Added line #L94 was not covered by tests
);
}

return new ArrayType(
new IntegerType(),
$calledOnType->isAsArray()
? new ArrayType(new StringType(), new MixedType())
: new ActiveRecordObjectType($calledOnType->getModelClass())
: new ActiveRecordObjectType($calledOnType->getModelClass()),

Check warning on line 102 in src/Type/ActiveQueryDynamicMethodReturnTypeExtension.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ActiveQueryDynamicMethodReturnTypeExtension.php#L102

Added line #L102 was not covered by tests
);
}
}
11 changes: 5 additions & 6 deletions src/Type/ActiveRecordDynamicMethodReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\ShouldNotHappenException;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
use PHPStan\Type\Type;
use yii\db\ActiveRecord;
Expand All @@ -35,7 +34,7 @@
public function getTypeFromMethodCall(
MethodReflection $methodReflection,
MethodCall $methodCall,
Scope $scope
Scope $scope,
): Type {
$arg = $methodCall->args[0];

Expand All @@ -45,22 +44,22 @@
'Unexpected arg %s during method call %s at line %d',
get_class($arg),
$methodReflection->getName(),
$methodCall->getLine()
$methodCall->getLine(),

Check warning on line 47 in src/Type/ActiveRecordDynamicMethodReturnTypeExtension.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ActiveRecordDynamicMethodReturnTypeExtension.php#L47

Added line #L47 was not covered by tests
),
);
}

$argType = $scope->getType($arg->value);
if (!$argType instanceof ConstantStringType) {
if (count($argType->getConstantStrings()) === 0) {

Check warning on line 53 in src/Type/ActiveRecordDynamicMethodReturnTypeExtension.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ActiveRecordDynamicMethodReturnTypeExtension.php#L53

Added line #L53 was not covered by tests
throw new ShouldNotHappenException(
sprintf(
'Invalid argument provided to method %s' . PHP_EOL .
'Hint: You should use ::class instead of ::className()',
$methodReflection->getName()
)
$methodReflection->getName(),
),

Check warning on line 59 in src/Type/ActiveRecordDynamicMethodReturnTypeExtension.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ActiveRecordDynamicMethodReturnTypeExtension.php#L58-L59

Added lines #L58 - L59 were not covered by tests
);
}

return new ActiveQueryObjectType($argType->getValue(), false);

Check failure on line 63 in src/Type/ActiveRecordDynamicMethodReturnTypeExtension.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

Call to an undefined method PHPStan\Type\Type::getValue().
}
}
34 changes: 21 additions & 13 deletions src/Type/ActiveRecordDynamicStaticMethodReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,27 @@
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\ShouldNotHappenException;
use PHPStan\Type\DynamicStaticMethodReturnTypeExtension;
use PHPStan\Type\NullType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\ThisType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\UnionType;
use yii\db\ActiveQuery;
use yii\db\ActiveRecord;

use function is_a;

final class ActiveRecordDynamicStaticMethodReturnTypeExtension implements DynamicStaticMethodReturnTypeExtension
{
private ReflectionProvider $reflectionProvider;

public function __construct(

Check warning on line 27 in src/Type/ActiveRecordDynamicStaticMethodReturnTypeExtension.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ActiveRecordDynamicStaticMethodReturnTypeExtension.php#L27

Added line #L27 was not covered by tests
ReflectionProvider $reflectionProvider,
) {
$this->reflectionProvider = $reflectionProvider;

Check warning on line 30 in src/Type/ActiveRecordDynamicStaticMethodReturnTypeExtension.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ActiveRecordDynamicStaticMethodReturnTypeExtension.php#L30

Added line #L30 was not covered by tests
}

public function getClass(): string
{
return ActiveRecord::class;
Expand All @@ -34,33 +40,35 @@
*/
public function isStaticMethodSupported(MethodReflection $methodReflection): bool
{
/** @phpstan-ignore staticMethod.deprecated */
$returnType = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType();
if ($returnType instanceof ThisType) {
return true;
}

if ($returnType instanceof UnionType) {
foreach ($returnType->getTypes() as $type) {
if ($type instanceof ObjectType) {
return is_a($type->getClassName(), $this->getClass(), true);
if ($type->isObject()->yes()) {
return $this->reflectionProvider->hasClass($this->getClass()) &&
$type->getClassName() === $this->getClass();

Check failure on line 53 in src/Type/ActiveRecordDynamicStaticMethodReturnTypeExtension.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

Call to an undefined method PHPStan\Type\Type::getClassName().

Check warning on line 53 in src/Type/ActiveRecordDynamicStaticMethodReturnTypeExtension.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ActiveRecordDynamicStaticMethodReturnTypeExtension.php#L51-L53

Added lines #L51 - L53 were not covered by tests
}
}
}

return $returnType instanceof ObjectType &&
is_a($returnType->getClassName(), ActiveQuery::class, true);
return $returnType->isObject()->yes() && $returnType->getClassName() === ActiveQuery::class;

Check failure on line 58 in src/Type/ActiveRecordDynamicStaticMethodReturnTypeExtension.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

Call to an undefined method PHPStan\Type\Type::getClassName().

Check warning on line 58 in src/Type/ActiveRecordDynamicStaticMethodReturnTypeExtension.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ActiveRecordDynamicStaticMethodReturnTypeExtension.php#L58

Added line #L58 was not covered by tests
}

/**
* @throws ShouldNotHappenException
*/
public function getTypeFromStaticMethodCall(
MethodReflection $methodReflection,
StaticCall $methodCall,
Scope $scope
Scope $scope,
): Type {
$className = $methodCall->class;
$returnType = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType();
$returnType = ParametersAcceptorSelector::selectFromArgs(
$scope,
$methodCall->getArgs(),
$methodReflection->getVariants(),
)->getReturnType();

Check warning on line 71 in src/Type/ActiveRecordDynamicStaticMethodReturnTypeExtension.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ActiveRecordDynamicStaticMethodReturnTypeExtension.php#L67-L71

Added lines #L67 - L71 were not covered by tests

if (!$className instanceof Name) {
return $returnType;
Expand All @@ -75,7 +83,7 @@
if ($returnType instanceof UnionType) {
return TypeCombinator::union(
new NullType(),
new ActiveRecordObjectType($name)
new ActiveRecordObjectType($name),

Check warning on line 86 in src/Type/ActiveRecordDynamicStaticMethodReturnTypeExtension.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ActiveRecordDynamicStaticMethodReturnTypeExtension.php#L86

Added line #L86 was not covered by tests
);
}

Expand Down
5 changes: 2 additions & 3 deletions src/Type/ActiveRecordObjectType.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use ArrayAccess;
use PHPStan\ShouldNotHappenException;
use PHPStan\TrinaryLogic;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\ErrorType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
Expand All @@ -19,12 +18,12 @@
*/
public function hasOffsetValueType(Type $offsetType): TrinaryLogic
{
if (!$offsetType instanceof ConstantStringType) {
if (count($offsetType->getConstantStrings()) === 0) {

Check warning on line 21 in src/Type/ActiveRecordObjectType.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ActiveRecordObjectType.php#L21

Added line #L21 was not covered by tests
return TrinaryLogic::createNo();
}

if ($this->isInstanceOf(ArrayAccess::class)->yes()) {
return TrinaryLogic::createFromBoolean($this->hasProperty($offsetType->getValue())->yes());

Check failure on line 26 in src/Type/ActiveRecordObjectType.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

Call to an undefined method PHPStan\Type\Type::getValue().
}

return parent::hasOffsetValueType($offsetType);
Expand All @@ -32,7 +31,7 @@

public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = true): Type
{
if ($offsetType instanceof ConstantStringType && $this->hasProperty($offsetType->getValue())->no()) {
if (count($offsetType->getConstantStrings()) > 0 && $this->hasProperty($offsetType->getValue())->no()) {

Check failure on line 34 in src/Type/ActiveRecordObjectType.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

Call to an undefined method PHPStan\Type\Type::getValue().

Check warning on line 34 in src/Type/ActiveRecordObjectType.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ActiveRecordObjectType.php#L34

Added line #L34 was not covered by tests
return new ErrorType();
}

Expand Down
6 changes: 5 additions & 1 deletion src/Type/ContainerDynamicMethodReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@
}
}

return ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType();
return ParametersAcceptorSelector::selectFromArgs(
$scope,
$methodCall->getArgs(),
$methodReflection->getVariants(),
)->getReturnType();

Check warning on line 49 in src/Type/ContainerDynamicMethodReturnTypeExtension.php

View check run for this annotation

Codecov / codecov/patch

src/Type/ContainerDynamicMethodReturnTypeExtension.php#L45-L49

Added lines #L45 - L49 were not covered by tests
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
/** @var Arg $arg */
$arg = $methodCall->args[2];
if ($arg->value instanceof ConstFetch) {
$value = $arg->value->name->parts[0];
$value = $arg->value->name->getParts()[0];

Check warning on line 48 in src/Type/HeaderCollectionDynamicMethodReturnTypeExtension.php

View check run for this annotation

Codecov / codecov/patch

src/Type/HeaderCollectionDynamicMethodReturnTypeExtension.php#L48

Added line #L48 was not covered by tests
if ($value === 'true') {
// $first === true, therefore string
return new StringType();
Expand Down
6 changes: 3 additions & 3 deletions tests/ServiceMapTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function testThrowExceptionWhenServiceHasUnsupportedType(): void
$this->expectExceptionMessage('Unsupported service definition for unsupported-type');

new ServiceMap(
__DIR__ . DIRECTORY_SEPARATOR . 'assets' . DIRECTORY_SEPARATOR . 'yii-config-invalid-unsupported-type.php'
__DIR__ . DIRECTORY_SEPARATOR . 'assets' . DIRECTORY_SEPARATOR . 'yii-config-invalid-unsupported-type.php',
);
}

Expand All @@ -58,7 +58,7 @@ public function testThrowExceptionWhenServiceHasUnsupportedArray(): void
$this->expectExceptionMessage('Cannot guess service definition for unsupported-array');

new ServiceMap(
__DIR__ . DIRECTORY_SEPARATOR . 'assets' . DIRECTORY_SEPARATOR . 'yii-config-invalid-unsupported-array.php'
__DIR__ . DIRECTORY_SEPARATOR . 'assets' . DIRECTORY_SEPARATOR . 'yii-config-invalid-unsupported-array.php',
);
}

Expand All @@ -71,7 +71,7 @@ public function testThrowExceptionWhenComponentHasInvalidValue(): void
$this->expectExceptionMessage('Invalid value for component with id customComponent. Expected object or array.');

new ServiceMap(
__DIR__ . DIRECTORY_SEPARATOR . 'assets' . DIRECTORY_SEPARATOR . 'yii-config-invalid-component.php'
__DIR__ . DIRECTORY_SEPARATOR . 'assets' . DIRECTORY_SEPARATOR . 'yii-config-invalid-component.php',
);
}

Expand Down
Loading