@@ -3,6 +3,7 @@ package twirllib
33
44import java .io .File
55import java .net .URLClassLoader
6+ import java .{lang , util }
67
78import ammonite .ops .{Path , ls }
89import mill .eval .PathRef
@@ -14,43 +15,41 @@ import scala.reflect.runtime.universe._
1415class TwirlWorker {
1516
1617 private var twirlInstanceCache = Option .empty[(Long , TwirlWorkerApi )]
18+ import scala .collection .JavaConverters ._
1719
1820 private def twirl (twirlClasspath : Agg [Path ]) = {
1921 val classloaderSig = twirlClasspath.map(p => p.toString().hashCode + p.mtime.toMillis).sum
2022 twirlInstanceCache match {
2123 case Some ((sig, instance)) if sig == classloaderSig => instance
2224 case _ =>
25+ val cl = new URLClassLoader (twirlClasspath.map(_.toIO.toURI.toURL).toArray)
26+ val twirlCompilerClass = cl.loadClass(" play.japi.twirl.compiler.TwirlCompiler" )
27+ // Use the Java API (available in Twirl 1.3+)
28+ // Using reflection on a method with "Seq[String] = Nil" parameter type does not seem to work.
29+
30+ // REMIND: Unable to call the compile method with a primitive boolean
31+ // codec and inclusiveDot will not be available
32+ val compileMethod = twirlCompilerClass.getMethod(" compile" ,
33+ classOf [java.io.File ],
34+ classOf [java.io.File ],
35+ classOf [java.io.File ],
36+ classOf [java.lang.String ],
37+ classOf [util.Collection [java.lang.String ]],
38+ classOf [util.List [java.lang.String ]])
39+
2340 val instance = new TwirlWorkerApi {
2441 override def compileTwirl (source : File ,
2542 sourceDirectory : File ,
2643 generatedDirectory : File ,
2744 formatterType : String ,
2845 additionalImports : Seq [String ] = Nil ,
29- constructorAnnotations : Seq [String ] = Nil ,
30- codec : Codec = Codec (scala.util.Properties .sourceEncoding),
31- inclusiveDot : Boolean = false ) {
32- val cl = new URLClassLoader (twirlClasspath.map(_.toIO.toURI.toURL).toArray)
33- val runtime = runtimeMirror(cl)
34- val moduleMirror = runtime.reflectModule(runtime.staticModule(" play.twirl.compiler.TwirlCompiler" ))
35- val moduleInstance = moduleMirror.instance
36- val instanceMirror = runtime.reflect(moduleInstance)
37- val compileSymbol = instanceMirror.symbol.typeSignature.member(TermName (" compile" )).asMethod
38- // FIXME: type erasure, unable to call "play.twirl.compiler.TwirlCompiler.compile" function
39- // https://github.com/playframework/twirl/blob/dd56444cf9ea2f95ef3961d3af911561f846df50/compiler/src/main/scala/play/twirl/compiler/TwirlCompiler.scala#L167
40-
41- // scala.MatchError: List() (of class scala.collection.immutable.Nil$)
42- // at scala.reflect.runtime.JavaMirrors$JavaMirror$DerivedValueClassMetadata.unboxer$lzycompute(JavaMirrors.scala:270)
43- // at scala.reflect.runtime.JavaMirrors$JavaMirror$DerivedValueClassMetadata.unboxer(JavaMirrors.scala:269)
44- // at scala.reflect.runtime.JavaMirrors$JavaMirror$MethodMetadata.paramUnboxers(JavaMirrors.scala:416)
45- // at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaTransformingMethodMirror.apply(JavaMirrors.scala:435)
46- instanceMirror.reflectMethod(compileSymbol)(source,
46+ constructorAnnotations : Seq [String ] = Nil ) {
47+ val o = compileMethod.invoke(null , source,
4748 sourceDirectory,
4849 generatedDirectory,
4950 formatterType,
50- additionalImports,
51- constructorAnnotations,
52- codec,
53- inclusiveDot)
51+ additionalImports.asJava,
52+ constructorAnnotations.asJava)
5453 }
5554 }
5655 twirlInstanceCache = Some ((classloaderSig, instance))
@@ -95,9 +94,7 @@ trait TwirlWorkerApi {
9594 generatedDirectory : File ,
9695 formatterType : String ,
9796 additionalImports : Seq [String ] = Nil ,
98- constructorAnnotations : Seq [String ] = Nil ,
99- codec : Codec = Codec (scala.util.Properties .sourceEncoding),
100- inclusiveDot : Boolean = false )
97+ constructorAnnotations : Seq [String ] = Nil )
10198}
10299
103100object TwirlWorkerApi {
0 commit comments