Chris@13: Chris@13: */ Chris@13: class ValidConstructorPass extends CodeCleanerPass Chris@13: { Chris@13: private $namespace; Chris@13: Chris@13: public function beforeTraverse(array $nodes) Chris@13: { Chris@13: $this->namespace = []; Chris@13: } Chris@13: Chris@13: /** Chris@13: * Validate that the constructor is not static and does not have a return type. Chris@13: * Chris@13: * @throws FatalErrorException the constructor function is static Chris@13: * @throws FatalErrorException the constructor function has a return type Chris@13: * Chris@13: * @param Node $node Chris@13: */ Chris@13: public function enterNode(Node $node) Chris@13: { Chris@13: if ($node instanceof Namespace_) { Chris@13: $this->namespace = isset($node->name) ? $node->name->parts : []; Chris@13: } elseif ($node instanceof Class_) { Chris@13: $constructor = null; Chris@13: foreach ($node->stmts as $stmt) { Chris@13: if ($stmt instanceof ClassMethod) { Chris@13: // If we find a new-style constructor, no need to look for the old-style Chris@17: if ('__construct' === \strtolower($stmt->name)) { Chris@13: $this->validateConstructor($stmt, $node); Chris@13: Chris@13: return; Chris@13: } Chris@13: Chris@13: // We found a possible old-style constructor (unless there is also a __construct method) Chris@17: if (empty($this->namespace) && \strtolower($node->name) === \strtolower($stmt->name)) { Chris@13: $constructor = $stmt; Chris@13: } Chris@13: } Chris@13: } Chris@13: Chris@13: if ($constructor) { Chris@13: $this->validateConstructor($constructor, $node); Chris@13: } Chris@13: } Chris@13: } Chris@13: Chris@13: /** Chris@13: * @throws FatalErrorException the constructor function is static Chris@13: * @throws FatalErrorException the constructor function has a return type Chris@13: * Chris@13: * @param Node $constructor Chris@13: * @param Node $classNode Chris@13: */ Chris@13: private function validateConstructor(Node $constructor, Node $classNode) Chris@13: { Chris@13: if ($constructor->isStatic()) { Chris@13: // For PHP Parser 4.x Chris@13: $className = $classNode->name instanceof Identifier ? $classNode->name->toString() : $classNode->name; Chris@13: Chris@17: $msg = \sprintf( Chris@13: 'Constructor %s::%s() cannot be static', Chris@17: \implode('\\', \array_merge($this->namespace, (array) $className)), Chris@13: $constructor->name Chris@13: ); Chris@13: throw new FatalErrorException($msg, 0, E_ERROR, null, $classNode->getLine()); Chris@13: } Chris@13: Chris@17: if (\method_exists($constructor, 'getReturnType') && $constructor->getReturnType()) { Chris@13: // For PHP Parser 4.x Chris@13: $className = $classNode->name instanceof Identifier ? $classNode->name->toString() : $classNode->name; Chris@13: Chris@17: $msg = \sprintf( Chris@13: 'Constructor %s::%s() cannot declare a return type', Chris@17: \implode('\\', \array_merge($this->namespace, (array) $className)), Chris@13: $constructor->name Chris@13: ); Chris@13: throw new FatalErrorException($msg, 0, E_ERROR, null, $classNode->getLine()); Chris@13: } Chris@13: } Chris@13: }