-
-
Notifications
You must be signed in to change notification settings - Fork 259
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
Add more generic phpdocs #306
Conversation
lib/Promise.php
Outdated
@@ -23,7 +24,7 @@ interface Promise | |||
* Note: You shouldn't implement this interface yourself. Instead, provide a method that returns a promise for the | |||
* operation you're implementing. Objects other than pure placeholders implementing it are a very bad idea. | |||
* | |||
* @param callable(\Throwable|null, TValue|null) $onResolved The first argument shall | |||
* @param callable(\Throwable|null, TValue|null): void $onResolved The first argument shall |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Phpstan wouldn't parse this without :void
(which is in the Psalm stub)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add @template
for the call
function too. It's one of the most frequently used ones so I think it deserves it.
https://github.com/vimeo/psalm/blob/master/src/Psalm/Internal/Stubs/Amp.php#L15-L24
I tried this, but at least with PHPStan it gives an error, and I'm not sure how to add the type information: /**
* @template TValue
*
* @param callable():(\Generator<mixed, mixed, mixed, TValue>|TValue) $gen
*
* @return Promise<TValue>
*/
function call(callable $callback, ...$args): Promise
|
lib/functions.php
Outdated
* | ||
* @return callable(mixed ...$args): \Amp\Promise | ||
* @param callable():\Generator<mixed, mixed, mixed, TValue> $callback |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$callback
is passed to call()
which accepts many different types as return types from the callback, not just Generator.
See https://github.com/amphp/amp/blob/master/lib/functions.php#L65-L77
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated to
* @param callable(mixed ...$args): (\Generator<mixed, mixed, mixed, TValue>|\Amp\Promise<TValue>|mixed) $callback
If that makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to use TValue
instead of the last mixed but I'm guessing that runs into the same issue you mentioned above, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Second mixed of the generator should possibly be Promise<mixed>
. Afaik yielding anything else than a Promise would cause an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, that works. However not sure about the ReactPromise? Should we add that too?
* @param callable(mixed ...$args): (\Generator<mixed, mixed, mixed, TValue>|\Amp\Promise<TValue>|\React\Promise\PromiseInterface<TValue>|TValue) $callback
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess... Personally I'm kinda against using React promises in Amphp code and would always call adapt()
anyway but it works so I guess it's correct to add it here.
By the way. technically the return value of the Generator is Promise<TValue>|ReactPromise<TValue>|TValue
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cool, updated to use local names
I see... yeah that complicates things. Maybe we should report it to PHPStan then. |
Pretty sure we don't.
…On Sat, Mar 28, 2020, 14:05 Niklas Keller ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In lib/Promise.php
<#306 (comment)>:
> @@ -5,6 +5,7 @@
/**
* Representation of the future value of an asynchronous operation.
*
+ * @template TValue
Why do we need both?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#306 (review)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAEDWRRLH4QSTLS7HLH5DSTRJXY2BANCNFSM4LVPZCJA>
.
|
I've added quite a lot of annotations I had locally already, so there are some conflicts now, sorry about that. |
d884c50
to
7585d05
Compare
lib/functions.php
Outdated
@@ -14,8 +14,7 @@ | |||
* | |||
* @template TReturn | |||
* | |||
* @param callable(mixed ...$args):(\Generator<mixed,Promise|ReactPromise|array<array-key, Promise|ReactPromise>,mixed,Promise<TReturn>|ReactPromise|TReturn>|Promise<TReturn>|ReactPromise|TReturn) | |||
* $callback | |||
* @param callable(mixed ...$args):(\Generator<mixed,Promise|ReactPromise|array<array-key, Promise|ReactPromise>,mixed,Promise<TReturn>|ReactPromise|TReturn>|Promise<TReturn>|ReactPromise|TReturn) $callback |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The phpstan docblock parser didn't like $callback
being ona new line for some reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please open an phpstan issue for that? Phpstorm automatically formats it like that for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, it works now it seems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PhpStorm doesn't understand this syntax at all so I'm not surprised it breaks on that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ondrejmirtes: PhpStorm doesn't break, it just reformats too long lines like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kelunik Yeah but it won't be able to understand the method accepts callable
. Maybe in this case yes, because the type starts with callable
, but definitely not in some more complex cases.
Updated most of it seems to be implemented now anyway, although it does fix a parsing issue with Phpstan. The new |
3fa7ede
to
9f73668
Compare
ok - so I think everything is covered by your changes and the original stuff in this PR can be discarded. I've updated the PR to replace |
I wouldn't use these in |
Then, I'll close this. Thanks for implementing the types @kelunik @ondrejmirtes I would create an issue for what seems like a Phpstan bug above , but I'm not quite sure yet how to reproduce, hopefully can do it later. |
I just tried running Psalm with the lastest annotations in master:
gives:
(after adding the psalm-return to
🤔 |
Even with the annotations both Psalm and PHPStan are very unlikely to recognize that |
I havent checked the actual annotations but Generator stubs in PHPStan/Psalm support this in TSend. |
@ondrejmirtes They just support one type per generator, but not a type based on the yielded value. |
@kelunik I don't understand. See this example: https://phpstan.org/r/0eaa8d12-2237-489a-9165-eb243d637329 What do you think wouldn't work in regards to Amp? |
@ondrejmirtes With Amphp the Generators are usually immediately called using the
|
In other words this code: /**
* @return Promise<string>
*/
function getExampleCom(HttpClient $http): Promise {
return Amp\call(function () use ($http) {
$response = yield $http->request("https://example.com/");
$body = yield $response->getBody();
return $body;
});
} would look like this with async-await: async function getExampleCom(HttpClient $http): string {
$response = await $http->request("https://example.com/");
$body = await $response->getBody();
return $body;
} |
The issue seems similar to: phpstan/phpstan-doctrine#101 |
See #305
This allows: