rectorphp / rector-book-feedback

[BOOK] Repository for feedback from readers of Rector book, to improve it continuously
https://leanpub.com/rector-the-power-of-automated-refactoring
15 stars 2 forks source link

Question: Rector can create new files? #42

Closed gauravmak closed 3 years ago

gauravmak commented 3 years ago

Page no 150 shares a couple of interesting Rector use cases:

Screenshot-from-2021-07-06-16-06-48

I would like to confirm - Are new files/classes created when x conditions are met?

PS - Thanks for writing this. Remarkable work.

Especially the last two chapters are very inspiring. I am sure the future of PHP is bright with this tool.

TomasVotruba commented 3 years ago

Hi, thanks for feedback and a great question!

Yes, it's possible to create new classes even now.


To create a new file you need to do 3 steps:


The simplest Rector rule would look like this:

public function enterNode(...)
{
    // ...

    // 1. build a node
    $classBuilder = new ClassBuilder('SomeClass');
    $classBuilder->addStmt(new Node\Stmt\ClassMethod('someMethod'));
    $class = $classBuilder->getNode();

    // 2. class printed to string
    $printedClassContent = $this->betterStandardPrinter->print($class);

    // 3. add a new file to collector - important for dry-run feature; if you're lazy, use simple `fule_put_contents()`
    $addedFileWithContent = new AddedFileWithContent($targetFilePath, $printedClassContent);
    $this->removedAndAddedFilesCollector->addAddedFile($addedFileWithContent);
gauravmak commented 3 years ago

And this opens a lot of possibilities, thanks.

I am too excited to ask - How about making changes in other files?

TomasVotruba commented 3 years ago

How about making changes in other files?

Well, Rector can changes those files you give as an argument:

vendor/bin/rector process src

So anything in src/* is processed.

Of course you can change some other unrelated file, e.g. app/config.xml in a file_get_contents() dirty way. But there is also a clean Rector file processor contract - https://github.com/rectorphp/rector/blob/main/docs/beyond_php_file_processors.md

Rector already supports composer.json modification, basic class rename in NEON/YAML/TWIG/LATTE etc.


Maybe the question is: what do you want to change in automated way and why? :)

gauravmak commented 3 years ago

Sorry I was not clear enough.

I meant to ask - can we modify any PHP file other than the one being traversed from a Rector class?

The use case - make some related changes that span across multiple files.

Turns out, creating a rule set does the job. I didn't think of it before asking this question.

Also, your latest blog article shares an extra tip about replacing a line with multiple lines.

Thanks.

TomasVotruba commented 3 years ago

I see. It might be too many new concepts to learn at once. AST thinkings is completely inversed compared to traditional "only the code we see can be changed". I recommend to read book slowly and give a time to your brain make new connections. It took me personally 6 months just to understand php-parser and make first modification above it.

I think you're on the right way to make most out of it :slightly_smiling_face: :muscle:

Turns out, creating a rule set does the job. I didn't think of it before asking this question

Exactly, well done :+1:

Good luck with your ruleset!

gauravmak commented 3 years ago

Luckily I do have little experience playing with AST.

Created a VSCode extension called Laravel Traveller where I used this JS based PHP Parser to add links in the routes file.

That project was only about reading the AST. Rector opens a lot of new possibilities by providing easy ways of modifying the AST. Appreciate your work.

TomasVotruba commented 3 years ago

Wow, then you have a huge head start :)

I look forward to your custom rules. If you have an open-source repository in the future, please share it here. Good luck and have fun

lulco commented 3 years ago

I can't find the rule “CreateFactoryForComponent” in Rector nette. I would like to inspire and create rule “CreateOrUpdateFormData” based on https://doc.nette.org/en/3.1/form-presenter Mapping to classes.

TomasVotruba commented 3 years ago

@lulco There is no such rule, but everything you need is here - https://github.com/rectorphp/the-power-of-automated-refactoring-feedback/issues/42#issuecomment-875178619