diff options
author | mihaylov <mihaylov@epfl.ch> | 2006-05-18 10:50:55 +0000 |
---|---|---|
committer | mihaylov <mihaylov@epfl.ch> | 2006-05-18 10:50:55 +0000 |
commit | b9f274691afa6ec54facf3ca56eeb8a04ccff505 (patch) | |
tree | 36416c890518f4dee210d1a73290a86a56cd1419 | |
parent | ac5aa786a066c2647e68775692adfc8e81156fa4 (diff) | |
download | scala-b9f274691afa6ec54facf3ca56eeb8a04ccff505.tar.gz scala-b9f274691afa6ec54facf3ca56eeb8a04ccff505.tar.bz2 scala-b9f274691afa6ec54facf3ca56eeb8a04ccff505.zip |
Treat Java enums as constants - allows their us...
Treat Java enums as constants - allows their use as attribute arguments
3 files changed, 29 insertions, 35 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 4d73965840..17f02944e0 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -188,7 +188,7 @@ abstract class GenJVM extends SubComponent { for (val Pair(typ, consts) <- attributes; typ.symbol.hasFlag(Flags.JAVA)) { nattr = nattr + 1; - val jtype = javaType(toTypeKind(typ)); + val jtype = javaType(typ); buf.putShort(cpool.addUtf8(jtype.getSignature()).toShort); assert(consts.length == 1, consts.toString()) buf.putShort(1.toShort); // for now only 1 constructor parameter @@ -220,11 +220,15 @@ abstract class GenJVM extends SubComponent { buf.put('D'.toByte) buf.putShort(cpool.addDouble(const.doubleValue).toShort) case StringTag => - buf.put('s'.toByte); + buf.put('s'.toByte) buf.putShort(cpool.addUtf8(const.stringValue).toShort) case ClassTag => - buf.put('c'.toByte); - buf.putShort(cpool.addUtf8(javaType(toTypeKind(const.typeValue)).getSignature()).toShort) + buf.put('c'.toByte) + buf.putShort(cpool.addUtf8(javaType(const.typeValue).getSignature()).toShort) + case EnumTag => + buf.put('e'.toByte) + buf.putShort(cpool.addUtf8(javaType(const.tpe).getSignature()).toShort) + buf.putShort(cpool.addUtf8(const.symbolValue.name.toString()).toShort) //case NullTag => AllRefClass.tpe } } @@ -265,7 +269,7 @@ abstract class GenJVM extends SubComponent { val jfield = jclass.addNewField(javaFlags(f.symbol) | attributes, javaName(f.symbol), - javaType(toTypeKind(f.symbol.tpe))); + javaType(f.symbol.tpe)); addAttributes(jfield, f.symbol.attributes) } @@ -278,7 +282,7 @@ abstract class GenJVM extends SubComponent { endPC.clear; computeLocalVarsIndex(m); - var resTpe = javaType(toTypeKind(m.symbol.tpe.resultType)); + var resTpe = javaType(m.symbol.tpe.resultType); if (m.symbol.isClassConstructor) resTpe = JType.VOID; @@ -389,7 +393,7 @@ abstract class GenJVM extends SubComponent { val mirrorMethod = mirrorClass .addNewMethod(ACC_PUBLIC | ACC_FINAL | ACC_STATIC, javaName(m), - javaType(toTypeKind(m.tpe.resultType)), + javaType(m.tpe.resultType), javaTypes(paramJavaTypes), paramNames); val mirrorCode = mirrorMethod.getCode().asInstanceOf[JExtendedCode]; @@ -533,6 +537,11 @@ abstract class GenJVM extends SubComponent { jcode.emitPUSH(classLiteral(kind)); else jcode.emitPUSH(javaType(kind).asInstanceOf[JReferenceType]); + case EnumTag => + val sym = const.symbolValue + jcode.emitGETSTATIC(javaName(sym.owner), + javaName(sym), + javaType(const.tpe)) case _ => abort("Unknown constant value: " + const); } @@ -1100,7 +1109,6 @@ abstract class GenJVM extends SubComponent { def javaType(t: TypeKind): JType = t match { case UNIT => JType.VOID; - case BOOL => JType.BOOLEAN; case BYTE => JType.BYTE; case SHORT => JType.SHORT; @@ -1113,14 +1121,15 @@ abstract class GenJVM extends SubComponent { case ARRAY(elem) => new JArrayType(javaType(elem)); } + def javaType(t: Type): JType = javaType(toTypeKind(t)) + def javaType(s: Symbol): JType = if (s.isMethod) new JMethodType( - if (s.isClassConstructor) - JType.VOID else javaType(toTypeKind(s.tpe.resultType)), - javaTypes(s.tpe.paramTypes map toTypeKind)) + if (s.isClassConstructor) JType.VOID else javaType(s.tpe.resultType), + s.tpe.paramTypes.map(javaType).toArray) else - javaType(toTypeKind(s.tpe)); + javaType(s.tpe); def javaTypes(ts: List[TypeKind]): Array[JType] = { val res = new Array[JType](ts.length); @@ -1129,13 +1138,6 @@ abstract class GenJVM extends SubComponent { res } -// def javaTypes(syms: List[Symbol]): Array[JType] = { -// val res = new Array[JType](syms.length); -// var i = 0; -// syms foreach ( s => { res(i) = javaType(toTypeKind(s.tpe)); i = i + 1; } ); -// res -// } - def getFile(cls: JClass, suffix: String): String = { val path = cls.getName().replace('.', File.separatorChar); settings.outdir.value + File.separatorChar + path + suffix diff --git a/src/compiler/scala/tools/nsc/symtab/Constants.scala b/src/compiler/scala/tools/nsc/symtab/Constants.scala index e040a0c84b..be12f93aa4 100644 --- a/src/compiler/scala/tools/nsc/symtab/Constants.scala +++ b/src/compiler/scala/tools/nsc/symtab/Constants.scala @@ -24,6 +24,7 @@ trait Constants requires SymbolTable { final val StringTag = LITERALstring - LITERAL; final val NullTag = LITERALnull - LITERAL; final val ClassTag = LITERALclass - LITERAL; + final val EnumTag = ClassTag + 1 case class Constant(value: Any) { @@ -39,6 +40,7 @@ trait Constants requires SymbolTable { else if (value.isInstanceOf[double]) DoubleTag else if (value.isInstanceOf[String]) StringTag else if (value.isInstanceOf[Type]) ClassTag + else if (value.isInstanceOf[Symbol]) EnumTag else if (value == null) NullTag else throw new Error("bad constant value: " + value); @@ -55,6 +57,7 @@ trait Constants requires SymbolTable { case StringTag => StringClass.tpe case NullTag => AllRefClass.tpe case ClassTag => ClassClass.tpe + case EnumTag => symbolValue.owner.linkedClass.tpe } /** We need the equals method to take account of tags as well as values */ @@ -132,21 +135,7 @@ trait Constants requires SymbolTable { case DoubleTag => value.asInstanceOf[double].asInstanceOf[float] case _ => throw new Error("value " + value + " is not a float") } -/* - def doubleValue: double = { - System.out.println("doubleValue " + tag + " " + value); - tag match { - case ByteTag => System.out.println("Byte"); value.asInstanceOf[byte].asInstanceOf[double] - case ShortTag => System.out.println("Short"); value.asInstanceOf[short].asInstanceOf[double] - case CharTag => System.out.println("Char"); value.asInstanceOf[char].asInstanceOf[double] - case IntTag => System.out.println("Int"); value.asInstanceOf[int].asInstanceOf[double] - case LongTag => System.out.println("Long"); value.asInstanceOf[long].asInstanceOf[double] - case FloatTag => System.out.println("Float"); value.asInstanceOf[float].asInstanceOf[double] - case DoubleTag => System.out.println("Double"); value.asInstanceOf[double] - case _ => System.out.println("error"); throw new Error("value " + value + " is not a double") - } - } -*/ + def doubleValue: double = tag match { case ByteTag => value.asInstanceOf[byte].asInstanceOf[double] case ShortTag => value.asInstanceOf[short].asInstanceOf[double] @@ -192,6 +181,8 @@ trait Constants requires SymbolTable { def typeValue: Type = value.asInstanceOf[Type] + def symbolValue: Symbol = value.asInstanceOf[Symbol] + override def hashCode(): int = if (value == null) 0 else value.hashCode() * 41 + 17; } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 0bd20198a4..93ae48e131 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -309,7 +309,8 @@ abstract class ClassfileParser { val name = pool.getName(in.nextChar); val info = pool.getType(in.nextChar); val sym = getOwner(jflags) - .newValue(Position.NOPOS, name).setFlag(sflags).setInfo(info); + .newValue(Position.NOPOS, name).setFlag(sflags); + sym.setInfo(if ((jflags & JAVA_ACC_ENUM) == 0) info else ConstantType(Constant(sym))); setPrivateWithin(sym, jflags); parseAttributes(sym, info); getScope(jflags).enter(sym); |