nette / php-generator

🐘 Generates neat PHP code for you. Supports new PHP 8.3 features.
https://doc.nette.org/php-generator
Other
2.11k stars 138 forks source link

PhpNamespace::unresolveName() does not preserve intentional leading backslash #21

Closed mrtnzlml closed 8 years ago

mrtnzlml commented 8 years ago

Due to this commit (https://github.com/nette/php-generator/commit/6e1b2935dae0b505aa56d1c31b725f0f69e42d83) it's not possible to generate namespace with leading backslash. I know it was intended, but unfortunately it can be BC break. For example Kdyby\AOP generates class namespaces with leading backslash, but classes are in custom block namespace and if the leading \ is removed, it generates nonsense:

namespace Kdyby\Aop_CG\Container_1ad39c5e84 {

use Kdyby\Aop\Pointcut\Matcher\Criteria;
use Symfony\Component\PropertyAccess\PropertyAccess;

final class Model_PagesClass_85_Model_Pages extends Model\Pages
{
    // ...                                          ^- should be \Model\Pages

It would be great to preserve leading \ (example why). Should I prepare PR or it's completely wrong approach and should it be fixed in Kdyby?

Suggested behavior (PhpNamespace.phpt:13):

$namespace = new PhpNamespace;

Assert::same('\A', $namespace->unresolveName('\A')); //preserve leading backslash
Assert::same('A', $namespace->unresolveName('A'));
Assert::same('foo\A', $namespace->unresolveName('foo\A'));
dg commented 8 years ago

What about to preserve class names when no namespace is passed to class constructor?

mrtnzlml commented 8 years ago

It would be satisfactory i guess. Namespace doesn't change anyway in this particular case. In other words it means return name immediately if there is no namespace (passed through constructor), right? If so, I'll prepare PR.

dg commented 8 years ago

I already have PR :)

mrtnzlml commented 8 years ago

It's much more better than my naive implementation. Thank you.

iberflow commented 7 years ago

@mrtnzlml @dg due to this change I am unable to extend a class with another class on a separate namespace. the only workaround is to use the full namespace after the extends keyword (which sucks :/).

I'm on v2.6 since I need php 5.6 support.

Example:

namespace App\Http\Controllers\Users;

use App\Http\Controllers\Controller;

class UserController extends \Controller
{
}
dg commented 7 years ago

Why not?

$namespace = new PhpNamespace('Foo');
$class = $namespace->addClass('A');
$class->addExtend('B');
echo $namespace;

generates

namespace Foo;

class A extends \B
{
}

or

$namespace = new PhpNamespace('Foo');
$namespace->addUse('B');
$class = $namespace->addClass('A');
$class->addExtend('B');
echo $namespace;

generates

namespace Foo;        

use B;                

class A extends B     
{                     
}