Giter Site home page Giter Site logo

nette / php-generator Goto Github PK

View Code? Open in Web Editor NEW
2.0K 62.0 133.0 928 KB

๐Ÿ˜ Generates neat PHP code for you. Supports new PHP 8.3 features.

Home Page: https://doc.nette.org/php-generator

License: Other

PHP 100.00%
nette nette-framework php-generator php code-generator

php-generator's Introduction

Nette Framework is a popular tool for PHP web development. It is designed to be as usable and as friendly as possible. It focuses on security and performance and is definitely one of the safest PHP frameworks.

Nette Framework speaks your language and helps you to easily build better websites.

The Quick Start tutorial gives you a first introduction to the framework by creating a simple database driven application.

Over 10 Yrs of Development

We have been developing Nette for over 10 years- and counting! Libraries we provide are therefore highly mature, stable and widely used. They are trusted by a number of global corporations and many significant websites rely on us.

Catching Bronze

We aim to create Nette as a fun and easy to use framework, that programmers can fall in love with. And we seem to be doing it well! We were rated as the 3rd most popular framework in a survey Best PHP Framework for 2015 by a well-know magazine SitePoint.

Security Is a Priority

There is nothing we care about more than security. That is why we had built Nette as the safest PHP framework. It had passed many audits with flying colours, it eliminates safety traps like XSS, CSRF and brings out ground-breaking methods.

Libraries & Framework

Nette consists of a number of handy standalone libraries, which can be used in any codebase, for example combined with WordPress or another framework. Careful, some of them are highly addictive! These are the components that Nette Framework is built on:

  • Application โ€“ The kernel of web application
  • Bootstrap โ€“ Bootstrap of your application
  • Caching โ€“ Cache layer with set of storages
  • Component Model โ€“ Foundation for component systems
  • DI โ€“ Dependency Injection Container
  • Finder โ€“ Find files and directories with an intuitive API
  • Database โ€“ Database layer
  • Forms โ€“ Greatly facilitates secure web forms
  • Http โ€“ Layer for the HTTP request & response
  • Latte โ€“ Amazing template engine
  • Mail โ€“ Sending E-mails
  • Neon โ€“ Loads and dumps NEON format
  • Php Generator โ€“ PHP code generator
  • Robot Loader โ€“ The most comfortable autoloading
  • Routing โ€“ Routing
  • Safe Stream โ€“ Safe atomic operations with files
  • Security โ€“ Provides access control system
  • Schema โ€“ User data validation
  • Tester โ€“ Enjoyable unit testing in PHP
  • Tracy โ€“ Debugging tool you will love โ™ฅ
  • Tokenizer โ€“ Source code tokenizer
  • Utils โ€“ Utilities and Core Classes

php-generator's People

Contributors

19bischof avatar adaamz avatar coffelius avatar dg avatar djaf77 avatar fprochazka avatar frosty22 avatar gromnan avatar iggyvolz avatar jakubkulhan avatar jantvrdik avatar jeroeny avatar jonsa avatar juniwalk avatar juzna avatar kukulich avatar majkl578 avatar pavelkouril avatar pierredup avatar pionl avatar sanderdlm avatar sisklu avatar uestla avatar xpavp03 avatar yoosefap avatar zeleznypa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

php-generator's Issues

Add possibility to use constants in attributes

Hi,
Is it possible to add support for constants in attributes arguments?

So generated code may look like this:

#[Argument('name', type: ArgumentTypes::REQUIRED)]

Currently it is possible to do something like [code below] or just use const value:

$class->setAttribute(
    'Argument', 
    [
        'name',
        'type' => 'ArgumentTypes::REQUIRED'
    ]
);

in the result a constant will be wrapped in the quotes and treated as a string

#[Argument('name', type: 'ArgumentTypes::REQUIRED')]

I believe this feature will be highly demanded as more and more libs and frameworks are adding support for PHP 8 attributes. And they already use constants.

no facility for adding "leafs"

  • bug report? no
  • feature request? yes
  • version: 3.1.0

Description

Specifically, Class created from reflection can't be added to PhpFile. Generally, you should be able to add leafs beyond mere string creations.

Steps To Reproduce

