Skip to content

Commit

Permalink
Use the Java API as a workaround
Browse files Browse the repository at this point in the history
  • Loading branch information
ggrossetie committed Apr 2, 2018
1 parent 648d078 commit 2fef9f0
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 27 deletions.
47 changes: 22 additions & 25 deletions twirllib/src/mill/twirllib/TwirlWorker.scala
Expand Up @@ -3,6 +3,7 @@ package twirllib

import java.io.File
import java.net.URLClassLoader
import java.{lang, util}

import ammonite.ops.{Path, ls}
import mill.eval.PathRef
Expand All @@ -14,43 +15,41 @@ import scala.reflect.runtime.universe._
class TwirlWorker {

private var twirlInstanceCache = Option.empty[(Long, TwirlWorkerApi)]
import scala.collection.JavaConverters._

private def twirl(twirlClasspath: Agg[Path]) = {
val classloaderSig = twirlClasspath.map(p => p.toString().hashCode + p.mtime.toMillis).sum
twirlInstanceCache match {
case Some((sig, instance)) if sig == classloaderSig => instance
case _ =>
val cl = new URLClassLoader(twirlClasspath.map(_.toIO.toURI.toURL).toArray)
val twirlCompilerClass = cl.loadClass("play.japi.twirl.compiler.TwirlCompiler")
// Use the Java API (available in Twirl 1.3+)
// Using reflection on a method with "Seq[String] = Nil" parameter type does not seem to work.

// REMIND: Unable to call the compile method with a primitive boolean
// codec and inclusiveDot will not be available
val compileMethod = twirlCompilerClass.getMethod("compile",
classOf[java.io.File],
classOf[java.io.File],
classOf[java.io.File],
classOf[java.lang.String],
classOf[util.Collection[java.lang.String]],
classOf[util.List[java.lang.String]])

val instance = new TwirlWorkerApi {
override def compileTwirl(source: File,
sourceDirectory: File,
generatedDirectory: File,
formatterType: String,
additionalImports: Seq[String] = Nil,
constructorAnnotations: Seq[String] = Nil,
codec: Codec = Codec(scala.util.Properties.sourceEncoding),
inclusiveDot: Boolean = false) {
val cl = new URLClassLoader(twirlClasspath.map(_.toIO.toURI.toURL).toArray)
val runtime = runtimeMirror(cl)
val moduleMirror = runtime.reflectModule(runtime.staticModule("play.twirl.compiler.TwirlCompiler"))
val moduleInstance = moduleMirror.instance
val instanceMirror = runtime.reflect(moduleInstance)
val compileSymbol = instanceMirror.symbol.typeSignature.member(TermName("compile")).asMethod
// FIXME: type erasure, unable to call "play.twirl.compiler.TwirlCompiler.compile" function
// https://github.com/playframework/twirl/blob/dd56444cf9ea2f95ef3961d3af911561f846df50/compiler/src/main/scala/play/twirl/compiler/TwirlCompiler.scala#L167

// scala.MatchError: List() (of class scala.collection.immutable.Nil$)
// at scala.reflect.runtime.JavaMirrors$JavaMirror$DerivedValueClassMetadata.unboxer$lzycompute(JavaMirrors.scala:270)
// at scala.reflect.runtime.JavaMirrors$JavaMirror$DerivedValueClassMetadata.unboxer(JavaMirrors.scala:269)
// at scala.reflect.runtime.JavaMirrors$JavaMirror$MethodMetadata.paramUnboxers(JavaMirrors.scala:416)
// at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaTransformingMethodMirror.apply(JavaMirrors.scala:435)
instanceMirror.reflectMethod(compileSymbol)(source,
constructorAnnotations: Seq[String] = Nil) {
val o = compileMethod.invoke(null, source,
sourceDirectory,
generatedDirectory,
formatterType,
additionalImports,
constructorAnnotations,
codec,
inclusiveDot)
additionalImports.asJava,
constructorAnnotations.asJava)
}
}
twirlInstanceCache = Some((classloaderSig, instance))
Expand Down Expand Up @@ -95,9 +94,7 @@ trait TwirlWorkerApi {
generatedDirectory: File,
formatterType: String,
additionalImports: Seq[String] = Nil,
constructorAnnotations: Seq[String] = Nil,
codec: Codec = Codec(scala.util.Properties.sourceEncoding),
inclusiveDot: Boolean = false)
constructorAnnotations: Seq[String] = Nil)
}

object TwirlWorkerApi {
Expand Down
4 changes: 2 additions & 2 deletions twirllib/test/src/mill/twirllib/HelloWorldTests.scala
Expand Up @@ -22,7 +22,7 @@ object HelloWorldTests extends TestSuite {

object HelloWorld extends HelloBase {
object core extends HelloWorldModule {
override def twirlVersion = "1.2.1"
override def twirlVersion = "1.3.15"
}
}

Expand Down Expand Up @@ -50,7 +50,7 @@ object HelloWorldTests extends TestSuite {
val Right((result, evalCount)) = eval.apply(HelloWorld.core.twirlVersion)

assert(
result == "1.2.1",
result == "1.3.15",
evalCount > 0
)
}
Expand Down

0 comments on commit 2fef9f0

Please sign in to comment.