Hey all,
Myself, @blangmuir, @Xi_Ge, and others who spend a lot of their time working on SourceKit/SourceKit-LSP and SwiftSyntax have been thinking about bringing formatting technology to SourceKit-LSP. Formatting is integral to the experience of editing source code which why it is included in the LSP specification. This functionality, however, is currently missing from SourceKit-LSP. We want to provide users a great out-of-the-box experience of using SourceKit-LSP, across all editors and platforms, and first-class support for formatting is a critical piece of the experience.
For SourceKit-LSP we'd like to have formatting functionality that is:
- Fast and capable of real-time, "as you type", performance
- Be robust and work even in the presence of invalid code
- Work in contexts that may only provide a string of Swift source code for context such as snippets in code-review
For these workflows doing full semantic analysis is either too expensive or impossible due to lack of context (e.g. missing compiler arguments and inability to import the SDK or other dependencies). Fortunately, the Swift grammar was designed to be parsed without semantic analysis to enable tooling like this. Combining these requirements and factors, our belief is that the formatting technology should focus on using the syntactic structure of code without doing semantic analysis.
Looking at higher level goals, the formatting technology for SourceKit-LSP should aim to provide the building blocks for doing code format transformations that can be used for a variety of tools. To provide these building blocks but also not pull in all of SourceKit-LSP, we believe that the formatting technology should be provided as a reusable SwiftPM package that SourceKit-LSP itself uses. This layering would allow other tools to build their own formatting pipelines or leverage pieces that help them focus on the tasks that are most relevant to those tools. For example, tools like SwiftLint (which is doing a lot more than just whitespace transformations) can delegate some tasks to this infrastructure and focus more on adding additional rules and functionality. Further, the formatting technology could be used by code-generation tools that would like to have available convenient APIs to format the resulting code. By using the formatting technology from the package, these kinds of tools can be liberated from worrying about the particulars of handling a Swift grammar construct unless it is relevant for some particular rule.
Following the principle of building foundational pieces that we can then utilize to build other functionality, we also believe that the formatting technology should be built on top of SwiftSyntax. SwiftSyntax is directly integrated with the Swift parser, and there are ongoing efforts focused to keep improving its performance and the convenience of using SwiftSyntax for building Swift tools that need to understand the syntactic structure of Swift code. For example, SwiftSyntax has performance features like incremental re-parsing so that a live editor will do only the minimum work necessary to get an updated syntax tree after small user edits. Further, any change in the Swift grammar is going to be reflected in the SwiftSyntax APIs, either from the direct implementation of a SE proposal or at least soon after a proposal is accepted.
Given the above goals and motivations I'm excited about Google's swift-format project. The work that has gone into the swift-format tool on Google's swift repository aligns with many of the technical goals outlined here, and that team, led by @allevato, has expressed interest in contributing that work back to be part of this new formatting package to help achieve the goals outlined above. We will create a new swift.org repository and the Google team will be providing pull requests to contribute their code to that repository. We'd like everyone who is interested to participate in discussions in reviewing and incorporating such contributions and any other new work to build the new formatting technology.
I'm super excited about getting formatting functionality into swift.org and SourceKit-LSP and would love to hear your feedback about the contributed code and also how you could utilize the technology and what use-cases and workflows are most important to you. Help us with our continuous efforts to build awesome Swift tools!