diff options
Diffstat (limited to 'contrib/twirllib/src')
-rw-r--r-- | contrib/twirllib/src/mill/twirllib/TwirlModule.scala | 3 | ||||
-rw-r--r-- | contrib/twirllib/src/mill/twirllib/TwirlWorker.scala | 58 |
2 files changed, 48 insertions, 13 deletions
diff --git a/contrib/twirllib/src/mill/twirllib/TwirlModule.scala b/contrib/twirllib/src/mill/twirllib/TwirlModule.scala index 2df70a1f..8f735f3a 100644 --- a/contrib/twirllib/src/mill/twirllib/TwirlModule.scala +++ b/contrib/twirllib/src/mill/twirllib/TwirlModule.scala @@ -33,8 +33,7 @@ trait TwirlModule extends mill.Module { ) } - // REMIND currently it's not possible to override these default settings - private def twirlAdditionalImports: Seq[String] = Nil + def twirlAdditionalImports: Seq[String] = Nil private def twirlConstructorAnnotations: Seq[String] = Nil diff --git a/contrib/twirllib/src/mill/twirllib/TwirlWorker.scala b/contrib/twirllib/src/mill/twirllib/TwirlWorker.scala index ce8175a6..b8fe9c66 100644 --- a/contrib/twirllib/src/mill/twirllib/TwirlWorker.scala +++ b/contrib/twirllib/src/mill/twirllib/TwirlWorker.scala @@ -20,21 +20,43 @@ class TwirlWorker { case Some((sig, instance)) if sig == classloaderSig => instance case _ => val cl = new URLClassLoader(twirlClasspath.map(_.toIO.toURI.toURL).toArray, null) - val twirlCompilerClass = cl.loadClass("play.twirl.compiler.TwirlCompiler") + + // Switched to using the java api because of the hack-ish thing going on later. + // + // * we'll need to construct a collection of additional imports + // * it will need to consider the defaults + // * and add the user-provided additional imports + // * the default collection in scala api is a Seq[String] + // * but it is defined in a different classloader (namely in cl) + // * so we can not construct our own Seq and pass it to the method - it will be from our classloader, and not compatible + // * the java api has a Collection as the type for this param, for which it is much more doable to append things to it using reflection + // + // NOTE: I tried creating the cl classloader passing the current classloader as the parent: + // val cl = new URLClassLoader(twirlClasspath.map(_.toIO.toURI.toURL).toArray, getClass.getClassLoader) + // in that case it was possible to cast the default to a Seq[String], construct our own Seq[String], and pass it to the method invoke- it was compatible. + // And the tests passed. But when run in a different mill project, I was getting exceptions like this: + // scala.reflect.internal.MissingRequirementError: object scala in compiler mirror not found. + + val twirlCompilerClass = cl.loadClass("play.japi.twirl.compiler.TwirlCompiler") + + // this one is only to get the codec: Codec parameter default value + val twirlScalaCompilerClass = cl.loadClass("play.twirl.compiler.TwirlCompiler") + val compileMethod = twirlCompilerClass.getMethod("compile", classOf[java.io.File], classOf[java.io.File], classOf[java.io.File], classOf[java.lang.String], - cl.loadClass("scala.collection.Seq"), - cl.loadClass("scala.collection.Seq"), + cl.loadClass("java.util.Collection"), + cl.loadClass("java.util.List"), cl.loadClass("scala.io.Codec"), classOf[Boolean]) - val defaultAdditionalImportsMethod = twirlCompilerClass.getMethod("compile$default$5") - val defaultConstructorAnnotationsMethod = twirlCompilerClass.getMethod("compile$default$6") - val defaultCodecMethod = twirlCompilerClass.getMethod("compile$default$7") - val defaultFlagMethod = twirlCompilerClass.getMethod("compile$default$8") + val arrayListClass = cl.loadClass("java.util.ArrayList") + val hashSetClass = cl.loadClass("java.util.HashSet") + + val defaultAdditionalImportsMethod = twirlCompilerClass.getField("DEFAULT_IMPORTS") + val defaultCodecMethod = twirlScalaCompilerClass.getMethod("compile$default$7") val instance = new TwirlWorkerApi { override def compileTwirl(source: File, @@ -45,14 +67,28 @@ class TwirlWorker { constructorAnnotations: Seq[String], codec: Codec, inclusiveDot: Boolean) { + val defaultAdditionalImports = defaultAdditionalImportsMethod.get(null) // unmodifiable collection + // copying it into a modifiable hash set and adding all additional imports + val allAdditionalImports = + hashSetClass + .getConstructor(cl.loadClass("java.util.Collection")) + .newInstance(defaultAdditionalImports) + .asInstanceOf[Object] + val hashSetAddMethod = + allAdditionalImports + .getClass + .getMethod("add", classOf[Object]) + additionalImports.foreach(hashSetAddMethod.invoke(allAdditionalImports, _)) + val o = compileMethod.invoke(null, source, sourceDirectory, generatedDirectory, formatterType, - defaultAdditionalImportsMethod.invoke(null), - defaultConstructorAnnotationsMethod.invoke(null), + allAdditionalImports, + arrayListClass.newInstance().asInstanceOf[Object], // empty list seems to be the default defaultCodecMethod.invoke(null), - defaultFlagMethod.invoke(null)) + Boolean.box(false) + ) } } twirlInstanceCache = Some((classloaderSig, instance)) @@ -89,7 +125,7 @@ class TwirlWorker { sourceDirectories.foreach(compileTwirlDir) val zincFile = ctx.dest / 'zinc - val classesDir = ctx.dest / 'html + val classesDir = ctx.dest mill.eval.Result.Success(CompilationResult(zincFile, PathRef(classesDir))) } |