@@ -3,104 +3,62 @@ package twirllib
33
44import java .io .File
55import java .net .URLClassLoader
6- import java .util
76
87import ammonite .ops .{Path , ls }
98import mill .eval .PathRef
109import mill .scalalib .CompilationResult
1110
1211import scala .io .Codec
13- import scala .reflect .runtime .universe ._
1412import scala .util .Properties
1513
1614class TwirlWorker {
1715
1816 private var twirlInstanceCache = Option .empty[(Long , TwirlWorkerApi )]
19- import scala .collection .JavaConverters ._
2017
2118 private def twirl (twirlClasspath : Agg [Path ]) = {
2219 val classloaderSig = twirlClasspath.map(p => p.toString().hashCode + p.mtime.toMillis).sum
2320 twirlInstanceCache match {
2421 case Some ((sig, instance)) if sig == classloaderSig => instance
2522 case _ =>
26- // callScalaAPI(twirlClasspath, classloaderSig)
27- callJavaAPI(twirlClasspath, classloaderSig)
28- }
29- }
30-
31- private def callJavaAPI (twirlClasspath : Agg [Path ], classloaderSig : Long ) = {
32- val cl = new URLClassLoader (twirlClasspath.map(_.toIO.toURI.toURL).toArray)
33- val twirlCompilerClass = cl.loadClass(" play.japi.twirl.compiler.TwirlCompiler" )
34- // Use the Java API (available in Twirl 1.3+)
35- // Using reflection on a method with "Seq[String] = Nil" parameter type does not seem to work.
36-
37- // REMIND: Unable to call the compile method with a primitive boolean
38- // codec and inclusiveDot will not be available
39- val compileMethod = twirlCompilerClass.getMethod(" compile" ,
40- classOf [File ],
41- classOf [File ],
42- classOf [File ],
43- classOf [String ],
44- classOf [util.Collection [String ]],
45- classOf [util.List [String ]])
46-
47- val instance = new TwirlWorkerApi {
48- override def compileTwirl (source : File ,
49- sourceDirectory : File ,
50- generatedDirectory : File ,
51- formatterType : String ,
52- additionalImports : Seq [String ] = Nil ,
53- constructorAnnotations : Seq [String ] = Nil ,
54- codec : Codec = Codec (Properties .sourceEncoding),
55- inclusiveDot : Boolean = false ) {
56- val o = compileMethod.invoke(null , source,
57- sourceDirectory,
58- generatedDirectory,
59- formatterType,
60- additionalImports.asJava,
61- constructorAnnotations.asJava)
62- }
63- }
64- twirlInstanceCache = Some ((classloaderSig, instance))
65- instance
66- }
67-
68- private def callScalaAPI (twirlClasspath : Agg [Path ], classloaderSig : Long ) = {
69- val cl = new URLClassLoader (twirlClasspath.map(_.toIO.toURI.toURL).toArray)
70- val runtime = runtimeMirror(cl)
71- val moduleMirror = runtime.reflectModule(runtime.staticModule(" play.twirl.compiler.TwirlCompiler" ))
72- val moduleInstance = moduleMirror.instance
73- val instanceMirror = runtime.reflect(moduleInstance)
74- val compileSymbol = instanceMirror.symbol.typeSignature.member(TermName (" compile" )).asMethod
75- // FIXME: type erasure, unable to call "play.twirl.compiler.TwirlCompiler.compile" function
76- // https://github.com/playframework/twirl/blob/dd56444cf9ea2f95ef3961d3af911561f846df50/compiler/src/main/scala/play/twirl/compiler/TwirlCompiler.scala#L167
77- val instance = new TwirlWorkerApi {
78- override def compileTwirl (source : File ,
79- sourceDirectory : File ,
80- generatedDirectory : File ,
81- formatterType : String ,
82- additionalImports : Seq [String ] = Nil ,
83- constructorAnnotations : Seq [String ] = Nil ,
84- codec : Codec = Codec (Properties .sourceEncoding),
85- inclusiveDot : Boolean = false ) {
86-
87- // scala.MatchError: List() (of class scala.collection.immutable.Nil$)
88- // at scala.reflect.runtime.JavaMirrors$JavaMirror$DerivedValueClassMetadata.unboxer$lzycompute(JavaMirrors.scala:270)
89- // at scala.reflect.runtime.JavaMirrors$JavaMirror$DerivedValueClassMetadata.unboxer(JavaMirrors.scala:269)
90- // at scala.reflect.runtime.JavaMirrors$JavaMirror$MethodMetadata.paramUnboxers(JavaMirrors.scala:416)
91- // at scala.reflect.runtime.JavaMirrors$JavaMirror$JavaTransformingMethodMirror.apply(JavaMirrors.scala:435)
92- instanceMirror.reflectMethod(compileSymbol)(source,
93- sourceDirectory,
94- generatedDirectory,
95- formatterType,
96- additionalImports,
97- constructorAnnotations,
98- codec,
99- inclusiveDot)
100- }
23+ val cl = new URLClassLoader (twirlClasspath.map(_.toIO.toURI.toURL).toArray)
24+ val twirlCompilerClass = cl.loadClass(" play.twirl.compiler.TwirlCompiler" )
25+ val compileMethod = twirlCompilerClass.getMethod(" compile" ,
26+ classOf [java.io.File ],
27+ classOf [java.io.File ],
28+ classOf [java.io.File ],
29+ classOf [java.lang.String ],
30+ cl.loadClass(" scala.collection.Seq" ),
31+ cl.loadClass(" scala.collection.Seq" ),
32+ cl.loadClass(" scala.io.Codec" ),
33+ classOf [Boolean ])
34+
35+ val defaultAdditionalImportsMethod = twirlCompilerClass.getMethod(" compile$default$5" )
36+ val defaultConstructorAnnotationsMethod = twirlCompilerClass.getMethod(" compile$default$6" )
37+ val defaultCodecMethod = twirlCompilerClass.getMethod(" compile$default$7" )
38+ val defaultFlagMethod = twirlCompilerClass.getMethod(" compile$default$8" )
39+
40+ val instance = new TwirlWorkerApi {
41+ override def compileTwirl (source : File ,
42+ sourceDirectory : File ,
43+ generatedDirectory : File ,
44+ formatterType : String ,
45+ additionalImports : Seq [String ] = Nil ,
46+ constructorAnnotations : Seq [String ] = Nil ,
47+ codec : Codec = Codec (Properties .sourceEncoding),
48+ inclusiveDot : Boolean = false ) {
49+ val o = compileMethod.invoke(null , source,
50+ sourceDirectory,
51+ generatedDirectory,
52+ formatterType,
53+ defaultAdditionalImportsMethod.invoke(additionalImports),
54+ defaultConstructorAnnotationsMethod.invoke(constructorAnnotations),
55+ defaultCodecMethod.invoke(codec),
56+ defaultFlagMethod.invoke(inclusiveDot))
57+ }
58+ }
59+ twirlInstanceCache = Some ((classloaderSig, instance))
60+ instance
10161 }
102- twirlInstanceCache = Some ((classloaderSig, instance))
103- instance
10462 }
10563
10664 def compile (twirlClasspath : Agg [Path ], sourceDirectories : Seq [Path ], dest : Path )
0 commit comments