Skip to content

Commit

Permalink
Merge pull request #39 from CakeDC/feature/phpstan-2
Browse files Browse the repository at this point in the history
Upgrade to PHPStan 2.0
  • Loading branch information
steinkel authored Nov 4, 2024
2 parents e7bb4a4 + 2d6b693 commit 1e70535
Show file tree
Hide file tree
Showing 42 changed files with 284 additions and 387 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ jobs:

- name: Run phpstan integration test app
if: always()
run: vendor/bin/phpstan analyse --debug --error-format=github tests/test_app/
run: vendor/bin/phpstan analyse --debug -c phpstan-test-app.neon --error-format=github tests/test_app/

- name: Run phpstan integration test plugin
if: always()
run: vendor/bin/phpstan analyse --debug --error-format=github tests/test_plugin/
run: vendor/bin/phpstan analyse --debug -c phpstan-test-plugin.neon --error-format=github tests/test_plugin/
17 changes: 10 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@
],
"require": {
"php": ">=8.1.0",
"phpstan/phpstan": "^1.12",
"phpstan/phpstan": "^2.0",
"cakephp/cakephp": "^5.0"
},
"require-dev": {
"phpstan/phpstan-phpunit": "^1.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpunit/phpunit": "^10.1",
"cakephp/cakephp-codesniffer": "^5.0",
"symplify/phpstan-rules": "^12.4"
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpstan/phpstan-strict-rules": "^2.0"
},
"extra": {
"phpstan": {
Expand All @@ -45,10 +46,10 @@
"cs-fix": "phpcbf -p src/ tests",
"test": "phpunit --stderr",
"stan-integration": [
"phpstan analyse --debug tests/test_app/",
"phpstan analyse --debug tests/test_plugin/"
"phpstan analyse --debug -c phpstan-test-app.neon",
"phpstan analyse --debug -c phpstan-test-plugin.neon"
],
"stan": "phpstan analyse --debug src/",
"stan": "phpstan analyse --debug",
"check": [
"@cs-check",
"@stan",
Expand All @@ -60,5 +61,7 @@
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
}
},
"minimum-stability": "dev",
"prefer-stable": true
}
16 changes: 0 additions & 16 deletions extension.neon
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,6 @@ services:
factory: CakeDC\PHPStan\Type\ControllerFetchTableDynamicReturnTypeExtension(Cake\Controller\Controller, fetchTable)
tags:
- phpstan.broker.dynamicMethodReturnTypeExtension
-
factory: CakeDC\PHPStan\Type\TableLocatorDynamicReturnTypeExtension(Cake\Command\Command, fetchTable)
tags:
- phpstan.broker.dynamicMethodReturnTypeExtension
-
factory: CakeDC\PHPStan\Type\TableLocatorDynamicReturnTypeExtension(Cake\Mailer\Mailer, fetchTable)
tags:
- phpstan.broker.dynamicMethodReturnTypeExtension
-
factory: CakeDC\PHPStan\Type\TableLocatorDynamicReturnTypeExtension(Cake\View\Cell, fetchTable)
tags:
- phpstan.broker.dynamicMethodReturnTypeExtension
-
factory: CakeDC\PHPStan\Type\TableLocatorDynamicReturnTypeExtension(Cake\Controller\Component, fetchTable)
tags:
- phpstan.broker.dynamicMethodReturnTypeExtension
-
factory: CakeDC\PHPStan\Type\TableLocatorDynamicReturnTypeExtension(Cake\ORM\Locator\LocatorInterface, get)
tags:
Expand Down
13 changes: 13 additions & 0 deletions phpstan-test-app.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
includes:
- extension.neon
- vendor/phpstan/phpstan-deprecation-rules/rules.neon
parameters:
level: max
paths:
- tests/test_app
treatPhpDocTypesAsCertain: false
cakeDC:
disallowEntityArrayAccessRule: true
ignoreErrors:
-
identifier: missingType.generics
10 changes: 10 additions & 0 deletions phpstan-test-plugin.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
includes:
- extension.neon
- vendor/phpstan/phpstan-deprecation-rules/rules.neon
parameters:
level: max
paths:
- tests/test_plugin
treatPhpDocTypesAsCertain: false
cakeDC:
disallowEntityArrayAccessRule: true
16 changes: 10 additions & 6 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
includes:
- extension.neon
rules:
- Symplify\PHPStanRules\Rules\Explicit\NoMixedPropertyFetcherRule
- Symplify\PHPStanRules\Rules\Explicit\NoMixedMethodCallerRule
- vendor/phpstan/phpstan-deprecation-rules/rules.neon
- vendor/phpstan/phpstan-strict-rules/rules.neon
parameters:
level: max
checkGenericClassInNonGenericObjectType: false
paths:
- src
- tests/TestCase
excludePaths:
- */Fake/*
treatPhpDocTypesAsCertain: false
cakeDC:
disallowEntityArrayAccessRule: true
ignoreErrors:
-
identifier: missingType.generics
3 changes: 2 additions & 1 deletion src/Constraint/ArrayOfStringStartsWith.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ protected function matches(mixed $other): bool
$this->notExpected = $this->actual;
assert(is_array($other));
foreach ($other as $key => $error) {
$error = is_string($error) ? $error : 'Wrong error: ' . json_encode($error);
if (!isset($this->actual[$key])) {
$this->result[$key] = ['expected' => $error, 'type' => 'missing', 'actual' => null];
$result = false;
Expand All @@ -58,7 +59,7 @@ protected function matches(mixed $other): bool
}
}

return $result && empty($this->notExpected);
return $result && $this->notExpected === [];
}

/**
Expand Down
19 changes: 8 additions & 11 deletions src/Method/AssociationTableMixinClassReflectionExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,36 @@

use Cake\ORM\Association;
use Cake\ORM\Table;
use PHPStan\Broker\Broker;
use PHPStan\Reflection\BrokerAwareExtension;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\MethodsClassReflectionExtension;
use PHPStan\Reflection\PropertiesClassReflectionExtension;
use PHPStan\Reflection\PropertyReflection;
use PHPStan\Reflection\ReflectionProvider;

class AssociationTableMixinClassReflectionExtension implements
PropertiesClassReflectionExtension,
MethodsClassReflectionExtension,
BrokerAwareExtension
MethodsClassReflectionExtension
{
/**
* @var \PHPStan\Broker\Broker
* @var \PHPStan\Reflection\ReflectionProvider
*/
private Broker $broker;
protected ReflectionProvider $reflectionProvider;

/**
* @param \PHPStan\Broker\Broker $broker Class reflection broker
* @return void
* @param \PHPStan\Reflection\ReflectionProvider $reflectionProvider
*/
public function setBroker(Broker $broker): void
public function __construct(ReflectionProvider $reflectionProvider)
{
$this->broker = $broker;
$this->reflectionProvider = $reflectionProvider;
}

/**
* @return \PHPStan\Reflection\ClassReflection
*/
protected function getTableReflection(): ClassReflection
{
return $this->broker->getClass(Table::class);
return $this->reflectionProvider->getClass(Table::class);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/Method/TableFindByPropertyMethodReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class TableFindByPropertyMethodReflection implements MethodReflection
private ClassReflection $declaringClass;

/**
* @var array<\PHPStan\Reflection\FunctionVariant>
* @var list<\PHPStan\Reflection\FunctionVariant>
*/
private array $variants;

Expand Down Expand Up @@ -205,7 +205,7 @@ public function hasSideEffects(): TrinaryLogic

/**
* @param string $method
* @return array<string>
* @return list<string>
*/
protected function getParams(string $method): array
{
Expand Down
14 changes: 8 additions & 6 deletions src/PhpDoc/TableAssociationTypeNodeResolverExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
use PHPStan\PhpDocParser\Ast\Type\IntersectionTypeNode;
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\Type\Generic\GenericObjectType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;

/**
Expand Down Expand Up @@ -65,19 +64,22 @@ public function resolve(TypeNode $typeNode, NameScope $nameScope): ?Type
'table' => null,
];
foreach ($types as $type) {
if (!$type instanceof ObjectType) {
if (!$type->isObject()->yes()) {
continue;
}
$className = $type->getClassName();
if ($config['association'] === null && in_array($className, $this->associationTypes)) {
$className = $type->getObjectClassNames()[0] ?? null;
if ($className === null) {
continue;
}
if ($config['association'] === null && in_array($className, $this->associationTypes, true)) {
$config['association'] = $type;
} elseif ($config['table'] === null && str_ends_with($className, 'Table')) {
$config['table'] = $type;
}
}
if ($config['table'] && $config['association']) {
if ($config['table'] !== null && $config['association'] !== null) {
return new GenericObjectType(
$config['association']->getClassName(),
$config['association']->getObjectClassNames()[0],
[$config['table']]
);
}
Expand Down
8 changes: 4 additions & 4 deletions src/Rule/LoadObjectExistsCakeClassRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ abstract class LoadObjectExistsCakeClassRule implements Rule
protected string $identifier;

/**
* @return string
* @inheritDoc
*/
public function getNodeType(): string
{
Expand All @@ -43,7 +43,7 @@ public function getNodeType(): string
/**
* @param \PhpParser\Node $node
* @param \PHPStan\Analyser\Scope $scope
* @return array<\PHPStan\Rules\RuleError>
* @return list<\PHPStan\Rules\IdentifierRuleError>
*/
public function processNode(Node $node, Scope $scope): array
{
Expand All @@ -60,7 +60,7 @@ public function processNode(Node $node, Scope $scope): array

if (
$details === null
|| !in_array($node->name->name, $details['sourceMethods'])
|| !in_array($node->name->name, $details['sourceMethods'], true)
|| !$details['alias'] instanceof Arg
|| !$details['alias']->value instanceof String_
) {
Expand All @@ -74,7 +74,7 @@ public function processNode(Node $node, Scope $scope): array
$details['options']
);
}
if ($inputClassName === null || $this->getTargetClassName($inputClassName)) {
if ($inputClassName === null || $this->getTargetClassName($inputClassName) !== null) {
return [];
}

Expand Down
6 changes: 3 additions & 3 deletions src/Rule/Mailer/GetMailerExistsClassRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class GetMailerExistsClassRule implements Rule
protected string $identifier = 'cake.getMailer.existClass';

/**
* @return string
* @inheritDoc
*/
public function getNodeType(): string
{
Expand All @@ -40,7 +40,7 @@ public function getNodeType(): string
/**
* @param \PhpParser\Node $node
* @param \PHPStan\Analyser\Scope $scope
* @return array<\PHPStan\Rules\RuleError>
* @return list<\PHPStan\Rules\IdentifierRuleError>
*/
public function processNode(Node $node, Scope $scope): array
{
Expand All @@ -66,7 +66,7 @@ public function processNode(Node $node, Scope $scope): array
}
$reflection = $callerType->getClassReflection();

if (CakeNameRegistry::getMailerClassName($value->value)) {
if (CakeNameRegistry::getMailerClassName($value->value) !== null) {
return [];
}

Expand Down
20 changes: 9 additions & 11 deletions src/Rule/Model/AddAssociationMatchOptionsTypesRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
use CakeDC\PHPStan\Rule\Traits\ParseClassNameFromArgTrait;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\ArrayItem;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Scalar\String_;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Rules\IdentifierRuleError;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleError;
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\Rules\RuleLevelHelper;
use PHPStan\Type\ObjectType;
Expand Down Expand Up @@ -51,17 +51,15 @@ public function __construct(RuleLevelHelper $ruleLevelHelper)
];

/**
* @return string
* @inheritDoc
*/
public function getNodeType(): string
{
return MethodCall::class;
}

/**
* @param \PhpParser\Node $node
* @param \PHPStan\Analyser\Scope $scope
* @return array<\PHPStan\Rules\RuleError>
* @inheritDoc
*/
public function processNode(Node $node, Scope $scope): array
{
Expand Down Expand Up @@ -100,7 +98,7 @@ public function processNode(Node $node, Scope $scope): array
$item,
$scope
);
if ($error) {
if ($error !== null) {
$errors[] = $error;
}
} else {
Expand Down Expand Up @@ -156,9 +154,9 @@ protected function getDetails(string $reference, string $methodName, array $args
/**
* @param array{'alias': ?string, 'options': ?\PhpParser\Node\Arg, 'type': string, 'reference':string, 'methodName':string} $details
* @param string $property
* @param \PhpParser\Node\Expr\ArrayItem $item
* @param \PhpParser\Node\ArrayItem $item
* @param \PHPStan\Analyser\Scope $scope
* @return \PHPStan\Rules\RuleError|null
* @return \PHPStan\Rules\IdentifierRuleError|null
* @throws \PHPStan\Reflection\MissingPropertyFromReflectionException
* @throws \PHPStan\ShouldNotHappenException
*/
Expand All @@ -167,15 +165,15 @@ protected function processPropertyTypeCheck(
string $property,
ArrayItem $item,
Scope $scope
): ?RuleError {
): ?IdentifierRuleError {
$object = new ObjectType($details['type']);
$classReflection = $object->getClassReflection();
assert($classReflection instanceof ClassReflection);
$propertyType = $classReflection
->getProperty('_' . $property, $scope)
->getWritableType();
$assignedValueType = $scope->getType($item->value);
$accepts = $this->ruleLevelHelper->acceptsWithReason($propertyType, $assignedValueType, true);//@phpstan-ignore-line
$accepts = $this->ruleLevelHelper->accepts($propertyType, $assignedValueType, true);
if ($accepts->result) {
return null;
}
Expand Down
Loading

0 comments on commit 1e70535

Please sign in to comment.