Getting resource path files from the context of a scala macro

836 views Asked by At

I would like to make a macro that validates at compile time the existence of resources in other projects. Is it possible to get this information from the context?

  def example_impl(c: Context): c.Expr[Unit] = {
    import c.universe._
    //instead of  
    // val r = this.getClass().getResource("/file.txt")

    val r = c.somthing.getResource("/file.txt")
    //...
  }

It may not be possible. But if it is, I'd like to know how to do it.

2

There are 2 answers

2
Daniel C. Sobral On

Let's first consider what is a "resource". A resource is a file that can be found starting at the directories in the classpath. Note that, for this purpose, a jar file is a directory, as it stores a zip filesystem. A classpath is an environment information available when running Java.

And there's the fundamental problem: the Scala compiler does not know where these resources are! It receives source files to compile, maybe a destination directory, and it has its own classpaths, but they are related to running scalac, not to the code scalac is compiling.

It's not the compiler which "generates" the resources -- neither scalac, nor javac. It's other tools, such as jar (the command line tool), and usually called by still other tools, like the build systems (ant, maven, sbt).

Therefore, there's no information on where these resources can be found -- they are usually in directories separate from the source code anyway. You could use normal Scala file i/o support to traverse directories and such, but there's no "resource source" information available at compile time.

0
user833970 On

I did eventually get this working with Context.classpath.

https://github.com/marklemay/sacala-validation-macros/blob/master/macroHost2/src/main/scala/macroHost/Macros.scala

However I have only tested it within the scala IDE (eclipse). It would have to be tested it in sbt, intelij, maven and scalac before I was confident with it.