Reputation: 1450
Is it possible to make Scala (or Java called from Scala) check whether a resource is missing at compile time and throw a compile error if it's missing?
I'm working on a large Java/Scala hybrid project with many developers and I'm providing a Scala component that kicks in near the end of the system run. So if my component throws a missing resource runtime error, it's only discovered very late. I try to make sure that my resource is there so this doesn't happen. But several times already, the head engineer decided to shift things around, my resources changed paths, I wasn't aware so didn't change my code, then the code died at my component because of the missing resource. We're working on more centralized resource control, but in the meantime, would it be possible to make Scala throw a compile error over a missing resource? Mostly curiosity, but might implement if it turns out simple enough.
ETA: There's questions about build tools. It's not straightforward because everyone is using their own environment. Some are using eclipse, some netbeans, I'm using emacs+sbt. So even if I insert a check for sbt, it won't matter to other people who are using eclipse.
Upvotes: 1
Views: 859
Reputation: 53348
In 2.10, it is definitely possible with help of a macro and string interpolation:
object CheckResource {
import scala.reflect.macros.Context
import scala.language.experimental.macros
implicit class StringResource(sc: StringContext) {
def res(): String = macro __res
}
def __res(c: Context)(): c.Expr[String] = {
import c.universe._
val str = c.prefix.tree match {
case Apply(_, List(Apply(_, List(Literal(Constant(const: String)))))) =>
if (!new java.io.File(const).exists())
c.abort(c.enclosingPosition, s"file '$const' does not exist")
else Literal(Constant(const))
}
c.Expr(str)
}
}
scala> import CheckResource._
import CheckResource._
scala> val file = new java.io.File("test")
file: java.io.File = test
scala> file.createNewFile
res7: Boolean = true
scala> res"test"
res8: String = test
scala> file.delete
res9: Boolean = true
scala> res"test"
<console>:12: error: file 'test' does not exist
res"test"
^
Upvotes: 3
Reputation: 10852
Actually, you probably could do this in Scala 2.10 with a macro - a macro being a piece of code that runs at compile time.
Whether it's a sensible thing to do is another question altogether (just because it's available at compile time doesn't necessarily mean that it will be at runtime, or vice-versa?). I would suggest that Richard's suggestion of doing something in your build tool is probably more sensible.
Upvotes: 2
Reputation: 8463
No, you can't induce the compiler to make this check for you.
Yes, ant/maven/buildr/sbt can do this check for you.
If you'd like more details, provide information on your build tools.
Upvotes: 0