Google Summer of Code 2021: Project Summary
Haskell Language Server: Rename Plugin
This project intended to implement a renaming feature as specified by the Language Server Protocol (LSP). The motivation being that renaming is a fundamental feature of an IDE that the Haskell Language Server (HLS) did not provide.
Motivating issues:
The deliverables of the plugin outlined in the initial proposal were to:
- perform workspace-wide renames;
- work for all names (including types and type constructors);
- work for qualified names;
- be thoroughly tested.
These were all achieved! The final work has been merged and can be found at #2108.
Tasks
Reference finding
Using HieDb allowed a relatively simple method of finding the correct name reference locations. However, naively replacing names at these locations would not work since Haskell can be sensitive to indentation. Therefore, a method of transforming the abstract syntax tree (AST) was required.
Transforming the AST
Throughout the project, many different solutions to this task were considered. Initially, transforming the AST using Retrie was suggested. However, when drafting this solution, several limitations became apparent:
- Retrie was not working on windows;
- Retrie had dropped support for older GHC versions (<8.8.0);
- Retrie would only work for top-level names.
Therefore, transforming the AST with SYB seemed more suitable since the full capability of Retrie was not required for a simple rewrite, and it resolved these limitations.
Reprinting the AST
ExactPrint for GHC was used to create the workspace edit needed to respond to the client.
The HieDb Limitation
The use of HieDb in the HLS has limitations since the database is populated when each project is indexed, which currently only happens when the editor loads a project file. This issue also impacts other features such as reference finding and definition finding.
The work towards resolving this has been started: #2009, #7498.
Due to this issue, the rename plugin currently has limited support in multi-project workspaces and is disabled by default.
Update: April 2022
While the work on full multi-component support continues, I have enabled the rename plugin for use within modules and added a plugin option for limited cross-module renaming.