-
Notifications
You must be signed in to change notification settings - Fork 672
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
[TypeProvider] Provide argument types during FunctionParamsProviderEvent #7394
[TypeProvider] Provide argument types during FunctionParamsProviderEvent #7394
Conversation
Can you check why https://psalm.dev/r/ab6674485b is detected? If you fixed a bug that was making args not being analyzed in existing functions, InvalidArgument should not be here. We must be missing something EDIT: I'm flagging this as draft to better see PR that are ready |
I found these snippets: https://psalm.dev/r/ab6674485b<?php
function test(int $i){}
test(new stdClass);
|
I'll investigate that case deeper somewhere next week. |
If it is, then it's running better the second time because it doesn't have false positive, so if we find the difference, we may find our solution |
@orklah : What I found for now is that the given code runs on the 4.X branch:
So in this case, the Not providing any So to summarize in short: The ArgumentsAnalyzer is currently never being triggered before the I'm feeling a bit too noob in this codebase to make the right decisions at this point. Any help is appreciated :) |
Ok, so there's two things that troubles me and both can be solved in one go:
I think both of these issues could be solved by moving this condition: psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallAnalyzer.php Line 525 in b9d8dd9
to here: psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallAnalyzer.php Line 189 in b9d8dd9 That way, the plugin will be always called and it should have arguments analyzed. Can you try that? |
Thinking about it a little bit more, I think we have a circular issue here... Analyzing the args require knowing the params, so it's hard to know the args types when retrieving the params. What this means is:
Just by curiosity, what was your goal in having args in order to provide params? |
The goal of the plugin is to finetune variadic params. $stages = pipe(
fn (string $x): int => 2,
fn (string $y): float => 1.2,
fn (float $z): int => 23
);
$res = $stages('hello'); It passes 'hello' to function 1 and then pipes the results to the other function, resulting in 23. It would be handy to have the analyzed types there, because it makes it easier to follow the arguments of the provided closures and to calculate the parameters of the stages closures and the return type. I am also planning to write a plugin for a
In this case we need to know from the If you would want to do something similar right now, you have to parse all possible expressions yourselves - which surely cannot be the intention for plugins to do so. |
80abcd9
to
be13717
Compare
be13717
to
6b789bb
Compare
@orklah Found something that works! So what changed:
@klimick : This change now results in the pipe plugin to be able to collect type information like this: /**
* @param array<array-key, Arg> $args
* @return StagesOrEmpty
*/
private static function parseStages(StatementsSource $source, array $args): array
{
$stages = [];
foreach ($args as $arg) {
$stage = $arg->value;
$nodeTypeProvider = $source->getNodeTypeProvider();
$stageType = $nodeTypeProvider->getType($stage)?->getSingleAtomic();
if (!$stageType instanceof TClosure) {
$stages[] = [Type::getMixed(), Type::getMixed(), 'input'];
continue;
}
$params = $stageType->params;
$firstParam = reset($params);
$paramName = $firstParam->name ?? 'input';
$in = self::determineValidatedStageInputParam($source, $stage, $stageType);
$out = $stageType->return_type ?? Type::getMixed();
$stages[] = [$in, $out, $paramName];
}
return $stages;
} |
Seems legit! Thanks! |
Wooooooooooooooooh ! |
Discussed in #7212
When adding following code in both a
FunctionParamsProviderInterface
andFunctionReturnTypeProviderInterface
event handler.getFunctionParams
hook always returnsnull
on this call.getFunctionReturnType
hook always returns the detected type on this call. Something likeimpure-Closure(string):int
This PR mostly rearranges some code so that the
ArgumentsAnalyzer
runs before theFunctionParamsProviderInterface
hook is called.