Skip to content

Implement AddConstructorParentCallRector#3430

Merged
samsonasik merged 4 commits intorectorphp:mainfrom
jackbentley:add-constructor-rule
Mar 9, 2023
Merged

Implement AddConstructorParentCallRector#3430
samsonasik merged 4 commits intorectorphp:mainfrom
jackbentley:add-constructor-rule

Conversation

@jackbentley
Copy link
Copy Markdown
Contributor

@jackbentley jackbentley commented Feb 28, 2023

This will automatically add parent::__construct() calls with the correct params when the parent call is missing.

This is mostly to fix up the mess that rectorphp/rector#7814 is causing in my code base but thought it might be useful none the less. Note that this does not fix the issue as it requires a re-run of rector after the files have been altered.

It's based on the similar AddMethodParentCallRector but doesn't need to be configured and considers the params.

@samsonasik
Copy link
Copy Markdown
Member

samsonasik commented Feb 28, 2023

Adding parent:__construct() or not is depends on the use case, so the correct way is to configure it instead of automatically add it as the override part can actually not call parent:__construct() on purpose.

The following code is valid:

class A
{
    public function __construct($a, $b)
    {
        echo 'first';
    }
}

class B extends A
{
    public function __construct()
    {
        echo 'two';
    }
}

ref https://3v4l.org/v1Bvk

@jackbentley
Copy link
Copy Markdown
Contributor Author

You're not wrong, it's valid code yes. However in conjunction with dependency injection I'd probably consider it a code smell myself.

As I say, I'm using it to fix a bug in another rector which makes my code break and thought it might be useful to others.

@jackbentley
Copy link
Copy Markdown
Contributor Author

It's worth noting PHPStan with strict rules reports this as an error:
https://phpstan.org/r/e1284f36-508b-4c79-b275-9e80293b0550

@samsonasik
Copy link
Copy Markdown
Member

That doesn't mean incorrect, inject or not is always depends, there are many uses in term of containerize object; autowire, initializers, etc, they are there on purpose

@jackbentley
Copy link
Copy Markdown
Contributor Author

I'm not saying it's incorrect to do so?

@samsonasik
Copy link
Copy Markdown
Member

What I meant is the parent::__construct($arg) is special, the usage can't be judged by automation

@jackbentley
Copy link
Copy Markdown
Contributor Author

PHPStan with strict rules disagrees with you

@samsonasik
Copy link
Copy Markdown
Member

That's doesn't mean it need to be added, as I said, it always depends on the use case, there are always use case that not call parent is on purpose :)

@jackbentley
Copy link
Copy Markdown
Contributor Author

In which case the claim of "getting to the latest PHPStan level" should probably be removed from this page https://getrector.com/about

As it's its own rule and is not implemented in any rule sets or otherwise enabled by default, I don't understand why this wouldn't be at place being in Rector.

@samsonasik
Copy link
Copy Markdown
Member

As far as that can't potentially make BC break that cause another reported issue regarding it, and we, as maintainer, need to take care :).

This rule can make more harm than usefull to be honest, yet, you can create your own on your dev for it.

@jackbentley
Copy link
Copy Markdown
Contributor Author

Not sure how a rule which no one has to implement is going to cause BC breaks they're not aware of when they do implement it. Is this the mindset of all maintainers or just yours?

@jackbentley
Copy link
Copy Markdown
Contributor Author

We should probably remove all of these rules as they may cause BC breaks https://github.com/rectorphp/rector/blob/main/docs/rector_rules_overview.md#strict

@samsonasik
Copy link
Copy Markdown
Member

samsonasik commented Mar 1, 2023

The strict rules mostly about operator changing, which equal the functionality, and configurable to be less strict :)

Changing to add parent::__construct() and its function __construct() param automatically is different, it need to verify:

  • how object next be created by service or manually
  • what functionality actually happened

that's cannot be applied on file basis, but also on dependencies and config, etc.

@jackbentley
Copy link
Copy Markdown
Contributor Author

configurable to be less strict

Unless I've completely mis-understood how to configure them, the examples for the following all give the same output for the example given regardless of how it's configure. Which would lead me to suggest the configuration is likely pointless and a false-economy:

If you like, I can also add a pointless configuration option so it can "be less strict"?

  • how object next be created by service or manually
  • what functionality actually happened

ContainerGetToConstructorInjectionRector doesn't care about this

Perhaps we should remove that rule also?

I can also move it to the Rector\Strict\Rector if that makes it better?

@samsonasik
Copy link
Copy Markdown
Member

I see that you reported issue on rector-symfony already for GetToConstructorInjectionRector:

I think that's should be discussed or fixed there instead of create new rule to cover it.

@jackbentley
Copy link
Copy Markdown
Contributor Author

I did and it would be great if that were to get fixed. It's beyond my knowledge and clearly requires good knowledge of Rector to fix though.

