scala.internal.tasty.TastyUnpickler.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of artifacts_2.11 Show documentation
Show all versions of artifacts_2.11 Show documentation
Scala.meta's APIs for reflecting artifacts of Scala ecosystem
The newest version!
// NOTE: copy/pasted from https://github.com/lampepfl/dotty/tree/1962ada58fcd2333a2e40179ab0ac6efb6167ed2
package scala.meta
package internal
package tasty
import scala.collection.mutable
import TastyFormat._
import java.util.UUID
object TastyUnpickler {
class UnpickleException(msg: String) extends Exception(msg)
abstract class SectionUnpickler[R](val name: String) {
def unpickle(reader: TastyReader, tastyName: TastyName.Table): R
}
}
import TastyUnpickler._
class TastyUnpickler(reader: TastyReader) {
import reader._
def this(bytes: Array[Byte]) = this(new TastyReader(bytes))
private val sectionReader = new mutable.HashMap[String, TastyReader]
val tastyName = new TastyName.Table
def check(cond: Boolean, msg: => String) =
if (!cond) throw new UnpickleException(msg)
def readString(): String = {
val TastyName.Simple(name) = tastyName(readNameRef())
name.toString
}
def readName(): TastyName = {
import TastyName._
val tag = readByte()
val length = readNat()
val start = currentAddr
val end = start + length
val result = tag match {
case UTF8 =>
goto(end)
Simple(new String(bytes, start.index, length, java.nio.charset.Charset.forName("UTF-8")))
case QUALIFIED =>
Qualified(readNameRef(), readNameRef())
case SIGNED =>
val original = readNameRef()
val result = readNameRef()
val params = until(end)(readNameRef())
Signed(original, params, result)
case EXPANDED =>
Expanded(readNameRef(), readNameRef())
case OBJECTCLASS =>
ModuleClass(readNameRef())
case SUPERACCESSOR =>
SuperAccessor(readNameRef())
case DEFAULTGETTER =>
DefaultGetter(readNameRef(), readNat())
case SHADOWED =>
Shadowed(readNameRef())
}
assert(currentAddr == end, s"bad name $result $start $currentAddr $end")
result
}
private def readHeader(): UUID = {
for (i <- 0 until header.length)
check(readByte() == header(i), "not a TASTy file")
val major = readNat()
val minor = readNat()
check(major == MajorVersion && minor <= MinorVersion,
s"""TASTy signature has wrong version.
| expected: $MajorVersion.$MinorVersion
| found : $major.$minor""".stripMargin)
new UUID(readUncompressedLong(), readUncompressedLong())
}
val uuid = readHeader()
locally {
until(readEnd()) { tastyName.add(readName()) }
while (!isAtEnd) {
val secName = readString()
val secEnd = readEnd()
sectionReader(secName) = new TastyReader(bytes, currentAddr.index, secEnd.index, currentAddr.index)
goto(secEnd)
}
}
def unpickle[R](sec: SectionUnpickler[R]): Option[R] =
for (reader <- sectionReader.get(sec.name)) yield
sec.unpickle(reader, tastyName)
}