Skip to content

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

Open
@lihaoyi

Description

@lihaoyi

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:

  • headerPattern is meant to tell the compiler to ignore lines of code during compilation and add the ignored line count for error reporting,
  • what we need for this ticket is to include the lines of code during compilation and subtract the ignored lines for error reporting.

CC @odersky we discussed this briefly in lausanne

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions