Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: add Factories::models() to suppress PHPStan error #5358

Merged
merged 1 commit into from
Jan 8, 2022

Conversation

kenjis
Copy link
Member

@kenjis kenjis commented Nov 19, 2021

Description
Follow-up: #5186

  • add Factories::models() to suppress PHPStan error

Checklist:

  • Securely signed commits
  • [] Component(s) with PHPDoc blocks, only if necessary or adds value
  • [] Unit testing, with >80% coverage
  • [] User guide updated
  • Conforms to style guide

@kenjis kenjis requested a review from MGatner November 19, 2021 23:57
@kenjis kenjis added the refactor Pull requests that refactor code label Nov 19, 2021
Copy link
Member

@MGatner MGatner left a comment

Choose a reason for hiding this comment

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

I still think this would be better handled by a stub file. I don't see the explicit method causing a problem right now but it will make maintenance harder.

I think this same docblock could be placed in a stub and work fine even though the method doesn't actually exist (not 100% sure on that but I believe so).

@kenjis
Copy link
Member Author

kenjis commented Nov 21, 2021

utils/PHPStan/stubs/Factories.stub:

<?php

namespace CodeIgniter\Config;

use CodeIgniter\Database\ConnectionInterface;
use CodeIgniter\Model;
use Config\Services;

class Factories
{
    /**
     * @template T of Model
     *
     * @param class-string<T> $name
     *
     * @return T
     */
    public static function models(string $name, array $options = [], ?ConnectionInterface &$conn = null);
}
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -61,3 +61,5 @@ parameters:
        - CI_DEBUG
        - ENVIRONMENT
        - SODIUM_LIBRARY_VERSION
+   stubFiles:
+       - utils/PHPStan/stubs/Factories.stub

But errors ocurres. Why invalid return type CodeIgniter\Model?

 ------ --------------------------------------------------------------------------------------------------------------- 
  Line   utils/PHPStan/stubs/Factories.stub                                                                             
 ------ --------------------------------------------------------------------------------------------------------------- 
  18     Method CodeIgniter\Config\Factories::models() has invalid return type CodeIgniter\Model.                       
  18     Method CodeIgniter\Config\Factories::models() has parameter $options with no value type specified in iterable  
         type array.                                                                                                    
  18     PHPDoc tag @template T for method CodeIgniter\Config\Factories::models() has invalid bound type                
         CodeIgniter\Model.                                                                                             
  18     Parameter $conn of method CodeIgniter\Config\Factories::models() has invalid type                              
         CodeIgniter\Database\ConnectionInterface.                                                                      
  18     Parameter $name of method CodeIgniter\Config\Factories::models() has invalid type CodeIgniter\Model.           
 ------ --------------------------------------------------------------------------------------------------------------- 

@MGatner
Copy link
Member

MGatner commented Nov 21, 2021

I will have to look on desktop.

@sfadschm
Copy link
Contributor

Any progress on this? The PHPStan errors are really annoying for both packages and projects...

@sfadschm
Copy link
Contributor

But errors ocurres. Why invalid return type CodeIgniter\Model?

It seems that if any type is used in a stub file, there needs to be a stub file for this type, too.
Do we maybe need to add a stub for CodeIgniter\Model?

See the bottom notice here:
https://phpstan.org/user-guide/stub-files
Possibly an empty shell will be enough.

@kenjis kenjis mentioned this pull request Dec 1, 2021
5 tasks
@kenjis
Copy link
Member Author

kenjis commented Dec 1, 2021

@sfadschm Thank you. But unfortunately it still does not work: #5418

@sfadschm
Copy link
Contributor

sfadschm commented Jan 5, 2022

Is there anyone a littlle more familiar with PHPStan? (Not me unfortunately...)

