microsoft / qsharp-compiler

Q# compiler, command line tool, and Q# language server
https://docs.microsoft.com/quantum
MIT License
682 stars 171 forks source link

Extensible diagnostics in design time builds #544

Open bamarsha opened 4 years ago

bamarsha commented 4 years ago

Is your feature request related to a problem? Please describe. The compiler has support for running arbitrary code on the Q# syntax tree during compilation in the form of the IRewriteStep interface. Rewrite steps can also generate arbitrary diagnostics that are displayed at build time. Unfortunately, rewrite steps don't run at design time when using the Q# language server, which means things like linters are limited to the command line, and can't provide live feedback in an editor.

Describe the solution you'd like The compiler should provide some mechanism to run arbitrary diagnostic-generating code analysis in design-time builds, similar to Roslyn analyzers.

Describe alternatives you've considered No known alternatives that don't involve modifying the language server.

Additional context This would have been useful for the runtime capabilities diagnostics (#449, #488). Those had to be built into the compiler, but they are not needed for compilation. Extensible diagnostics would make this kind of static analysis easier to add in a modular way.

swernli commented 4 years ago

One important concern that was brought up about invoking too much of the IRewriteStep infrastructure is the overall impact on performance. We definitely want to keep the language server performant, as having the design time feedback be fast is key to providing a good IDE experience.

bamarsha commented 4 years ago

Yes, running all of the rewrite steps in full should probably be avoided. We could add a method that IRewriteSteps could implement that would only return diagnostics, which depending on the rewrite step could be implemented in a more efficient way. Another way is to make a separate plugin interface for analyzers only.

bamarsha commented 2 years ago

I can think of two hooks in the compiler that could be used to generate diagnostics:

  1. When a specialization is recompiled
  2. When global type checking runs

I feel like having a way to listen for just these two events could take care of a lot of diagnostics in a more modular way.