Skip to content

Commit

Permalink
Support reflecting node context and function context arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
dantleech committed Feb 7, 2024
1 parent c2e2fa3 commit 9db45c9
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

use Amp\Promise;
use Generator;
use Microsoft\PhpParser\Node;
use Microsoft\PhpParser\Node\SourceFileNode;
use Phpactor\WorseReflection\Bridge\TolerantParser\Reflection\ReflectionNavigation;
use Phpactor\WorseReflection\Core\Diagnostic;
use Phpactor\WorseReflection\Core\Diagnostics;
use Phpactor\WorseReflection\Core\Exception\CouldNotResolveNode;
use Phpactor\WorseReflection\Core\Exception\MethodCallNotFound;
use Phpactor\WorseReflection\Core\Inference\NodeContext;
use Phpactor\WorseReflection\Core\Inference\Walker;
use Phpactor\WorseReflection\Core\Reflection\Collection\ReflectionDeclaredConstantCollection;
use Phpactor\WorseReflection\Core\Reflection\ReflectionNode;
Expand Down Expand Up @@ -125,6 +127,13 @@ public function navigate(TextDocument $sourceCode): ReflectionNavigation
return new ReflectionNavigation($this->serviceLocator, $this->parseSourceCode($sourceCode));
}

public function reflectNodeContext(Node $node): NodeContext
{
$frame = $this->serviceLocator->frameBuilder()->build($node);
return $this->serviceLocator->nodeContextResolver()->resolveNode($frame, $node);
}


public function reflectNode(
TextDocument $sourceCode,
ByteOffset|int $offset
Expand Down
20 changes: 18 additions & 2 deletions src/Core/Inference/Context/FunctionCallContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Phpactor\WorseReflection\Core\Inference\Context;

use Phpactor\TextDocument\ByteOffsetRange;
use Phpactor\WorseReflection\Core\Inference\FunctionArguments;
use Phpactor\WorseReflection\Core\Inference\NodeContext;
use Phpactor\WorseReflection\Core\Inference\Symbol;
use Phpactor\WorseReflection\Core\Name;
Expand All @@ -14,6 +15,7 @@ public function __construct(
Symbol $symbol,
private ByteOffsetRange $byteOffsetRange,
private ReflectionFunction $function,
private FunctionArguments $arguments,
) {
parent::__construct(
$symbol,
Expand All @@ -31,8 +33,22 @@ public function function(): ReflectionFunction
return $this->function;
}

public static function create(Name $name, ByteOffsetRange $byteOffsetRange, ReflectionFunction $function): self
public function arguments(): FunctionArguments
{
return new self(Symbol::fromTypeNameAndPosition(Symbol::FUNCTION, $name, $byteOffsetRange), $byteOffsetRange, $function);
return $this->arguments;
}

public static function create(
Name $name,
ByteOffsetRange $byteOffsetRange,
ReflectionFunction $function,
FunctionArguments $arguments,
): self {
return new self(
Symbol::fromTypeNameAndPosition(Symbol::FUNCTION, $name, $byteOffsetRange),
$byteOffsetRange,
$function,
$arguments,
);
}
}
5 changes: 5 additions & 0 deletions src/Core/Inference/FunctionArguments.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ public static function fromList(NodeContextResolver $resolver, Frame $frame, ?Ar
)));
}

public function has(int $index): bool
{
return isset($this->arguments[$index]);
}

