Skip to content

Commit

Permalink
Constant completion (#499)
Browse files Browse the repository at this point in the history
* Support for completing constants

* Constant completion

* Added completion section

* Updated CHANGELOG
  • Loading branch information
dantleech committed Jun 17, 2018
1 parent 9fee09a commit 52d9c56
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 7 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ Changelog
Features:

- [CodeTransforn] Extract expression
- [Completion] Support constant completion

Improvements:

- [Completion] Support namespaced functions, fixes #473
- [Docs] Added section on completion

## 2018-06-16 0.6.0

Expand Down
8 changes: 4 additions & 4 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions couscous.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ menu:
reference:
name: Reference
items:
completion:
text: Completion
relativeUrl: completion.html
navigation:
text: Navigation
relativeUrl: navigation.html
Expand Down
1 change: 1 addition & 0 deletions doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Phpactor is made up of a few different packages:
- [phpactor/class-to-file](https://github.com/phpactor/class-to-file): Convert files to class names and vice-versa.
- [phpactor/code-builder](https://github.com/phpactor/code-builder): Library for creating and idempotently updating source code.
- [phpactor/code-transform](https://github.com/phpactor/code-transform): Transform code.
- [phpactor/completion](https://github.com/phpactor/completion): Completion library.
- [phpactor/path-finder](https://github.com/phpactor/path-finder): Simple for file relationships when they share common path segments.
- [phpactor/source-code-filesystem](https://github.com/phpactor/source-code-filesystem): Manage source code trees.
- [phpactor/test-utils](https://github.com/phpactor/test-utils): Shared test utilities for Phpactor
Expand Down
124 changes: 124 additions & 0 deletions doc/completion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
Completion
==========

Phpactor provides completion for:

- **Class names**: All PSR compliant classes in the project and vendor tree.
- **Class members**: Methods, constants, properties of auto-loadable classes.
- **Functions**: Built-in and bootstrapped.
- **Constants**: Built-in and bootstrapped.
- **Parameters**: Will suggest appropriate local variables for method parameters.

Uniquely, Phpactor does not pre-index anything, completion happens in _real
time_, file locations are guessed based on composer locations (or brute forced
if not using composer). For non-autoloadable entities (e.g. functions) it is
assumed that these are defined during bootstrap.

Type inference
--------------

Phpactors type inference is based on
[WorseReflection](https://github.com/phpactot/worse-reflection).

### Assert

When encountering an `assert` with `instanceof` it will cast the variable
to that type, or a union of that type. See also [#instanceof](#instanceof).

```php
assert($foo instanceof Hello);
assert($foo instanceof Hello || $foo instanceof Goodbye)

$foo-> // type: Hello|Goodbye
```

### Assignments

Phpactor will track assignemnts:

```php
$a = 'hello';
$b = $a;
$b; // type: string
```

### Catch

```php

try {
// something
} catch (MyException $e) {
$e-> // type: MyException
}
```

### Foreach

Understands `foreach` with the docblock array annotation:

```php
/** @var Hello[] $foos */
$foos = [];

foreach ($foos as $foo) {
$foo-> // type:Hello
}
```

Also understands simple generics:

```php
/** @var ArrayIterator<Hello> $foos */
$foos = new ArrayIterator([ new Hello() ]);

foreach ($foos as $foo) {
$foo-> // type:Hello
}
```

### FunctionLike

Understands annonymous functions:

```
$barfoo = new Barfoo();
$function = function (Foobar $foobar) use ($barfoo) {
$foobar-> // type: Foobar
$barfoo-> // type: Barfoo
}
```

### InstanceOf

`if` statements are evaluated, if they contain `instanceof` then the type is
inferred:

```php
if ($foobar instanceof Hello) {
$foobar-> // type: Hello
}
```

```php
if (false === $foobar instanceof Hello) {
return;
}

$foobar-> // type: Hello
```

```php
if ($foobar instanceof Hello || $foobar instanceof Goodbye) {
$foobar-> // type: Hello|Goodbye
}
```

### Variables

Phpactor supports type injection via. docblock:

```
/** @var Foobar $foobar */
$foobar-> // type: Foobar
```
11 changes: 8 additions & 3 deletions lib/Extension/Completion/CompletionExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
namespace Phpactor\Extension\Completion;

use Phpactor\Completion\Bridge\TolerantParser\SourceCodeFilesystem\ScfClassCompletor;
use Phpactor\Completion\Bridge\TolerantParser\WorseReflection\WorseConstantCompletor;
use Phpactor\Completion\Bridge\WorseReflection\Formatter\FunctionFormatter;
use Phpactor\Completion\Bridge\WorseReflection\Formatter\MethodFormatter;
use Phpactor\Completion\Bridge\WorseReflection\Formatter\VariableFormatter;
use Phpactor\Completion\Bridge\TolerantParser\ChainTolerantCompletor;
use Phpactor\Completion\Bridge\TolerantParser\WorseReflection\WorseClassMemberCompletor;
use Phpactor\Completion\Bridge\TolerantParser\WorseReflection\WorseBuiltInFunctionCompletor;
use Phpactor\Completion\Bridge\TolerantParser\WorseReflection\WorseFunctionCompletor;
use Phpactor\Completion\Bridge\TolerantParser\WorseReflection\WorseParameterCompletor;
use Phpactor\Completion\Bridge\TolerantParser\WorseReflection\WorseLocalVariableCompletor;
use Phpactor\Completion\Core\Formatter\ObjectFormatter;
Expand Down Expand Up @@ -95,13 +96,17 @@ private function registerCompletion(ContainerBuilder $container)
);
}, [ 'completion.tolerant_completor' => []]);

$container->register('completion.completor.builtin_function', function (Container $container) {
return new WorseBuiltInFunctionCompletor(
$container->register('completion.completor.function', function (Container $container) {
return new WorseFunctionCompletor(
$container->get('reflection.reflector'),
$container->get('completion.formatter')
);
}, [ 'completion.tolerant_completor' => []]);

$container->register('completion.completor.constant', function (Container $container) {
return new WorseConstantCompletor();
}, [ 'completion.tolerant_completor' => []]);

$container->register('completion.formatter', function (Container $container) {
return new ObjectFormatter([
new TypeFormatter(),
Expand Down

0 comments on commit 52d9c56

Please sign in to comment.