Skip to content
This repository has been archived by the owner on Jun 26, 2018. It is now read-only.

Commit

Permalink
Merge 93f60f0 into e6454d1
Browse files Browse the repository at this point in the history
  • Loading branch information
mzk committed Jan 15, 2018
2 parents e6454d1 + 93f60f0 commit abbfc1a
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 4 deletions.
4 changes: 4 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
includes:
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-phpunit/rules.neon

parameters:
excludes_analyse:
- %rootDir%/../../../tests/*/data/*
7 changes: 5 additions & 2 deletions src/Rules/ContainerInterfacePrivateServiceRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Type\ObjectType;
use PHPStan\Type\ThisType;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\MethodCall;
Expand All @@ -34,8 +35,10 @@ public function processNode(Node $node, Scope $scope): array
{
if ($node instanceof MethodCall && $node->name === 'get') {
$type = $scope->getType($node->var);
if ($type instanceof ObjectType
&& \in_array($type->getClassName(), ['Symfony\Component\DependencyInjection\ContainerInterface', 'Symfony\Bundle\FrameworkBundle\Controller\Controller'], \true)
$baseController = new ObjectType('Symfony\Bundle\FrameworkBundle\Controller\Controller');
$isInstanceOfController = $type instanceof ThisType && $baseController->isSuperTypeOf($type)->yes();
$isContainerInterface = $type instanceof ObjectType && $type->getClassName() === 'Symfony\Component\DependencyInjection\ContainerInterface';
if (($isContainerInterface || $isInstanceOfController)
&& isset($node->args[0])
&& $node->args[0] instanceof Arg
) {
Expand Down
9 changes: 7 additions & 2 deletions src/Rules/ContainerInterfaceUnknownServiceRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
namespace Lookyman\PHPStan\Symfony\Rules;

use Lookyman\PHPStan\Symfony\ServiceMap;
use PhpParser\Node\Expr\Variable;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Type\ObjectType;
use PHPStan\Type\ThisType;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\MethodCall;
Expand All @@ -34,10 +36,13 @@ public function processNode(Node $node, Scope $scope): array
{
if ($node instanceof MethodCall && $node->name === 'get') {
$type = $scope->getType($node->var);
if ($type instanceof ObjectType
&& \in_array($type->getClassName(), ['Symfony\Component\DependencyInjection\ContainerInterface', 'Symfony\Bundle\FrameworkBundle\Controller\Controller'], \true)
$baseController = new ObjectType('Symfony\Bundle\FrameworkBundle\Controller\Controller');
$isInstanceOfController = $type instanceof ThisType && $baseController->isSuperTypeOf($type)->yes();
$isContainerInterface = $type instanceof ObjectType && $type->getClassName() === 'Symfony\Component\DependencyInjection\ContainerInterface';
if (($isInstanceOfController || $isContainerInterface)
&& isset($node->args[0])
&& $node->args[0] instanceof Arg
&& !$node->args[0]->value instanceof Variable
) {
$service = $this->serviceMap->getServiceFromNode($node->args[0]->value);
if ($service === \null) {
Expand Down
35 changes: 35 additions & 0 deletions tests/Rules/ContainerInterfacePrivateServiceRuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types = 1);

namespace Lookyman\PHPStan\Symfony\Rules;

use Lookyman\PHPStan\Symfony\ServiceMap;
use PHPStan\Rules\Rule;

final class ContainerInterfacePrivateServiceRuleTest extends \PHPStan\Testing\RuleTestCase
{

protected function setUp()
{
include_once __DIR__ . '/data/Controller.php';
}

protected function getRule(): Rule
{
$serviceMap = new ServiceMap(__DIR__ . '/../container.xml');

return new ContainerInterfacePrivateServiceRule($serviceMap);
}

public function testGetPrivateService()
{
$this->analyse([__DIR__ . '/data/ExampleController.php'], [
[
'Service "private" is private.',
14,
],
]);
}

}
35 changes: 35 additions & 0 deletions tests/Rules/ContainerInterfaceUnknownServiceRuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types = 1);

namespace Lookyman\PHPStan\Symfony\Rules;

use Lookyman\PHPStan\Symfony\ServiceMap;
use PHPStan\Rules\Rule;

final class ContainerInterfaceUnknownServiceRuleTest extends \PHPStan\Testing\RuleTestCase
{

protected function setUp()
{
include_once __DIR__ . '/data/Controller.php';
}

protected function getRule(): Rule
{
$serviceMap = new ServiceMap(__DIR__ . '/../container.xml');

return new ContainerInterfaceUnknownServiceRule($serviceMap);
}

public function testGetUnknownService()
{
$this->analyse([__DIR__ . '/data/ExampleController.php'], [
[
'Service "service.not.found" is not registered in the container.',
20,
],
]);
}

}
10 changes: 10 additions & 0 deletions tests/Rules/data/Controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types = 1);

namespace Symfony\Bundle\FrameworkBundle\Controller;

abstract class Controller
{

}
30 changes: 30 additions & 0 deletions tests/Rules/data/ExampleController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types = 1);

namespace Lookyman\PHPStan\Symfony\Rules\data;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

final class ExampleController extends Controller
{

public function getPrivateServiceAction()
{
$service = $this->get('private');
$service->noMethod();
}

public function getUnknownService()
{
$service = $this->get('service.not.found');
$service->noMethod();
}

public function getVariableService(string $serviceKey)
{
$service = $this->get($serviceKey);
$service->noMethod();
}

}

0 comments on commit abbfc1a

Please sign in to comment.