scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
230 stars 21 forks source link

Scala 2 (and Zinc) have (possibly) inconsistent internal representation of class symbol names that differs from the produced bytecode #12847

Closed vasilmkd closed 9 months ago

vasilmkd commented 10 months ago

Please also see the relevant Zinc ticket: https://github.com/sbt/zinc/issues/1233.

At first, I thought it was a problem on the Zinc side, that Zinc was using the full names of inner classes instead of the compactified names (source code of compactification here).

However, it seems that Zinc simply replicates what the compiler internals do, in terms of symbol naming.

I will be talking about scala.reflect.internal.Symbols.Symbol#fullName and its Zinc counterpart.

  1. The compiler version is here: https://github.com/scala/scala/blob/3b154a09de7a7527d5e15804e252b74294c52881/src/reflect/scala/reflect/internal/Symbols.scala#L1306-L1324.
  2. The Zinc version is here: https://github.com/sbt/zinc/blob/51d73f1ec8bd4ee7b05517c2139ec010f592f7e9/internal/compiler-bridge/src/main/scala/xsbt/CallbackGlobal.scala#L220-L248.

I do not know the full details, but the Zinc version seems to follow the compiler version of this method with reasonable modifications. The core of the logic seems identical.

Which leads me to believe that the internal names of symbols are expanded, and the final class names are compactified. This is reasonable to me, because I understand that the class file names need to be limited, to fit the needs of the filesystems of our Operating Systems, and I don't think is problematic as a concept.

But then, when we examine the output .class files, the class inside a .class file matches the file name, so, to the JVM, the classes only exist with their compactified names. Again, I don't think this is problematic.

javap OuterLevelWithVeryVeryVeryLongClassName1$OuterLevelWithVer$$$$9a7e92c93110f2442b3ebd9c453788$$$$yLongClassName11$OuterLevelWithVeryVeryVeryLongClassName12$:

Compiled from "main.scala"
public class OuterLevelWithVeryVeryVeryLongClassName1$OuterLevelWithVer$$$$9a7e92c93110f2442b3ebd9c453788$$$$yLongClassName11$OuterLevelWithVeryVeryVeryLongClassName12$ {
  public static final OuterLevelWithVeryVeryVeryLongClassName1$OuterLevelWithVer$$$$9a7e92c93110f2442b3ebd9c453788$$$$yLongClassName11$OuterLevelWithVeryVeryVeryLongClassName12$ MODULE$;
  public static {};
  public OuterLevelWithVeryVeryVeryLongClassName1$OuterLevelWithVer$$$$9a7e92c93110f2442b3ebd9c453788$$$$yLongClassName11$OuterLevelWithVeryVeryVeryLongClassName12$();
}

Unfortunately, the problem remains for anyone that wishes to consume the information generated by Zinc, namely the list of generated class files. The produced information cannot be trusted.

We need this list of generated class files (and also deleted during last incremental compilation run) in IntelliJ IDEA to integrate with the build pipeline of the IDE and get additional support like annotation processing, code instrumentation, etc.

Any ideas what can be done here? I'm open for collaboration. Thanks in advance.

vasilmkd commented 10 months ago

This is not a problem in Scala 3, because it seems that the information that is passed on to Zinc is done after the bytecode is generated, so, the correct (compactified) class file names are provided.

vasilmkd commented 10 months ago

I'm tagging people who I think have previous experience or can contribute to this discussion. Feel free to tag other people as well. Thank you in advance.

@retronym @eed3si9n @som-snytt

lrytz commented 10 months ago

Thanks for the detailed report @vasilmkd. We'll take a look but only in 1-2 weeks.

dwijnand commented 9 months ago

Fixed in sbt/zinc#1244

som-snytt commented 9 months ago

I missed my chance to say, "I zinc zo."