Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\DependencyInjection\Compiler; Chris@0: Chris@0: use Symfony\Component\DependencyInjection\ContainerBuilder; Chris@0: use Symfony\Component\DependencyInjection\Exception\RuntimeException; Chris@0: Chris@0: /** Chris@0: * This pass validates each definition individually only taking the information Chris@0: * into account which is contained in the definition itself. Chris@0: * Chris@0: * Later passes can rely on the following, and specifically do not need to Chris@0: * perform these checks themselves: Chris@0: * Chris@0: * - non synthetic, non abstract services always have a class set Chris@0: * - synthetic services are always public Chris@0: * Chris@0: * @author Johannes M. Schmitt Chris@0: */ Chris@0: class CheckDefinitionValidityPass implements CompilerPassInterface Chris@0: { Chris@0: /** Chris@0: * Processes the ContainerBuilder to validate the Definition. Chris@0: * Chris@0: * @param ContainerBuilder $container Chris@0: * Chris@0: * @throws RuntimeException When the Definition is invalid Chris@0: */ Chris@0: public function process(ContainerBuilder $container) Chris@0: { Chris@0: foreach ($container->getDefinitions() as $id => $definition) { Chris@0: // synthetic service is public Chris@0: if ($definition->isSynthetic() && !$definition->isPublic()) { Chris@0: throw new RuntimeException(sprintf('A synthetic service ("%s") must be public.', $id)); Chris@0: } Chris@0: Chris@0: // non-synthetic, non-abstract service has class Chris@0: if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass()) { Chris@0: if ($definition->getFactory()) { Chris@0: throw new RuntimeException(sprintf('Please add the class to service "%s" even if it is constructed by a factory since we might need to add method calls based on compile-time checks.', $id)); Chris@0: } Chris@0: Chris@0: throw new RuntimeException(sprintf( Chris@0: 'The definition for "%s" has no class. If you intend to inject ' Chris@0: .'this service dynamically at runtime, please mark it as synthetic=true. ' Chris@0: .'If this is an abstract definition solely used by child definitions, ' Chris@0: .'please add abstract=true, otherwise specify a class to get rid of this error.', Chris@0: $id Chris@0: )); Chris@0: } Chris@0: Chris@0: // tag attribute values must be scalars Chris@0: foreach ($definition->getTags() as $name => $tags) { Chris@0: foreach ($tags as $attributes) { Chris@0: foreach ($attributes as $attribute => $value) { Chris@0: if (!is_scalar($value) && null !== $value) { Chris@0: throw new RuntimeException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s".', $id, $name, $attribute)); Chris@0: } Chris@0: } Chris@0: } Chris@0: } Chris@0: } Chris@0: } Chris@0: }