Skip to content

scala 3: ExplicitResultTypesΒ #1583

@mlachkar

Description

@mlachkar

Adapt Explicit result types for Scala 3

The current state

ExplicitResultTypes rule calls the scala 2 presentation compiler to infer types for each val, def or var. To make this rule available for scala 3, we need to re-write it to interface this time with the Scala 3 presentation compiler, in other words, ExplicitResultTypes rule for Scala 3, need to be written in Scala 3.

How to implement ?

flowchart LR
A(Scalafix-cli) -->|depends on| B(Scalafix-rules)
Loading

The actual design of Scalafix requires that the module scalafix-rules uses the same Scala Version than the Scalafix-cli module. To be able to use the Scala 3 presentation compiler, the rule needs to be rewritten in Scala 3 and therefore scalafix-cli needs to be able to load a Scala 3 rule.

Most likely implementation

  1. Create a Java interface for ExplicitResultTypes that provides the minimum needed methods for it to work. The interface would look like below:
public interface ExplictResultTypesInterface {
  List<PositionWithString> fix(Optional<Object>: global, Path: relativePathToSemanticDbFile)
  Object createGlobal(scalacClasspath, scalacOptions)
}
  • Currently ExplicitResultTypes rule needs a SemanticDocument, that cannot be passed as a parameter to the java method, so each implementation of this rule will need to recreate it from its relative path.
  • The fix method would return a list of Position and String, which should be enough to create a scalafix.Patch.
  • The global instance needs also to be created differently depending on the Scala Version. We can maybe stop using ScalafixGlobal and use directly scala.tools.nsc.interactive.Global (in Scala 2) and dotty.tools.dotc.interactive.InteractiveDriver (in Scala 3). ScalafixGlobal is almost only wrapping the Global from the presentation compiler. In this Java interface, it would be an Object, and then each implementation would cast it as a Global instance or InteractiveDriver instance depending on the Scala version.

Here is an example of the interface implemented by Metals to deal with the same issue. Their global is called PresentationCompiler, and in their case, they only infer the type for one position, whereas ExplicitResultTypes needs to do it for the entire file.

  1. The module Scalafix-cli or Scalafix-rules (still need to be defined) would need some specific code to be able to classload the right jar of ExplicitResultTypes , in other words either the version written in Scala 2 or Scala 3. (link to metals that does that, or other project that does that too)

  2. Write the new ExplicitResultTypes for scala 3, that implements the ExplictResultTypesInterface interface. We can definitely get inspired by Metals implementation for inferType code action (link)

Other possible implementation

If we are able to cross compiler scalafix-core, scalafix-cli in Scala 3 , it should be possible to write a specific version of Explicit Result types for Scala 3.

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