summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormihaylov <mihaylov@epfl.ch>2006-05-18 10:50:55 +0000
committermihaylov <mihaylov@epfl.ch>2006-05-18 10:50:55 +0000
commitb9f274691afa6ec54facf3ca56eeb8a04ccff505 (patch)
tree36416c890518f4dee210d1a73290a86a56cd1419 /src
parentac5aa786a066c2647e68775692adfc8e81156fa4 (diff)
downloadscala-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
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala40
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Constants.scala21
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala3
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);