reftree
reftree copied to clipboard
Internal macro error building reftree
Exception building diagram (on scala 2.12.5)
[info] Compiling 1 Scala source to /home/wsargent/work/scala-capabilities/images/target/scala-2.12/classes ...
[error] /home/wsargent/work/scala-capabilities/images/src/main/scala/Main.scala:90:44: Internal error: unable to find the outer accessor symbol of class anon$Generic Coproduct RefTree$macro$14
[error] val diagram = Diagram(nameChanger)
[error] ^
[error] ## Exception when compiling 1 sources to /home/wsargent/work/scala-capabilities/images/target/scala-2.12/classes
[error] null
[error] java.lang.String.valueOf(String.java:2994)
code is as follows
import java.nio.file.{Path, Paths}
import reftree.diagram.Diagram
import reftree.render.{Renderer, RenderingOptions}
object Main {
// #definition
final class Document(private var name: String) {
private object capabilities {
val nameChanger = new Document.NameChanger {
override def changeName(newName: String): Unit = {
name = newName
}
}
}
override def toString: String = s"Document($name)"
}
// #definition
// #access
object Document {
sealed trait NameChanger {
def changeName(name: String): Unit
}
// Policy controls who has access to what
class Access private {
def nameChanger(doc: Document): NameChanger = {
doc.capabilities.nameChanger
}
}
object Access {
def apply(): Access = new Access
}
}
// #access
// https://www.youtube.com/watch?v=6mWaqGHeg3g
def main(args: Array[String]): Unit = {
val imagePath = Paths.get("images") // current relative path + "images"
implicit val renderer = Renderer(
renderingOptions = RenderingOptions(),
directory = imagePath.resolve("overview")
)
import renderer._
def render(name: String, diagram: Diagram): Path = {
diagram.render(name)
directory.resolve(s"$name.${renderer.format}")
}
def display(path: Path) = {
println(s"Open with Browser ${path.toUri}")
println(s"Open with IntelliJ IDEA http://localhost:63342/api/file/${path.toString}")
}
val document = new Document("will")
val access = Document.Access()
val nameChanger = access.nameChanger(document)
println(s"result = $document")
val diagram = Diagram(nameChanger)
display(render("nameChanger", diagram))
}
}
Looks like a bug/limitation of shapeless (reftree doesn’t have any macros of its own). But I am wondering how a diagram can be automatically derived for NameChanger. It’s a sealed trait with only a private anonymous subclass, and that subclass does not have any attributes. I don’t think shapeless can support that (see https://github.com/milessabin/shapeless/wiki/Feature-overview:-shapeless-2.0.0#generic-representation-of-sealed-families-of-case-classes), but if it did, what output would you expect?