I really think this should be handled somehow. In the worst case, my personal opinion would be that improving auto-complete for a single IDE (phpstorm, #5186) does not really justify having to suppress phpstan errors all across projects/packages (as these now occur in projects wherever methods of models derived from the model class are called.

@kenjis
Copy link
Member Author

kenjis commented Jan 5, 2022

improving auto-complete for a single IDE (phpstorm, #5186) does not really justify having to suppress phpstan errors all across projects/packages

It is not so. PhpStorm does not need the @phpstan-return Model:
https://github.com/codeigniter4/CodeIgniter4/pull/5186/files#diff-99c83f6a1ccaee1c1ebabad8faa8dac62c69ecee1bab9ec323ea127c6a2263d0R785

But removing it causes PHPStan error.

I recommend to merge this PR. I don't know why everybody loves magic method.

@MGatner
Copy link
Member

MGatner commented Jan 5, 2022

My ideal would still be to handle this with stub files but it seems like we lack the expertise currently to pull it off. I'm okay with proceeding since this is not a likely candidate for changes in the near future.

@sfadschm
Copy link
Contributor

sfadschm commented Jan 5, 2022

How about merging for now and then create a new help wanted issue to replace this workaround with stubs or whatever else is the best practice here?
Just to keep track.

@MGatner
Copy link
Member

MGatner commented Jan 5, 2022

I wonder if adding @internal to this would cause issues with people calling it?

@MGatner
Copy link
Member

MGatner commented Jan 5, 2022

Actually, can't we just fix this with a @method tag? https://docs.phpdoc.org/3.0/guide/references/phpdoc/tags/method.html#method

Nevermind, that is what used to be there 🤦‍♂️ They don't support generics.

@paulbalandan
Copy link
Member

I have tried this with stub files before, way before @kenjis tried in his other PR, and it doesn't work. A better solution would be I think is a PHPStan rule for this, but merging this for now is our best compromise.

@kenjis
Copy link
Member Author

kenjis commented Jan 5, 2022

A better solution would be I think is a PHPStan rule for this

I don't like to make special rules/stubs for CI4. Essentially it should not be needed.
Basically, I think if we write good OOP code, PHPStan could understand.

Apart from my own preferences, this PR is a small hack and easily can be reverted anytime.
I think merging this for now is our best choice.

@MGatner
Copy link
Member

MGatner commented Jan 6, 2022

Does anyone have the capacity to see what impact it would have on PHPStan and PHPStorm if we added @internal to this new method?

@sfadschm
Copy link
Contributor

sfadschm commented Jan 6, 2022

Does anyone have the capacity to see what impact it would have on PHPStan and PHPStorm if we added @internal to this new method?

I don't have phpstorm, but it should not be affected, as the fix for the autocompletion was the other changes that led to the PHPStan errors (that are fixed with this PR). I can try if it affects PHPStan when I'm home.

@sfadschm
Copy link
Contributor

sfadschm commented Jan 6, 2022

Passes locally with @internal.

@kenjis
Copy link
Member Author

kenjis commented Jan 7, 2022

@sfadschm Thank you for confirmation.

@MGatner I also checked. It seems @internal only strikes the models method in PhpStorm:
Screenshot 2022-01-07 9 46 51

Do you really want to add @internal?

@MGatner
Copy link
Member

MGatner commented Jan 7, 2022

I guess not - those strikes will get us questions and issues. Maybe just add a note on the method stating something like "This method is supplied only to assist with static analysis and should not be relied on as a non-magic method."

@sfadschm
Copy link
Contributor

sfadschm commented Jan 7, 2022

I guess not - those strikes will get us questions and issues. Maybe just add a note on the method stating something like "This method is supplied only to assist with static analysis and should not be relied on as a non-magic method."

And that it is not covered by the BC promise, probably.

@kenjis
Copy link
Member Author

kenjis commented Jan 7, 2022

@MGatner I added a commen already.
https://github.com/codeigniter4/CodeIgniter4/pull/5358/files#diff-2642753b4779273c429a26af7d57ca99f2235e5c52748a05dabcbe5cd2970b6aR71

should not be relied on as a non-magic method

What do you mean? I don't understand what users should not do.

@sfadschm
Copy link
Contributor

sfadschm commented Jan 7, 2022

Basically people should not use this method in their apps/modules/whatever, as it is intended for internal SA use only.

@kenjis
Copy link
Member Author

kenjis commented Jan 7, 2022

@sfadschm What's SA ?

It is not real @internal.
Users can use Factories. It is documented:
https://codeigniter4.github.io/CodeIgniter4/concepts/factories.html

@sfadschm
Copy link
Contributor

sfadschm commented Jan 7, 2022

@sfadschm What's SA ?

It is not real @internal. Users can use Factories. It is documented: https://codeigniter4.github.io/CodeIgniter4/concepts/factories.html

Sorry, SA is static analysis.
Yes, Factories can be used, but with Factories::models being public, people could use it directly or overwrite/extend it in their apps, which they should not, as the method can be deleted anytime. I think this is what MGatner had in mind. But lets wait for him 😄

@MGatner
Copy link
Member

MGatner commented Jan 8, 2022

Yes, sorry to be unclear! I want this method to be considered "internal", but we can't flag it like that because IDEs will complain even though the "magic version" is acceptable.

Basically, it is fine for people to do this:

Factories::model('Foo');

But I don't want people's code to rely on this being there, so none of this:

if (method_exists(Factories::class, 'model')) {
    echo 'Modeling!';
}

@kenjis i forgot you already had a note on there, I think what you said is fine. Let's merge, unless there are more thoughts?

@kenjis kenjis merged commit 7016083 into codeigniter4:develop Jan 8, 2022
@kenjis kenjis deleted the fix-model-phpstan-error branch January 8, 2022 13:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
refactor Pull requests that refactor code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants