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

Breadcrumb

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

function PhpFileParser::findClasses

Extract the classes in the given file

Parameters

string $path The file to check:

Return value

list<class-string> The found classes

Throws

\RuntimeException

1 call to PhpFileParser::findClasses()
ClassMapGenerator::scanPaths in vendor/composer/class-map-generator/src/ClassMapGenerator.php
Iterate over all files in the given directory searching for classes

File

vendor/composer/class-map-generator/src/PhpFileParser.php, line 29

Class

PhpFileParser
@author Jordi Boggiano <j.boggiano@seld.be>

Namespace

Composer\ClassMapGenerator

Code

public static function findClasses(string $path) : array {
    $extraTypes = self::getExtraTypes();
    // Use @ here instead of Silencer to actively suppress 'unhelpful' output
    // @link https://github.com/composer/composer/pull/4886
    $contents = @php_strip_whitespace($path);
    if ('' === $contents) {
        if (!file_exists($path)) {
            $message = 'File at "%s" does not exist, check your classmap definitions';
        }
        elseif (!self::isReadable($path)) {
            $message = 'File at "%s" is not readable, check its permissions';
        }
        elseif ('' === trim((string) file_get_contents($path))) {
            // The input file was really empty and thus contains no classes
            return array();
        }
        else {
            $message = 'File at "%s" could not be parsed as PHP, it may be binary or corrupted';
        }
        $error = error_get_last();
        if (isset($error['message'])) {
            $message .= PHP_EOL . 'The following message may be helpful:' . PHP_EOL . $error['message'];
        }
        throw new \RuntimeException(sprintf($message, $path));
    }
    // return early if there is no chance of matching anything in this file
    Preg::matchAllStrictGroups('{\\b(?:class|interface|trait' . $extraTypes . ')\\s}i', $contents, $matches);
    if (0 === \count($matches)) {
        return array();
    }
    $p = new PhpFileCleaner($contents, count($matches[0]));
    $contents = $p->clean();
    unset($p);
    Preg::matchAll('{
            (?:
                 \\b(?<![\\\\$:>])(?P<type>class|interface|trait' . $extraTypes . ') \\s++ (?P<name>[a-zA-Z_\\x7f-\\xff:][a-zA-Z0-9_\\x7f-\\xff:\\-]*+)
               | \\b(?<![\\\\$:>])(?P<ns>namespace) (?P<nsname>\\s++[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+(?:\\s*+\\\\\\s*+[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+)*+)? \\s*+ [\\{;]
            )
        }ix', $contents, $matches);
    $classes = array();
    $namespace = '';
    for ($i = 0, $len = count($matches['type']); $i < $len; $i++) {
        if (isset($matches['ns'][$i]) && $matches['ns'][$i] !== '') {
            $namespace = str_replace(array(
                ' ',
                "\t",
                "\r",
                "\n",
            ), '', (string) $matches['nsname'][$i]) . '\\';
        }
        else {
            $name = $matches['name'][$i];
            assert(is_string($name));
            // skip anon classes extending/implementing
            if ($name === 'extends' || $name === 'implements') {
                continue;
            }
            if ($name[0] === ':') {
                // This is an XHP class, https://github.com/facebook/xhp
                $name = 'xhp' . substr(str_replace(array(
                    '-',
                    ':',
                ), array(
                    '_',
                    '__',
                ), $name), 1);
            }
            elseif (strtolower((string) $matches['type'][$i]) === 'enum') {
                // something like:
                //   enum Foo: int { HERP = '123'; }
                // The regex above captures the colon, which isn't part of
                // the class name.
                // or:
                //   enum Foo:int { HERP = '123'; }
                // The regex above captures the colon and type, which isn't part of
                // the class name.
                $colonPos = strrpos($name, ':');
                if (false !== $colonPos) {
                    $name = substr($name, 0, $colonPos);
                }
            }
            
            /** @var class-string */
            $className = ltrim($namespace . $name, '\\');
            $classes[] = $className;
        }
    }
    return $classes;
}

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal