Skip to content

Commit

Permalink
GH-2603: Do not filter static method invocations and variadic
Browse files Browse the repository at this point in the history
  • Loading branch information
dantleech committed Apr 6, 2024
1 parent eadaa21 commit d492b40
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 27 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -11,9 +11,11 @@ Improvements:

- Fix contextual completion in constructor agrument position #2504
- Basic support for `array_reduce` stub #2576
- Support variadics in contextual completion #2603

Bug fixes:

- Only filter new object expression names in contextual completion #2603
- Fixing include and exclude patterns #2593 @mamazu

## 2024-03-09
Expand Down
Expand Up @@ -35,6 +35,13 @@ public function __construct(private TolerantCompletor $inner, private Reflector
public function complete(Node $node, TextDocument $source, ByteOffset $offset): Generator
{
$generator = $this->inner->complete($node, $source, $offset);
if (
!$node instanceof CallExpression &&
($node instanceof QualifiedName && !$node->parent instanceof ObjectCreationExpression)
) {
yield from $generator;
return $generator->getReturn();
}

$type = $this->resolveFilterableType($node, $source, $offset);
if (null === $type) {
Expand Down Expand Up @@ -77,6 +84,7 @@ private function resolveFilterableType(Node $node, TextDocument $source, ByteOff
{
$argumentNb = 0;
$memberAccessOrObjectCreation = $node;
$node = NodeUtil::firstDescendantNodeBeforeOffset($node, $offset->toInt());
if ($node instanceof QualifiedName) {
$memberAccessOrObjectCreation = null;
$argumentExpression = $node->getFirstAncestor(ArgumentExpression::class);
Expand All @@ -89,9 +97,10 @@ private function resolveFilterableType(Node $node, TextDocument $source, ByteOff
$memberAccessOrObjectCreation = $list->parent;
}
}
if ($node instanceof ArgumentExpressionList) {
$argumentNb = count(iterator_to_array($node->getValues()));
$memberAccessOrObjectCreation = $node->parent;
$argumentList = $node->getFirstAncestor(ArgumentExpressionList::class);
if ($argumentList instanceof ArgumentExpressionList) {
$argumentNb = max(0, count(iterator_to_array($argumentList->getValues())) - 1);
$memberAccessOrObjectCreation = $argumentList->parent;
}

if (!$memberAccessOrObjectCreation instanceof CallExpression && !$memberAccessOrObjectCreation instanceof ObjectCreationExpression) {
Expand All @@ -103,7 +112,6 @@ private function resolveFilterableType(Node $node, TextDocument $source, ByteOff
return null;
}
try {
;
$memberAccessOrObjectCreation = $this->reflector->reflectOffset($source, $offset)->nodeContext();
} catch (NotFound $e) {
return null;
Expand Down Expand Up @@ -155,7 +163,14 @@ private function typeFromParameters(ReflectionParameterCollection $parameters, i
{
$parameter = $parameters->at($argumentNb);
if (null === $parameter) {
return null;
$lastParameter = $parameters->lastOrNull();
if (null === $lastParameter) {
return null;
}
if (!$lastParameter->isVariadic()) {
return null;
}
$parameter = $lastParameter;
}

$type = $parameter->type();
Expand Down
Expand Up @@ -60,13 +60,13 @@ class Obj {}
class Foo { public function bar(Obj $obj){}}
$f = new Foo();
$f->bar(<>)
$f->bar(new <>)
EOT,
[
'Bar\Obj',
],
];
yield 'namespaced open method call' => [
yield 'static call returns all' => [
[
'Bar\Foo',
'Bar\Obj',
Expand All @@ -78,7 +78,26 @@ class Obj {}
class Foo { public function bar(Obj $obj){}}
$f = new Foo();
$f->bar(<>
$f->bar(F<>)
EOT,
[
'Bar\Foo',
'Bar\Obj',
],
];
yield 'namespaced method call' => [
[
'Bar\Foo',
'Bar\Obj',
],
<<<'EOT'
<?php
namespace Bar;
class Obj {}
class Foo { public function bar(Obj $obj){}}
$f = new Foo();
$f->bar(new <>)
EOT,
[
'Bar\Obj',
Expand All @@ -95,7 +114,7 @@ class Obj {}
class Foo { public function bar(Obj $obj){}}
$f = new Foo();
$f->bar(<>
$f->bar(new <>)
EOT,
[
'Obj',
Expand All @@ -112,7 +131,7 @@ class Obj {}
class Foo { public function bar(Obj $obj){}}
$f = new Foo();
$f->bar(O<>
$f->bar(new O<>
EOT,
[
'Obj',
Expand All @@ -129,7 +148,7 @@ class Obj {}
class Foo { public function bar($obj){}}
$f = new Foo();
$f->bar(O<>
$f->bar(new O<>
EOT,
[
'Foo',
Expand All @@ -148,12 +167,13 @@ class Baz {}
class Foo { public function bar(Obj $obj, Baz $baz){}}
$f = new Foo();
$f->bar(Obj::new(),<>
$f->bar(Obj::new(), new <>)
EOT,
[
'Baz',
],
];

yield '2nd arg partial' => [
[
'Obj',
Expand All @@ -166,7 +186,7 @@ class Baz {}
class Foo { public function bar(Obj $obj, Baz $baz){}}
$f = new Foo();
$f->bar(Obj::new(),B<>
$f->bar(Obj::new(),new B<>
EOT,
[
'Baz',
Expand All @@ -184,20 +204,20 @@ class Baz {}
class Foo { public function bar(Obj $obj, Baz ...$baz){}}
$f = new Foo();
$f->bar(Obj::new(),B<>
$f->bar(Obj::new(),new B<>
EOT,
[
'Baz',
],
];
yield 'new' => [
yield 'enum' => [
[
'Obj',
'Baz',
],
<<<'EOT'
<?php
class Obj {}
enum Obj {}
class Baz {}
class Foo { public function bar(Obj $obj, Baz ...$baz){}}
Expand All @@ -208,7 +228,7 @@ class Foo { public function bar(Obj $obj, Baz ...$baz){}}
'Obj',
],
];
yield 'enum' => [
yield 'on static call' => [
[
'Obj',
'Baz',
Expand All @@ -217,16 +237,15 @@ class Foo { public function bar(Obj $obj, Baz ...$baz){}}
<?php
enum Obj {}
class Baz {}
class Foo { public function bar(Obj $obj, Baz ...$baz){}}
class Foo { public static function bar(Obj $obj, Baz ...$baz){}}
$f = new Foo();
$f->bar(new O<>
Foo::bar(new O<>
EOT,
[
'Obj',
],
];
yield 'static' => [
yield 'on variadic' => [
[
'Obj',
'Baz',
Expand All @@ -235,9 +254,9 @@ class Foo { public function bar(Obj $obj, Baz ...$baz){}}
<?php
enum Obj {}
class Baz {}
class Foo { public static function bar(Obj $obj, Baz ...$baz){}}
class Foo { public static function bar(Obj ...$objz){}}
Foo::bar(new O<>
Foo::bar(new Obj(), new Obj(), new O<>)
EOT,
[
'Obj',
Expand Down
4 changes: 0 additions & 4 deletions lib/Indexer/Model/IndexJob.php
Expand Up @@ -3,12 +3,8 @@
namespace Phpactor\Indexer\Model;

use Generator;
use Phar;
use PharFileInfo;
use Phpactor\TextDocument\TextDocumentBuilder;
use RecursiveIteratorIterator;
use SplFileInfo;
use UnexpectedValueException;

class IndexJob
{
Expand Down
Expand Up @@ -116,6 +116,18 @@ public function last()
return end($this->items);
}

/**
* @return T|null
*/
public function lastOrNull()
{
if (empty($this->items)) {
return null;
}

return end($this->items);
}

public function has(string $name): bool
{
return isset($this->items[$name]);
Expand Down

0 comments on commit d492b40

Please sign in to comment.