Skip to content

Commit 7ea64b2

Browse files
committed
improve reserved keywords checking
1 parent c16493f commit 7ea64b2

File tree

1 file changed

+34
-7
lines changed

1 file changed

+34
-7
lines changed

src/Mtrgen/Template/Generator.php

+34-7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515

1616
class Generator
1717
{
18+
public const RESERVED_KEYWORDS = ['__halt_compiler', 'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval', 'exit', 'extends', 'final', 'finally', 'fn', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'match', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'readonly', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor', 'yield', 'yield_from'];
19+
public const RESERVED_CONSTANTS = ['__CLASS__', '__DIR__', '__FILE__', '__FUNCTION__', '__LINE__', '__METHOD__', '__NAMESPACE__', '__TRAIT__'];
20+
1821
/**
1922
* Checks if template is bundle
2023
*
@@ -107,7 +110,7 @@ public static function generate(object $body, array $args): PhpFile
107110
*/
108111
private static function class(object $object, array $args, mixed &$parent = null): ClassType
109112
{
110-
$class = !$parent ? new ClassType(Parser::parseString($object->name, $args)) : $parent->addClass(Parser::parseString($object->name, $args));
113+
$class = !$parent ? new ClassType(self::makeNameSafe(Parser::parseString($object->name, $args))) : $parent->addClass(self::makeNameSafe(Parser::parseString($object->name, $args)));
111114

112115
return self::defineObject($object, $args, $class);
113116
}
@@ -120,7 +123,7 @@ private static function class(object $object, array $args, mixed &$parent = null
120123
*/
121124
private static function interface(object $object, array $args, mixed &$parent = null): ClassType
122125
{
123-
$interface = !$parent ? ClassType::interface(Parser::parseString($object->name, $args)) : $parent->addInterface(Parser::parseString($object->name, $args));
126+
$interface = !$parent ? ClassType::interface(self::makeNameSafe(Parser::parseString($object->name, $args))) : $parent->addInterface(self::makeNameSafe(Parser::parseString($object->name, $args)));
124127

125128
return self::defineObject($object, $args, $interface);
126129
}
@@ -133,7 +136,7 @@ private static function interface(object $object, array $args, mixed &$parent =
133136
*/
134137
private static function trait(object $object, array $args, mixed &$parent = null): ClassType
135138
{
136-
$trait = !$parent ? ClassType::trait(Parser::parseString($object->name, $args)) : $parent->addTrait(Parser::parseString($object->name, $args));
139+
$trait = !$parent ? ClassType::trait(self::makeNameSafe(Parser::parseString($object->name, $args))) : $parent->addTrait(self::makeNameSafe(Parser::parseString($object->name, $args)));
137140

138141
return self::defineObject($object, $args, $trait);
139142
}
@@ -163,7 +166,7 @@ private static function defineObject(object $object, array $args, ClassType $cla
163166
}
164167
if (self::is($object->constants)) {
165168
foreach ($object->constants as $const) {
166-
$constant = $class->addConstant(Parser::parseString($const->name, $args), Parser::parseString($const->value, $args));
169+
$constant = $class->addConstant(self::makeNameSafe(Parser::parseString($const->name, $args)), Parser::parseString($const->value, $args));
167170
if (self::is($const->visibility)) $constant->setVisibility($const->visibility);
168171
if (self::is($const->comments)) {
169172
foreach ($const->comments as $comment) {
@@ -195,7 +198,7 @@ private static function defineObject(object $object, array $args, ClassType $cla
195198

196199
private static function namespace(object $object, PhpFile &$file, array $args): PhpNamespace
197200
{
198-
$namespace = $file->addNamespace(Parser::parseString($object->name, $args));
201+
$namespace = $file->addNamespace(self::makeNameSafe(Parser::parseString($object->name, $args)));
199202

200203
if (self::is($object->use)) {
201204
foreach ($object->use as $use) {
@@ -251,7 +254,7 @@ private static function property(object $prop, array $args, ?ClassType $class =
251254

252255
private static function getter(string $name, string $type): Method
253256
{
254-
$getter = new Method('get' . ucfirst($name));
257+
$getter = new Method(self::makeNameSafe('get' . ucfirst($name)));
255258
$getter->addComment("@return $type");
256259

257260
$getter->setReturnType($type);
@@ -262,7 +265,7 @@ private static function getter(string $name, string $type): Method
262265

263266
private static function setter(string $name, string $type): Method
264267
{
265-
$setter = new Method('set' . ucfirst($name));
268+
$setter = new Method(self::makeNameSafe('set' . ucfirst($name)));
266269
$setter->addComment("@param $type \$$name");
267270

268271
$param = $setter->addParameter($name);
@@ -346,4 +349,28 @@ public static function is(mixed &$subject): bool
346349
{
347350
return is_array($subject) ? isset($subject) && count($subject) > 0 : isset($subject);
348351
}
352+
353+
/**
354+
* Check if the given name is a reserved keyword
355+
* @param string $name
356+
* @return bool
357+
*/
358+
public static function isReservedKeyword(string $name): bool
359+
{
360+
return in_array($name, self::RESERVED_KEYWORDS) || in_array($name, self::RESERVED_CONSTANTS);
361+
}
362+
363+
/**
364+
* Make the given name safe by adding an underscore if it is a reserved keyword
365+
* @param string $name
366+
* @return string
367+
*/
368+
public static function makeNameSafe(string $name): string
369+
{
370+
$newName = self::isReservedKeyword($name) ? '_' . $name : $name;
371+
if (self::isReservedKeyword($newName)) {
372+
return self::makeNameSafe($newName);
373+
}
374+
return $newName;
375+
}
349376
}

0 commit comments

Comments
 (0)