rules_scala icon indicating copy to clipboard operation
rules_scala copied to clipboard

Implement an ijar equivalent for Scala 3

Open jadenPete opened this issue 10 months ago • 6 comments
trafficstars

Description

From my comment in https://github.com/bazelbuild/rules_scala/issues/1657:

From what I understand, though, TASTy markes a major shift in how type information is stored between compiler invocations from Scala 2.13's "Pickle" format in that it includes a completely typed representation of the program's AST. I'm of the opinion that this defeats the purpose of using ijar, since most changes to a program's source code will now induce changes in its TASTy files, thus changing the generated ijar and invalidating reverse dependencies' cached compilation actions.

When you consider that and the fact that "scalac doesn’t have to read their .class files anymore; it can read their .tasty files", it may make more sense to develop an alternative to ijar specially for Scala 3 targets, as opposed to modifying ijar. That way, we can strip out information from TASTy files not needed for compilation (e.g. positional information, documentation, private members, etc.), similar to what @susliko described.

Given these changes in how symbols are read from the compile classpath in Scala 3 vs Scala 2, I don't think ijar is an appropriate solution for producing Scala 3 interface JARs. For that reason, I've developed "dottyijar", a version of ijar that produces an interface JAR by removing all .class files and performing a few modifications to .tasty files:

  • Clearing the UUID, "Positions" section, and "Comments" section
  • Removing all val and def definitions that are private and not inline
  • Replace the values of all val and def definitions and class parent arguments with ???
  • Remove unused names from the name table

For context on the TASTy format, see dotty.tools.tasty.TastyFormat.

Thus, dottyijar produces interface JARs that are far less sensitive to implementation changes than those produced by ijar. Although it's not as fast as ijar (mainly because it's written in Scala and doesn't read and write in a single pass), it's very fast—dottyijar produced an interface JAR for the Scala 3 compiler, which contains 1,011 TASTy files, in 4.369 seconds on my machine, whereas ijar took 0.292 seconds.

Motivation

I'm implementing this change to close https://github.com/bazelbuild/rules_scala/issues/1657.

jadenPete avatar Jan 15 '25 05:01 jadenPete