public function at(int $index): NodeContext
{
if (!isset($this->arguments[$index])) {
Expand Down
6 changes: 4 additions & 2 deletions src/Core/Inference/Resolver/CallExpressionResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,18 @@ private function processConditionalType(

if ($context->symbol()->symbolType() === Symbol::FUNCTION) {
$function = $resolver->reflector()->reflectFunction($context->symbol()->name());
$arguments = FunctionArguments::fromList($resolver, $frame, $node->argumentExpressionList);
return (new FunctionCallContext(
$context->symbol(),
ByteOffsetRange::fromInts(
$node->getStartPosition(),
$node->getEndPosition()
),
$function
$function,
$arguments,
))->withType($type->evaluate(
$function,
FunctionArguments::fromList($resolver, $frame, $node->argumentExpressionList)
$arguments
));
}

Expand Down
2 changes: 1 addition & 1 deletion src/Core/Inference/Resolver/QualifiedNameResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ private function resolveContextFromCall(
$function = VirtualReflectionFunction::empty($name, $range);
}

$context = FunctionCallContext::create($name, $range, $function);
$context = FunctionCallContext::create($name, $range, $function, FunctionArguments::fromList($resolver, $frame, $parent->argumentExpressionList));

$stub = $this->registry->get($name->short());

Expand Down
5 changes: 4 additions & 1 deletion src/Core/Inference/Walker/TestAssertWalker.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,16 +196,19 @@ private function resolveArgs(?ArgumentExpressionList $argList, FrameResolver $re
private function assertTypeIs(Node $node, Type $actualType, Type $expectedType, ?NodeContext $message = null): void
{
$message = isset($message) ? TypeUtil::valueOrNull($message->type()) : null;
$position = PositionConverter::intByteOffsetToPosition($node->getStartPosition(), $node->getFileContents());
if ($actualType->__toString() === TypeUtil::valueOrNull($expectedType)) {
$this->testCase->addToAssertionCount(1);
return;
}
$this->testCase->fail(sprintf(
"%s: \n\n %s\n\nis:\n\n %s\n\non offset",
"%s: \n\n %s\n\nis:\n\n %s\n\non offset %s line %s char %s",
$message ?: 'Failed asserting that:',
$actualType->__toString(),
trim($expectedType->__toString(), '"'),
$node->getStartPosition(),
$position->line + 1,
$position->character + 1,
));
}
}
7 changes: 7 additions & 0 deletions src/Core/Reflector/CompositeReflector.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

use Amp\Promise;
use Generator;
use Microsoft\PhpParser\Node;
use Phpactor\WorseReflection\Bridge\TolerantParser\Reflection\ReflectionNavigation;
use Phpactor\WorseReflection\Core\Inference\NodeContext;
use Phpactor\WorseReflection\Core\Inference\Walker;
use Phpactor\WorseReflection\Core\Reflection\Collection\ReflectionDeclaredConstantCollection;
use Phpactor\WorseReflection\Core\Reflection\ReflectionDeclaredConstant;
Expand Down Expand Up @@ -102,6 +104,11 @@ public function diagnostics(TextDocument $sourceCode): Promise
return $this->sourceCodeReflector->diagnostics($sourceCode);
}

public function reflectNodeContext(Node $node): NodeContext
{
return $this->sourceCodeReflector->reflectNodeContext($node);
}

public function reflectNode(TextDocument $sourceCode, $offset): ReflectionNode
{
return $this->sourceCodeReflector->reflectNode($sourceCode, $offset);
Expand Down
7 changes: 7 additions & 0 deletions src/Core/Reflector/CoreReflector.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Amp\Promise;
use Generator;
use Microsoft\PhpParser\Node;
use Phpactor\TextDocument\ByteOffset;
use Phpactor\WorseReflection\Bridge\TolerantParser\Reflection\ReflectionNavigation;
use Phpactor\WorseReflection\Core\ClassName;
Expand All @@ -12,6 +13,7 @@
use Phpactor\WorseReflection\Core\Exception\CycleDetected;
use Phpactor\WorseReflection\Core\Exception\FunctionNotFound;
use Phpactor\WorseReflection\Core\Exception\NotFound;
use Phpactor\WorseReflection\Core\Inference\NodeContext;
use Phpactor\WorseReflection\Core\Inference\Walker;
use Phpactor\WorseReflection\Core\Name;
use Phpactor\WorseReflection\Core\Reflection\Collection\ReflectionDeclaredConstantCollection;
Expand Down Expand Up @@ -247,6 +249,11 @@ public function diagnostics(TextDocument $sourceCode): Promise
return $this->sourceReflector->diagnostics($sourceCode);
}

public function reflectNodeContext(Node $node): NodeContext
{
return $this->sourceReflector->reflectNodeContext($node);
}

public function reflectNode($sourceCode, $offset): ReflectionNode
{
return $this->sourceReflector->reflectNode($sourceCode, $offset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

use Amp\Promise;
use Generator;
use Microsoft\PhpParser\Node;
use Phpactor\TextDocument\TextDocument;
use Phpactor\TextDocument\TextDocumentBuilder;
use Phpactor\WorseReflection\Bridge\TolerantParser\Reflection\ReflectionNavigation;
use Phpactor\WorseReflection\Core\Inference\NodeContext;
use Phpactor\WorseReflection\Core\Inference\Walker;
use Phpactor\WorseReflection\Core\Reflection\Collection\ReflectionDeclaredConstantCollection;
use Phpactor\WorseReflection\Core\Reflection\Collection\ReflectionFunctionCollection;
Expand Down Expand Up @@ -86,4 +88,9 @@ public function walk(TextDocument $sourceCode, Walker $walker): Generator
{
return $this->innerReflector->walk($sourceCode, $walker);
}

public function reflectNodeContext(Node $node): NodeContext
{
return $this->innerReflector->reflectNodeContext($node);
}
}
4 changes: 4 additions & 0 deletions src/Core/Reflector/SourceCodeReflector.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

use Amp\Promise;
use Generator;
use Microsoft\PhpParser\Node;
use Phpactor\TextDocument\ByteOffset;
use Phpactor\TextDocument\TextDocument;
use Phpactor\WorseReflection\Bridge\TolerantParser\Reflection\ReflectionNavigation;
use Phpactor\WorseReflection\Core\Diagnostic;
use Phpactor\WorseReflection\Core\Diagnostics;
use Phpactor\WorseReflection\Core\Inference\Frame;
use Phpactor\WorseReflection\Core\Inference\NodeContext;
use Phpactor\WorseReflection\Core\Inference\Walker;
use Phpactor\WorseReflection\Core\Reflection\Collection\ReflectionClassLikeCollection;
use Phpactor\WorseReflection\Core\Reflection\Collection\ReflectionDeclaredConstantCollection;
Expand Down Expand Up @@ -64,6 +66,8 @@ public function reflectNode(
ByteOffset|int $offset
): ReflectionNode;

public function reflectNodeContext(Node $node): NodeContext;

public function reflectConstantsIn(
TextDocument $sourceCode
): ReflectionDeclaredConstantCollection;
Expand Down

0 comments on commit 9db45c9

Please sign in to comment.