-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[DX][DI] Add compiler pass which check extistence of service class name #11315
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\DependencyInjection\Compiler; | ||
|
||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use Symfony\Component\DependencyInjection\Definition; | ||
use Symfony\Component\DependencyInjection\Exception\BadServiceClassException; | ||
|
||
/** | ||
* Checks your service exists by checking its definition "class" and "factory_class" keys | ||
* | ||
* @author Leszek "l3l0" Prabucki <[email protected]> | ||
*/ | ||
class CheckServiceClassPass implements CompilerPassInterface | ||
{ | ||
/** | ||
* Checks if ContainerBuilder services exists | ||
* | ||
* @param ContainerBuilder $container The ContainerBuilder instances | ||
*/ | ||
public function process(ContainerBuilder $container) | ||
{ | ||
$parameterBag = $container->getParameterBag(); | ||
foreach ($container->getDefinitions() as $id => $definition) { | ||
if ($this->allowsToCheckClassExistenceForClass($definition) && !class_exists($parameterBag->resolveValue($definition->getClass()))) { | ||
throw new BadServiceClassException($id, $definition->getClass(), 'class'); | ||
} | ||
if ($this->allowsToCheckClassExistenceForFactoryClass($definition) && !class_exists($parameterBag->resolveValue($definition->getFactoryClass()))) { | ||
throw new BadServiceClassException($id, $definition->getFactoryClass(), 'factory_class'); | ||
} | ||
} | ||
} | ||
|
||
private function allowsToCheckClassExistenceForClass(Definition $definition) | ||
{ | ||
return $definition->getClass() && !$this->isFactoryDefinition($definition) && !$definition->isSynthetic(); | ||
} | ||
|
||
private function allowsToCheckClassExistenceForFactoryClass(Definition $definition) | ||
{ | ||
return $definition->getFactoryClass() && !$definition->isSynthetic(); | ||
} | ||
|
||
private function isFactoryDefinition(Definition $definition) | ||
{ | ||
return $definition->getFactoryClass() || $definition->getFactoryService(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in case of a definition using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah right :) I will add that. |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\DependencyInjection\Exception; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing license note. |
||
|
||
class BadServiceClassException extends RuntimeException | ||
{ | ||
public function __construct($id, $className, $key) | ||
{ | ||
parent::__construct( | ||
sprintf( | ||
'Class "%s" not found. Check the spelling on the "%s" configuration for your "%s" service.', | ||
$className, | ||
$key, | ||
$id | ||
) | ||
); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should be on one line. |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\DependencyInjection\Tests\Compiler; | ||
|
||
use Symfony\Component\DependencyInjection\Compiler\CheckServiceClassPass; | ||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
|
||
class CheckServiceClassPassTest extends \PHPUnit_Framework_TestCase | ||
{ | ||
/** | ||
* @expectedException \Symfony\Component\DependencyInjection\Exception\BadServiceClassException | ||
* @expectedExceptionMessage Class "\InvalidName\TestClass" not found. Check the spelling on the "class" configuration for your "a" service. | ||
*/ | ||
public function testThrowsBadNameExceptionWhenServiceHasInvalidClassName() | ||
{ | ||
$container = new ContainerBuilder(); | ||
$container->register('a', '\InvalidName\TestClass'); | ||
|
||
$this->process($container); | ||
} | ||
|
||
public function testDoesNotThrowExceptionIfClassExists() | ||
{ | ||
$container = new ContainerBuilder(); | ||
$container->register('a', '\Symfony\Component\DependencyInjection\Compiler\CheckServiceClassPass'); | ||
$container->register('b', '\stdClass'); | ||
$container->register('c', '\Symfony\Component\DependencyInjection\Tests\Compiler\MyTestService'); | ||
$container | ||
->register('d', '\stdClass') | ||
->setFactoryService('\Symfony\Component\DependencyInjection\Tests\Compiler\MyTestService') | ||
->setFactoryMethod('factoryMethod') | ||
; | ||
|
||
$this->process($container); | ||
} | ||
|
||
public function testSynteticServicesClassNamesAreNotChecked() | ||
{ | ||
$container = new ContainerBuilder(); | ||
$container | ||
->register('a', '\InvalidName\TestClass') | ||
->setSynthetic(true) | ||
; | ||
|
||
$this->process($container); | ||
} | ||
|
||
/** | ||
* @expectedException \Symfony\Component\DependencyInjection\Exception\BadServiceClassException | ||
* @expectedExceptionMessage Class "\InvalidName\TestClass" not found. Check the spelling on the "factory_class" configuration for your "a" service. | ||
*/ | ||
public function testFactoryMethodServicesClassNamesAreNotChecked() | ||
{ | ||
$container = new ContainerBuilder(); | ||
$container | ||
->register('a', '\stdClass') | ||
->setFactoryClass('\InvalidName\TestClass') | ||
->setFactoryMethod('factoryMethod') | ||
; | ||
|
||
$this->process($container); | ||
} | ||
|
||
public function testServicesWithoutNameAreNotChecked() | ||
{ | ||
$container = new ContainerBuilder(); | ||
$container | ||
->register('a') | ||
; | ||
|
||
$this->process($container); | ||
} | ||
|
||
public function testSynteticServicesNameAreNotChecked() | ||
{ | ||
$container = new ContainerBuilder(); | ||
$container | ||
->register('a', '\InvalidName\TestClass') | ||
->setSynthetic(true) | ||
; | ||
|
||
$this->process($container); | ||
} | ||
|
||
protected function process(ContainerBuilder $container) | ||
{ | ||
$pass = new CheckServiceClassPass(); | ||
$pass->process($container); | ||
} | ||
} | ||
|
||
class MyTestService | ||
{ | ||
public function factoryMethod() | ||
{ | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why changing these tests ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cause when we run all symfony test suites at once foo class exist (cause of this probably https://github.com/l3l0/symfony/blob/feature/better-error-on-bad-service-class-name-issue-11301/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/ProjectExtension.php#L16)