Skip to content

Commit

Permalink
Add AfterFunctionCallAnalysisEvent and AfterMethodCallAnalysisEvent s…
Browse files Browse the repository at this point in the history
…upport for Args::getCallArgs
  • Loading branch information
klimick committed Sep 11, 2022
1 parent be711e6 commit f76505b
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 15 deletions.
34 changes: 19 additions & 15 deletions src/Toolkit/Args.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@
namespace Fp\PsalmToolkit\Toolkit;

use Fp\Collections\ArrayList;
use Fp\Collections\NonEmptyArrayList;
use PhpParser\Node;
use Fp\Functional\Option\Option;
use Psalm\CodeLocation;
use Psalm\NodeTypeProvider;
use Psalm\Plugin\EventHandler\Event\AfterExpressionAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\AfterFunctionCallAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\AfterStatementAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\AfterMethodCallAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\Event\MethodReturnTypeProviderEvent;
use Psalm\StatementsSource;
use Psalm\Type\Union;

use function Fp\Evidence\proveOf;

final class Args
Expand All @@ -29,38 +30,41 @@ public function getArgType(
NodeTypeProvider |
AfterStatementAnalysisEvent |
AfterMethodCallAnalysisEvent |
AfterFunctionCallAnalysisEvent |
MethodReturnTypeProviderEvent |
FunctionReturnTypeProviderEvent |
AfterExpressionAnalysisEvent $from,
Node\Arg | Node\VariadicPlaceholder $for,
): Option
{
): Option {
return proveOf($for, Node\Arg::class)
->flatMap(fn(Node\Arg $arg) => PsalmApi::$types->getType($from, $arg->value));
}

/**
* @return Option<ArrayList<CallArg>>
*/
public function getCallArgs(MethodReturnTypeProviderEvent | FunctionReturnTypeProviderEvent $from): Option
{
public function getCallArgs(
MethodReturnTypeProviderEvent |
FunctionReturnTypeProviderEvent |
AfterFunctionCallAnalysisEvent |
AfterMethodCallAnalysisEvent $from,
): Option {
$source = match (true) {
$from instanceof MethodReturnTypeProviderEvent => $from->getSource(),
$from instanceof FunctionReturnTypeProviderEvent => $from->getStatementsSource(),
$from instanceof AfterFunctionCallAnalysisEvent => $from->getStatementsSource(),
$from instanceof AfterMethodCallAnalysisEvent => $from->getStatementsSource(),
};

$args = match (true) {
$from instanceof AfterFunctionCallAnalysisEvent => $from->getExpr()->getArgs(),
$from instanceof AfterMethodCallAnalysisEvent => $from->getExpr()->getArgs(),
default => $from->getCallArgs(),
};

return ArrayList::collect($from->getCallArgs())
return ArrayList::collect($args)
->traverseOption(fn($arg) => $this->getArgType($from, $arg)->map(
fn(Union $type) => new CallArg($arg, new CodeLocation($source, $arg), $type)
));
}

/**
* @return Option<NonEmptyArrayList<CallArg>>
*/
public function getNonEmptyCallArgs(MethodReturnTypeProviderEvent | FunctionReturnTypeProviderEvent $from): Option
{
return $this->getCallArgs($from)
->flatMap(fn($args) => $args->toNonEmptyArrayList());
}
}
3 changes: 3 additions & 0 deletions src/Toolkit/Types.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Psalm\Internal\Type\TypeExpander;
use Psalm\NodeTypeProvider;
use Psalm\Plugin\EventHandler\Event\AfterExpressionAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\AfterFunctionCallAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\AfterMethodCallAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\Event\MethodReturnTypeProviderEvent;
Expand Down Expand Up @@ -140,6 +141,7 @@ public function getType(
StatementsSource |
NodeTypeProvider |
AfterMethodCallAnalysisEvent |
AfterFunctionCallAnalysisEvent |
MethodReturnTypeProviderEvent |
AfterStatementAnalysisEvent |
FunctionReturnTypeProviderEvent |
Expand All @@ -155,6 +157,7 @@ public function getType(
$from instanceof FunctionReturnTypeProviderEvent => $from->getStatementsSource()->getNodeTypeProvider(),
$from instanceof AfterExpressionAnalysisEvent => $from->getStatementsSource()->getNodeTypeProvider(),
$from instanceof AfterMethodCallAnalysisEvent => $from->getStatementsSource()->getNodeTypeProvider(),
$from instanceof AfterFunctionCallAnalysisEvent => $from->getStatementsSource()->getNodeTypeProvider(),
};

return Option::fromNullable($provider->getType($for));
Expand Down

0 comments on commit f76505b

Please sign in to comment.