• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nette / php-generator / 16782402262

06 Aug 2025 04:13PM UTC coverage: 93.058%. Remained the same
16782402262

push

github

dg
Visibility, PropertyHookType & PropertyAccessMode are enums (BC break)

1783 of 1916 relevant lines covered (93.06%)

0.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.96
/src/PhpGenerator/Helpers.php
1
<?php
2

3
/**
4
 * This file is part of the Nette Framework (https://nette.org)
5
 * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6
 */
7

8
declare(strict_types=1);
9

10
namespace Nette\PhpGenerator;
11

12
use Nette;
13
use function is_string, preg_match, preg_replace, preg_replace_callback, str_contains, str_repeat, str_replace, strrpos, strtolower, substr, trim;
14

15

16
/**
17
 * @internal
18
 */
19
final class Helpers
20
{
21
        use Nette\StaticClass;
22

23
        public const ReIdentifier = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*';
24

25
        public const Keywords = [
26
                // class keywords
27
                'bool' => 1, 'false' => 1, 'float' => 1, 'int' => 1, 'iterable' => 1, 'mixed' => 1, 'never' => 1, 'null' => 1,
28
                'object' => 1, 'parent' => 1, 'self' => 1, 'string' => 1, 'true' => 1, 'void' => 1,
29

30
                // PHP keywords
31
                '__halt_compiler' => 1, 'abstract' => 1, 'and' => 1, 'array' => 1, 'as' => 1, 'break' => 1, 'callable' => 1,
32
                'case' => 1, 'catch' => 1, 'class' => 1, 'clone' => 1, 'const' => 1, 'continue' => 1, 'declare' => 1, 'default' => 1,
33
                'die' => 1, 'do' => 1, 'echo' => 1, 'else' => 1, 'elseif' => 1, 'empty' => 1, 'enddeclare' => 1, 'endfor' => 1,
34
                'endforeach' => 1, 'endif' => 1, 'endswitch' => 1, 'endwhile' => 1, 'eval' => 1, 'exit' => 1, 'extends' => 1,
35
                'final' => 1, 'finally' => 1, 'fn' => 1, 'for' => 1, 'foreach' => 1, 'function' => 1, 'global' => 1, 'goto' => 1,
36
                'if' => 1, 'implements' => 1, 'include' => 1, 'include_once' => 1, 'instanceof' => 1, 'insteadof' => 1,
37
                'interface' => 1, 'isset' => 1, 'list' => 1, 'match' => 1, 'namespace' => 1, 'new' => 1, 'or' => 1, 'print' => 1,
38
                'private' => 1, 'protected' => 1, 'public' => 1, 'readonly' => 1, 'require' => 1, 'require_once' => 1, 'return' => 1,
39
                'static' => 1, 'switch' => 1, 'throw' => 1, 'trait' => 1, 'try' => 1, 'unset' => 1, 'use' => 1, 'var' => 1,
40
                'while' => 1, 'xor' => 1, 'yield' => 1, '__CLASS__' => 1, '__DIR__' => 1, '__FILE__' => 1, '__FUNCTION__' => 1,
41
                '__LINE__' => 1, '__METHOD__' => 1, '__NAMESPACE__' => 1, '__PROPERTY__' => 1, '__TRAIT__' => 1,
42
        ];
43

44
        #[\Deprecated]
45
        public const
46
                PHP_IDENT = self::ReIdentifier,
47
                KEYWORDS = self::Keywords;
48

49

50
        public static function formatDocComment(string $content, bool $forceMultiLine = false): string
1✔
51
        {
52
                $s = trim($content);
1✔
53
                $s = str_replace('*/', '* /', $s);
1✔
54
                if ($s === '') {
1✔
55
                        return '';
1✔
56
                } elseif ($forceMultiLine || str_contains($content, "\n")) {
1✔
57
                        $s = str_replace("\n", "\n * ", "/**\n$s") . "\n */";
1✔
58
                        return Nette\Utils\Strings::normalize($s) . "\n";
1✔
59
                } else {
60
                        return "/** $s */\n";
1✔
61
                }
62
        }
63

64

65
        public static function tagName(string $name, string $of = PhpNamespace::NameNormal): string
1✔
66
        {
67
                return isset(self::Keywords[strtolower($name)])
1✔
68
                        ? $name
1✔
69
                        : "/*($of*/$name";
1✔
70
        }
71

72

73
        public static function simplifyTaggedNames(string $code, ?PhpNamespace $namespace): string
1✔
74
        {
75
                return preg_replace_callback('~/\*\(([ncf])\*/([\w\x7f-\xff\\\]++)~', function ($m) use ($namespace) {
1✔
76
                        [, $of, $name] = $m;
1✔
77
                        return $namespace
1✔
78
                                ? $namespace->simplifyType($name, $of)
1✔
79
                                : $name;
1✔
80
                }, $code);
1✔
81
        }
82

83

84
        public static function unformatDocComment(string $comment): string
1✔
85
        {
86
                return preg_replace('#^\s*\* ?#m', '', trim(trim(trim($comment), '/*')));
1✔
87
        }
88

89

90
        public static function unindent(string $s, int $level = 1): string
1✔
91
        {
92
                return $level
1✔
93
                        ? preg_replace('#^(\t| {4}){1,' . $level . '}#m', '', $s)
1✔
94
                        : $s;
1✔
95
        }
96

97

98
        public static function isIdentifier(mixed $value): bool
1✔
99
        {
100
                return is_string($value) && preg_match('#^' . self::ReIdentifier . '$#D', $value);
1✔
101
        }
102

103

104
        public static function isNamespaceIdentifier(mixed $value, bool $allowLeadingSlash = false): bool
1✔
105
        {
106
                $re = '#^' . ($allowLeadingSlash ? '\\\?' : '') . self::ReIdentifier . '(\\\\' . self::ReIdentifier . ')*$#D';
1✔
107
                return is_string($value) && preg_match($re, $value);
1✔
108
        }
109

110

111
        public static function extractNamespace(string $name): string
1✔
112
        {
113
                return ($pos = strrpos($name, '\\')) ? substr($name, 0, $pos) : '';
1✔
114
        }
115

116

117
        public static function extractShortName(string $name): string
1✔
118
        {
119
                return ($pos = strrpos($name, '\\')) === false
1✔
120
                        ? $name
1✔
121
                        : substr($name, $pos + 1);
1✔
122
        }
123

124

125
        public static function tabsToSpaces(string $s, int $count = 4): string
1✔
126
        {
127
                return str_replace("\t", str_repeat(' ', $count), $s);
1✔
128
        }
129

130

131
        /**
132
         * @param  mixed[]  $props
133
         * @internal
134
         */
135
        public static function createObject(string $class, array $props): object
136
        {
137
                return Dumper::createObject($class, $props);
×
138
        }
139

140

141
        public static function validateType(?string $type, bool &$nullable = false): ?string
1✔
142
        {
143
                if ($type === '' || $type === null) {
1✔
144
                        return null;
1✔
145
                } elseif (!Nette\Utils\Validators::isTypeDeclaration($type)) {
1✔
146
                        throw new Nette\InvalidArgumentException("Value '$type' is not valid type.");
1✔
147
                }
148

149
                if ($type[0] === '?') {
1✔
150
                        $nullable = true;
1✔
151
                        return substr($type, 1);
1✔
152
                }
153

154
                return $type;
1✔
155
        }
156
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc