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

Support PHPStan 1 #29

Merged
merged 6 commits into from
Nov 9, 2021
Merged
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
32 changes: 12 additions & 20 deletions .github/workflows/integrate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
strategy:
matrix:
php-version:
- "7.4"
- "8.0"

steps:
- name: "Checkout"
Expand All @@ -42,8 +42,8 @@ jobs:
strategy:
matrix:
php-version:
- "7.4"
- "8.0"
- "8.1"
dependencies:
- "lowest"
- "highest"
Expand Down Expand Up @@ -71,23 +71,15 @@ jobs:
restore-keys: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ matrix.dependencies }}-composer-

- name: "Install lowest dependencies"
if: ${{ matrix.dependencies == 'lowest' && matrix.php-version != '8.0' }}
run: "composer update --no-interaction --no-progress --prefer-lowest"

- name: "Install highest dependencies"
if: ${{ matrix.dependencies == 'highest' && matrix.php-version != '8.0' }}
run: "composer update --no-interaction --no-progress"

- name: "Install lowest dependencies PHP 8.0"
if: ${{ matrix.dependencies == 'lowest' && matrix.php-version == '8.0' }}
if: ${{ matrix.dependencies == 'lowest' }}
run: "composer update --no-interaction --no-progress --ignore-platform-reqs --prefer-lowest"

- name: "Install highest dependencies PHP 8.0"
if: ${{ matrix.dependencies == 'highest' && matrix.php-version == '8.0' }}
- name: "Install highest dependencies"
if: ${{ matrix.dependencies == 'highest' }}
run: "composer update --no-interaction --no-progress --ignore-platform-reqs"

- name: "Run tests"
timeout-minutes: 3
timeout-minutes: 5
run: "vendor/bin/phpunit --no-coverage --no-logging"

code-coverage:
Expand All @@ -98,7 +90,7 @@ jobs:
strategy:
matrix:
php-version:
- "7.4"
- "8.0"

steps:
- name: "Checkout"
Expand All @@ -123,7 +115,7 @@ jobs:
restore-keys: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ matrix.dependencies }}-composer-

- name: "Install dependencies"
run: "composer update --no-interaction --no-progress"
run: "composer update --no-interaction --no-progress --ignore-platform-reqs"

- name: "Run tests"
timeout-minutes: 3
Expand All @@ -144,7 +136,7 @@ jobs:
strategy:
matrix:
php-version:
- "7.4"
- "8.0"

steps:
- name: "Checkout"
Expand All @@ -168,7 +160,7 @@ jobs:
restore-keys: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ matrix.dependencies }}-composer-

- name: "Install dependencies"
run: "composer update --no-interaction --no-progress"
run: "composer update --no-interaction --no-progress --ignore-platform-reqs"

- name: "Check coding standards"
run: "vendor/bin/php-cs-fixer fix --verbose --dry-run --diff"
Expand All @@ -181,7 +173,7 @@ jobs:
strategy:
matrix:
php-version:
- "7.4"
- "8.0"

steps:
- name: "Checkout"
Expand All @@ -206,7 +198,7 @@ jobs:
restore-keys: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ matrix.dependencies }}-composer-

- name: "Install dependencies"
run: "composer update --no-interaction --no-progress"
run: "composer update --no-interaction --no-progress --ignore-platform-reqs"

- name: "Run static analysis"
run: "vendor/bin/phpstan analyse --no-progress --error-format=checkstyle | cs2pr"
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ static-analysis: vendor

.PHONY: test
test: vendor
php -d zend.assertions=1 vendor/bin/phpunit
php -d zend.assertions=1 vendor/bin/phpunit ${arg}
25 changes: 13 additions & 12 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
}
],
"require": {
"php": "^7.4 || ^8.0",
"phpstan/phpstan": "^0.12.99"
"php": ">=8.0",
"phpstan/phpstan": "^1.1.2"
},
"conflict": {
"laminas/laminas-cache": "<2.13",
"laminas/laminas-filter": "<2.11",
"laminas/laminas-form": "<2.17",
"laminas/laminas-form": "<3.0",
"laminas/laminas-hydrator": "<4.3",
"laminas/laminas-i18n": "<2.11",
"laminas/laminas-inputfilter": "<2.12",
Expand All @@ -35,20 +35,21 @@
"laminas/laminas-validator": "<2.15"
},
"require-dev": {
"laminas/laminas-cache": "^2.13.0",
"laminas/laminas-filter": "^2.11.1",
"laminas/laminas-form": "^2.17.0",
"laminas/laminas-cache": "^2.13.2",
"laminas/laminas-filter": "^2.12.0",
"laminas/laminas-form": "^3.0.1",
"laminas/laminas-hydrator": "^4.3.1",
"laminas/laminas-i18n": "^2.11.2",
"laminas/laminas-i18n": "^2.11.3",
"laminas/laminas-inputfilter": "^2.12.0",
"laminas/laminas-log": "^2.13.1",
"laminas/laminas-mail": "^2.15.0",
"laminas/laminas-mvc": "^3.2.0",
"laminas/laminas-paginator": "^2.10.0",
"laminas/laminas-mail": "^2.15.1",
"laminas/laminas-mvc": "^3.3.0",
"laminas/laminas-paginator": "^2.11.0",
"laminas/laminas-validator": "^2.15.0",
"malukenho/mcbumpface": "^1.1.5",
"phpstan/phpstan-phpunit": "^0.12.22",
"phpunit/phpunit": "^9.5.9",
"phpstan/phpstan-deprecation-rules": "^1.0.0",
"phpstan/phpstan-phpunit": "^1.0.0",
"phpunit/phpunit": "^9.5.10",
"slam/php-cs-fixer-extensions": "^v3.1.0",
"slam/php-debug-r": "^v1.7.0"
},
Expand Down
14 changes: 12 additions & 2 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
parameters:
ignoreErrors:
-
message: "#^Parameter \\#2 \\$args of static method PHPStan\\\\Reflection\\\\ParametersAcceptorSelector\\:\\:selectFromArgs\\(\\) expects array\\<PhpParser\\\\Node\\\\Arg\\>, array\\<PhpParser\\\\Node\\\\Arg\\|PhpParser\\\\Node\\\\VariadicPlaceholder\\> given\\.$#"
message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertInstanceOf\\(\\) with 'LaminasPhpStan\\\\\\\\TestAsset\\\\\\\\BarService' and Laminas\\\\Stdlib\\\\DispatchableInterface will always evaluate to false\\.$#"
count: 1
path: src/Type/Laminas/PluginMethodDynamicReturnTypeExtension/AbstractPluginMethodDynamicReturnTypeExtension.php
path: tests/Type/Laminas/ServiceManagerLoaderTest.php

-
message:
"""
#^Fetching class constant class of deprecated class Laminas\\\\Cache\\\\PatternPluginManager\\:
This will be removed in v3\\.0\\.0\\. Cache pattern will require dependency injection and thus, a generic
plugin manager makes no sense anymore\\.$#
"""
count: 1
path: tests/Type/Laminas/ServiceManagerLoaderTest.php

12 changes: 7 additions & 5 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
includes:
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-deprecation-rules/rules.neon
- phpstan-baseline.neon

