alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Scala example source code file (Classfile.scala)

This example Scala source code file (Classfile.scala) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Scala tags/keywords

bytearrayreader, constant_long, empty, int, int, list, list, member, nil, nil, pool, poolentry, poolentry, utf8

The Scala Classfile.scala source code

/*     ___ ____ ___   __   ___   ___
**    / _// __// _ | / /  / _ | / _ \    Scala classfile decoder
**  __\ \/ /__/ __ |/ /__/ __ |/ ___/    (c) 2003-2011, LAMP/EPFL
** /____/\___/_/ |_/____/_/ |_/_/
**
*/


package scala.tools.scalap


class Classfile(in: ByteArrayReader) {
  import Classfiles._
  
  type UTF8 = Pool#UTF8

  assert(in.nextInt == JAVA_MAGIC)
  val minorVersion = in.nextChar
  val majorVersion = in.nextChar
  val pool = new Pool()
  val flags = in.nextChar
  val classname = in.nextChar
  val superclass = in.nextChar
  val interfaces = readInterfaces
  val fields = readMembers(true)
  val methods = readMembers(false)
  val attribs = readAttribs
  def scalaSigAttribute = attribs find (_.toString == Main.SCALA_SIG)
  
  def readAttribs = {
    val n = in.nextChar
    var attribs: List[Attribute] = Nil
    var i = 0
    while (i < n) {
      attribs = Attribute(in.nextChar, in.nextBytes(in.nextInt)) :: attribs
      i = i + 1
    }
    attribs
  }

  def readMembers(field: Boolean) = {
    val n = in.nextChar
    var members: List[Member] = Nil
    var i = 0
    while (i < n) {
      members = Member(field, in.nextChar, in.nextChar, in.nextChar, readAttribs) :: members
      i = i + 1
    }
    members
  }

  def readInterfaces = {
    val n = in.nextChar
    var intfs: List[Int] = Nil
    var i = 0
    while (i < n) {
      intfs = in.nextChar :: intfs
      i = i + 1
    }
    intfs
  }

  class Pool() {
    sealed abstract class PoolEntry(val tag: Int) {
      def typeString = constantTagToString(tag)
    }
    case class UTF8(str: String) extends PoolEntry(CONSTANT_UTF8) { override def toString = "\"" + str + "\"" }
    case class ClassRef(classId: Int) extends PoolEntry(CONSTANT_CLASS) { override def toString = "Class(%s)".format(entries(classId)) }
    case class FieldRef(classId: Int, memberId: Int) extends PoolEntry(CONSTANT_FIELDREF)
    case class MethodRef(classId: Int, memberId: Int) extends PoolEntry(CONSTANT_METHODREF) { 
      // //Method java/lang/Object."<init>":()V
      override def toString() = "Method %s.\"%s\"".format(entries(classId), entries(memberId))
    }
    case class IntfMethodRef(classId: Int, memberId: Int) extends PoolEntry(CONSTANT_INTFMETHODREF)
    case class StringConst(strId: Int) extends PoolEntry(CONSTANT_STRING)
    case class IntegerConst(x: Int) extends PoolEntry(CONSTANT_INTEGER)
    case class FloatConst(x: Float) extends PoolEntry(CONSTANT_FLOAT)
    case class LongConst(x: Long) extends PoolEntry(CONSTANT_LONG)
    case class DoubleConst(x: Double) extends PoolEntry(CONSTANT_DOUBLE)
    case class NameAndType(nameId: Int, typeId: Int) extends PoolEntry(CONSTANT_NAMEANDTYPE)
    case object Empty extends PoolEntry(0) { }

    val entries = {
      val pool = new Array[PoolEntry](in.nextChar)
      var i = 1
      while (i < pool.length) {
        val tag = in.nextByte
        // Double sized entry
        if (tag == CONSTANT_LONG || tag == CONSTANT_DOUBLE) {
          pool(i) = if (tag == CONSTANT_LONG) LongConst(in.nextLong) else DoubleConst(in.nextDouble)
          i = i + 1
          pool(i) = Empty
        }
        else pool(i) = tag match {
          case CONSTANT_UTF8            => UTF8(in.nextUTF8(in.nextChar))
          case CONSTANT_UNICODE         => in.skip(in.nextChar) ; Empty
          case CONSTANT_CLASS           => ClassRef(in.nextChar)
          case CONSTANT_STRING          => StringConst(in.nextChar)
          case CONSTANT_FIELDREF        => FieldRef(in.nextChar, in.nextChar)
          case CONSTANT_METHODREF       => MethodRef(in.nextChar, in.nextChar)
          case CONSTANT_INTFMETHODREF   => IntfMethodRef(in.nextChar, in.nextChar)
          case CONSTANT_NAMEANDTYPE     => NameAndType(in.nextChar, in.nextChar)
          case CONSTANT_INTEGER         => IntegerConst(in.nextInt)
          case CONSTANT_FLOAT           => FloatConst(in.nextFloat)
        }
        
        i += 1
      }
      pool
    }
    
    lazy val length = entries.length
    def apply(x: Int) = entries(x)
    def stringOf(x: Int) = apply(x).toString
    override def toString = (
      for ((x, i) <- entries.zipWithIndex ; if x != null) yield 
        "const #%d = %s\t%s\n".format(i + 1, x.typeString, x)
    ).mkString
  }
    
  /** **/
  case class Member(field: Boolean, flags: Int, name: Int, tpe: Int, attribs: List[Attribute])
  case class Attribute(name: Int, data: Array[Byte]) {
    override def toString = (pool(name): @unchecked) match {
      case pool.UTF8(s) => s
    }
    def reader: ByteArrayReader = new ByteArrayReader(data)
  }
}

Other Scala examples (source code examples)

Here is a short list of links related to this Scala Classfile.scala source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.