summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLex Spoon <lex@lexspoon.org>2007-04-01 17:29:40 +0000
committerLex Spoon <lex@lexspoon.org>2007-04-01 17:29:40 +0000
commit3bf0245b79dfaed2b011f7e85979278c896265d7 (patch)
tree5e17575bebfad8da34123549ee9170eecc3e3f95 /src
parent4d8b3694b34d3a3f328e7eb7d55d75bc66d842c1 (diff)
downloadscala-3bf0245b79dfaed2b011f7e85979278c896265d7.tar.gz
scala-3bf0245b79dfaed2b011f7e85979278c896265d7.tar.bz2
scala-3bf0245b79dfaed2b011f7e85979278c896265d7.zip
- annotations on types use lifted reflect trees...
- annotations on types use lifted reflect trees instead of internal compiler trees - type annotations are pickled and unpickled in the class-file symbol tables - lifted code uses NoType in places it used to use null - type attributes propagate just a little bit further in the compiler than they used to (see changes to Type.scala)
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala8
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/PickleBuffer.scala6
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala64
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala317
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala220
-rw-r--r--src/compiler/scala/tools/nsc/transform/LiftCode.scala28
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
7 files changed, 616 insertions, 29 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 024d71b7e8..69853c37bc 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -1254,7 +1254,7 @@ trait Types requires SymbolTable {
if(attributes.isEmpty)
""
else
- attributes.mkString("[", "] [", "] ")
+ attributes.mkString("", " ", "")
attString + tp
}
@@ -1278,9 +1278,9 @@ trait Types requires SymbolTable {
// ---------------- methods forwarded to tp ------------------ \\
override def symbol: Symbol = tp.symbol
- override def singleDeref: Type = tp.singleDeref
- override def widen: Type = tp.widen
- override def deconst: Type = tp.deconst
+ override def singleDeref: Type = maybeRewrap(tp.singleDeref)
+ override def widen: Type = maybeRewrap(tp.widen)
+ override def deconst: Type = maybeRewrap(tp.deconst)
override def bounds: TypeBounds = {
val oftp = tp.bounds
oftp match {
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/PickleBuffer.scala b/src/compiler/scala/tools/nsc/symtab/classfile/PickleBuffer.scala
index fb8a3a5ed8..6e85d606d4 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/PickleBuffer.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/PickleBuffer.scala
@@ -123,6 +123,12 @@ class PickleBuffer(data: Array[byte], from: int, to: int) {
def until[T](end: int, op: () => T): List[T] =
if (readIndex == end) List() else op() :: until(end, op);
+ /** Perform operation <code>op</code> the number of
+ * times specified. Concatenate the results into a list.
+ */
+ def times[T](n: int, op: ()=>T): List[T] =
+ if (n == 0) List() else op() :: times(n-1, op)
+
/** Create an index.
*
* @return ...
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala b/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala
index 5b26443932..86077f5852 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala
@@ -102,15 +102,71 @@ object PickleFormat {
final val LITERALstring = 33
final val LITERALnull = 34
final val LITERALclass = 35
- final val ATTRIBUTE = 40
+ final val ATTRIBUTE = 40 // an attribute with constants
final val CHILDREN = 41
+
+ final val ANNOTATEDtpe = 42
+
+
+ final val ATTRIBTREE = 43 // an annotation with trees
+
+ final val REFLTREE = 44 // prefix saying that a prefix tree is coming
+ final val IDENTtree = 1
+ final val SELECTtree = 2
+ final val LITERALtree = 3
+ final val APPLYtree = 4
+ final val TYPEAPPLYtree = 5
+ final val FUNCTIONtree = 6
+ final val THIStree = 7
+ final val BLOCKtree = 8
+ final val NEWtree = 9
+ final val IFtree = 10
+ final val ASSIGNtree = 11
+ final val TARGETtree = 12
+ final val GOTOtree = 13
+ final val VALDEFtree = 14
+ final val CLASSDEFtree = 15
+ final val DEFDEFtree = 16
+ final val SUPERtree = 17
+ final val TEMPLATEtree = 18
+
+
+ final val REFLTYPE = 45 // prefix code that means a reflect type is coming
+ final val NOPREFIXrtpe = 1
+ final val NOrtpe = 2
+ final val NAMEDrtpe = 3
+ final val PREFIXEDrtpe = 4
+ final val SINGLErtpe = 5
+ final val THISrtpe = 6
+ final val APPLIEDrtpe = 7
+ final val TYPEBOUNDSrtpe = 8
+ final val METHODrtpe = 9
+ final val POLYrtpe = 10
+ final val IMPLICITMETHODrtpe = 11
+
+ final val REFLSYM = 46
+ final val CLASSrsym = 1
+ final val METHODrsym = 2
+ final val FIELDrsym = 3
+ final val TYPEFIELDrsym = 4
+ final val LOCALVALUErsym = 5
+ final val LOCALMETHODrsym = 6
+ final val NOSYMBOLrsym = 7
+ final val ROOTSYMBOLrsym = 8
+ final val LABELSYMBOLrsym = 9
+
+
final val firstSymTag = NONEsym
final val lastSymTag = VALsym
final val lastExtSymTag = EXTMODCLASSref
- final val firstTypeTag = NOtpe
- final val lastTypeTag = POLYtpe
- final val PosOffset = 64
+
+ //The following two are no longer accurate, because ATTRIBUTEDtpe
+ //is not in the same range as the other types
+ //final val firstTypeTag = NOtpe
+ //final val lastTypeTag = POLYtpe
+
+ final val PosOffset = 64
final val PosTYPEsym = PosOffset + TYPEsym
final val PosALIASsym = PosOffset + ALIASsym
final val PosCLASSsym = PosOffset + CLASSsym
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index c40cbba935..be95558b6b 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -123,6 +123,7 @@ abstract class Pickler extends SubComponent {
private def putSymbols(syms: List[Symbol]) =
syms foreach putSymbol
+
/** Store type and everythig it refers to in map <code>index</code>.
*
* @param tp ...
@@ -150,14 +151,104 @@ abstract class Pickler extends SubComponent {
case PolyType(tparams, restpe) =>
putType(restpe); putSymbols(tparams)
case AnnotatedType(attribs, tp) =>
- putType(tp) // the attributes should be stored, but it is not yet
- // decided how to handle that.
+ putType(tp); putAnnotations(attribs)
case _ =>
- throw new FatalError("bad type: " + tp + "(" + tp.getClass() + ")")
+ throw new FatalError("bad type: " + tp + "(" + tp.getClass + ")")
}
}
private def putTypes(tps: List[Type]): unit = tps foreach putType
+ private def putTree(tree: reflect.Tree): unit = if(putEntry(tree)) {
+ tree match {
+ case reflect.Ident(sym) => putSymbol(sym)
+ case reflect.Select(qual, sym) => putTree(qual); putSymbol(sym)
+ case reflect.Literal(value) => putConstant(Constant(value))
+ case reflect.Apply(fun, args) => putTree(fun); putRefTrees(args)
+ case reflect.TypeApply(fun, args) => putTree(fun); putRefTypes(args)
+ case reflect.Function(params, body) =>
+ putRefSymbols(params); putTree(body)
+ case reflect.This(sym) => putSymbol(sym)
+ case reflect.Block(stats, expr) => putRefTrees(stats); putTree(expr)
+ case reflect.New(clz) => putTree(clz)
+ case reflect.If(condition, trueCase, falseCase) =>
+ putTree(condition); putTree(trueCase); putTree(falseCase)
+ case reflect.Assign(destination, source) =>
+ putTree(destination); putTree(source)
+ case reflect.Target(sym, body) => putSymbol(sym); putTree(body)
+ case reflect.Goto(target) => putSymbol(target)
+ case reflect.ValDef(sym, rhs) => putSymbol(sym); putTree(rhs)
+ case reflect.ClassDef(sym, tpe, impl) =>
+ putSymbol(sym); putType(tpe); putTree(impl)
+ case reflect.DefDef(sym, vparamss, ret, rhs) =>
+ putSymbol(sym); putRefTreess(vparamss); putType(ret); putTree(rhs)
+ case reflect.Super(psym) => putSymbol(psym)
+ case reflect.Template(parents, body) =>
+ putRefTypes(parents); putRefTrees(body)
+ case _ =>
+ throw new FatalError("bad tree: " + tree + "(" + tree.getClass + ")")
+ }
+ }
+ private def putRefTrees(trees: List[reflect.Tree]) = trees foreach putTree
+ private def putRefTreess(trees: List[List[reflect.Tree]]) =
+ trees foreach putRefTrees
+
+ private def putType(tpe: reflect.Type): unit = if(putEntry(tpe)) {
+ tpe match {
+ case reflect.NoPrefix => ()
+ case reflect.NoType => ()
+ case reflect.NamedType(fullname) => putConstant(Constant(fullname))
+ case reflect.PrefixedType(pre, sym) => putType(pre); putSymbol(sym)
+ case reflect.SingleType(pre, sym) => putType(pre); putSymbol(sym)
+ case reflect.ThisType(clazz) => putSymbol(clazz)
+ case reflect.AppliedType(tpe, args) => putType(tpe); putRefTypes(args)
+ case reflect.TypeBounds(lo, hi) => putType(lo); putType(hi)
+ case reflect.MethodType(formals, restpe) => //can be implicit
+ putRefTypes(formals); putType(restpe)
+ case reflect.PolyType(typeParams, typeBounds, resultType) =>
+ putRefSymbols(typeParams)
+ for(val (t1,t2) <- typeBounds) {
+ putType(t1)
+ putType(t2)
+ }
+ putType(resultType)
+ case _ =>
+ throw new FatalError("bad type: " + tpe + "(" + tpe.getClass + ")")
+
+ }
+ }
+ private def putRefTypes(tpes: List[reflect.Type]) =
+ tpes foreach putType
+
+ private def putSymbol(sym: reflect.Symbol): unit = if(putEntry(sym)) {
+ sym match {
+ case reflect.Class(fullname) =>
+ putConstant(Constant(fullname))
+ case reflect.Method(fullname, tpe) =>
+ putConstant(Constant(fullname))
+ putType(tpe)
+ case reflect.Field(fullname, tpe) =>
+ putConstant(Constant(fullname))
+ putType(tpe)
+ case reflect.TypeField(fullname, tpe) =>
+ putConstant(Constant(fullname))
+ putType(tpe)
+ case reflect.LocalValue(owner, name, tpe) =>
+ putSymbol(owner)
+ putConstant(Constant(name))
+ putType(tpe)
+ case reflect.LocalMethod(owner, name, tpe) =>
+ putSymbol(owner)
+ putConstant(Constant(name))
+ putType(tpe)
+ case reflect.NoSymbol => ()
+ case reflect.RootSymbol => ()
+ case reflect.LabelSymbol(name) =>
+ putConstant(Constant(name))
+ }
+ }
+ private def putRefSymbols(syms: List[reflect.Symbol]) =
+ syms foreach putSymbol
+
/** Store constant in map <code>index</code>.
*
* @param c ...
@@ -180,6 +271,26 @@ abstract class Pickler extends SubComponent {
for (val (name, c) <- attr.assocs) { putEntry(name); putConstant(c) }
}
+ private def putAnnotation(annot: AnnotationInfo[Any]): unit =
+ if(putEntry(annot)) {
+ val AnnotationInfo(tpe, args, assocs) = annot
+ putType(tpe)
+ args foreach putTreeOrConstant
+ for (val (name, rhs) <- assocs) { putEntry(name); putTreeOrConstant(rhs) }
+ }
+
+ private def putTreeOrConstant(x: Any) {
+ x match {
+ case c:Constant => putConstant(c)
+ case tree:reflect.Tree => putTree(tree)
+ case _ =>
+ throw new FatalError("attribute neither tree nor constant: " + x)
+ }
+ }
+
+ private def putAnnotations(annots: List[AnnotationInfo[Any]]): unit =
+ annots foreach putAnnotation
+
// Phase 2 methods: Write all entries to byte array ------------------------------
private val buf = new PickleBuffer(new Array[byte](4096), -1, 0)
@@ -278,7 +389,9 @@ abstract class Pickler extends SubComponent {
else if (c.tag == ClassTag) writeRef(c.typeValue)
LITERAL + c.tag
case AnnotatedType(attribs, tp) =>
- writeBody(tp) // obviously, this should be improved
+ writeRef(tp)
+ writeRefs(attribs)
+ ANNOTATEDtpe
case (target: Symbol, attr @ AnnotationInfo(atp, args, assocs)) =>
writeRef(target)
writeRef(atp)
@@ -289,8 +402,202 @@ abstract class Pickler extends SubComponent {
writeRef(target)
for (val c <- children) writeRef(c.asInstanceOf[Symbol])
CHILDREN
+ case reflect.Ident(sym) =>
+ writeNat(IDENTtree)
+ writeRef(sym)
+ REFLTREE
+ case reflect.Select(qual, sym) =>
+ writeNat(SELECTtree)
+ writeRef(qual)
+ writeRef(sym)
+ REFLTREE
+ case reflect.Literal(value) =>
+ writeNat(LITERALtree)
+ writeRef(Constant(value))
+ REFLTREE
+ case reflect.Apply(fun, args) =>
+ writeNat(APPLYtree)
+ writeRef(fun)
+ writeRefs(args)
+ REFLTREE
+ case reflect.TypeApply(fun, args) =>
+ writeNat(TYPEAPPLYtree)
+ writeRef(fun)
+ writeRef(args)
+ REFLTREE
+ case reflect.Function(params, body) =>
+ writeNat(FUNCTIONtree)
+ writeRef(body)
+ writeRefs(params)
+ REFLTREE
+ case reflect.This(sym) =>
+ writeNat(THIStree)
+ writeRef(sym)
+ REFLTREE
+ case reflect.Block(stats, expr) =>
+ writeNat(BLOCKtree)
+ writeRef(expr)
+ writeRefs(stats)
+ REFLTREE
+ case reflect.New(clz) =>
+ writeNat(NEWtree)
+ writeRef(clz)
+ REFLTREE
+ case reflect.If(condition, trueCase, falseCase) =>
+ writeNat(IFtree)
+ writeRef(condition)
+ writeRef(trueCase)
+ writeRef(falseCase)
+ REFLTREE
+ case reflect.Assign(destination, source) =>
+ writeNat(ASSIGNtree)
+ writeRef(destination)
+ writeRef(source)
+ REFLTREE
+ case reflect.Target(sym, body) =>
+ writeNat(TARGETtree)
+ writeRef(sym)
+ writeRef(body)
+ REFLTREE
+ case reflect.Goto(target) =>
+ writeNat(GOTOtree)
+ writeRef(target)
+ REFLTREE
+ case reflect.ValDef(sym, rhs) =>
+ writeNat(VALDEFtree)
+ writeRef(sym)
+ writeRef(rhs)
+ REFLTREE
+ case reflect.ClassDef(sym, tpe, impl) =>
+ writeNat(CLASSDEFtree)
+ writeRef(sym)
+ writeRef(tpe)
+ writeRef(impl)
+ REFLTREE
+ case reflect.DefDef(sym, vparamss, ret, rhs) =>
+ writeNat(DEFDEFtree)
+ writeRef(sym)
+ writeRef(ret)
+ writeRef(rhs)
+ for(val vparams <- vparamss) {
+ writeNat(vparams.length)
+ writeRefs(vparams)
+ }
+ REFLTREE
+ case reflect.Super(psym) =>
+ writeNat(SUPERtree)
+ writeRef(psym)
+ REFLTREE
+ case reflect.Template(parents, body) =>
+ writeNat(TEMPLATEtree)
+ writeNat(parents.length)
+ writeRefs(parents)
+ writeRefs(body)
+ REFLTREE
+ case reflect.NoPrefix =>
+ writeNat(NOPREFIXrtpe)
+ REFLTYPE
+ case reflect.NoType =>
+ writeNat(NOrtpe)
+ REFLTYPE
+ case reflect.NamedType(fullname) =>
+ writeNat(NAMEDrtpe)
+ writeRef(Constant(fullname))
+ REFLTYPE
+ case reflect.PrefixedType(pre, sym) =>
+ writeNat(PREFIXEDrtpe)
+ writeRef(pre)
+ writeRef(sym)
+ REFLTYPE
+ case reflect.SingleType(pre, sym) =>
+ writeNat(SINGLErtpe)
+ writeRef(pre)
+ writeRef(sym)
+ REFLTYPE
+ case reflect.ThisType(clazz) =>
+ writeNat(THISrtpe)
+ writeRef(clazz)
+ REFLTYPE
+ case reflect.AppliedType(tpe, args) =>
+ writeNat(APPLIEDrtpe)
+ writeRef(tpe)
+ writeRef(args)
+ REFLTYPE
+ case reflect.TypeBounds(lo, hi) =>
+ writeNat(TYPEBOUNDSrtpe)
+ writeRef(lo)
+ writeRef(hi)
+ REFLTYPE
+ case entry@reflect.MethodType(formals, restpe) => //can be implicit
+ if(entry.isInstanceOf[ImplicitMethodType])
+ writeNat(IMPLICITMETHODrtpe)
+ else
+ writeNat(METHODrtpe)
+ writeRef(restpe)
+ writeRefs(formals)
+ REFLTYPE
+ case reflect.PolyType(typeParams, typeBounds, resultType) =>
+ writeNat(POLYrtpe)
+ writeRef(resultType)
+ writeNat(typeBounds.length)
+ for(val (t1,t2) <- typeBounds) {
+ writeRef(t1)
+ writeRef(t2)
+ }
+ writeRefs(typeParams)
+ REFLTYPE
+ case reflect.Class(fullname) =>
+ writeNat(CLASSrsym)
+ writeRef(Constant(fullname))
+ REFLSYM
+ case reflect.Method(fullname, tpe) =>
+ writeNat(METHODrsym)
+ writeRef(Constant(fullname))
+ writeRef(tpe)
+ REFLSYM
+ case reflect.Field(fullname, tpe) =>
+ writeNat(FIELDrsym)
+ writeRef(Constant(fullname))
+ writeRef(tpe)
+ REFLSYM
+ case reflect.TypeField(fullname, tpe) =>
+ writeNat(TYPEFIELDrsym)
+ writeRef(Constant(fullname))
+ writeRef(tpe)
+ REFLSYM
+ case reflect.LocalValue(owner, name, tpe) =>
+ writeNat(LOCALVALUErsym)
+ writeRef(owner)
+ writeRef(Constant(name))
+ writeRef(tpe)
+ REFLSYM
+ case reflect.LocalMethod(owner, name, tpe) =>
+ writeNat(LOCALMETHODrsym)
+ writeRef(owner)
+ writeRef(Constant(name))
+ writeRef(tpe)
+ REFLSYM
+ case reflect.NoSymbol =>
+ writeNat(NOSYMBOLrsym)
+ REFLSYM
+ case reflect.RootSymbol =>
+ writeNat(ROOTSYMBOLrsym)
+ REFLSYM
+ case reflect.LabelSymbol(name) =>
+ writeNat(LABELSYMBOLrsym)
+ REFLSYM
+ case AnnotationInfo(target, args, assocs) =>
+ writeRef(target)
+ writeNat(args.length)
+ for (val tree <- args) writeRef(tree.asInstanceOf[reflect.Tree])
+ for (val (name, tree) <- assocs) {
+ writeRef(name);
+ writeRef(tree.asInstanceOf[reflect.Tree])
+ }
+ ATTRIBTREE
+
case _ =>
- throw new FatalError("bad entry: " + entry + " " + entry.getClass())//debug
+ throw new FatalError("bad entry: " + entry + " " + entry.getClass)
}
val startpos = writeIndex
writeByte(0); writeByte(0)
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala
index 70fcc5e7d7..136a69f126 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala
@@ -254,6 +254,16 @@ abstract class UnPickler {
case POLYtpe =>
val restpe = readTypeRef()
PolyType(until(end, readSymbolRef), restpe)
+ case ANNOTATEDtpe =>
+ val tp = readTypeRef()
+ val attribs = until(end, readTreeAttribRef)
+ if(global.settings.Xplugtypes.value)
+ AnnotatedType(attribs, tp)
+ else
+ tp // Drop the annotations unless -Xplugtypes.
+ // This way, people can distribute classfiles
+ // including annotated types without them much
+ // affecting those who disable -Xplugtypes
case _ =>
errorBadSignature("bad type tag: " + tag)
}
@@ -302,11 +312,219 @@ abstract class UnPickler {
null
}
- /** Read a reference to a name, symbol, type or constant */
+ /** Read a reflect.Tree */
+ private def readReflTree(): reflect.Tree = {
+ val outerTag = readByte()
+ if(outerTag != REFLTREE)
+ errorBadSignature("reflection tree expected (" + outerTag + ")")
+ val end = readNat() + readIndex
+ val tag = readByte()
+ tag match {
+ case IDENTtree =>
+ val sym = readReflSymbolRef()
+ reflect.Ident(sym)
+ case SELECTtree =>
+ val qual = readReflTreeRef()
+ val sym = readReflSymbolRef()
+ reflect.Select(qual, sym)
+ case LITERALtree =>
+ val value = readConstantRef()
+ reflect.Literal(value)
+ case APPLYtree =>
+ val fun = readReflTreeRef()
+ val args = until(end, readReflTreeRef)
+ reflect.Apply(fun, args)
+ case TYPEAPPLYtree =>
+ val fun = readReflTreeRef()
+ val args = until(end, readReflTypeRef)
+ reflect.TypeApply(fun, args)
+ case FUNCTIONtree =>
+ val body = readReflTreeRef()
+ val params = until(end, readReflSymbolRef)
+ reflect.Function(params, body)
+ case THIStree =>
+ val sym = readReflSymbolRef()
+ reflect.This(sym)
+ case BLOCKtree =>
+ val expr = readReflTreeRef()
+ val stats = until(end, readReflTreeRef)
+ reflect.Block(stats, expr)
+ case NEWtree =>
+ val clz = readReflTreeRef()
+ reflect.New(clz)
+ case IFtree =>
+ val condition = readReflTreeRef()
+ val trueCase = readReflTreeRef()
+ val falseCase = readReflTreeRef()
+ reflect.If(condition, trueCase, falseCase)
+ case ASSIGNtree =>
+ val destination = readReflTreeRef()
+ val source = readReflTreeRef()
+ reflect.Assign(destination, source)
+ case TARGETtree =>
+ val sym = readReflSymbolRef()
+ val body = readReflTreeRef()
+ sym match {
+ case sym:reflect.LabelSymbol => reflect.Target(sym, body)
+ case _ => errorBadSignature("bad label for target: " + sym)
+ }
+ case GOTOtree =>
+ val target = readReflSymbolRef()
+ target match {
+ case target:reflect.LabelSymbol => reflect.Goto(target)
+ case _ => errorBadSignature("bad target for goto: " + target)
+ }
+ case VALDEFtree =>
+ val sym = readReflSymbolRef()
+ val rhs = readReflTreeRef()
+ reflect.ValDef(sym, rhs)
+ case CLASSDEFtree =>
+ val sym = readReflSymbolRef()
+ val tpe = readReflTypeRef()
+ val impl = readReflTreeRef()
+ impl match {
+ case impl:reflect.Template => reflect.ClassDef(sym, tpe, impl)
+ case _ =>
+ errorBadSignature("body of class not a template: " + impl)
+ }
+ case tag =>
+ errorBadSignature("unknown reflection tree (" + tag + ")")
+ }
+ }
+
+ /** Read a reflect.Symbol */
+ private def readReflSymbol(): reflect.Symbol = {
+ val outerTag = readByte()
+ if(outerTag != REFLSYM)
+ errorBadSignature("reflection symbol expected (" + outerTag + ")")
+ val end = readNat() + readIndex
+ val tag = readNat()
+ tag match {
+ case CLASSrsym =>
+ val fullname = readConstantRef().stringValue
+ reflect.Class(fullname)
+ case METHODrsym =>
+ val fullname = readConstantRef().stringValue
+ val tpe = readReflTypeRef()
+ reflect.Method(fullname, tpe)
+ case FIELDrsym =>
+ val fullname = readConstantRef().stringValue
+ val tpe = readReflTypeRef()
+ reflect.Field(fullname, tpe)
+ case TYPEFIELDrsym =>
+ val fullname = readConstantRef().stringValue
+ val tpe = readReflTypeRef()
+ reflect.TypeField(fullname, tpe)
+ case LOCALVALUErsym =>
+ val owner = readReflSymbolRef()
+ val name = readConstantRef().stringValue
+ val tpe = readReflTypeRef()
+ reflect.LocalValue(owner, name, tpe)
+ case LOCALMETHODrsym =>
+ val owner = readReflSymbolRef()
+ val name = readConstantRef().stringValue
+ val tpe = readReflTypeRef()
+ reflect.LocalMethod(owner, name, tpe)
+ case NOSYMBOLrsym =>
+ reflect.NoSymbol
+ case ROOTSYMBOLrsym =>
+ reflect.RootSymbol
+ case LABELSYMBOLrsym =>
+ val name = readConstantRef().stringValue
+ reflect.LabelSymbol(name)
+ case tag =>
+ errorBadSignature("unknown reflection symbol (" + tag + ")")
+ }
+ }
+
+ /** Read a reflect.Type */
+ private def readReflType(): reflect.Type = {
+ val outerTag = readByte()
+ if(outerTag != REFLTYPE)
+ errorBadSignature("reflection type expected (" + outerTag + ")")
+ val end = readNat() + readIndex
+ val tag = readNat()
+ tag match {
+ case NOPREFIXrtpe =>
+ reflect.NoPrefix
+ case NOrtpe =>
+ reflect.NoType
+ case NAMEDrtpe =>
+ val fullname = readConstantRef()
+ reflect.NamedType(fullname.stringValue)
+ case PREFIXEDrtpe =>
+ val pre = readReflTypeRef()
+ val sym = readReflSymbolRef()
+ reflect.PrefixedType(pre, sym)
+ case SINGLErtpe =>
+ val pre = readReflTypeRef()
+ val sym = readReflSymbolRef()
+ reflect.SingleType(pre, sym)
+ case THISrtpe =>
+ val clazz = readReflSymbolRef()
+ reflect.ThisType(clazz)
+ case APPLIEDrtpe =>
+ val tpe = readReflTypeRef()
+ val args = until(end, readReflTypeRef)
+ reflect.AppliedType(tpe, args)
+ case TYPEBOUNDSrtpe =>
+ val lo = readReflTypeRef()
+ val hi = readReflTypeRef()
+ reflect.TypeBounds(lo, hi)
+ case IMPLICITMETHODrtpe =>
+ val restpe = readReflTypeRef()
+ val formals = until(end, readReflTypeRef)
+ new reflect.ImplicitMethodType(formals, restpe)
+ case METHODrtpe =>
+ val restpe = readReflTypeRef()
+ val formals = until(end, readReflTypeRef)
+ reflect.MethodType(formals, restpe)
+ case POLYrtpe =>
+ val resultType = readReflTypeRef()
+ val numBounds = readNat()
+ val typeBounds = times(numBounds, {() =>
+ val lo = readReflTypeRef()
+ val hi = readReflTypeRef()
+ (lo,hi)
+ })
+ val typeParams = until(end, readReflSymbolRef)
+ reflect.PolyType(typeParams, typeBounds, resultType)
+ case tag =>
+ errorBadSignature("unknown reflection type (" + tag + ")")
+ }
+ }
+
+ /** Read an annotation with reflect.Tree's */
+ private def readTreeAttrib(): AnnotationInfo[reflect.Tree] = {
+ val tag = readByte()
+ if(tag != ATTRIBTREE)
+ errorBadSignature("tree-based annotation expected (" + tag + ")")
+ val end = readNat() + readIndex
+
+ val target = readTypeRef()
+ val numargs = readNat()
+ val args = times(numargs, readReflTreeRef)
+ val assocs =
+ until(end, {() =>
+ val name = readNameRef()
+ val tree = readReflTreeRef()
+ (name,tree)})
+ AnnotationInfo(target, args, assocs)
+ }
+
+ /* Read a reference to a pickled item */
private def readNameRef(): Name = at(readNat(), readName)
private def readSymbolRef(): Symbol = at(readNat(), readSymbol)
private def readTypeRef(): Type = at(readNat(), readType)
private def readConstantRef(): Constant = at(readNat(), readConstant)
+ private def readReflTreeRef(): reflect.Tree =
+ at(readNat(), readReflTree)
+ private def readReflSymbolRef(): reflect.Symbol =
+ at(readNat(), readReflSymbol)
+ private def readReflTypeRef(): reflect.Type =
+ at(readNat(), readReflType)
+ private def readTreeAttribRef(): AnnotationInfo[reflect.Tree] =
+ at(readNat(), readTreeAttrib)
private def errorBadSignature(msg: String) =
throw new RuntimeException("malformed Scala signature of " + classRoot.name + " at " + readIndex + "; " + msg)
diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
index f5426083dd..df301eb159 100644
--- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala
+++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
@@ -183,40 +183,40 @@ abstract class LiftCode extends Transform {
def reify(tp: Type): reflect.Type = tp match {
case ErrorType =>
- if (_log_reify_type_) Console.println("cannot handle ErrorType"); null
+ if (_log_reify_type_) Console.println("cannot handle ErrorType"); reflect.NoType
case WildcardType =>
- if (_log_reify_type_) Console.println("cannot handle WildcardType"); null
+ if (_log_reify_type_) Console.println("cannot handle WildcardType"); reflect.NoType
case NoType =>
- if (_log_reify_type_) Console.println("cannot handle NoType"); null
+ if (_log_reify_type_) Console.println("cannot handle NoType"); reflect.NoType
case NoPrefix =>
- if (_log_reify_type_) Console.println("cannot handle NoPrefix"); null
+ if (_log_reify_type_) Console.println("cannot handle NoPrefix"); reflect.NoType
case ThisType(sym) =>
if (_log_reify_type_) Console.println("ThisType ("+sym+")")
val rsym = reify(sym)
- if (_log_reify_type_) Console.println("reified is "+rsym+" cannot handle ThisType "+tp); null
+ if (_log_reify_type_) Console.println("reified is "+rsym+" cannot handle ThisType "+tp); reflect.NoType
case SingleType(pre, sym) =>
- if (_log_reify_type_) Console.println("cannot handle SingleType "+tp); null
+ if (_log_reify_type_) Console.println("cannot handle SingleType "+tp); reflect.NoType
case ConstantType(value) =>
- if (_log_reify_type_) Console.println("cannot handle ConstantType("+value+") "+tp); null
+ if (_log_reify_type_) Console.println("cannot handle ConstantType("+value+") "+tp); reflect.NoType
case TypeRef(pre, sym, args) =>
if (_log_reify_type_) Console.println("TypeRef! try to handle prefix")
val rpre = reify(pre)
- if (_log_reify_type_) Console.println("cannot handle TypeRef("+pre+","+sym+","+args+") == "+tp+")"); null
+ if (_log_reify_type_) Console.println("cannot handle TypeRef("+pre+","+sym+","+args+") == "+tp+")"); reflect.NoType
case TypeBounds(lo, hi) =>
- if (_log_reify_type_) Console.println("cannot handle TypeBounds "+tp); null
+ if (_log_reify_type_) Console.println("cannot handle TypeBounds "+tp); reflect.NoType
case RefinedType(parents, defs) =>
- if (_log_reify_type_) Console.println("cannot handle RefinedType "+tp); null
+ if (_log_reify_type_) Console.println("cannot handle RefinedType "+tp); reflect.NoType
case ClassInfoType(parents, defs, clazz) =>
- if (_log_reify_type_) Console.println("cannot handle ClassInfoType "+tp); null
+ if (_log_reify_type_) Console.println("cannot handle ClassInfoType "+tp); reflect.NoType
case MethodType(paramtypes, result) =>
- if (_log_reify_type_) Console.println("cannot handle MethodType "+tp); null
+ if (_log_reify_type_) Console.println("cannot handle MethodType "+tp); reflect.NoType
case PolyType(tparams, result) =>
- if (_log_reify_type_) Console.println("cannot handle PolyType "+tp); null;
+ if (_log_reify_type_) Console.println("cannot handle PolyType "+tp); reflect.NoType
case AnnotatedType(attribs, tp) =>
reify(tp)
case _ =>
- null
+ reflect.NoType
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 630a5253ef..084ed5df2e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2023,7 +2023,7 @@ trait Typers requires Analyzer {
def annotTypeTree(ainfo: AnnotationInfo[Any]): Tree =
TypeTree(arg1.tpe.withAttribute(ainfo)) setOriginal tree
if (arg1.isType) {
- val annotInfo = typedAnnotation(annot, identity[Tree])
+ val annotInfo = typedAnnotation(annot, liftcode.reify)
if (settings.Xplugtypes.value) annotTypeTree(annotInfo) else arg1
} else {
val annotInfo = typedAnnotation(annot, getConstant)