Skip to content

Commit

Permalink
Better support for non-default constructors.
Browse files Browse the repository at this point in the history
  • Loading branch information
psuter committed Dec 6, 2012
1 parent f6ff475 commit a93a8dd
Showing 1 changed file with 23 additions and 9 deletions.
32 changes: 23 additions & 9 deletions src/main/scala/cafebabe/ClassFile.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,17 @@ class ClassFile(val className: String, parentName: Option[String] = None) extend
def addMethod(retTpe: String, name: String, args: String*): MethodHandler = addMethod(retTpe,name,args.toList)

def addMethod(retTpe: String, name: String, args: List[String]): MethodHandler = {
val concatArgs = args.mkString("")

val accessFlags: U2 = defaultMethodAccessFlags
val nameIndex: U2 = constantPool.addString(name)
val descriptorIndex: U2 = constantPool.addString(args.toList.mkString("(", "", ")") + retTpe)
val descriptorIndex: U2 = constantPool.addString(
"(" + concatArgs + ")" + retTpe
)
val code = CodeAttributeInfo(codeNameIndex)
val inf = MethodInfo(accessFlags, nameIndex, descriptorIndex, List(code))
methods = methods ::: (inf :: Nil)

val concatArgs = args.mkString("")

new MethodHandler(inf, code, constantPool, concatArgs)
}
Expand All @@ -85,21 +88,32 @@ class ClassFile(val className: String, parentName: Option[String] = None) extend
handler
}

/** Adds a default constructor. */
def addDefaultConstructor: MethodHandler = {
val accessFlags: U2 = Flags.METHOD_ACC_PUBLIC
val nameIndex: U2 = constantPool.addString(constructorName)
val descriptorIndex: U2 = constantPool.addString(constructorSig)
/** Adds a constructor to the class. Constructor code should always start by invoking a constructor from the super class. */
def addConstructor(args : String*) : MethodHandler = addConstructor(args.toList)

def addConstructor(args : List[String]) : MethodHandler = {
val concatArgs = args.mkString("")

val accessFlags : U2 = Flags.METHOD_ACC_PUBLIC
val nameIndex : U2 = constantPool.addString(constructorName)
val descriptorIndex : U2 = constantPool.addString(
"(" + concatArgs + ")V"
)
val code = CodeAttributeInfo(codeNameIndex)
val inf = MethodInfo(accessFlags, nameIndex, descriptorIndex, List(code))
methods = methods ::: (inf :: Nil)
val mh = new MethodHandler(inf, code, constantPool, "")
val mh = new MethodHandler(inf, code, constantPool, concatArgs)
mh
}

/** Adds a default constructor. */
def addDefaultConstructor: MethodHandler = {
import ByteCodes._
import AbstractByteCodes._

val mh = addConstructor(Nil)
mh.codeHandler << ALOAD_0
mh.codeHandler << InvokeSpecial(superClassName, constructorName, constructorSig)
mh.codeHandler << InvokeSpecial(superClassName, constructorName, "()V")
mh.codeHandler << RETURN
mh.codeHandler.freeze
mh
Expand Down

0 comments on commit a93a8dd

Please sign in to comment.