Is it possible to use scalap from a scala script?

627 Views Asked by At

I am using scalap to read out the field names of some case classes (as discussed in this question). Both the case classes and the code that uses scalap to analyze them have been compiled and put into a jar file on the classpath.

Now I want to run a script that uses this code, so I followed the instructions and came up with something like

::#!
@echo off
call scala -classpath *;./libs/* %0 %*
goto :eof
::!#
//Code relying on pre-compiled code that uses scalap

which does not work:

java.lang.ClassCastException: scala.None$ cannot be cast to scala.Option at scala.tools.nsc.interpreter.ByteCode$.caseParamNamesForPath(ByteCode. scala:45) at scala.tools.nsc.interpreter.ProductCompletion.caseNames(ProductComple tion.scala:22)

However, the code works just fine when I compile everything. I played around with additional scala options like -savecompiled, but this did not help. Is this a bug, or can't this work in principle? (If so, could someone explain why not? As I said, the case classes that shall be analyzed by scalap are compiled.)

Note: I use Scala 2.9.1-1.

EDIT

Here is what I am essentially trying to do (providing a simple way to create multiple instances of a case class):

//This is pre-compiled:
import scala.tools.nsc.interpreter.ProductCompletion
//...
trait MyFactoryTrait[T <: MyFactoryTrait[T] with Product] {
  this: T =>

  private[this] val copyMethod = this.getClass.getMethods.find(x => x.getName == "copy").get

  lazy val productCompletion = new ProductCompletion(this)

  /** The names of all specified fields. */
  lazy val fieldNames = productCompletion.caseNames //<- provokes the exception (see above)

  def createSeq(...):Seq[T] = {
    val x = fieldNames map { ... } // <- this method uses the fieldNames value
    //[...] invoke copyMethod to create instances
  }   
 // ...
}

//This is pre-compiled too: 
case class MyCaseClass(x: Int = 0, y: Int = 0) extends MyFactoryTrait[MyCaseClass]

//This should be interpreted (but crashes):
val seq = MyCaseClass().createSeq(...)

Note: I moved on to Scala 2.9.2, the error stays the same (so probably not a bug).

1

There are 1 best solutions below

0
On

This is a bug in the compiler:

  • If you run the program inside an ide, for example Intellij IDEA the code is executed fine, however no fields names are found.
  • If you run it from command line using scala, you obtain the error you mentioned.

There is no way type-safe could should ever compiler and throw a runtime ClassCastException.

Please open a bug at https://issues.scala-lang.org/secure/Dashboard.jspa