parameters:
level: max
paths:
- src/
- tests/
excludes_analyse:
- tests/Rules/Laminas/ServiceManagerGetMethodCallRule/
- tests/Rules/Laminas/PluginManagerGetMethodCallRule/
- tests/TestAsset/
- tests/LaminasIntegration/data/
excludePaths:
analyseAndScan:
- tests/Rules/Laminas/ServiceManagerGetMethodCallRule/
- tests/Rules/Laminas/PluginManagerGetMethodCallRule/
- tests/TestAsset/
- tests/LaminasIntegration/data/
21 changes: 9 additions & 12 deletions src/Rules/Laminas/ServiceManagerGetMethodCallRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use PhpParser\Node;
use PhpParser\Node\Arg;
use PHPStan\Analyser\Scope;
use PHPStan\Broker\Broker;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Rules\Rule;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\ObjectType;
Expand All @@ -24,14 +24,10 @@
*/
final class ServiceManagerGetMethodCallRule implements Rule
{
private Broker $broker;

private ServiceManagerLoader $serviceManagerLoader;

public function __construct(Broker $broker, ServiceManagerLoader $serviceManagerLoader)
{
$this->broker = $broker;
$this->serviceManagerLoader = $serviceManagerLoader;
public function __construct(
private ReflectionProvider $reflectionProvider,
private ServiceManagerLoader $serviceManagerLoader
) {
}

public function getNodeType(): string
Expand All @@ -46,11 +42,12 @@ public function getNodeType(): string
*/
public function processNode(Node $node, Scope $scope): array
{
if (1 !== \count($node->args)) {
$args = $node->getArgs();
if (1 !== \count($args)) {
return [];
}

$firstArg = $node->args[0];
$firstArg = $args[0];
if (! $firstArg instanceof Arg) {
return [];
}
Expand Down Expand Up @@ -88,7 +85,7 @@ public function processNode(Node $node, Scope $scope): array
$refProperty->setAccessible(true);
$autoAddInvokableClass = $refProperty->getValue($serviceManager);
if ($autoAddInvokableClass) {
if ($this->broker->hasClass($serviceName)) {
if ($this->reflectionProvider->hasClass($serviceName)) {
return [];
}
$classDoesNotExistNote = \sprintf(' nor the class "%s" exists', $serviceName);
Expand Down
7 changes: 6 additions & 1 deletion src/ServiceManagerLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,17 @@ public function getServiceLocator(string $serviceManagerName): ServiceLocatorInt
$refProp = new ReflectionProperty(ServiceListenerFactory::class, 'defaultServiceConfig');
$refProp->setAccessible(true);
$config = $refProp->getValue(new ServiceListenerFactory());
\assert(\is_array($config));
\assert(\is_array($config['factories']));
unset($config['factories']['config']);
$refProp->setAccessible(false);
$serviceManager->configure($config);
}
foreach ($this->knownModules as $module) {
if (\class_exists($module)) {
$serviceManager->configure((new $module())->getDependencyConfig());
$module = new $module();
\assert(\method_exists($module, 'getDependencyConfig'));
$serviceManager->configure($module->getDependencyConfig());
}
}

Expand All @@ -88,6 +92,7 @@ public function getServiceLocator(string $serviceManagerName): ServiceLocatorInt
$serviceLocator = $this->serviceLocator;
if (! isset($this->serviceManagerNames[$serviceManagerName])) {
$serviceLocator = $serviceLocator->get($serviceManagerName);
\assert($serviceLocator instanceof ServiceLocatorInterface);
}

return $serviceLocator;
Expand Down
27 changes: 10 additions & 17 deletions src/Type/Laminas/ControllerPluginClassReflectionExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,18 @@
use Laminas\Mvc\Controller\AbstractController;
use Laminas\ServiceManager\ServiceLocatorInterface;
use LaminasPhpStan\ServiceManagerLoader;
use PHPStan\Broker\Broker;
use PHPStan\Reflection\BrokerAwareExtension;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\MethodsClassReflectionExtension;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\ObjectType;

final class ControllerPluginClassReflectionExtension implements BrokerAwareExtension, MethodsClassReflectionExtension
final class ControllerPluginClassReflectionExtension implements MethodsClassReflectionExtension
{
private ServiceManagerLoader $serviceManagerLoader;

private Broker $broker;

public function __construct(ServiceManagerLoader $serviceManagerLoader)
{
$this->serviceManagerLoader = $serviceManagerLoader;
}

public function setBroker(Broker $broker): void
{
$this->broker = $broker;
public function __construct(
private ReflectionProvider $reflectionProvider,
private ServiceManagerLoader $serviceManagerLoader
) {
}

public function hasMethod(ClassReflection $classReflection, string $methodName): bool
Expand All @@ -37,11 +28,13 @@ public function hasMethod(ClassReflection $classReflection, string $methodName):

public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection
{
$plugin = $this->getControllerPluginManager()->get($methodName);
$plugin = $this->getControllerPluginManager()->get($methodName);
\assert(\is_object($plugin));

$pluginClassName = \get_class($plugin);

if (\is_callable($plugin)) {
return $this->broker->getClass($pluginClassName)->getNativeMethod('__invoke');
return $this->reflectionProvider->getClass($pluginClassName)->getNativeMethod('__invoke');
}

$returnType = new ObjectType($pluginClassName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ final public function getTypeFromMethodCall(
MethodCall $methodCall,
Scope $scope
): Type {
$firstArg = $methodCall->args[0];
$firstArg = $methodCall->getArgs()[0];
if (! $firstArg instanceof Arg) {
throw new \PHPStan\ShouldNotHappenException(\sprintf(
'Argument passed to %s::%s should be a string, %s given',
Expand All @@ -52,11 +52,14 @@ final public function getTypeFromMethodCall(
if (null !== $plugin) {
$pluginManager = $this->serviceManagerLoader->getServiceLocator($this->getPluginManagerName());

return new ObjectType(\get_class($pluginManager->get($plugin)));
$pluginInstance = $pluginManager->get($plugin);
\assert(\is_object($pluginInstance));

return new ObjectType(\get_class($pluginInstance));
}

if ($argType instanceof StringType) {
return ParametersAcceptorSelector::selectFromArgs($scope, $methodCall->args, $methodReflection->getVariants())->getReturnType();
return ParametersAcceptorSelector::selectFromArgs($scope, $methodCall->getArgs(), $methodReflection->getVariants())->getReturnType();
}

throw new \PHPStan\ShouldNotHappenException(\sprintf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@ final public function getTypeFromMethodCall(
MethodCall $methodCall,
Scope $scope
): Type {
$serviceManager = $this->serviceManagerLoader->getServiceLocator(ServiceLocatorInterface::class);
$serviceName = $this->methodToServiceMap[$methodReflection->getName()];
$serviceClass = \get_class($serviceManager->get($serviceName));
$serviceManager = $this->serviceManagerLoader->getServiceLocator(ServiceLocatorInterface::class);
$serviceName = $this->methodToServiceMap[$methodReflection->getName()];
$serviceInstance = $serviceManager->get($serviceName);
\assert(\is_object($serviceInstance));
$serviceClass = \get_class($serviceInstance);

return new ObjectType($serviceClass);
}
Expand Down
Loading