Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. ShouldCallParentMethodsRule.php

class ShouldCallParentMethodsRule

@implements Rule<InClassMethodNode>

Hierarchy

  • class \PHPStan\Rules\PHPUnit\ShouldCallParentMethodsRule implements \PHPStan\Rules\Rule

Expanded class hierarchy of ShouldCallParentMethodsRule

File

vendor/phpstan/phpstan-phpunit/src/Rules/PHPUnit/ShouldCallParentMethodsRule.php, line 18

Namespace

PHPStan\Rules\PHPUnit
View source
class ShouldCallParentMethodsRule implements Rule {
    public function getNodeType() : string {
        return InClassMethodNode::class;
    }
    public function processNode(Node $node, Scope $scope) : array {
        $methodName = $node->getOriginalNode()->name->name;
        if (!in_array(strtolower($methodName), [
            'setup',
            'teardown',
        ], true)) {
            return [];
        }
        if ($scope->getClassReflection() === null) {
            return [];
        }
        if (!$scope->getClassReflection()
            ->isSubclassOf(TestCase::class)) {
            return [];
        }
        $parentClass = $scope->getClassReflection()
            ->getParentClass();
        if ($parentClass === null) {
            return [];
        }
        if (!$parentClass->hasNativeMethod($methodName)) {
            return [];
        }
        $parentMethod = $parentClass->getNativeMethod($methodName);
        if ($parentMethod->getDeclaringClass()
            ->getName() === TestCase::class) {
            return [];
        }
        $hasParentCall = $this->hasParentClassCall($node->getOriginalNode()
            ->getStmts(), strtolower($methodName));
        if (!$hasParentCall) {
            return [
                RuleErrorBuilder::message(sprintf('Missing call to parent::%s() method.', $methodName))->identifier('phpunit.callParent')
                    ->build(),
            ];
        }
        return [];
    }
    
    /**
     * @param Node\Stmt[]|null $stmts
     *
     */
    private function hasParentClassCall(?array $stmts, string $methodName) : bool {
        if ($stmts === null) {
            return false;
        }
        foreach ($stmts as $stmt) {
            if (!$stmt instanceof Node\Stmt\Expression) {
                continue;
            }
            if (!$stmt->expr instanceof Node\Expr\StaticCall) {
                continue;
            }
            if (!$stmt->expr->class instanceof Node\Name) {
                continue;
            }
            $class = (string) $stmt->expr->class;
            if (strtolower($class) !== 'parent') {
                continue;
            }
            if (!$stmt->expr->name instanceof Node\Identifier) {
                continue;
            }
            if ($stmt->expr->name
                ->toLowerString() === $methodName) {
                return true;
            }
        }
        return false;
    }

}

Members

Title Sort descending Modifiers Object type Summary
ShouldCallParentMethodsRule::getNodeType public function
ShouldCallParentMethodsRule::hasParentClassCall private function *
ShouldCallParentMethodsRule::processNode public function
RSS feed
Powered by Drupal