PHPStan\Rules\Methods\CallStaticMethodsRule::processNode PHP Method

processNode() public method

public processNode ( PhpParser\Node $node, Scope $scope ) : array
$node PhpParser\Node
$scope PHPStan\Analyser\Scope
return array
    public function processNode(Node $node, Scope $scope) : array
    {
        if (!is_string($node->name)) {
            return [];
        }
        $name = $node->name;
        $currentClass = $scope->getClass();
        if ($currentClass === null) {
            return [];
        }
        $currentClassReflection = $this->broker->getClass($currentClass);
        if (!$node->class instanceof Name) {
            return [];
        }
        $class = (string) $node->class;
        if ($class === 'self' || $class === 'static') {
            $class = $currentClass;
        }
        if ($class === 'parent') {
            if ($currentClassReflection->getParentClass() === false) {
                return [sprintf('%s::%s() calls to parent::%s() but %s does not extend any class.', $currentClass, $scope->getFunctionName(), $name, $currentClass)];
            }
            $currentMethodReflection = $currentClassReflection->getMethod($scope->getFunctionName());
            if (!$currentMethodReflection->isStatic()) {
                if ($name === '__construct' && $currentClassReflection->getParentClass()->hasMethod('__construct')) {
                    return $this->check->check($currentClassReflection->getParentClass()->getMethod('__construct'), $node, ['Parent constructor invoked with %d parameter, %d required.', 'Parent constructor invoked with %d parameters, %d required.', 'Parent constructor invoked with %d parameter, at least %d required.', 'Parent constructor invoked with %d parameters, at least %d required.', 'Parent constructor invoked with %d parameter, %d-%d required.', 'Parent constructor invoked with %d parameters, %d-%d required.']);
                }
                return [];
            }
            $class = $currentClassReflection->getParentClass()->getName();
        }
        $classReflection = $this->broker->getClass($class);
        if (!$classReflection->hasMethod($name)) {
            return [sprintf('Call to an undefined static method %s::%s().', $class, $name)];
        }
        $method = $classReflection->getMethod($name);
        if (!$method->isStatic()) {
            return [sprintf('Static call to instance method %s::%s().', $class, $method->getName())];
        }
        if ($currentClass !== null && $method->getDeclaringClass()->getName() !== $currentClass) {
            if (in_array($method->getDeclaringClass()->getName(), $currentClassReflection->getParentClassesNames(), true)) {
                if ($method->isPrivate()) {
                    return [sprintf('Call to private static method %s() of class %s.', $method->getName(), $method->getDeclaringClass()->getName())];
                }
            } else {
                if (!$method->isPublic()) {
                    return [sprintf('Call to %s static method %s() of class %s.', $method->isPrivate() ? 'private' : 'protected', $method->getName(), $method->getDeclaringClass()->getName())];
                }
            }
        }
        $methodName = $class . '::' . $method->getName() . '()';
        $errors = $this->check->check($method, $node, ['Static method ' . $methodName . ' invoked with %d parameter, %d required.', 'Static method ' . $methodName . ' invoked with %d parameters, %d required.', 'Static method ' . $methodName . ' invoked with %d parameter, at least %d required.', 'Static method ' . $methodName . ' invoked with %d parameters, at least %d required.', 'Static method ' . $methodName . ' invoked with %d parameter, %d-%d required.', 'Static method ' . $methodName . ' invoked with %d parameters, %d-%d required.']);
        if ($method->getName() !== $name) {
            $errors[] = sprintf('Call to static method %s with incorrect case: %s', $methodName, $name);
        }
        return $errors;
    }