/* NSC -- new Scala compiler * Copyright 2005-2013 LAMP/EPFL * @author Paul Phillips */ package scala package reflect package internal package pickling import PickleFormat._ import util.shortClassOfInstance trait Translations { self: SymbolTable => def isTreeSymbolPickled(code: Int): Boolean = (code: @annotation.switch) match { case PACKAGEtree | CLASStree | MODULEtree | VALDEFtree | DEFDEFtree | TYPEDEFtree | LABELtree => true case IMPORTtree | TEMPLATEtree | BINDtree | FUNCTIONtree | RETURNtree => true case APPLYDYNAMICtree | SUPERtree | THIStree | SELECTtree | IDENTtree => true case _ => false } /** This method should be equivalent to tree.hasSymbolField, but that method * doesn't do us any good when we're unpickling because we need to know based * on the Int tag - the tree doesn't exist yet. Thus, this method is documentation only. */ def isTreeSymbolPickled(tree: Tree): Boolean = isTreeSymbolPickled(picklerSubTag(tree)) // The ad hoc pattern matching of tuples out of AnyRefs is a // truly terrible idea. It reaches the height of its powers in // combination with scala's insistence on helpfully tupling // multiple arguments passed to a single-arg AnyRef. def picklerTag(ref: AnyRef): Int = ref match { case tp: Type => picklerTag(tp) case sym: Symbol => picklerTag(sym) case const: Constant => LITERAL + const.tag case _: Tree => TREE // its sub tag more precisely identifies it case _: TermName => TERMname case _: TypeName => TYPEname case _: ArrayAnnotArg => ANNOTARGARRAY // an array of annotation arguments case _: AnnotationInfo => ANNOTINFO // annotations on types (not linked to a symbol) case (_: Symbol, _: AnnotationInfo) => SYMANNOT // symbol annotations, i.e. on terms case (_: Symbol, _: List[_]) => CHILDREN // the direct subclasses of a sealed symbol case _: Modifiers => MODIFIERS case _ => sys.error(s"unpicklable entry ${shortClassOfInstance(ref)} $ref") } /** Local symbols only. The assessment of locality depends * on convoluted conditions which depends in part on the root * symbol being pickled, so it cannot be reproduced here. * The pickler tags at stake are EXTMODCLASSref and EXTref. * Those tags are never produced here - such symbols must be * excluded prior to calling this method. */ def picklerTag(sym: Symbol): Int = sym match { case NoSymbol => NONEsym case _: ClassSymbol => CLASSsym case _: TypeSymbol if sym.isAbstractType => TYPEsym case _: TypeSymbol => ALIASsym case _: TermSymbol if sym.isModule => MODULEsym case _: TermSymbol => VALsym } def picklerTag(tpe: Type): Int = tpe match { case NoType => NOtpe case NoPrefix => NOPREFIXtpe case _: ThisType => THIStpe case _: SingleType => SINGLEtpe case _: SuperType => SUPERtpe case _: ConstantType => CONSTANTtpe case _: TypeBounds => TYPEBOUNDStpe case _: TypeRef => TYPEREFtpe case _: RefinedType => REFINEDtpe case _: ClassInfoType => CLASSINFOtpe case _: MethodType => METHODtpe case _: PolyType => POLYtpe case _: NullaryMethodType => POLYtpe // bad juju, distinct ints are not at a premium! case _: ExistentialType => EXISTENTIALtpe case StaticallyAnnotatedType(_, _) => ANNOTATEDtpe case _: AnnotatedType => picklerTag(tpe.underlying) } def picklerSubTag(tree: Tree): Int = tree match { case EmptyTree => EMPTYtree case _: PackageDef => PACKAGEtree case _: ClassDef => CLASStree case _: ModuleDef => MODULEtree case _: ValDef => VALDEFtree case _: DefDef => DEFDEFtree case _: TypeDef => TYPEDEFtree case _: LabelDef => LABELtree case _: Import => IMPORTtree // case _: DocDef => DOCDEFtree case _: Template => TEMPLATEtree case _: Block => BLOCKtree case _: CaseDef => CASEtree case _: Alternative => ALTERNATIVEtree case _: Star => STARtree case _: Bind => BINDtree case _: UnApply => UNAPPLYtree case _: ArrayValue => ARRAYVALUEtree case _: Function => FUNCTIONtree case _: Assign => ASSIGNtree case _: If => IFtree case _: Match => MATCHtree case _: Return => RETURNtree case _: Try => TREtree // TREtree? case _: Throw => THROWtree case _: New => NEWtree case _: Typed => TYPEDtree case _: TypeApply => TYPEAPPLYtree case _: Apply => APPLYtree case _: ApplyDynamic => APPLYDYNAMICtree case _: Super => SUPERtree case _: This => THIStree case _: Select => SELECTtree case _: Ident => IDENTtree case _: Literal => LITERALtree case _: TypeTree => TYPEtree case _: Annotated => ANNOTATEDtree case _: SingletonTypeTree => SINGLETONTYPEtree case _: SelectFromTypeTree => SELECTFROMTYPEtree case _: CompoundTypeTree => COMPOUNDTYPEtree case _: AppliedTypeTree => APPLIEDTYPEtree case _: TypeBoundsTree => TYPEBOUNDStree case _: ExistentialTypeTree => EXISTENTIALTYPEtree } }