Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package scala.pickling
package generator
importHasCompat._
import scala.reflect.api.Universeimport scala.reflect.macros.Contextprivate[pickling] classUnclosedSubclassesException(errors: Seq[String]) extendsException(errors.mkString("\n")) {
overridedeffillInStackTrace(): Throwable = this
}
/** An implementation of a symbol lookup table based on scala reflection.
*
*
* Note: Scala reflection/compiler have known inaccuracies in some lookups. For example, the compiler may
* remove all knowledge of private symbols from Java classes, because generally it doesn't care about
* Java's privates.
*/private[pickling] classIrScalaSymbols[U <: Universe with Singleton, C <: Context](override val u: U, tools: Tools[C]) extendsIrSymbolLoader[U](u) {
import u._
import compat._
import definitions._
import tools._
import scala.pickling.internal.RichSymbol// HELPER METHODS FOR SUBCLASSESdefisCaseClass(sym: TypeSymbol): Boolean =
sym.isClass && sym.asClass.isCaseClass
defisClosed(sym: tools.u.TypeSymbol): Boolean =
whyNotClosed(sym).isEmpty
defwhyNotClosed(sym: tools.u.TypeSymbol): Seq[String] = {
if (sym.isEffectivelyFinal)
Nilelseif (isCaseClass(sym.asInstanceOf[u.TypeSymbol]))
Nilelseif (sym.isClass) {
val classSym = sym.asClass
if (tools.treatAsSealed(classSym)) {
tools.directSubclasses(classSym).flatMap(cl => whyNotClosed(cl.asType))
} else {
List(s"'${sym.fullName}' allows unknown subclasses (it is not sealed or final isCaseClass=${isCaseClass(sym.asInstanceOf[u.TypeSymbol])} isEffectivelyFinal=${sym.isEffectivelyFinal} isSealed=${classSym.isSealed} directSubclasses=${tools.directSubclasses(classSym)})")
}
} else {
List(s"'${sym.fullName}' is not a class or trait")
}
}
defnewClass(tpe: Type): IrClass =
if(tpe.typeSymbol.isClass) {
val (quantified, rawTpe) = tpe match { caseExistentialType(quantified, rtpe) => (quantified, rtpe); case rtpe => (Nil, rtpe) }
newScalaIrClass(tpe, quantified, rawTpe)
} else sys.error(s"Don't know how to handle $tpe, ${tpe.typeSymbol.owner}")
// Implementation of IrClass symbol using a scala Type.privateclassScalaIrClass(private[generator] val tpe: Type) extendsIrClass{
//System.err.println(s"New class: $tpe")defthis(tpe: Type, quantified: List[Symbol], rawType: Type) = this(tpe)
private[generator] val (quantified, rawType) = tpe match { caseExistentialType(quantified, rtpe) => (quantified, rtpe); case rtpe => (Nil, rtpe) }
privatedefclassSymbol= tpe.typeSymbol.asClass
/** The class name represented by this symbol. */overridedefclassName: String = classSymbol.fullName
overridedefisTrait: Boolean = classSymbol.isTrait
overridedefisAbstract: Boolean = {
classSymbol.isAbstractType
// NOte: This doesn't exist on scala 2.10//classSymbol.isAbstract
classSymbol.isAbstractClass
}
overridedefprimaryConstructor: Option[IrConstructor] = {
tpe.declaration(nme.CONSTRUCTOR) match {
// NOTE: primary ctor is always the first in the listcase overloaded: TermSymbol => Some(newScalaIrConstructor(overloaded.alternatives.head.asMethod, this))
case primaryCtor: MethodSymbol => Some(newScalaIrConstructor(primaryCtor, this))
caseNoSymbol => None
}
}
privateval allMethods = {
val constructorArgs = tpe.members.collect {
case meth: MethodSymbol => meth
}.toList.filter { x =>
//System.err.println(s"$x - param: ${x.isParamAccessor}, var: ${x.isVar}, val: ${x.isVal}, owner: ${x.owner}, owner-constructor: ${x.owner.isConstructor}")
(x.owner == tpe.typeSymbol) && (x.isParamAccessor)
}.toList
//System.err.println(s"$tpe has constructor args:\n - ${constructorArgs.mkString("\n - ")}")// NOTE - This will only collect memeber vals/vals. It's possible some things come from the constructor.val declaredVars = (tpe.declarations).collect { case meth: MethodSymbol => meth }.toList
// NOTE - There can be duplication between 'constructor args' and 'declared vars' we'd like to avoid.
declaredVars
}
// The list of all "accessor" method symbols of the class. We filter to only these to avoid ahving too many symbols//private val fields? = allMethods.collect { case meth: MethodSymbol if meth.isAccessor || meth.isParamAccessor => meth }// Here we only return "accessor" methods.overrideval methods: Seq[IrMethod] = {
(allMethods map { mth =>
newScalaIrMethod(mth, this)
})(collection.breakOut)
}
overridedeffields: Seq[IrField] = {
// TODO - It's possible some terms come from the constructor. We don't really know if they are available at runtime// or not, so we may ignore them.// It's actually a really bad scenario because you can't distinguish between something which// is actually annotated as a val and something which is just a constructor argument.defisConstructorArg(x: TermSymbol): Boolean = {
// Note available in scala 2.10// x.owner.isConstructor
x.owner.name == nme.CONSTRUCTOR
}
tpe.members.filter(_.isTerm).map(_.asTerm).filter(x => x.isVal || x.isVar).map(x => newScalaIrField(x, this)).toList
}
overridedefcompanion: Option[IrClass] = {
if(tpe.typeSymbol.isType) {
val tmp = tpe.typeSymbol.asType.companionSymbol
if(tmp.isType) {
val cp = tmp.asType.toType
if (cp != NoType) Some(newScalaIrClass(cp, quantified, rawType))
elseNone
}
elseNone
} elseNone
}
overridedefisScala= !tpe.typeSymbol.isJava
overridedefisScalaModule: Boolean = classSymbol.isModuleClass
/** True if this class is a scala case class. */overridedefisCaseClass: Boolean = classSymbol.isCaseClass
/** True if this class is 'final' (or cannot be extended). */overridedefisFinal: Boolean = classSymbol.isFinal
overridedeftpe[U <: UniversewithSingleton](u: U): u.Type = tpe.asInstanceOf[u.Type]
/** The set of known subclasses for this type. May be empty if we don't know of any.
* Note: This method will return a failure if the known subclasses aren't "closed"
*/overridedefclosedSubclasses: scala.util.Try[Seq[IrClass]] = {
val closedError = whyNotClosed(tpe.typeSymbol.asType.asInstanceOf[tools.u.TypeSymbol])
closedError match {
caseNil =>
scala.util.Success({
val dispatchees = tools.compileTimeDispatchees(tpe.asInstanceOf[tools.c.universe.Type], tools.u.rootMirror, false)
dispatchees.map(t => newScalaIrClass(t.asInstanceOf[u.Type], quantified, rawType))(collection.breakOut)
})
case errors =>
scala.util.Failure(newUnclosedSubclassesException(errors))
}
}
// TODO - use tpe.key implicit from helpers to get a consistent tag key here.overridedeftoString= s"$tpe"/** Returs all the parent classes (traits, interfaces, etc,) for this type. */overridedefparentClasses: Seq[IrClass] = {
// We always drop the first class, becasue it is ourself.
classSymbol.baseClasses.drop(1) filter (_.isClass) map { x =>
//new ScalaIrClass(fillParameters(x), quantified, rawType)newScalaIrClass(tpe.baseType(x), quantified, rawType)
}
}
/** Fill is the concrete types for a given symbol using the concrete types this class knows about. */finaldeffillParameters(baseSym: Symbol): Type = {
//System.err.println(s"baseSym= ${baseSym.toString}")val baseSymTpe = baseSym.typeSignature.asSeenFrom(rawType, rawType.typeSymbol.asClass)
//System.err.println(s"baseSymTpe: ${baseSymTpe.toString}")val rawSymTpe = baseSymTpe match { caseNullaryMethodType(ntpe) => ntpe; case ntpe => ntpe }
val result = existentialAbstraction(quantified, rawSymTpe)
//System.err.println(s"result = ${result.toString}")
result
}
/** This is part of a workaround for issues discovering transient annotations on fields. */private[IrScalaSymbols] val transientArgNames: Set[String] = {
IrSymbol.allDeclaredMethodIncludingSubclasses(this).filter(x => x.isParamAccessor || x.isVar || x.isVal).filter(_.isMarkedTransient).map(_.methodName).toSet
}
}
privateclassScalaIrField(field: TermSymbol, override val owner: ScalaIrClass) extendsIrField{
overridedefisMarkedTransient: Boolean = {
val tr = scala.util.Try {
((field.accessed != NoSymbol) && field.accessed.annotations.exists(_.tpe =:= typeOf[scala.transient])) ||
((field.getter != NoSymbol) && field.getter.annotations.exists(_.tpe =:= typeOf[scala.transient])) ||
(field.annotations.exists(_.tpe =:= typeOf[scala.transient]))
}
// Here we wrokaround a scala symbol issue where the field is never annotated with transient.val isSameNameAsTransientVar = owner.transientArgNames(fieldName)
isSameNameAsTransientVar || tr.getOrElse(false)
}
privatedefremoveTrailingSpace(orig: String): String =
orig match {
// TODO - Why do we need this random fix, is this a bug?case x if x endsWith " " =>
//System.err.println(s"Caugh funny symbol: $field, name: ${field.name}, fullName: ${field.fullName}")
x.dropRight(1).toString
case x => x
}
overridedeffieldName: String = removeTrailingSpace(field.name.toString)
overridedeftpe[U <: UniversewithSingleton](u: U): u.Type = field.typeSignature.asSeenFrom(owner.tpe, owner.tpe.typeSymbol).asInstanceOf[u.Type]
overridedefisPublic: Boolean = field.isPublic
overridedefisStatic: Boolean = field.isStatic
overridedefisFinal: Boolean = field.isFinal
overridedefisScala: Boolean = true// We don't generate fields for java typesoverridedefisPrivate: Boolean = field.isPrivate
overridedefisParameter: Boolean = field.isParameter
// TODO - isPrivateThis// TODO - We want to make sure this name matches what we'll see in reflection.overridedeftoString= s"field ${fieldName}: ${field.typeSignature}"// TODO - some kind of check to see if the field actually exists in runtime. Scala sometimes erases// fields completely, and having a field is actually more of a runtime concern for scala.// Unforutnately, this TODO may be impossible.overridedefjavaReflectionName: String =
removeTrailingSpace(field.name.toString)
}
privateclassScalaIrMethod(mthd: MethodSymbol, override val owner: ScalaIrClass) extendsIrMethod{
import owner.fillParameters
overridedefparameterNames: List[List[String]] =
mthd.paramss.map(_.map(_.name.toString))
overridedefparameterTypes[U <: UniversewithSingleton](u: U): List[List[u.Type]] = {
mthd.paramss.map(_.map(x => fillParameters(x).asSeenFrom(owner.tpe, owner.tpe.typeSymbol)).map(_.asInstanceOf[u.Type]))
}
overridedefisMarkedTransient: Boolean = {
// TODO - is this correct?val tr = scala.util.Try {
((mthd.accessed != NoSymbol) && mthd.accessed.annotations.exists(_.tpe =:= typeOf[scala.transient])) ||
((mthd.getter != NoSymbol) && mthd.getter.annotations.exists(_.tpe =:= typeOf[scala.transient])) ||
(mthd.annotations.exists(_.tpe =:= typeOf[scala.transient]))
}
tr.getOrElse(false)
}
overridedefmethodName: String = {
mthd.name.toString match {
// TODO - Why do we need this random fix, is this a bug?case x if x endsWith " " => x.dropRight(1).toString
case x => x
}
}
overridedefjavaReflectionName: String = {
val isPrivateThis = {
// Note: Scala 2.10 does not support this//mthd.isPrivateThisfalse
}
if(mthd.isParamAccessor && (mthd.isPrivate || isPrivateThis)) {
// Here we check to see if we need to encode the funky name that scala gives private fields to avoid conflicts// with fields in the parent class.defmakeEncodedJvmName(names: List[String], buf: StringBuilder, isStart: Boolean = false): String =
names match {
caseNil => buf.toString
case next :: rest if isStart =>
buf.append(next)
makeEncodedJvmName(rest, buf, isStart = false)
case next :: Nil =>
buf.append("$$").append(next)
buf.toString
case next :: rest =>
buf.append("$").append(next)
makeEncodedJvmName(rest, buf, isStart = false)
}
val split = mthd.fullName.split('.').toList
val result = makeEncodedJvmName(split, newStringBuilder, true)
result
} else mthd match {
// Note: Not available in Scala 2.10.x//case TermName(n) => ncase x: TermName => x.toString
case _ => mthd.name.encodedName.toString
}
}
// TODO - Figure out if the method is JVM public or not (different than scala public)overridedefisPublic: Boolean = mthd.isPublic
overridedefisStatic: Boolean = mthd.isStatic
overridedefisFinal: Boolean = mthd.isFinal
overridedefisPrivate: Boolean = mthd.isPrivate
overridedefisScala: Boolean = !mthd.isJava
overridedeftoString= s"def ${methodName}: ${mthd.typeSignature}"overridedefisParamAccessor: Boolean = mthd.isParamAccessor
overridedefisVal: Boolean = mthd.isVal
overridedefisVar: Boolean =
(mthd.getter != NoSymbol) && (mthd.setter != NoSymbol) &&
(mthd.setter != mthd) // THis is hack so the setter doesn't show up in our list of vars.overridedefreturnType[U <: UniversewithSingleton](u: Universe): u.Type =
mthd.returnType.asSeenFrom(owner.tpe, owner.tpe.typeSymbol).asInstanceOf[u.Type]
overridedefsetter: Option[IrMethod] = {
mthd.setter match {
caseNoSymbol => Nonecase x => Some(newScalaIrMethod(x.asMethod, owner))
}
}
}
privateclassScalaIrConstructor(mthd: MethodSymbol, owner: ScalaIrClass) extendsScalaIrMethod(mthd, owner) withIrConstructor{
overridedefreturnType[U <: UniversewithSingleton](u: Universe): u.Type = owner.tpe[u.type](u)
overridedeftoString= s"CONSTRUCTOR ${owner} (${parameterNames.mkString(",")}}): ${mthd.typeSignature}"
}
}