Passed
Push — master ( 6f7339...89f27a )
by P.R.
02:14
created

ClassHelper::classPath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 13
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Plaisio\Console\Kernel\Helper;
5
6
use Composer\Autoload\ClassLoader;
7
use SetBased\Exception\RuntimeException;
8
9
/**
10
 * Utility class for classes.
11
 */
12
class ClassHelper
13
{
14
  //--------------------------------------------------------------------------------------------------------------------
15
  /**
16
   * Returns the first line of the class declaration in the source code of a class.
17
   *
18
   * @param string[] $lines The source code of the class.
19
   * @param string   $class The name of the class.
20
   *
21
   * @return int
22
   */
23
  public static function classDeclarationLine(array $lines, string $class): int
24
  {
25
    $pattern = sprintf('/(\w\s+)?class\s+%s/', preg_quote($class));
26
    $line    = self::searchPattern($lines, $pattern);
27
28
    if ($line===null)
29
    {
30
      throw new RuntimeException('Unable to find declaration of class %s', $class);
31
    }
32
33
    return $line;
34
  }
35
36
  //--------------------------------------------------------------------------------------------------------------------
37
  /**
38
   * Returns the path to the source file of a class.
39
   *
40
   * @param string $class The fully qualified name of the class.
41
   *
42
   * @return string
43
   */
44
  public static function classPath(string $class): string
45
  {
46
    /** @var ClassLoader $loader */
47
    $loader = spl_autoload_functions()[0][0];
48
49
    // Find the source file of the constant class.
50
    $filename = $loader->findFile(ltrim($class, '\\'));
51
    if ($filename===false)
52
    {
53
      throw new RuntimeException("ClassLoader can not find class '%s'", $class);
54
    }
55
56
    return realpath($filename);
57
  }
58
59
  //--------------------------------------------------------------------------------------------------------------------
60
  /**
61
   * Returns the line of a property declaration in the source code of a class.
62
   *
63
   * @param string[] $lines The source code of the class.
64
   * @param string   $name  The name of the property.
65
   *
66
   * @return int
67
   */
68
  public static function propertyDeclarationLine(array $lines, string $name): int
69
  {
70
    $pattern = sprintf('/^.*@property(-read)? (.+) (%s) (.*)$/',
71
                       preg_quote($name));
72
    $line    = self::searchPattern($lines, $pattern);
73
74
    if ($line===null)
75
    {
76
      throw new RuntimeException('Unable to find property %s', $name);
77
    }
78
79
    return $line;
80
  }
81
82
  //--------------------------------------------------------------------------------------------------------------------
83
  /**
84
   * Returns the first line matching a regular expression.
85
   *
86
   * @param array  $lines   The source code of the class.
87
   * @param string $pattern The regular expression.
88
   *
89
   * @return int|null
90
   */
91
  private static function searchPattern(array $lines, string $pattern): ?int
92
  {
93
    foreach ($lines as $key => $line)
94
    {
95
      if (preg_match($pattern, $line)==1)
96
      {
97
        return $key;
98
      }
99
    }
100
101
    return null;
102
  }
103
104
  //--------------------------------------------------------------------------------------------------------------------
105
}
106
107
//----------------------------------------------------------------------------------------------------------------------
108