summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-10-12 13:22:29 -0700
committerPaul Phillips <paulp@improving.org>2013-10-12 13:22:29 -0700
commit2e396cfd408b4a10b41dbca7993aae603f290ab5 (patch)
tree48a2c4b8bd95e74496d0504292004fba71afb7ef
parenteaad52c95a4a8c7752b68931902fa63d9d4cc800 (diff)
downloadscala-2e396cfd408b4a10b41dbca7993aae603f290ab5.tar.gz
scala-2e396cfd408b4a10b41dbca7993aae603f290ab5.tar.bz2
scala-2e396cfd408b4a10b41dbca7993aae603f290ab5.zip
Mappings between classes and pickler tags.
This enables a measure of "command/query separation", which is to say: the same method shouldn't go on a side effecting binge and also return a value.
-rw-r--r--src/reflect/scala/reflect/internal/pickling/Translations.scala128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/reflect/scala/reflect/internal/pickling/Translations.scala b/src/reflect/scala/reflect/internal/pickling/Translations.scala
new file mode 100644
index 0000000000..e56cf796cb
--- /dev/null
+++ b/src/reflect/scala/reflect/internal/pickling/Translations.scala
@@ -0,0 +1,128 @@
+/* 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 _: AnnotatedType => ANNOTATEDtpe
+ }
+
+ 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
+ }
+}
+