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

Phpstan Level 3 #566

Merged
merged 84 commits into from
Nov 3, 2019
Merged

Phpstan Level 3 #566

merged 84 commits into from
Nov 3, 2019

Conversation

shmax
Copy link
Contributor

@shmax shmax commented Oct 27, 2019

PHPStan Level 3!

This is already a really tight, beautifully put together code base, so there wasn't that much to do, but there were a few points of interest:

  • I wrote PHPStan extensions to direct inferred type for some static methods, namely isInputType, isOutputType, and isCompositeType
  • It turns out I was able to bring in native PHP type hinting in a lot of places, so a few of the tests wound up in the position of needlessly validating stuff that would get caught by PHP's natural checking, so I removed them

private $type;

/** @var bool */
private $defaultValueExists = false;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I removed this because you can do the same logic by checking the config bucket, but there was and still is a potential bug, here--defaultValue is public with no setter, so if no default value is passed at construction time but is set after the fact, then defaultValueExists will still return false.

Copy link
Member

Choose a reason for hiding this comment

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

Technically GQL types are supposed to be immutable once created. Unfortunately, PHP doesn't provide any means for read-only properties. Doing getters for every single data point is tedious; __isset and __get are readability and static checking nightmares (although definitely useful for backward compatibility)

I prefer assuming that people are sane enough not to shoot themselves in the foot. But when they want to - nothing will stop them. We even have a dedicated tool for this called Reflection %)

Copy link
Contributor Author

@shmax shmax Nov 2, 2019

Choose a reason for hiding this comment

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

I don't intend to fight this battle in this PR, but there are ways to have read-only properties. For example:

class FieldArgument {
   private $_defaultValue;

   public function __get($name) {
       switch($name) {
          case 'defaultValue`:
             return $_defaultValue;
       } 
   }
}

There are, of course, drawbacks to this kind of thing (eg. no intellisense), and I'm not seriously recommending it at this point.

/**
* @see it('rejects an empty Object field type')
*/
public function testRejectsAnEmptyObjectFieldType() : void
Copy link
Contributor Author

Choose a reason for hiding this comment

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

No longer needed! PHP itself will throw an error if type is not provided and not Type.

