scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.88k stars 1.06k forks source link

Provide a way to offset line numbers in wrapped scripts #21919

Open lihaoyi opened 2 days ago

lihaoyi commented 2 days ago

Many Scala tools wrap snippets of Scala code before execution: Mill, Ammonite, ScalaCLI, and others. In Scala 2, we could use a post-parser compiler plugin to fix up all the line numbers and positions, such that source locations reported by sourcecode.Line/sourcecode.File and downstream error messages surfaced by typer or runtime exceptions were properly attributed.

In Scala 3, this is no longer possible. Thus tools like Mill/Ammonite/ScalaCLI now need a three-pronged approach:

  1. A custom Zinc reporter to fix error locations generated pre-typer
  2. A compiler plugin to update locations generated by sourcecode.Line and sourcecode.File, and for post-typer compile error messages
  3. An ASM bytecode rewriter to fix error locations in final bytecode to ensure locations are properly set in runtime exceptions.

This logic has been implemented at least three times, with @alexarchambault being the author of the Ammonite and ScalaCLI copies, and @bishabosha being the author of the Mill copy. To be clear, the Scala 2 approach wasn't perfect (parser errors would still use the wrong line number), so both workflows can be improved upon

It would be nice if we could provide something built in to just make the Scala compiler subtract certain lines from the line number reporting automatically. Mill and Ammonite internally use magic comments (see below) to power the Scala 2 compiler plugin and the Scala 3 triple code paths (above), and perhaps similar magic comments could be adapted to work generally across all Scala 3 tooling

//MILL_ORIGINAL_FILE_PATH=/Users/lihaoyi/Github/mill/ci/shared.mill
//MILL_USER_CODE_START_MARKER

The existing dotty.tools.SourceFile.headerPattern is similar, but ultimately the exact opposite of this use case:

CC @odersky we discussed this briefly in lausanne

bishabosha commented 2 days ago

So the SourceFile abstraction does allow to encode an underlying file and an offset, but plugins cannot customise the source files