Phpactor 2022.10.11
Last modified 2022/10/12 21:10Today I have tagged version 2022.10.11.
This is the first (and hopefully not the last) monthly release, the full changelog is on the release page. I’ll run through some of the highlights in this post.
Generate Decorator ¶
Thanks to the perserverance mamazu there is now a code action to generate a decorator:
This is an LSP only action, and must be invoked in a file with an empty class which implements one or more interfaces.
I’m really happy to see this, I don’t use decorators often, but when I do I always think “this should be automated”. Now it is 🎉
Goto Interface Definition of Method Declaration ¶
This is a very minor feature, but also surprisingly useful. Before the ticket was raised I hadn’t really considered it.
Given you on method in a class which is implementing an interface (<>
below):
interface Foo {
public function bar(): void; // will jump here
}
class FooImplementation implements Foo {
public function b<>ar(): void
{
}
}
You can now jump to the signature in the interface by invoking “Goto
Definition” on the signature in the implementation (bar
in the case above).
The inverse operation is the existing “Goto Implementations” action.
Class String Template and Better Generics ¶
The code for generics has been improved significantly, and while there are still some features to come (e.g. injecting template vars through the constructor) these features will now be much easier to implement.
This release:
- Fixes the behavior of
iterable
generics when multiple levels of inheritance are used (#1875) - Supports the use of method-level template vars. (e.g.
@param T
and@return T
) - Supports the use of
class-string<T>
The last feature is quite exciting:
Given the following class:
class Container {
/**
* @tempalte T
* @param class-string<T> $fqn
* @return T
*/
public function get(string $fqn): object
}
When you call $foobar = $container->get(Foobar::class)
Phpactor will be able
to infer that $foobar
is an object of type Foobar
.
A wild usage can be seen in the valinor library, something like:
Like Valinor
Dedicated Stubs ¶
Previously Phpactor used PHPStorm
stubs exclusively (by default at
least) - that was
until I realised that a bug with enums
was caused by this library - namely
that the interface BackedEnum
has a
property.
The parser wasn’t happy about that and subsequently enums had no method
completion.
Phpactor now has a few “dedicated” stubs. This allows us to fix the enum
“issue” above, and also, mainly for testing purposes, be able to depend on
fundamental stubs like Iterable
, ArrayAccess
, IteratorAggregate
, etc.
Summary ¶
There are more bug fixes and improvements listed in the changelog, including a significant performance improvement for large documents.
I know that performance is still an issue, especially with very large and complicated source files. I’ve been thinking about ways to improve it. One possible way would be to distribute the language server work over multiple processes (e.g. diagnostics, completion, code actions, etc), which would allow the use of multiple cores. This isn’t trivial however and adds more complexity.
Another option is investing more time into untangling WorseReflection
which I
suspect to be highly inefficient, if it’s not highly inefficient then it
could at least be made to be more efficient, or at least, intelligible.
Next month should see the final pieces of the generics puzzle fall into place.