*/
public function testRejectsANonTypeValueAsAnObjectFieldType()
{
$schema = $this->schemaWithObjectFieldOfType($this->Number);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

No longer necessary. PHP will throw.

*/
public function testRejectsAnEmptyInterfaceFieldType() : void
{
$schema = $this->schemaWithInterfaceFieldOfType(null);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not needed.

'arg1' => ['name' => 'arg1'],
'arg1' => [
'name' => 'arg1',
'type' => Type::string()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This missing type property was caught by PHP's natural checking.

@mfn
Copy link
Contributor

mfn commented Oct 27, 2019

Multiline array shape syntax

🤔 wow, #TIL

When I look through the PR, 99% (just a feeling) of what I saw regarding the type changes (ecept the multiline array) looks great.

Any reason this would need to be part of this "waiting" PR?

Looks to me the majority of the changes (i.e. "no brainer changes") could be made independently already, no?

@shmax
Copy link
Contributor Author

shmax commented Oct 27, 2019

Looks to me the majority of the changes (i.e. "no brainer changes") could be made independently already, no?

That's a good point. I'll see if I can separate that stuff out tomorrow morning...

@mfn
Copy link
Contributor

mfn commented Oct 27, 2019

Multiline array shape syntax

Btw, its there a "standard" for this? Does any IDE out there support this? Quickly tried PhpStorm, doesn't seem so.

Neither the referenced PR nor the issue seem to reference the origin of this format.

Thanks

@shmax
Copy link
Contributor Author

shmax commented Oct 27, 2019

Btw, its there a "standard" for this? Does any IDE out there support this? Quickly tried PhpStorm, doesn't seem so.

I don't know. The original PR that brought it into phpstan/phpdoc-parser didn't mention anything; best I could find is this issue, which mentions a similar feature in psalm's docblocks.

Digging further, I found this, which describes the feature as a "special format for arrays". The PHPDoc proposed PSR-5 standard doesn't have this feature.

Phan also has something similar, though I didn't bother digging down to find its source (interestingly, phan seems to credit the idea to phpdoc).

I guess we'll have to consider this sort of a graphql/phan/psalm-only feature.

@simPod
Copy link
Collaborator

simPod commented Oct 27, 2019

I think it was first introduced in psalm https://psalm.dev/docs/annotating_code/type_syntax/array_types/#object-like-arrays.

PHPStorm is kinda slow in implementing this, I think I even created ticket for them. But eg. ticket for generic collection support is there in top voted tickets for ages already.

@mfn
Copy link
Contributor

mfn commented Oct 27, 2019

PHPStorm is kinda slow in implementing this

Interesting. When PSR-12 was about to be ratified, I couldn't change my shirt faster than they started implementing it.

Guess having something "official" can boost this.

Sorry for OT and @shmax thanks for digging deeper, obviously I did a bad job at researching 👍

@shmax
Copy link
Contributor Author

shmax commented Oct 27, 2019

Removed the array shape stuff for now. Will open a new PR if this gets merged.

@simPod simPod self-requested a review October 27, 2019 18:03
Copy link
Collaborator

@simPod simPod left a comment

Choose a reason for hiding this comment

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

gj!

src/Executor/ReferenceExecutor.php Outdated Show resolved Hide resolved
src/Experimental/Executor/Collector.php Outdated Show resolved Hide resolved
src/Experimental/Executor/CoroutineExecutor.php Outdated Show resolved Hide resolved
src/GraphQL.php Outdated Show resolved Hide resolved
src/Language/DirectiveLocation.php Outdated Show resolved Hide resolved
src/Utils/BreakingChangesFinder.php Outdated Show resolved Hide resolved
src/Utils/TypeInfo.php Outdated Show resolved Hide resolved
src/Validator/Rules/FieldsOnCorrectType.php Outdated Show resolved Hide resolved
src/Validator/Rules/UniqueInputFieldNames.php Outdated Show resolved Hide resolved
src/Validator/Rules/UniqueInputFieldNames.php Outdated Show resolved Hide resolved
@shmax
Copy link
Contributor Author

shmax commented Oct 27, 2019

@simPod thanks very much for the thorough review! I think I addressed all your comments. Ready for the next round...

@shmax shmax requested a review from simPod October 27, 2019 19:51
@shmax
Copy link
Contributor Author

shmax commented Oct 28, 2019

Sorry for all the extra commits in this PR--I had to keep fighting with it to make Scrutinizer happy. By the way, are you guys still all-in on Scrutinizer? Trying to keep its black-box code analyzer happy (its got plenty of its own bugs) is a serious pain. We could probably configure it to use PHPStan instead of its own checker; I'm willing to investigate the idea if anyone is interested...

docs/type-system/scalar-types.md Outdated Show resolved Hide resolved
examples/01-blog/Blog/Type/Scalar/UrlType.php Outdated Show resolved Hide resolved
phpstan.neon.dist Outdated Show resolved Hide resolved
src/Language/Token.php Outdated Show resolved Hide resolved
src/Language/Token.php Show resolved Hide resolved
src/Utils/TypeInfo.php Show resolved Hide resolved
src/Utils/TypeInfo.php Outdated Show resolved Hide resolved
src/Utils/TypeInfo.php Outdated Show resolved Hide resolved
tests/Type/ValidationTest.php Outdated Show resolved Hide resolved
src/Type/Schema.php Outdated Show resolved Hide resolved
src/Type/Definition/NonNull.php Outdated Show resolved Hide resolved
src/Type/Definition/NonNull.php Show resolved Hide resolved
src/Utils/AST.php Show resolved Hide resolved
@shmax
Copy link
Contributor Author

shmax commented Nov 1, 2019

I've addressed all open comments (thanks, @simPod !). At this point all tests and checkers pass (even Scrutinizer). There is still a lot to do, but I think we're at a good stopping point here, and I will resume in PHPStan lvl 4.

Would love some more reviewers! @vladar @spawnia @mfn

@shmax shmax requested a review from simPod November 1, 2019 16:35
Copy link
Collaborator

@simPod simPod left a comment

Choose a reason for hiding this comment

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

LGTM!

@simPod
Copy link
Collaborator

simPod commented Nov 1, 2019

If @vladar thinks it's good to go, I'd squash commits before merge.

@shmax
Copy link
Contributor Author

shmax commented Nov 1, 2019

If @vladar thinks it's good to go, I'd squash commits before merge.

Sure, happy to squash, but doesn't Github have the Squash and Merge button?

Copy link
Member

@vladar vladar left a comment

Choose a reason for hiding this comment

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

That is trully a great job! I've left a bunch of comments but we'll definitely merge this as soon as remaining questions are resolved.

src/Executor/ReferenceExecutor.php Outdated Show resolved Hide resolved
src/Experimental/Executor/Collector.php Show resolved Hide resolved
src/Experimental/Executor/CoroutineExecutor.php Outdated Show resolved Hide resolved
src/Language/AST/DocumentNode.php Show resolved Hide resolved
src/Utils/TypeInfo.php Outdated Show resolved Hide resolved
src/Validator/Rules/FieldsOnCorrectType.php Outdated Show resolved Hide resolved
tests/Executor/DeferredFieldsTest.php Outdated Show resolved Hide resolved
tests/Type/DefinitionTest.php Show resolved Hide resolved
tests/Type/DefinitionTest.php Show resolved Hide resolved
@vladar vladar merged commit baad32b into webonyx:master Nov 3, 2019
@vladar
Copy link
Member

vladar commented Nov 3, 2019

Merged! Thanks for this exceptionally useful PR!

@shmax
Copy link
Contributor Author

shmax commented Nov 3, 2019

Woot! Thanks for merging, and thanks all for reviewing!

@shmax shmax deleted the stan-level-3 branch November 3, 2019 09:22
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.

4 participants