Skip to content

Commit f277471

Browse files
committed
Use the Java API as a workaround
1 parent e093631 commit f277471

File tree

2 files changed

+24
-27
lines changed

2 files changed

+24
-27
lines changed

twirllib/src/mill/twirllib/TwirlWorker.scala

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package twirllib
33

44
import java.io.File
55
import java.net.URLClassLoader
6+
import java.{lang, util}
67

78
import ammonite.ops.{Path, ls}
89
import mill.eval.PathRef
@@ -14,43 +15,41 @@ import scala.reflect.runtime.universe._
1415
class 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

103100
object TwirlWorkerApi {

twirllib/test/src/mill/twirllib/HelloWorldTests.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ object HelloWorldTests extends TestSuite {
2222

2323
object HelloWorld extends HelloBase {
2424
object core extends HelloWorldModule {
25-
override def twirlVersion = "1.2.1"
25+
override def twirlVersion = "1.3.15"
2626
}
2727
}
2828

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

5252
assert(
53-
result == "1.2.1",
53+
result == "1.3.15",
5454
evalCount > 0
5555
)
5656
}

0 commit comments

Comments
 (0)