diff options
Diffstat (limited to 'src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala | 1144 |
1 files changed, 585 insertions, 559 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index b82417c4a3..a44270468b 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -49,6 +49,7 @@ abstract class Pickler extends SubComponent { add(sym, pickle) add(sym.linkedSym, pickle) pickle.finish + // pickleHash is used to track changes in a signature (-> IDE) val doPickleHash = global.doPickleHash if (doPickleHash) { var i = 0 @@ -91,6 +92,10 @@ abstract class Pickler extends SubComponent { sym != NoSymbol && isLocal(sym.owner) || isUnrootedExistential(sym) + private def staticAnnotations(annots: List[AnnotationInfo]) = + annots filter(ann => + ann.atp.typeSymbol isNonBottomSubClass definitions.StaticAnnotationClass) + // Phase 1 methods: Populate entries/index ------------------------------------ /** Store entry <code>e</code> in index at next available position unless @@ -145,10 +150,8 @@ abstract class Pickler extends SubComponent { } putChildren(sym, children.sort((x, y) => x isLess y)) } - for (attr <- sym.attributes.reverse) { - if (attr.atp.typeSymbol isNonBottomSubClass definitions.StaticAnnotationClass) - putAnnotation(sym, attr) - } + for (annot <- staticAnnotations(sym.annotations.reverse)) + putAnnotation(sym, annot) } else if (sym != NoSymbol) { putEntry(if (sym.isModuleClass) sym.name.toTermName else sym.name) if (!sym.owner.isRoot) putSymbol(sym.owner) @@ -171,8 +174,11 @@ abstract class Pickler extends SubComponent { putSymbol(sym) case SingleType(pre, sym) => putType(pre); putSymbol(sym) + case SuperType(thistpe, supertpe) => + putType(thistpe) + putType(supertpe) case ConstantType(value) => - putConstant(value) + putConstant(value) case TypeRef(pre, sym, args) => putType(pre); putSymbol(sym); putTypes(args) case TypeBounds(lo, hi) => @@ -190,9 +196,10 @@ abstract class Pickler extends SubComponent { putType(restpe); putSymbols(tparams) case ExistentialType(tparams, restpe) => putType(restpe); putSymbols(tparams) - case AnnotatedType(attribs, tp, selfsym) => - putType(tp); putAnnotations(attribs) - if (settings.selfInAnnots.value) putSymbol(selfsym) + case AnnotatedType(annotations, underlying, selfsym) => + putType(underlying) + if (settings.selfInAnnots.value) putSymbol(selfsym) + putAnnotations(staticAnnotations(annotations)) case _ => throw new FatalError("bad type: " + tp + "(" + tp.getClass + ")") } @@ -201,199 +208,192 @@ abstract class Pickler extends SubComponent { private def putTree(tree: Tree): Unit = if (putEntry(tree)) { if (tree != EmptyTree) - putType(tree.tpe) + putType(tree.tpe) if (tree.hasSymbol) - putSymbol(tree.symbol) + putSymbol(tree.symbol) tree match { - case EmptyTree => + case EmptyTree => - case tree@PackageDef(name, stats) => - putEntry(name) + case tree@PackageDef(name, stats) => + putEntry(name) putTrees(stats) - case ClassDef(mods, name, tparams, impl) => - putMods(mods) - putEntry(name) + case ClassDef(mods, name, tparams, impl) => + putMods(mods) + putEntry(name) putTree(impl) - putTrees(tparams) - - case ModuleDef(mods, name, impl) => - putMods(mods) - putEntry(name) - putTree(impl) - - case ValDef(mods, name, tpt, rhs) => - putMods(mods) - putEntry(name) - putTree(tpt) - putTree(rhs) - - case DefDef(mods, name, tparams, vparamss, tpt, rhs) => - putMods(mods) - putEntry(name) - putTrees(tparams) - putTreess(vparamss) - putTree(tpt) - putTree(rhs) - - - case TypeDef(mods, name, tparams, rhs) => - putMods(mods) - putEntry(name) - putTree(rhs) - putTrees(tparams) - - - case LabelDef(name, params, rhs) => - putEntry(name) - putTree(rhs) - putTrees(params) - + putTrees(tparams) - case Import(expr, selectors) => - putTree(expr) - for ((from,to) <- selectors) { - putEntry(from) - putEntry(to) - } + case ModuleDef(mods, name, impl) => + putMods(mods) + putEntry(name) + putTree(impl) - case Annotation(constr, elements) => - putTree(constr) - putTrees(elements) + case ValDef(mods, name, tpt, rhs) => + putMods(mods) + putEntry(name) + putTree(tpt) + putTree(rhs) + + case DefDef(mods, name, tparams, vparamss, tpt, rhs) => + putMods(mods) + putEntry(name) + putTrees(tparams) + putTreess(vparamss) + putTree(tpt) + putTree(rhs) + + case TypeDef(mods, name, tparams, rhs) => + putMods(mods) + putEntry(name) + putTree(rhs) + putTrees(tparams) + + case LabelDef(name, params, rhs) => + putEntry(name) + putTree(rhs) + putTrees(params) + + case Import(expr, selectors) => + putTree(expr) + for ((from,to) <- selectors) { + putEntry(from) + putEntry(to) + } - case DocDef(comment, definition) => - putConstant(Constant(comment)) - putTree(definition) + case DocDef(comment, definition) => + putConstant(Constant(comment)) + putTree(definition) - case Template(parents, self, body) => + case Template(parents, self, body) => writeNat(parents.length) - putTrees(parents) - putTree(self) - putTrees(body) + putTrees(parents) + putTree(self) + putTrees(body) - case Block(stats, expr) => - putTree(expr) - putTrees(stats) + case Block(stats, expr) => + putTree(expr) + putTrees(stats) - case CaseDef(pat, guard, body) => - putTree(pat) - putTree(guard) - putTree(body) + case CaseDef(pat, guard, body) => + putTree(pat) + putTree(guard) + putTree(body) - case Sequence(trees) => - putTrees(trees) + case Sequence(trees) => + putTrees(trees) - case Alternative(trees) => - putTrees(trees) + case Alternative(trees) => + putTrees(trees) - case Star(elem) => - putTree(elem) + case Star(elem) => + putTree(elem) - case Bind(name, body) => - putEntry(name) - putTree(body) + case Bind(name, body) => + putEntry(name) + putTree(body) - case UnApply(fun: Tree, args) => - putTree(fun) - putTrees(args) + case UnApply(fun: Tree, args) => + putTree(fun) + putTrees(args) - case ArrayValue(elemtpt, trees) => - putTree(elemtpt) - putTrees(trees) + case ArrayValue(elemtpt, trees) => + putTree(elemtpt) + putTrees(trees) - case Function(vparams, body) => - putTree(body) - putTrees(vparams) + case Function(vparams, body) => + putTree(body) + putTrees(vparams) - case Assign(lhs, rhs) => - putTree(lhs) - putTree(rhs) + case Assign(lhs, rhs) => + putTree(lhs) + putTree(rhs) - case If(cond, thenp, elsep) => - putTree(cond) - putTree(thenp) - putTree(elsep) + case If(cond, thenp, elsep) => + putTree(cond) + putTree(thenp) + putTree(elsep) - case Match(selector, cases) => - putTree(selector) - putTrees(cases) + case Match(selector, cases) => + putTree(selector) + putTrees(cases) - case Return(expr) => - putTree(expr) + case Return(expr) => + putTree(expr) - case Try(block, catches, finalizer) => - putTree(block) - putTree(finalizer) - putTrees(catches) + case Try(block, catches, finalizer) => + putTree(block) + putTree(finalizer) + putTrees(catches) - case Throw(expr) => - putTree(expr) + case Throw(expr) => + putTree(expr) - case New(tpt) => - putTree(tpt) + case New(tpt) => + putTree(tpt) - case Typed(expr, tpt) => - putTree(expr) - putTree(tpt) + case Typed(expr, tpt) => + putTree(expr) + putTree(tpt) - case TypeApply(fun, args) => - putTree(fun) - putTrees(args) + case TypeApply(fun, args) => + putTree(fun) + putTrees(args) - case Apply(fun, args) => - putTree(fun) - putTrees(args) + case Apply(fun, args) => + putTree(fun) + putTrees(args) - case ApplyDynamic(qual, args) => - writeEntry(qual) - putTrees(args) + case ApplyDynamic(qual, args) => + putTree(qual) + putTrees(args) - case Super(qual, mix) => - putEntry(qual:Name) - putEntry(mix:Name) + case Super(qual, mix) => + putEntry(qual:Name) + putEntry(mix:Name) case This(qual) => - putEntry(qual) + putEntry(qual) case Select(qualifier, selector) => - putTree(qualifier) - putEntry(selector) + putTree(qualifier) + putEntry(selector) - case Ident(name) => - putEntry(name) + case Ident(name) => + putEntry(name) - case Literal(value) => - putEntry(value) + case Literal(value) => + putEntry(value) - case TypeTree() => + case TypeTree() => - case Annotated(annot, arg) => - putTree(annot) - putTree(arg) + case Annotated(annot, arg) => + putTree(annot) + putTree(arg) - case SingletonTypeTree(ref) => - putTree(ref) + case SingletonTypeTree(ref) => + putTree(ref) - case SelectFromTypeTree(qualifier, selector) => - putTree(qualifier) - putEntry(selector) + case SelectFromTypeTree(qualifier, selector) => + putTree(qualifier) + putEntry(selector) - case CompoundTypeTree(templ: Template) => - putTree(templ) + case CompoundTypeTree(templ: Template) => + putTree(templ) - case AppliedTypeTree(tpt, args) => - putTree(tpt) - putTrees(args) + case AppliedTypeTree(tpt, args) => + putTree(tpt) + putTrees(args) - case TypeBoundsTree(lo, hi) => - putTree(lo) - putTree(hi) + case TypeBoundsTree(lo, hi) => + putTree(lo) + putTree(hi) - case ExistentialTypeTree(tpt, whereClauses) => - putTree(tpt) - putTrees(whereClauses) + case ExistentialTypeTree(tpt, whereClauses) => + putTree(tpt) + putTrees(whereClauses) } } @@ -403,63 +403,78 @@ abstract class Pickler extends SubComponent { private def putTreess(treess: List[List[Tree]]) = treess.foreach(putTrees _) + /** only used when pickling trees, i.e. in an + * argument of some Annotation */ private def putMods(mods: Modifiers) = if (putEntry(mods)) { - val Modifiers(flags, privateWithin, annotations) = mods + // annotations in Modifiers are removed by the typechecker + val Modifiers(flags, privateWithin, Nil) = mods putEntry(privateWithin) - putTrees(annotations) } /** Store a constant in map <code>index</code> along with * anything it references. + * No need to treat Constants with EnumTag (only used for Java + * annotations with Java enum parameters) */ - private def putConstant(c: Constant) = + private def putConstant(c: Constant) { if (putEntry(c)) { if (c.tag == StringTag) putEntry(newTermName(c.stringValue)) else if (c.tag == ClassTag) putType(c.typeValue) } + } private def putChildren(sym: Symbol, children: List[Symbol]) { assert(putEntry((sym, children))) children foreach putSymbol } + /** used in putSymbol only, i.e. annotations on definitions, not on types */ private def putAnnotation(sym: Symbol, annot: AnnotationInfo) { // if an annotation with the same arguments is applied to the // same symbol multiple times, it's only pickled once. - if (putEntry((sym, annot))) { - val AnnotationInfo(atp, args, assocs) = annot - putType(atp) - args foreach putAnnotationArg - for ((name, c) <- assocs) { putEntry(name); putAnnotationArg(c) } - } + if (putEntry((sym, annot))) + putAnnotationBody(annot) } + /** used in AnnotatedType only, i.e. annotations on types */ + private def putAnnotations(annots: List[AnnotationInfo]) { + annots foreach putAnnotation + } private def putAnnotation(annot: AnnotationInfo) { - if (putEntry(annot)) { - val AnnotationInfo(tpe, args, assocs) = annot - putType(tpe) - args foreach putAnnotationArg - for ((name, rhs) <- assocs) { putEntry(name); putAnnotationArg(rhs) } - } + if (putEntry(annot)) + putAnnotationBody(annot) } - private def putAnnotationArg(arg: AnnotationArgument) { - if (putEntry(arg)) { + /** Puts the members of an AnnotationInfo */ + private def putAnnotationBody(annot: AnnotationInfo) { + def putAnnotationArg(arg: AnnotationArgument) { arg.constant match { - case Some(c) => putConstant(c) - case _ => putTree(arg.intTree) - } + case Some(c) => putConstant(c) + case None => putTree(arg.intTree) + } + } + def putConstantAnnotationArg(carg: ConstantAnnotationArgument) { + carg match { + case LiteralAnnotationArgument(const) => + putConstant(const) + case ArrayAnnotationArgument(args) => + if (putEntry(carg)) + args foreach putConstantAnnotationArg + case NestedAnnotationArgument(annInfo) => + putAnnotation(annInfo) + } + } + val AnnotationInfo(tpe, args, assocs) = annot + putType(tpe) + args foreach putAnnotationArg + assocs foreach { asc => + putEntry(asc._1) + putConstantAnnotationArg(asc._2) } - } - - private def putAnnotations(annots: List[AnnotationInfo]) { - annots foreach putAnnotation } // Phase 2 methods: Write all entries to byte array ------------------------------ - private val buf = new PickleBuffer(new Array[Byte](4096), -1, 0) - /** Write a reference to object, i.e., the object's number in the map * <code>index</code>. * @@ -478,26 +493,50 @@ abstract class Pickler extends SubComponent { private def writeRefs(refs: List[AnyRef]) { refs foreach writeRef } /** Write name, owner, flags, and info of a symbol. - * - * @param sym ... - * @return the position offset */ - private def writeSymInfo(sym: Symbol): Int = { - var posOffset = 0 + private def writeSymInfo(sym: Symbol) { writeRef(sym.name) writeRef(normalizedOwner(sym)) writeLongNat((rawFlagsToPickled(sym.flags & PickledFlags))) if (sym.privateWithin != NoSymbol) writeRef(sym.privateWithin) writeRef(sym.info) - posOffset } /** Write a name in UTF8 format. */ - def writeName(name: Name) { + private def writeName(name: Name) { ensureCapacity(name.length * 3) writeIndex = name.copyUTF8(bytes, writeIndex) } + /** Write an annotation */ + private def writeAnnotation(annot: AnnotationInfo) { + def writeAnnotationArg(arg: AnnotationArgument) { + arg.constant match { + case Some(c) => writeRef(c) + case None => writeRef(arg.intTree) + } + } + + writeRef(annot.atp) + annot.args foreach writeAnnotationArg + annot.assocs foreach { asc => + writeRef(asc._1) + writeConstantAnnotationArg(asc._2) + } + } + + /** Write a ConstantAnnotationArgument (argument to java annotation) */ + def writeConstantAnnotationArg(carg: ConstantAnnotationArgument) { + carg match { + case LiteralAnnotationArgument(const) => + writeRef(const) + case ArrayAnnotationArgument(args) => + writeRef(carg) + case NestedAnnotationArgument(annInfo) => + writeRef(annInfo) + } + } + /** Write an entry */ private def writeEntry(entry: AnyRef) { def writeBody(entry: AnyRef): Int = entry match { @@ -516,18 +555,18 @@ abstract class Pickler extends SubComponent { if (!sym.owner.isRoot) writeRef(sym.owner) tag case sym: ClassSymbol => - val posOffset = writeSymInfo(sym) + writeSymInfo(sym) if (sym.thisSym.tpe != sym.tpe) writeRef(sym.typeOfThis) - CLASSsym + posOffset + CLASSsym case sym: TypeSymbol => - val posOffset = writeSymInfo(sym) - (if (sym.isAbstractType) TYPEsym else ALIASsym) + posOffset + writeSymInfo(sym) + if (sym.isAbstractType) TYPEsym else ALIASsym case sym: TermSymbol => if (!sym.isModule && sym.defaultGetter != NoSymbol) writeRef(sym.defaultGetter) - val posOffset = writeSymInfo(sym) + writeSymInfo(sym) if (sym.alias != NoSymbol) writeRef(sym.alias) - (if (sym.isModule) MODULEsym else VALsym) + posOffset + if (sym.isModule) MODULEsym else VALsym case NoType => NOtpe case NoPrefix => @@ -536,6 +575,8 @@ abstract class Pickler extends SubComponent { writeRef(sym); THIStpe case SingleType(pre, sym) => writeRef(pre); writeRef(sym); SINGLEtpe + case SuperType(thistpe, supertpe) => + writeRef(thistpe); writeRef(supertpe); SUPERtpe case ConstantType(value) => writeRef(value); CONSTANTtpe case TypeRef(pre, sym, args) => @@ -557,414 +598,396 @@ abstract class Pickler extends SubComponent { case DeBruijnIndex(l, i) => writeNat(l); writeNat(i); DEBRUIJNINDEXtpe case c @ Constant(_) => + // No case for Constant with EnumTag. See comment on "def putConstant" if (c.tag == BooleanTag) writeLong(if (c.booleanValue) 1 else 0) else if (ByteTag <= c.tag && c.tag <= LongTag) writeLong(c.longValue) else if (c.tag == FloatTag) writeLong(Float.floatToIntBits(c.floatValue)) else if (c.tag == DoubleTag) writeLong(Double.doubleToLongBits(c.doubleValue)) else if (c.tag == StringTag) writeRef(newTermName(c.stringValue)) else if (c.tag == ClassTag) writeRef(c.typeValue) - LITERAL + c.tag - case AnnotatedType(attribs, tp, selfsym) => - if (settings.selfInAnnots.value) { - writeRef(tp) - writeRef(selfsym) - writeRefs(attribs) - ANNOTATEDWSELFtpe - } else { + LITERAL + c.tag // also treats UnitTag, NullTag; no value required + case AnnotatedType(annotations, tp, selfsym) => + val staticAnnots = staticAnnotations(annotations) + if (staticAnnots isEmpty) { + writeBody(tp) // write the underlying type if there are no annotations + } else { + if (settings.selfInAnnots.value && selfsym != NoSymbol) + writeRef(selfsym) writeRef(tp) - writeRefs(attribs) + writeRefs(staticAnnots) ANNOTATEDtpe - } - case (target: Symbol, attr @ AnnotationInfo(atp, args, assocs)) => + } + + // annotations attached to a symbol (i.e. annots on terms) + case (target: Symbol, annot@AnnotationInfo(_, _, _)) => writeRef(target) - writeRef(atp) - for (c <- args) writeRef(c) - for ((name, c) <- assocs) { writeRef(name); writeRef(c) } - ATTRIBUTE - case (target: Symbol, children: List[_]) => + writeAnnotation(annot) + SYMANNOT + + case ArrayAnnotationArgument(args) => + args foreach writeConstantAnnotationArg + ANNOTARGARRAY + + case (target: Symbol, children: List[Symbol]) => writeRef(target) for (c <- children) writeRef(c.asInstanceOf[Symbol]) CHILDREN - case EmptyTree => - writeNat(EMPTYtree) - TREE + case EmptyTree => + writeNat(EMPTYtree) + TREE - case tree@PackageDef(name, stats) => - writeNat(PACKAGEtree) - writeRef(tree.tpe) - writeRef(tree.symbol) - writeRef(tree.mods) - writeRef(name) + case tree@PackageDef(name, stats) => + writeNat(PACKAGEtree) + writeRef(tree.tpe) + writeRef(tree.symbol) + writeRef(tree.mods) + writeRef(name) writeRefs(stats) - TREE - - case tree@ClassDef(mods, name, tparams, impl) => - writeNat(CLASStree) - writeRef(tree.tpe) - writeRef(tree.symbol) - writeRef(mods) - writeRef(name) + TREE + + case tree@ClassDef(mods, name, tparams, impl) => + writeNat(CLASStree) + writeRef(tree.tpe) + writeRef(tree.symbol) + writeRef(mods) + writeRef(name) writeRef(impl) - writeRefs(tparams) - TREE - - case tree@ModuleDef(mods, name, impl) => - writeNat(MODULEtree) - writeRef(tree.tpe) - writeRef(tree.symbol) - writeRef(mods) - writeRef(name) - writeRef(impl) - TREE - - case tree@ValDef(mods, name, tpt, rhs) => - writeNat(VALDEFtree) - writeRef(tree.tpe) - writeRef(tree.symbol) - writeRef(mods) - writeRef(name) - writeRef(tpt) - writeRef(rhs) - TREE + writeRefs(tparams) + TREE + case tree@ModuleDef(mods, name, impl) => + writeNat(MODULEtree) + writeRef(tree.tpe) + writeRef(tree.symbol) + writeRef(mods) + writeRef(name) + writeRef(impl) + TREE - case tree@DefDef(mods, name, tparams, vparamss, tpt, rhs) => + case tree@ValDef(mods, name, tpt, rhs) => + writeNat(VALDEFtree) + writeRef(tree.tpe) + writeRef(tree.symbol) + writeRef(mods) + writeRef(name) + writeRef(tpt) + writeRef(rhs) + TREE + + case tree@DefDef(mods, name, tparams, vparamss, tpt, rhs) => writeNat(DEFDEFtree) - writeRef(tree.tpe) - writeRef(tree.symbol) - writeRef(mods) - writeRef(name) - writeNat(tparams.length) - writeRefs(tparams) - writeNat(vparamss.length) - for(vparams <- vparamss) { - writeNat(vparams.length) - writeRefs(vparams) - } - writeRef(tpt) - writeRef(rhs) - TREE - - - case tree@TypeDef(mods, name, tparams, rhs) => - writeNat(TYPEDEFtree) - writeRef(tree.tpe) - writeRef(tree.symbol) - writeRef(mods) - writeRef(name) - writeRef(rhs) - writeRefs(tparams) - TREE - - - case tree@LabelDef(name, params, rhs) => - writeNat(LABELtree) - writeRef(tree.tpe) - writeRef(tree.symbol) - writeRef(name) - writeRef(rhs) - writeRefs(params) - TREE - - - case tree@Import(expr, selectors) => - writeNat(IMPORTtree) - writeRef(tree.tpe) - writeRef(tree.symbol) - writeRef(expr) - for ((from, to) <- selectors) { - writeRef(from) - writeRef(to) - } - TREE - - - case tree@Annotation(constr, elements) => - writeNat(ANNOTATIONtree) - writeRef(tree.tpe) - writeRef(constr) - writeRefs(elements) - TREE - - case tree@DocDef(comment, definition) => + writeRef(tree.tpe) + writeRef(tree.symbol) + writeRef(mods) + writeRef(name) + writeNat(tparams.length) + writeRefs(tparams) + writeNat(vparamss.length) + for(vparams <- vparamss) { + writeNat(vparams.length) + writeRefs(vparams) + } + writeRef(tpt) + writeRef(rhs) + TREE + + case tree@TypeDef(mods, name, tparams, rhs) => + writeNat(TYPEDEFtree) + writeRef(tree.tpe) + writeRef(tree.symbol) + writeRef(mods) + writeRef(name) + writeRef(rhs) + writeRefs(tparams) + TREE + + case tree@LabelDef(name, params, rhs) => + writeNat(LABELtree) + writeRef(tree.tpe) + writeRef(tree.symbol) + writeRef(name) + writeRef(rhs) + writeRefs(params) + TREE + + case tree@Import(expr, selectors) => + writeNat(IMPORTtree) + writeRef(tree.tpe) + writeRef(tree.symbol) + writeRef(expr) + for ((from, to) <- selectors) { + writeRef(from) + writeRef(to) + } + TREE + + case tree@DocDef(comment, definition) => writeNat(DOCDEFtree) - writeRef(tree.tpe) - writeRef(Constant(comment)) - writeRef(definition) - TREE + writeRef(tree.tpe) + writeRef(Constant(comment)) + writeRef(definition) + TREE - case tree@Template(parents, self, body) => + case tree@Template(parents, self, body) => writeNat(TEMPLATEtree) - writeRef(tree.tpe) + writeRef(tree.tpe) writeRef(tree.symbol) writeNat(parents.length) - writeRefs(parents) - writeRef(self) - writeRefs(body) - TREE + writeRefs(parents) + writeRef(self) + writeRefs(body) + TREE - case tree@Block(stats, expr) => + case tree@Block(stats, expr) => writeNat(BLOCKtree) - writeRef(tree.tpe) - writeRef(expr) - writeRefs(stats) - TREE - - case tree@CaseDef(pat, guard, body) => - writeNat(CASEtree) - writeRef(tree.tpe) - writeRef(pat) - writeRef(guard) - writeRef(body) - TREE - - case tree@Sequence(trees) => + writeRef(tree.tpe) + writeRef(expr) + writeRefs(stats) + TREE + + case tree@CaseDef(pat, guard, body) => + writeNat(CASEtree) + writeRef(tree.tpe) + writeRef(pat) + writeRef(guard) + writeRef(body) + TREE + + case tree@Sequence(trees) => writeNat(SEQUENCEtree) - writeRef(tree.tpe) - writeRefs(trees) - TREE + writeRef(tree.tpe) + writeRefs(trees) + TREE - case tree@Alternative(trees) => - writeNat(ALTERNATIVEtree) - writeRef(tree.tpe) - writeRefs(trees) - TREE + case tree@Alternative(trees) => + writeNat(ALTERNATIVEtree) + writeRef(tree.tpe) + writeRefs(trees) + TREE - case tree@Star(elem) => + case tree@Star(elem) => writeNat(STARtree) - writeRef(tree.tpe) - writeRef(elem) - TREE - - case tree@Bind(name, body) => - writeNat(BINDtree) - writeRef(tree.tpe) - writeRef(tree.symbol) - writeRef(name) - writeRef(body) - TREE - - case tree@UnApply(fun: Tree, args) => - writeNat(UNAPPLYtree) - writeRef(tree.tpe) - writeRef(fun) - writeRefs(args) - TREE - - case tree@ArrayValue(elemtpt, trees) => - writeNat(ARRAYVALUEtree) - writeRef(tree.tpe) - writeRef(elemtpt) - writeRefs(trees) - TREE - - - case tree@Function(vparams, body) => + writeRef(tree.tpe) + writeRef(elem) + TREE + + case tree@Bind(name, body) => + writeNat(BINDtree) + writeRef(tree.tpe) + writeRef(tree.symbol) + writeRef(name) + writeRef(body) + TREE + + case tree@UnApply(fun: Tree, args) => + writeNat(UNAPPLYtree) + writeRef(tree.tpe) + writeRef(fun) + writeRefs(args) + TREE + + case tree@ArrayValue(elemtpt, trees) => + writeNat(ARRAYVALUEtree) + writeRef(tree.tpe) + writeRef(elemtpt) + writeRefs(trees) + TREE + + + case tree@Function(vparams, body) => writeNat(FUNCTIONtree) - writeRef(tree.tpe) - writeRef(tree.symbol) - writeRef(body) - writeRefs(vparams) - TREE + writeRef(tree.tpe) + writeRef(tree.symbol) + writeRef(body) + writeRefs(vparams) + TREE - case tree@Assign(lhs, rhs) => + case tree@Assign(lhs, rhs) => writeNat(ASSIGNtree) - writeRef(tree.tpe) - writeRef(lhs) - writeRef(rhs) - TREE + writeRef(tree.tpe) + writeRef(lhs) + writeRef(rhs) + TREE - case tree@If(cond, thenp, elsep) => + case tree@If(cond, thenp, elsep) => writeNat(IFtree) writeRef(tree.tpe) - writeRef(cond) - writeRef(thenp) - writeRef(elsep) - TREE + writeRef(cond) + writeRef(thenp) + writeRef(elsep) + TREE - case tree@Match(selector, cases) => + case tree@Match(selector, cases) => writeNat(MATCHtree) - writeRef(tree.tpe) - writeRef(selector) - writeRefs(cases) - TREE - - case tree@Return(expr) => - writeNat(RETURNtree) - writeRef(tree.tpe) - writeRef(tree.symbol) - writeRef(expr) - TREE - - case tree@Try(block, catches, finalizer) => + writeRef(tree.tpe) + writeRef(selector) + writeRefs(cases) + TREE + + case tree@Return(expr) => + writeNat(RETURNtree) + writeRef(tree.tpe) + writeRef(tree.symbol) + writeRef(expr) + TREE + + case tree@Try(block, catches, finalizer) => writeNat(TREtree) - writeRef(tree.tpe) - writeRef(block) - writeRef(finalizer) - writeRefs(catches) - TREE - - case tree@Throw(expr) => - writeNat(THROWtree) - writeRef(tree.tpe) - writeRef(expr) - TREE - - case tree@New(tpt) => - writeNat(NEWtree) - writeRef(tree.tpe) - writeRef(tpt) - TREE - - case tree@Typed(expr, tpt) => - writeNat(TYPEDtree) - writeRef(tree.tpe) - writeRef(expr) - writeRef(tpt) - TREE - - case tree@TypeApply(fun, args) => - writeNat(TYPEAPPLYtree) - writeRef(tree.tpe) - writeRef(fun) - writeRefs(args) - TREE - - case tree@Apply(fun, args) => - writeNat(APPLYtree) - writeRef(tree.tpe) - writeRef(fun) - writeRefs(args) - TREE - - case tree@ApplyDynamic(qual, args) => - writeNat(APPLYDYNAMICtree) - writeRef(tree.tpe) - writeRef(tree.symbol) - writeRef(qual) - writeRefs(args) - TREE - - case tree@Super(qual, mix) => - writeNat(SUPERtree) - writeRef(tree.tpe) - writeRef(tree.symbol) - writeRef(qual) - writeRef(mix) - TREE + writeRef(tree.tpe) + writeRef(block) + writeRef(finalizer) + writeRefs(catches) + TREE + + case tree@Throw(expr) => + writeNat(THROWtree) + writeRef(tree.tpe) + writeRef(expr) + TREE + + case tree@New(tpt) => + writeNat(NEWtree) + writeRef(tree.tpe) + writeRef(tpt) + TREE + + case tree@Typed(expr, tpt) => + writeNat(TYPEDtree) + writeRef(tree.tpe) + writeRef(expr) + writeRef(tpt) + TREE + + case tree@TypeApply(fun, args) => + writeNat(TYPEAPPLYtree) + writeRef(tree.tpe) + writeRef(fun) + writeRefs(args) + TREE + + case tree@Apply(fun, args) => + writeNat(APPLYtree) + writeRef(tree.tpe) + writeRef(fun) + writeRefs(args) + TREE + + case tree@ApplyDynamic(qual, args) => + writeNat(APPLYDYNAMICtree) + writeRef(tree.tpe) + writeRef(tree.symbol) + writeRef(qual) + writeRefs(args) + TREE + + case tree@Super(qual, mix) => + writeNat(SUPERtree) + writeRef(tree.tpe) + writeRef(tree.symbol) + writeRef(qual) + writeRef(mix) + TREE case tree@This(qual) => - writeNat(THIStree) - writeRef(tree.tpe) - writeRef(tree.symbol) - writeRef(qual) - TREE + writeNat(THIStree) + writeRef(tree.tpe) + writeRef(tree.symbol) + writeRef(qual) + TREE case tree@Select(qualifier, selector) => - writeNat(SELECTtree) - writeRef(tree.tpe) - writeRef(tree.symbol) - writeRef(qualifier) - writeRef(selector) - TREE - - case tree@Ident(name) => - writeNat(IDENTtree) - writeRef(tree.tpe) - writeRef(tree.symbol) - writeRef(name) - TREE - - case tree@Literal(value) => - writeNat(LITERALtree) - writeRef(tree.tpe) - writeRef(value) - TREE - - case tree@TypeTree() => - writeNat(TYPEtree) - writeRef(tree.tpe) - TREE - - case tree@Annotated(annot, arg) => - writeNat(ANNOTATEDtree) - writeRef(tree.tpe) - writeRef(annot) - writeRef(arg) - TREE - - case tree@SingletonTypeTree(ref) => - writeNat(SINGLETONTYPEtree) - writeRef(tree.tpe) - writeRef(ref) - TREE - - case tree@SelectFromTypeTree(qualifier, selector) => - writeNat(SELECTFROMTYPEtree) - writeRef(tree.tpe) - writeRef(qualifier) - writeRef(selector) - TREE - - case tree@CompoundTypeTree(templ: Template) => - writeNat(COMPOUNDTYPEtree) - writeRef(tree.tpe) - writeRef(templ) - TREE - - case tree@AppliedTypeTree(tpt, args) => - writeNat(APPLIEDTYPEtree) - writeRef(tree.tpe) - writeRef(tpt) - writeRefs(args) - TREE - - case tree@TypeBoundsTree(lo, hi) => - writeNat(TYPEBOUNDStree) - writeRef(tree.tpe) - writeRef(lo) - writeRef(hi) - TREE - - case tree@ExistentialTypeTree(tpt, whereClauses) => - writeNat(EXISTENTIALTYPEtree) - writeRef(tree.tpe) - writeRef(tpt) - writeRefs(whereClauses) - TREE - - - case Modifiers(flags, privateWithin, annotations) => + writeNat(SELECTtree) + writeRef(tree.tpe) + writeRef(tree.symbol) + writeRef(qualifier) + writeRef(selector) + TREE + + case tree@Ident(name) => + writeNat(IDENTtree) + writeRef(tree.tpe) + writeRef(tree.symbol) + writeRef(name) + TREE + + case tree@Literal(value) => + writeNat(LITERALtree) + writeRef(tree.tpe) + writeRef(value) + TREE + + case tree@TypeTree() => + writeNat(TYPEtree) + writeRef(tree.tpe) + TREE + + case tree@Annotated(annot, arg) => + writeNat(ANNOTATEDtree) + writeRef(tree.tpe) + writeRef(annot) + writeRef(arg) + TREE + + case tree@SingletonTypeTree(ref) => + writeNat(SINGLETONTYPEtree) + writeRef(tree.tpe) + writeRef(ref) + TREE + + case tree@SelectFromTypeTree(qualifier, selector) => + writeNat(SELECTFROMTYPEtree) + writeRef(tree.tpe) + writeRef(qualifier) + writeRef(selector) + TREE + + case tree@CompoundTypeTree(templ: Template) => + writeNat(COMPOUNDTYPEtree) + writeRef(tree.tpe) + writeRef(templ) + TREE + + case tree@AppliedTypeTree(tpt, args) => + writeNat(APPLIEDTYPEtree) + writeRef(tree.tpe) + writeRef(tpt) + writeRefs(args) + TREE + + case tree@TypeBoundsTree(lo, hi) => + writeNat(TYPEBOUNDStree) + writeRef(tree.tpe) + writeRef(lo) + writeRef(hi) + TREE + + case tree@ExistentialTypeTree(tpt, whereClauses) => + writeNat(EXISTENTIALTYPEtree) + writeRef(tree.tpe) + writeRef(tpt) + writeRefs(whereClauses) + TREE + + case Modifiers(flags, privateWithin, annotations) => val pflags = rawFlagsToPickled(flags) - writeNat((pflags >> 32).toInt) - writeNat((pflags & 0xFFFFFFFF).toInt) - writeRef(privateWithin) - writeRefs(annotations) - MODIFIERS - - case AnnotationInfo(atp, args, assocs) => - writeRef(atp) - writeNat(args.length) - for (arg <- args) writeRef(arg) - for ((name, arg) <- assocs) { - writeRef(name); - writeRef(arg) - } + writeNat((pflags >> 32).toInt) + writeNat((pflags & 0xFFFFFFFF).toInt) + writeRef(privateWithin) + MODIFIERS + + // annotations on types (not linked to a symbol) + case annot@AnnotationInfo(_, _, _) => + writeAnnotation(annot) ANNOTINFO - case arg:AnnotationArgument => - arg.constant match { - case Some(c) => writeBody(c) - case None => writeBody(arg.intTree) - } - case _ => throw new FatalError("bad entry: " + entry + " " + entry.getClass) } // begin writeEntry val startpos = writeIndex + // reserve some space so that the patchNat's most likely won't need to shift writeByte(0); writeByte(0) patchNat(startpos, writeBody(entry)) patchNat(startpos + 1, writeIndex - (startpos + 2)) @@ -1048,27 +1071,30 @@ abstract class Pickler extends SubComponent { else if (c.tag == DoubleTag) print("Double "+c.doubleValue) else if (c.tag == StringTag) { print("String "); printRef(newTermName(c.stringValue)) } else if (c.tag == ClassTag) { print("Class "); printRef(c.typeValue) } - case AnnotatedType(attribs, tp, selfsym) => - if (settings.selfInAnnots.value) { + case AnnotatedType(annots, tp, selfsym) => + if (settings.selfInAnnots.value) { print("ANNOTATEDWSELFtpe ") - printRef(tp) - printRef(selfsym) - printRefs(attribs) - } else { + printRef(tp) + printRef(selfsym) + printRefs(annots) + } else { print("ANNOTATEDtpe ") printRef(tp) - printRefs(attribs) - } - case (target: Symbol, attr @ AnnotationInfo(atp, args, assocs)) => - print("ATTRIBUTE ") + printRefs(annots) + } + case (target: Symbol, AnnotationInfo(atp, args, Nil)) => + print("SYMANNOT ") printRef(target) printRef(atp) for (c <- args) printRef(c) - for ((name, c) <- assocs) { printRef(name); printRef(c) } case (target: Symbol, children: List[_]) => print("CHILDREN ") printRef(target) for (c <- children) printRef(c.asInstanceOf[Symbol]) + case AnnotationInfo(atp, args, Nil) => + print("ANNOTINFO") + printRef(atp) + for (c <- args) printRef(c) case _ => throw new FatalError("bad entry: " + entry + " " + entry.getClass) } |