I.E FPhpFile->add(new ClassType), ClassType->add(new Method)

@see SimpleXML

Parsing a Class doesn't includes method body.

Version: 3.3.4

Bug Description

Using an existing class won't register method bodies at all.

Steps To Reproduce

Create one class with a method body, and then parse it manually.

<?php

namespace App\Providers;

use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
    ];

    /**
     * Register any events for your application.
     *
     * @return void
     */
    public function boot()
    {
        parent::boot();

        //
    }
}
use App\Providers\EventServiceProvider;

$class = \Nette\PhpGenerator\ClassType::from(EventServiceProvider::class);

echo $class->getMethod('boot')->getBody(); // ''

Expected Behavior

use App\Providers\EventServiceProvider;

$class = \Nette\PhpGenerator\ClassType::from(EventServiceProvider::class);

echo $class->getMethod('boot')->getBody(); //  'parent::boot();\n\n//'

Possible Solution

Add this method to retrieve the body inside the \PhpGenerator\Factory::fromMethodReflection:

protected function getMethodBody(\ReflectionMethod $from) : string
{
    $lines = file($from->getFileName());
    $string = '';

    for ($start = $from->getStartLine()+1, $end = $from->getEndLine()-1; $start < $end; $start++) {
        $string .= $lines[$start];
    }

    return $string;
}

From there, the only thing would be to "unpad" each line.

Force the rendering of `use`

Hi @nette team,

I am building an ORM (LightQL) for my framework and now I'm creating a CLI tool used to generate PHP entities from a database schema. I'm able to generate the PHP file perfectly through your package but I'm facing a little problem: I'm unable to force the rendering of use.

These use have to be rendered for the entities to work well since even if they are not used in PHP code or even if the class to use believe in the same namespace than the generated one, they are used by annotations in comments and resolved by the LightQL backend (for one-to-one or one-to-many associations for example). Because this goal cannot be achieved now (or maybe I have missed some configurations), generated entities looks very fine but cannot be used without be edited manually...

So I think it could be fine if we have a configuration value used to define if the we want to force the rendering of use (or other objects) or not.

Thanks a lot for this awesome work! ๐Ÿ˜

Namespace not recognizing boolean and integer as keywords

Version: 3.3.4

Bug Description

When generating a namespace the PhpNamespace contains a constant of primitive types to be considered as "keywords" and thus not to be imported. The boolean keyword is missing from the list (bool is present instead), same goes for integer. The problem with this is, that if you are using reflections to determine type hints the returned names would be the full-length names, e.g. integer and not int, which in turn would generate stuff like getTheValue(): \boolean;.

How to use ->setType('OtherClass') within the same namespace

Version: 3.4.0

Bug Description

The class then with a backslash reports that the class was not found if you have the same namespace.

Steps To Reproduce

Generates this:
public \OtherClass $class

Expected Behavior

But in the same namespace I need this:
public OtherClass $class;

printParameters is not taking into account the rest of the method to determine line length for wrapping

Version: 3.5.2

Bug Description

The method printParameters in the Printer class checks if the length of the arguments is greater than (new Dumper)->wrapLength. But this only checks if the list of parameters exceeds the 120 character limit but ignores the string length of the rest of the method head like the visibility, method name, function keyword and the return type

Steps To Reproduce

Example code:

$file = new PhpFile();
$namespace = $file->addNamespace('Foo');
$class = $namespace->addClass('Bar');
$method = $class->addMethod('baz')
                ->setPublic()
                ->setReturnType('string');
$method->addParameter('lorem')
       ->setType('string');
$method->addParameter('ipsum')
       ->setType('string');
$method->addParameter('dolor')
       ->setType('string');
$method->addParameter('sit')
       ->setType('string');
$method->addParameter('amet')
       ->setType('string');
$method->addParameter('foo')
       ->setType('string');
$method->addParameter('bar')
       ->setType('string');

echo (new PsrPrinter())->printFile($file);

Will print the following:

<?php

namespace Foo;

class Bar
{
    public function baz(string $lorem, string $ipsum, string $dolor, string $sit, string $amet, string $foo, string $bar): string
    {
    }
}

The function baz now has a line length of 130 characters which is too long for PSR2 and PSR12

Expected Behavior

I expect, that the rest of the method head is also taken into account when checking the line length so the following output would be generated which is PSR2 and PSR12 valid:

<?php

namespace Foo;

class Bar
{
    public function baz(
        string $lorem,
        string $ipsum,
        string $dolor,
        string $sit,
        string $amet,
        string $foo,
        string $bar
    ): string {
    }
}

Load a class from a file template

Hello
Thank you for this lib and its well designed api.

Is it possible to load a class from a file?

This could avoid loading a class in the current namespace to use reflection.
It could make php tools based on this library possible. Like refactoring tool.
The usecase here is to manipulate files wherever they are, independently from the current execution context.

Something like Factory::fromClassFile

Thanks

Loading from code should not use FQCN

Version: 3.6.4

Bug Description

When loading from the code (PhpFile::fromCode($content)), everything is resolved to its FQCN because of the NameResolver visitor.
It is then very difficult to merge new generated code with the loaded one, since the first one is not using FQCN.

Expected Behavior

Loading from code should not use FQCN for its nodes.

Possible Solution

Either do not use NameResolver when loading, or use the originalName attribute of the node instead.

Dumping an array variable does not use the Printer's overridden indentation

php version: 7.3.0
nette/php-generator version: 3.2.1

Bug Description

When adding a constant to a class as below

$map = [
    'foo' => 'bar',
    'example' => 'value',
];

$class
    ->addConstant('MAP', $map)
    ->setVisibility(ClassType::VISIBILITY_PROTECTED);

it results in:

    protected const MAP = [
	'foo' => 'bar',
	'example' => 'value',
    ];

When printing with Nette\PhpGenerator\PsrPrinter.

Expected Behavior

The constant printed with PsrPrinter's 4 spaces indentation instead of tabs.

Possible Solution

The tab is hardcoded at https://github.com/nette/php-generator/blob/master/src/PhpGenerator/Helpers.php#L74. Could we change it so that we can pass the indentation to the helper?

Proposal: Adding previously created objects to existing ones

Hey there,
I currently use this awesome library to regenerate existing classes with some modifications.
For this reason I'm often forced to to something like this:

$target = ClassType::from($targetClass);

$methods = $target->getMethods();
$newMethods = [];

foreach ($methods as $method) {
    # do some work
    $newMethods[] = $someNewMethod;
}

$target->setMethods(array_merge($methods, $newMethods));

It would be really nice if it would be possible to directly add existing Method or Property instances to an ClassType instance, instead of using this workaround. Currently it's only possible to create new methods or properties through their respective add...() methods as far as I know.
I imagine something like this:

$target = ClassType::from($targetClass);

foreach ($target->getMethods() as $method) {
    # do some work
    $target->addExistingMethod($someNewMethod);
}

Even worse is the process of adding ClassType objects to a PhpFile. For that purpose I had to write a helper method looking like this:

public static function addClassFromTemplate(PhpNamespace &$target, ClassType $tpl): ClassType
{
    return $target->addClass($tpl->getName())
                ->setType($tpl->getType())
                ->setFinal($tpl->isFinal())
                ->setAbstract($tpl->isAbstract())
                ->setExtends($tpl->getExtends())
                ->setImplements($tpl->getImplements())
                ->setTraits($tpl->getTraits())
                ->setConstants($tpl->getConstants())
                ->setProperties($tpl->getProperties())
                ->setMethods($tpl->getMethods())
                ->setComment($tpl->getComment());
}

In this case, it would be even more helpful to add the class with a one-liner.
Let me know what you think about my proposal.

Greetings, MCStreetguy

Update project description.

Hi, the description of the repository still says:

๐Ÿ˜ Generates neat PHP code for you. Supports new PHP 7.3 features. https://nette.org

But PHP 7.4 is already supported.

Just a minor tweak, nothing important!

Your sincerely,
Mike van Diepen

"Uses" and "Extend"

  • bug report? yes
  • feature request? no
  • version: 2.6

Description

When you specify "uses", the class is not inherited correctly from the specified class, if they are partially matched and there is a difference in the registers.

Steps To Reproduce

