<commit_before><?php

final class UserReadModel
{
    private $id;
    private $firstName;
    private $lastName;

    private function __construct(int $id, string $firstName, string $lastName)
    {
        $this->guardPublicMethodsHaveReturnTypes();

        $this->id        = $id;
        $this->firstName = $firstName;
        $this->lastName  = $lastName;
    }

    public static function fromState(array $state): UserReadModel
    {
        return new UserReadModel($state['id'], $state['firstname'], $state['lastname']);
    }

    public function getId(): integer
    {
        return $this->id;
    }

    public function getFirstName(): string
    {
        return $this->firstName;
    }

    public function getLastName(): string
    {
        return $this->lastName;
    }

    public function getFullName(): string
    {
        return $this->firstName . ' ' . $this->lastName;
    }

    private function guardPublicMethodsHaveReturnTypes()
    {
        $reflectionClass = new ReflectionClass($this);
        $methods         = $reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC);

        /** @var ReflectionMethod[] $methods */
        foreach ($methods as $method) {
            if ($method->getName() == '__construct') {
                continue;
            }

            $reflectionMethod = new ReflectionMethod(__CLASS__, $method->getName());
            if ($reflectionMethod->getReturnType() === null) {
                trigger_error(sprintf('All public methods in the %s require a return type. None found for %s', get_class($this), $method->getName()));
            }
        }
    }
}<commit_msg>I did it! Built checker that checks if a method that returns a value has a return type.<commit_after><?php

final class UserReadModel
{
    private $id;
    private $firstName;
    private $lastName;

    const NO_RETURN_VALUE = 'void';

    public function __construct(int $id, string $firstName, string $lastName)
    {
        $this->guardPublicMethodsHaveReturnTypes();

        $this->id        = $id;
        $this->firstName = $firstName;
        $this->lastName  = $lastName;
    }

    public function foo()
    {
        return 'bla';
    }

    public static function fromState(array $state): UserReadModel
    {
        return new UserReadModel($state['id'], $state['firstname'], $state['lastname']);
    }

    public function getId(): integer
    {
        return $this->id;
    }

    public function getFirstName(): string
    {
        return $this->firstName;
    }

    public function getLastName(): string
    {
        return $this->lastName;
    }

    public function getFullName(): string
    {
        return $this->firstName . ' ' . $this->lastName;
    }

    private function guardPublicMethodsHaveReturnTypes()
    {
        $reflectionClass = new ReflectionClass($this);
        $methods         = $reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC);

        /** @var ReflectionMethod[] $methods */
        foreach ($methods as $method) {
            if ($method->getName() == '__construct') {
                continue;
            }

            $returnValue = $this->getReturnValue($this->parseMethod($method));

            $reflectionMethod = new ReflectionMethod(__CLASS__, $method->getName());

            if ($returnValue !== self::NO_RETURN_VALUE && $reflectionMethod->getReturnType() === null) {
                trigger_error(sprintf('All public methods in the %s require a return type. Method "%s" returns %s', get_class($this), $method->getName(), $returnValue));
            }
        }
    }

    private function parseMethod(ReflectionMethod $method): array
    {
        $file = explode(PHP_EOL, file_get_contents(__FILE__));

        $reflectionMethod = new ReflectionMethod(__CLASS__, $method->getName());

        foreach ($file as $key => $row) {
            if ($key < $reflectionMethod->getStartLine() - 1) {
                unset($file[$key]);
                continue;
            }

            if ($key > $reflectionMethod->getEndLine() - 1) {
                unset($file[$key]);
                continue;
            }

            if (strpos($row, '    ') === 0) {
                $file[$key] = substr_replace($row, '', 0, 4);
            }
        }

        return $file;
    }

    private function getReturnValue(array $parsedMethod): string
    {
        $returnValue = self::NO_RETURN_VALUE;

        foreach ($parsedMethod as $key => $row) {
            if (strpos(strtolower(trim($row)), 'return') === 0) {
                $returnValue = substr(ltrim($row), 6);

                return ltrim($this->stripSemicolon($returnValue));
            }
        }

        if ($returnValue === self::NO_RETURN_VALUE) {
            return self::NO_RETURN_VALUE;
        }
    }

    private function stripSemicolon($returnValue): string
    {
        if (strpos($returnValue, ';', strlen($returnValue) - 1) !== false) {
            $returnValue = substr($returnValue, 0, strlen($returnValue) - 1);
        }

        return $returnValue;
    }
}
{'fraction_non_alphanumeric': 0.13174603174603175, 'fraction_numerical': 0.001984126984126984, 'mean_word_length': 2.2169751116783663, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3703937', 'n_tokens_mistral': 1421, 'n_tokens_neox': 1369, 'n_words': 316}