This project began as an experiment in rewriting Typelevel Simulacrum as a set of Scalafix rules. It's currently still a proof-of-concept, but it is able to replace Simulacrum 1 in the Cats repository without breaking any tests or binary-compatibility checks.
Please see this Cats issue for discussion about this experiment.
Development of this tool has been supported by Permutive. Please see our monthly reports for updates on the work of the Permutive Community Engineering team.
Simulacrum 1's @typeclass
macro annotation adds three kinds of boilerplate, which this project
factors into three Scalafix rules:
AddSerializable
: This rule adds extends Serializable
to the root type classes in a type class hierarchy.AddImplicitNotFound
: This rule adds custom @implicitNotFound
annotations for type classes.TypeClassSupport
: This rule adds a summoner method and syntax method support to the type class companion object.This repo currently includes a few miscellaneous Scalafix rules that may be useful for experimenting with Dotty cross-compilation:
ExpandPolymorphicLambdas
: This rule rewrites kind-projector's polymorphic lambda values to
explicit anonymous class instantiations that work on both Scala 2 and Dotty.ExpandTypeLambdas
: This rule rewrites (a large subset of) kind-projector's
type lambda syntax to a representation that currently works on both Scala 2 and Dotty.ParenthesizeLambdaParamWithType
: This rule parenthesizes lambda parameters with type annotations
as needed.The first rule may be used in Cats—it's not yet clear whether the polymorphic SAM support that may eventually be added to Dotty will support cross-building there.
The latter two rules should no longer be necessary in most cases, since Dotty
now supports a subset of kind-projector's syntax via the -Ykind-projector
compiler option, and can add parentheses to lambda parameters with type annotations with
-language:Scala2Compat -rewrite
.
It's not currently possible to build Cats with Dotty because Simulacrum 1 uses macro annotations, which Dotty doesn't support. The goal of this project is to change that by providing a non-macro-annotation-based version of Simulacrum.
I have a Cats branch that demonstrates how these Scalafix rules work. You can follow along with the following steps:
@noop
annotations to FlatMap#ifM
, Functor#ifF
, and Monad#whileM
and whileM_
.
This is necessary for
compatibility because Simulacrum 1 didn't handle these methods.sbt:cats> scalafix AddSerializable
sbt:cats> scalafix AddImplicitNotFound
sbt:cats> scalafix TypeClassSupport
sbt:cats> scalafmtAll
This will result in some boilerplate being added to the Cats source files:
50 files changed, 2461 insertions(+), 17 deletions(-)
sbt validateJVM
to verify that tests and binary-compatibility checks pass after the change
(and sbt ++2.13.1 buildJVM
if you want to check Scala 2.13 as well).The instructions below are not up-to-date with Cats master, although they should still work. Please follow this work-in-progress PR for the current status of Dotty cross-building.
You can add Dotty cross-building with a few additional steps:
sbt:cats> +scalafix ExpandTypeLambdas
sbt:cats> +scalafix ExpandPolymorphicLambdas
sbt:cats> +scalafmtAll
This will result in a pretty big diff. Unlike the similar Simulacrum boilerplate expansion we did above, this kind-projector expansion probably isn't something we'd ever want to merge—it's just a convenient way to try out Dotty cross-building.
sbt:cats> ++0.21.0-bin-20191201-65a404f-NIGHTLY
sbt:cats> coreJVM/compile
sbt:cats> kernelLawsJVM/compile
sbt:cats> alleycatsCoreJVM/compile
These modules should compile without errors (the other laws modules and cats-free will currently fail).
People are expected to follow the Scala Code of Conduct on GitHub and in any other project channels.
This experimental code is licensed under the Apache License, Version 2.0 (the "License"); you may not use this software except in compliance with the License.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.