$namespace = new PhpNamespace('app\models');
$namespace->addUse('Yii');
$class = $namespace->addClass('Demo');
$class->addExtend('yii\db\ActiveRecord');
echo "<?php\n\n".$namespace;
<?php

namespace app\models;

use Yii;

class Demo extends Yii\db\ActiveRecord // <= Wrong namespace, expected yii\db\ActiveRecord
{
}

Attributes are not loaded correctly

Version: 3.6.4

Bug Description

When loading from the code (PhpFile::fromCode($content)), attribute arguments are not loaded as expected: arguments are "duplicated".
For instance, with this attribute:

#[AnAttribute(foo: 'bar')]

The loaded arguments will be:

$args = ['foo' => new Literal("foo: 'bar'")];

Expected Behavior

The loaded arguments should be:

$args = ['foo' => new Literal("'bar'")];

Possible Solution

The issue comes from the call to getReformattedContents which gets everything inside the attribute as raw. It shouldn't be the case when loading content.

AddConstant does not validate name.

  • bug report? yes
  • feature request?no
  • version: v2.5.x-dev

Description

Constant names are not validated resulting in invalid PHP files.

Steps To Reproduce

$file = new \Nette\PhpGenerator\PhpFile();
$object = $file->addClass('Tester');
$object->addConstant('test-invalid-name', "value");

3.3.0 contains BC Break

Version: 3.3.0

Bug Description

When updating version 3.2.3 -> 3.3.0, nette/di vendor throws an err:

Fatal error: Uncaught Nette\MemberAccessException: Call to undefined static method Nette\PhpGenerator\Helpers::createObject(). in /Users/paveljanda/www/gamee/apps/admin/vendor/nette/utils/src/Utils/ObjectHelpers.php:78

Nette DIC is creating instances using following call:

Nette\PhpGenerator\Helpers::createObject

Steps To Reproduce

Upgrade nette/php-generator 3.2.3 -> 3.3.0 and try to build a DIC possibly using phpstan command.
PHPstan version: 0.11.19
(Nette\PhpGenerator\Helpers::createObject)

Expected Behavior

No BC Breaks when updating minor version

Possible Solution

Maybe releasing a 4.0.0 with BC breaks or leaving the minor release without BC Breaks

Versions diff: v3.2.3...v3.3.0

Missing possibility to add variadic parameter to a method

Simple example:

$method = $class->addMethod('count')
                ->addParameter('entities')
                ->setType('object ...');

Would result in the following:

function count(object ... $entities)
{
}

The space between the variadic operator ... and the variable name $entities is not allowed by PSR12 standard.
A method like setVariadic(bool $state = true): self; on the Nette\PhpGenerator\Parameter could help with that.

Passing Array to addUse method

I have been looking for this type of library which helps me lot to generate the code

I am Working with laravel so i have created the base example model for post

$namespace = new Nette\PhpGenerator\PhpNamespace('App\Models');

$namespace->addUse('Illuminate\Database\Eloquent\Model');
$namespace->addUse('Illuminate\Database\Eloquent\SoftDeletes');

And the generated Code is here

