Phpactor 2023.04.10

Last modified 2023/04/10 17:16

I have tagged Phpactor 2023.04.10.

It has been almost 3 months since the last tag, part of the reason for the delay has been the implementation of some great features which required some time to settle down, and also due to me chasing some white whales.

Happily this release does include performance improvements, which will be noticeable on large and complicated files.

Diagnostic Outsourcing

By default Phpactor will now run diagnostic analysis in a separate process. In the previous release diagnostics were a blocking process, and contributed to poor performance with large files. By running the diagnostics in a separate process we allow them to be run on a separate CPU, freeing up the main Phpactor process to do other CPU intensive work.

Async more things

If you are familiar with the history of Phpactor then you will know it started off life not as a language server but as a synchronous CLI tool. Over the past years it has gradually evolved into an almost respectable language server but there are still lots of relics from the “old days” - lots of things are blocking which could be non-blocking.

With this release some bottlenecks in the reflection and analysis package (worse reflection) have been made non-blocking, meaning they can be interrupted and allow other things to happen while analysing code - notably diagnostics.

Inlay Hints!

Users of PHPStorm are probably familiar with the concept of inlay hints – the virtual text that is added to your source code to show the parameter names for functions. Inlay Hints are supported in Language Server Protocol 3.17 and Phpactor’s LSP library has been updated accordingly.

Inlay hint support is disabled by default as it can affect performance, it can be enabled with:

{
    "language_server_worse_reflection.inlay_hints.enable": false,
    "language_server_worse_reflection.inlay_hints.params": true,
    "language_server_worse_reflection.inlay_hints.types": false,
}

Inlay Hints do require support in your editor. As of writing Neovim requires an additional plugin and I cannot get this feature working in VS Code at all so if anybody has any hints please raise an issue.

Inlay Hints “Inlay Hints” in Neovim with lsp-inlayhints

Deprecation Diagnostics

Phpactor now includes a warning diagnostic if you call a deprecated method or instantiate a deprecated class:

Depreaction Warning Deprecation warning in Neovim

Auto Configuration

I work on many projects, and I find it annoying to have to customize my Phpactor configuration each time and often I will not even know IF I can enable more functionality for a given project (does it use Psalm? Prophecy? Behat?).

Autoconfiguration solves this problem by detecting which extensions can be enabled in the current project and prompting you to enable or disable them.

Auto configuration

This comes at the cost of creating a phpactor.json file in each project, but I personally think this is a small price to pay, and I inevitably end up creating this file regardless.

Promote constructor parameters

One of my most used Phpactor refactorings has been complete constructor - this refactoring would add assignments and the properties to your class after adding a minimal constructor.

As of PHP 8.0 we have constructor property promotion which makes complete constructor largely unnecessary, but it is still kindof annoying to add the visibility.

There is now an additional refactoring Promote Constructor which will automatically add the visibility keywords to unassigned constructor parameters.

Promote constructor parameters

Hierarchical Namespace Completion

This is an overdue and much requested feature, it allow you to enter the start of an FQN and autocomplete the subsequent sections. It’s great for discovering classes and suggesting for example, all classes with an Event\\ namespace or similar.

Namespace completion

Show class __construtor instantiations

Quite frequently I find myself wanting to know all the places where a class is instantiated via. its constructor (i.e. via the new keyword).

You can now invoke the references LSP action on a __construct method and it will return all the places where the construtor is invoked.

Only suggest Attributes for attributes

Previously we suggested any class when presenting suggestion for PHP Attributes. We now additionally index whether a given class is an attribute or not - enabling us to only suggest attributes.

CHANGELOG

There are a bunch of bug fixes and a number of other improvements, the full changelog:

Features:

  - Show references to new objects when finding references to `__construct` method #2194
  - Support for inlay hints #2138
  - Deprecation diagnostics #2120
  - Auto configuration - automatically suggest and apply configuration #2114
  - Transform to "promote" unassigned consturctor properties #2106
  - Hierarchical namespace segment completion #2070
  - Completion for promoted property visiblity #2087
  - Option `language_server.diagnostic_outsource` to outsource diagnostics in separate process #2105

Bug fixes:

  - Also use in-memory files when enanching indexed records #2187
  - Prophecy: Do not crash when used in trait #2129
  - Prophecy: fixing chaining of methods via. `getObjectProphecy` #2122
  - `new class-string<Foo>` now resolves to `new Foo` #2065
  - Fix extract method within trait #2076 @mamazu
  - Do not attempt to index classes whose names are reserved words #2098
  - Fix typo in LanguageServerExtension::PARAM_FILE_EVENTS resulting in typo in documentation
  - Fix parsing array types in `@param` Tags in doc blocks #2172

Improvements:

  - Only show completion suggestions for real attributes #2183, #2100 @mamazu @przepompownia
  - Code action and formatting handlers now send progress notifications #2192
  - Invalidate diagnostics cache only when document changes #2191
  - Optimize analysis for scopes with many many assignments #2188
  - Made some heavy blocking operations non-blocking (e.g. diagnostics, code
    actions).
  - ⚠ Removed frame sorting which increases radically in some cases, but may
    also cause regressions #2179
  - Psalm: Support for overriding the error level #2174
  - Generating constructor at the top of the file #2113 @mamazu
  - Include (complex) docblock params when generating method
  - Take into account named parameters when "guessing" parameter names #2090
  - Show full FQN for classes in hover #2081
  - Upgrade to 3.17 of the language server protocol #2082
  - Facilitate changing visiblity on promoted properties @mamazu
  - Allow generation of constructor for Attributes.

Summaries and Thanks

Since the last release:

  • 74 PRs merged since the 21st January
  • 102 hours of my time used

Sponsorship:

  • I have 10 sponsors and get $181 a month - which is better than a kick up the bum.

Contributors:

  • Special thanks to @mamazu for the many improvements he has contributed, including improving our PHPStan baseline.

NixOS:

Next Steps

  • Performance has been addressed in this release, and Phpactor is far better than it was, but still not ideal. There is more work to do here, hopefully some low hanging fruits before big scary changes like implementing an incremental analyser.
  • Phpactor’s documentation is need of attention. It gets frequently neglected and I would like to see a more automated approach, especially for things like code actions. We could also start to more visibly deprecate the use of the VIM Plugin.
  • Provide an automated PHAR build. This would make it easier to distribute Phpactor and cut the dependence on Composer, in addition to having a sensible reason to tag releases other than writing a blog post.