However, this rule (to me) is clearly able to be something in it's own right given that without it manual fixes would be required in order to meet the requirements for PHPStan strict rules:
https://phpstan.org/r/e1284f36-508b-4c79-b275-9e80293b0550

@samsonasik
Copy link
Copy Markdown
Member

Ok, deal, move to Strict category will be better than 👍

@jackbentley
Copy link
Copy Markdown
Contributor Author

Done 👍

@samsonasik
Copy link
Copy Markdown
Member

I am not sure about rector workflow error: https://github.com/rectorphp/rector-src/actions/runs/4305120316/jobs/7507111232#step:2:12

Could you rebase? The skip run on fork should work

# Don't run on forks.
if: github.repository == 'rectorphp/rector-src'

@samsonasik
Copy link
Copy Markdown
Member

Oh, I see, looking on older commit before, the repo name check seems still needed

if: github.event.pull_request.head.repo.full_name == github.repository

@samsonasik
Copy link
Copy Markdown
Member

Please rebase to make CI green

@jackbentley jackbentley force-pushed the add-constructor-rule branch from b50b567 to 8b5c52b Compare March 2, 2023 09:07
@jackbentley
Copy link
Copy Markdown
Contributor Author

Rebased and all green 👍 Thanks for sorting that

@samsonasik
Copy link
Copy Markdown
Member

Please rebase again to see if CI keep green

@jackbentley jackbentley force-pushed the add-constructor-rule branch from 8b5c52b to 01b350c Compare March 2, 2023 18:34
@jackbentley
Copy link
Copy Markdown
Contributor Author

Rebased. Looks to be green still and Rector job is skipped. Not sure why the expected checks are showing still. Might be worth trying with another PR to see if it's just this one messing up?

@samsonasik
Copy link
Copy Markdown
Member

samsonasik commented Mar 2, 2023

Not sure, could you try create new PR to update workflow config that possibly can solve that to see if it skip on forks? Thank you.

@TomasVotruba
Copy link
Copy Markdown
Member

I think this is actually expected :) Rector should run only on our code, as it would force contributors to re-run Rector, which is an obstacle for contributing. Devs should not be forced to put any Rector manuall work to their code.

Rector should only run, when allowed to contribute and handle 100 % work for us and the contributors.

This works as expected 👍

@samsonasik
Copy link
Copy Markdown
Member

@TomasVotruba no, the pending parts make me cannot merge the PR now

@jackbentley
Copy link
Copy Markdown
Contributor Author

jackbentley commented Mar 2, 2023

I don't think you'll see the "3 expected checks" going forwards on new PRs. It will just skip the Rector workflow and green tick the PR instead of the pending/running state this one is in. I've seen it before and I think it was resolved by pushing a new commit after the rebase - I'm not sure though but it went away. You can skip the "pending" checks and merge if you have enough privileges.

@jackbentley
Copy link
Copy Markdown
Contributor Author

If I'm wrong it might be branch protection rules and required checks

@samsonasik
Copy link
Copy Markdown
Member

I don't know, it shows : "Required statuses must pass before merging", that make no longer able to merge PR from forks

Screenshot_20230303-023139_Firefox

@TomasVotruba
Copy link
Copy Markdown
Member

TomasVotruba commented Mar 2, 2023

@samsonasik I've removed the requirement from the branch protection, as it doesn't make sense to require these if we don't want contributors to mantain Rector changes.

Good to go now 👍


class SunshineCommand extends ParentClassWithConstructor
{
public function __construct()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add new fixture to skip if it has parameter already? Because the usage of parameter in child can be different

public function __construct(DifferentParamType $param)

see https://3v4l.org/MTsnC

Copy link
Copy Markdown
Contributor Author

@jackbentley jackbentley Mar 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it should skip as PHPStan still errors as there's no call to parent still (https://phpstan.org/r/34e37898-4200-4259-856f-bca40810f3f8).

However, I've added a new fixture for the case of params of same name but different type.

Looks like there was a bug where it would add the new param as expected but it would be invalid PHP code because the names would be the same. You'd end up with two params with the same name and different types. I've fixed it so it adds an increment on the new param name. This bug would affect GetToConstructorInjectionRector also I think.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to just skip that as I think the usage may vary, __construct() usage is very fragile on this case IMO, but I will let @TomasVotruba decide on this

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samsonasik I think we can merge it as it is and iterate from there. Different parameter type is a different check of PHPStsan.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TomasVotruba Ok then 👍

@jackbentley jackbentley force-pushed the add-constructor-rule branch from 02f6d59 to c146f37 Compare March 3, 2023 21:02
@samsonasik
Copy link
Copy Markdown
Member

Thank you @jackbentley

@samsonasik samsonasik merged commit f87827c into rectorphp:main Mar 9, 2023
samsonasik pushed a commit that referenced this pull request May 8, 2023
* Implement AddConstructorParentCallRector

* Move to Strict namespace

* Fix bug when params have same name but different type

* Fix tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants