Skip to content

Improve decompilation to generate compilable sources #4526

Closed
@nicolasstucki

Description

@nicolasstucki

Currently the decompilation printer scala.tasty.util.ShowSourceCode is the main step in decompilation of class files. It is a glorified TASTY tree pretty printer. It is still quite rough but it prints out a version of the sources that are fully typed (all types are inferred, all implicit are resolved, ...). There are still two kinds of issues to iron out: (i) Resugaring and (ii) leaking internals.

  • (i) We need to print some trees that were generated by desugaring back into a source like code. For example, we currently do this for lambdas.
  • (ii) The TASTY trees do not match exactly Scala source. We have some internal flags that do not make sense in source code and that should not be printed. Fields are defined in the class and not in the constructor when they should appear in the sources. And many more little details.

The Goal is to have a decompiler that produces back sources that can be recompiled and would generate the same program. We expect to fix this by small incremental steps, supporting more and more features.

Currently, the simplest way to test if some code is decompiled correctly is to create a file Foo.scala (or any of the available tests in tests/pos), write some code in it and run the following scripts from the dotty project:

sbt
;dotc -d output Foo.scala; dotc -decompile -d output -classpath output Foo; dotc -d output2 output/decompiled.scala

If some issue is fixed, regression test must be added by adding a .scala source in tests/pos along with a .decompiled with the same name. For example tests/pos/lambda.scala and tests/pos/lambda.decompiled.

You can test this file by running sbt testFromTasty (or sbt "testFromTasty XYZ" where XYZ is the name of the test), if the test fails a .decompiled.out will be generated besides the .decompiled. You can just rename it if the output of the current run was actually correct.

Note that this file is currently sensitive to spaces at the end of the line (painful and needs to be fixed) and that FromTastyTests append to any existing .decompiled.out which is problematic if you still have one from a previous FromTastyTests. There is also no way to only run a single test under FromTastyTests which is another improvement that must be done.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions