public function getName(): string
    {
        // Check cache.
        if (null === $this->name) {
            $tokens = $this->getTokenStream();
            // Find class token
            try {
                $loc = $tokens->scan(0, [T_CLASS, T_TRAIT]);
            } catch (\OutOfBoundsException $e) {
                throw new ClassDefinitionNotFoundException('No class is found inside ' . $this->filename . '.', 0, $e);
            }

            // Get the following token
            if ($loc !== null) {
                $loc = $tokens->next($loc);
            }

            // Make sure it is not :: but a name
            if ($loc !== null && $tokens->type($loc) === T_STRING) {
                // Read the name from the token
                $this->name           = $tokens->value($loc);
                $this->class_location = $loc;
            } else {
                // Mark the name as NOT found (in contrast to not initialized)
                $this->name = false;
            }
        }

        // Return the name if a class was found or throw an exception.
        if ($this->name) {
            return $this->name;
        }

        throw new ClassDefinitionNotFoundException('No class is found inside ' . $this->filename . '.');
    }