namespace App\Models;
--
ย  ย 
ย   use Illuminate\Database\Eloquent\Model;
ย   use Illuminate\Database\Eloquent\SoftDeletes;
ย   ย 
ย   /**
ย   * Class Post
ย   *
ย   * @package App\Models
ย   */
ย   class Post extends Model
ย   {
ย   use SoftDeletes;

And its working fine but i was planning to add multiple addUse statment so the code becomed bigger so IT WILL BE FINE IF THE addUse method accepts the array

$namespace->addUse(
[
'Illuminate\Database\Eloquent\SoftDeletes',
'Illuminate\Database\Eloquent\Model',
]
);

Printer handles null value of Property as no value incorrectly

Version: 3.4.1

Bug Description

When printing class, there is this line:

($property->getValue() === null && !$property->isInitialized() ? '' : ' = ' . $this->dump($property->getValue(), strlen($def) + 3)) // 3 = ' = '

which basically means that if I set value of Property to null intentionally, this value is not printed.

Steps To Reproduce

E.g. $property->setPrivate()->setValue(null) generates private $property;
But $property->setPrivate()->setValue('test') generates private $property = 'test'; properly

Expected Behavior

It should generate private $property = null;

Possible Solution

Mark null state with some constant instead of null. So it would look something like this:

class Property
{
    public const NO_DEFAULT_VALUE = '$73aad02e-7f5a-4ef2-8cdd-0fd09e6d9863ยง'; // hopefully no one is going to pass this string as default value

    // ...
}

// in printer:
($property->getValue() === Property::NO_DEFAULT_VALUE && !$property->isInitialized() ? '' : ' = ' . $this->dump($property->getValue(), strlen($def) + 3)) // 3 = ' = '

Define PHP version manually

It would be nice to have option to define PHP version support manually as production environment might be different from development and certain syntax might not be supported.

Incorrect method property mixed type generated from reflection

Version: 3.5.1

Bug Description

class SomeClass {
  public function something(mixed $param) {}
}

// ClassType::withBodiesFrom(SomeClass::class) generates:

class SomeClass {
  public function something(?mixed $param) {}
}

which is incorrect as null is implicitly contained in mixed.

image

ClassType::from() resolves too much interfaces

Version: v3.1.2

Bug Description

When "copying" a class through the static factory method ClassType::from(...), it appears that all parent interfaces are applied, not only the ones directly set on the class.

Steps To Reproduce

  1. Create some class that implements interfaces
class Query implements \ArrayAccess, \Countable, \Iterator
{
    # ...
}
  1. Then create a ClassType instance through:
    $class = ClassType::from('MyClass');
  2. Convert it to a string and take a closer look on the result:
class Query implements \ArrayAccess, \Countable, \Iterator, \Traversable
{
    # ...
}

Expected Behavior

The instance of ClassType should be exactly the same as the original one.
Instead, it implements the parental interface Traversable which then leads to an E_COMPILE_ERROR, due to the interface beeing implemented twice:

Class Melior\Database\Query\Query cannot implement previously implemented interface Traversable

Possible Solution

I don't got any handy solution on this, but it seems as ReflectionClass doesn't care about whether something has been defined directly in the class or has been inherited from parents.
So gathering the interfaces from the ReflectionClass results in all interfaces and their parents, not just the ones directly named behind implements.

Wrong wrapping condition in array formater

Version: 3.2.*

Bug Description

Wrapping condition ignore the length of the property name and needed characters $ = []
https://github.com/nette/php-generator/blob/master/src/PhpGenerator/Helpers.php#L97

Steps To Reproduce

Actual generator produce code:

    /** @var int[] */
    public $terminalsValues = ['true' => 3, 'false' => 4, 'null' => 5, '{' => 6, '}' => 7, ',' => 8, ':' => 9, '[' => 10, ']' => 11];

Expected Behavior

Generate code:

    /** @var int[] */
    public $terminalsValues = [
        'true' => 3, 
        'false' => 4, 
        'null' => 5, 
        '{' => 6, 
        '}' => 7, 
        ',' => 8, 
        ':' => 9, 
        '[' => 10, 
        ']' => 11
    ];

Possible Solution

Add possibility to modify Helper::WRAP_LENGTH by custom length that will be filled here by str_len($property->getName()) + 6

Method's and function's bodies are copied without name resolve

Version: 3.4.0

Bug Description

Class generated using Reflection have fully-qualified names, because Reflection return all names as FQN. But method's and function's bodies are copied without fully-qualified name.
Nikic's NodeVisitor\NameResolver resolve name, but not change node's position in file, which used for copying body.

Steps To Reproduce

We have class for reflection:

namespace Abc;

abstract class MyClass
{
	function method(AnotherClass $object): string
	{
		return AnotherClass::class;
	}
}

after Nette\PhpGenerator\ClassType::withBodiesFrom(MyClass::class); we'll get:

abstract class Class7
{
	function method(\Abc\AnotherClass $object): string
	{
		return AnotherClass::class;
	}
}

Expected Behavior

We must get FQN in method's and global function's body too.

abstract class Class7
{
	function method(\Abc\AnotherClass $object): string
	{
		return \Abc\AnotherClass::class;
	}
}

Possible Solution

There are two way for problem solving:

  1. We can use Nikic's PhpParser\PrettyPrinter for print traversed expression nodes from body. But prettyPrint() will changed original formatting, and printFormatPreserving() can work with whole file only... :(
  2. Collect all Name Nodes from importing method/function, and replace them in extracted body's string by position. I used this way in my fork and I'll create PR little later

Invalid typehints for nullable properties with union type

Version: 3.5.1

Bug Description

For now for nullable properties this library generates typehint with ?, but this conflicts with PHP8 Union Types.
Generated typehint for union types now looks like ?OneType|OtherType, which is not valid PHP syntax.
Could you fix this for PHP8 please?

Possible Solution

Check PHP version and if it's larger than 8.0 - replace ? for |nullin typehint.

Nette\PhpGenerator\Parameter havent option/method to detect is Method parameter variadic

Version: 3.3.3

Bug Description

I tried to copy class using reflection then make some changes with method parameters, calling it through different method. So i join params using php native implode() function and failed, because i had some params variadic with ...$param definition in method signature.

I tried to check, but there's no method, will use php reflection method for that at now

Dump double quoted strings

  • Is there a way to dump double quoted strings?

I want to do something like:

return "Something ${value}";

// so php can interpret the variable 'value' and return its value, not the string 'Something ${value}'

Feature Request: Files that return directly

I'm looking to be able to build files that return directly.

<?php
return [
    'mysql' => [
        'host'      =>  'localhost',
        'database' =>  'database',
        'username' =>  'username',
        'password' =>  'password',
    ]
];

This is a common way to configure things in various frameworks.

You can use a simple config getting function like so:

    function config($Label)
    {
        $Config = static::$ApplicationPath . '/config/' . $Label . '.php';
        if (!file_exists($Config)) {
            throw new \Exception($Config . ' not found in '.static::class.'::config()');
        }
        return require $Config;
    }

Helpers::createObject() creates public property

Hi. Take this code:

class SomeObject
{
    private $someProperty;

    function __construct($someProperty)
    {
        $this->someProperty = $someProperty;
    }
}

var_dump(\Nette\PhpGenerator\Helpers::createObject('SomeObject', ['someProperty' => 'test']));

Expected result:

object(SomeObject)[2]
  private 'someProperty' => string 'test' (length=4)

Actual result:

object(SomeObject)[2]
  private 'someProperty' => null
  public 'someProperty' => string 'test' (length=4)

Its on master. I've found this bug when I wanted create service in DI extension and used:

$builder->addDefinition($this->prefix('someService'))
    ->setClass('SomeService', ['someProperty' => $value]);

Packagist distributes an outdated version

Took me some time to figures this out, but looks like packagist is distributing a old version of the code (at least older than 9d3d8d4). Step to reproduce:

mkdir bug && cd bug
rm -rf ~/.composer/cache
composer require nette/php-generator
# gives a few lines and notably   - Installing nette/php-generator (v2.3.4) Downloading: 100%
cat vendor/nette/php-generator/src/PhpGenerator/ClassType.php | grep addComment
# nothing... the addComment is not part of ClassType, which is indeed not the case in v2.3.4

I wonder if it is related to .gitattributes being so aggressive (well first time I see it used for excluding tests, but maybe it is a long shot).

A fast fix is to download the source or force a specific revision, in which case it is all right, we have the latest version.

Functions in namespace

Currently it is only possible to add ClassTypes to namespaces. I would also like to add functions.

Force root namespace

Hi
I crate class with namespace and i want to extend from that namespace but not imposible
Because it create backslash before extend class:
image

Automatically import (`use`) classes to namespace

I'm using this library to generate a lot of PHP classes.

For every returnType, propertyType, argumentType I have to remember to call $namespace->addUse().

It would be really nice if these types could be automatically imported.

For example like this:

$file = new PhpFile();

$ns = $file->addNamespace('My\\App', $autoImport = true);

$class = $ns->addClass('MyClass');

$constructor = $class->addMethod('__construct');

$constructor->addParameter('data')
    ->setType('\My\\App\\Entity\\User');

Would such a change be accepted? Or is there a better way to deal with this?

Extended interfaces are marked as implemented in ClassType::from

Version: 3.5.4 (also reproduced on master)

Bug Description

When performing a ClassType::from on an interface which extends another interface, the relation is marked as an implements relationship rather than an extends relationship.

Steps To Reproduce

<?php
require_once __DIR__ . "/vendor/autoload.php";
interface a{}
interface b extends a{}
echo \Nette\PhpGenerator\ClassType::from(b::class);

Gives:

interface b implements a
{
}

Expected Behavior

interface b extends a
{
}

Possible Solution

The check here

$class->setImplements(array_diff($class->getImplements(), $from->getParentClass()->getInterfaceNames()));
may need to split based on whether the class is an interface or not - from my understanding interfaces can only extend other interfaces.

Add use statements to import global functions is not backwards compatible anymore

Since Version: 3.6.2

The Nette\PhpGenerator\PhpNamespace::addUse method can only handle namespaces.

So the following code snippet is not working anymore while it was working in version <= 3.6.1:

<?php

use Nette\PhpGenerator\ClassType;
use Nette\PhpGenerator\PhpNamespace;

require 'vendor/autoload.php';

$class = new ClassType('MyClass', new PhpNamespace('MyNamespace\MySubNamespace'));
$class->getNamespace()->addUse('function strtoupper');

How to remove traits from class parsed from reflection?

This is damn awesome work with this library, you saved my life.

Not sure i would need it, but really - there's no deleteTrait() method inside ClassType, currently i made some static facades for my services, and not sure, what if i add some traits to my services - will it be inside created class.

Anyway, THANK YOU.

--------------^ Click "Preview" for a nicer view!
We primarily use GitHub as an issue tracker; for usage and support questions, please check out these resources below. Thanks! ๐Ÿ˜.

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

Due to this commit (6e1b293) 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'));

Feature request: Make spacing between class properties configurable

I've noticed that v3.4.0 contains the following change: Printer: one-line properties without comments are not separated using one empty line.

In our codebase we have a code standard where we do have an empty line between properties, regardless of there being a comment or not. Now of course I understand that everyone has their own standards.

So maybe it could be nice if this value is configurable, just like linesBetweenMethods. So we can override it in our Printer.

I hope this is something that can be considered. If it is, I'd be happy to contribute a PR.

Feature Request: add PhpNamespace to PhpFile

Description

PhpNamespace classes can't be added to a PhpFile class.

Example

<?php declare(strict_types=1); 

use Nette\PhpGenerator\ClassType;
use Nette\PhpGenerator\PhpFile;
use Nette\PhpGenerator\PhpNamespace;

$phpFile= new PhpFile();
$namespace = new PhpNamespace('FooBar');
$class = new ClassType('Foo');

$method = $class->addMethod('baz');
$method->setReturnType('FooBar\\Bar');
$method->setBody('return new Bar();');

$namespace->add($class);
$namespace->add(new ClassType('Bar'));

$phpFile->add($namespace);

echo $phpFile;

Expected result:

<?php

namespace FooBar;

class Foo
{
    public function baz(): Bar
    {
        return new Bar();
    }
}

class Bar
{
}

Make space between closing method parentheses and colon configurable

Our coding standards enforces a space after the closing method parentheses and the proceeding colon.
It would super advantageous if this space could be configurable and honored in the printReturnType method.

Currently we have to manually go to all generated files and apply the spacing. As you can imagine this is very monotonous. I'm sure many others could also benefit from this.

I would super happy to contribute a PR if this is taken into consideration.

Loading a class and continue editing that class.

First of all, great package, amazing really!
I'm trying to use it to build my models, and that works great already.

Creating things like:

public function properties()
	{
		return [
			(new Text)->name('Naam')
				->alias('name')
				->required()
				->placement('left'),
		];
	}

This "new Text" is a type that I choose using a form.
A second time I want to edit this model with that form, I could want to remove a type for instance.
That's fine and possible if I generate the whole class again.

The problem is that I want it to be open for modification.
So if I add a method to it. Let's say:

public function properties()
	{
		return [
			(new Text)->name('Naam')
				->alias('name')
				->required()
				->placement('left'),
		];
	}

public function test()
{
    return 'test';
}

That method is not in the form where I edit the model.
So if I generate it again I can't know if there are methods that need to be preserved.

My feature request therefor is that there is an option to load a full class with everything.
This way I can just edit a method instead of regenerating everything.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.