Skip to content
This repository has been archived by the owner on Feb 20, 2019. It is now read-only.

Experiment to compile to 2.12 and cross to 2.11, drop 2.10. #451

Open
wants to merge 5 commits into
base: 0.11.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@ cache:
language: scala

scala:
- 2.11.8
- 2.10.6
- 2.12.2
- 2.11.11
jdk:
- openjdk7
- oraclejdk7
- oraclejdk8

notifications:
email:
Expand Down
9 changes: 7 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Dependencies._ // see project/Dependencies.scala
import scala.xml.{Node => XmlNode, NodeSeq => XmlNodeSeq, _}
import scala.xml.transform.{RewriteRule, RuleTransformer}

val buildVersion = "0.11.0-M2"
val buildVersion = "0.12.0"

def commonSettings = Seq(
version in ThisBuild := buildVersion,
Expand All @@ -13,6 +13,7 @@ def commonSettings = Seq(
case "2.10" => Seq("-Xmax-classfile-name", "254")
case _ => Seq()
}),
scalacOptions ++= Seq("-deprecation"),
organization in ThisBuild := "org.scala-lang.modules",
organizationName in ThisBuild := "LAMP/EPFL",
organizationHomepage in ThisBuild := Some(url("http://lamp.epfl.ch")),
Expand Down Expand Up @@ -143,7 +144,11 @@ lazy val benchmark: Project = (project in file("benchmark")).
dependsOn(core).
settings(commonSettings ++ noPublish ++ benchmarkSettings: _*).
settings(
scalacOptions ++= Seq("-optimise"),
// -optimise is deprecated: In 2.12,
// -optimise enables -opt:l:classpath.
// Check -opt:help for using the Scala 2.12 optimizer.
//scalacOptions ++= Seq("-optimise"),
scalacOptions ++= Seq("-Xlog-implicits"),
libraryDependencies ++= Seq(
"org.scala-lang" % "scala-compiler" % scalaVersion.value,
kryoSerializers, kryo)
Expand Down
3 changes: 1 addition & 2 deletions core/src/main/scala/scala/pickling/Compat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ package scala.pickling

import scala.language.experimental.macros
import scala.language.existentials

import scala.reflect.macros.Context
import scala.reflect.macros.whitebox.Context
import scala.reflect.runtime.{universe => ru}

// this is only necessary because 2.10.x doesn't support macro bundles
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/scala/pickling/Macros.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ trait PickleMacros extends Macro with TypeAnalysis {
val tpe = weakTypeOf[T]
val q"${_}($pickleeArg)" = c.prefix.tree
val endPickle = if (shouldBotherAboutCleaning(tpe)) q"clearPicklees()" else q"";
val pickleeName = newTermName("picklee$pickleTo$")
val builderName = newTermName("builder$pickleTo$")
val pickleeName = TermName("picklee$pickleTo$")
val builderName = TermName("builder$pickleTo$")
q"""
import _root_.scala.pickling._
import _root_.scala.pickling.internal._
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/scala/pickling/PicklingErrors.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ private[pickling] object Feedback {

private[pickling] object MacrosErrors {

import scala.reflect.macros.Context
import scala.reflect.macros.whitebox.Context

def failedGeneration(culprit: String)(implicit c: Context, l: AlgorithmLogger): Nothing = {
l.error(s"Failed pickler/unpickler generation for $culprit")
Expand Down
47 changes: 26 additions & 21 deletions core/src/main/scala/scala/pickling/Tools.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ import scala.pickling.internal._

import scala.language.existentials

import scala.reflect.macros.Context
import scala.reflect.macros.whitebox.Context
import scala.reflect.api.Universe

import scala.collection.mutable.{Map => MutableMap, ListBuffer => MutableList, WeakHashMap}
import java.lang.ref.WeakReference

import HasCompat._
import sun.misc.Unsafe

object Tools {
private val subclassCaches = new WeakHashMap[AnyRef, WeakReference[AnyRef]]()
Expand All @@ -33,6 +32,12 @@ object Tools {
value
}
}

lazy val unsafe: Unsafe = {
val ctor = classOf[Unsafe].getDeclaredConstructor()
ctor.setAccessible(true)
ctor.newInstance()
}
}

class Tools[C <: Context](val c: C) {
Expand All @@ -47,7 +52,7 @@ class Tools[C <: Context](val c: C) {
annotation
}).headOption map {
annotation =>
annotation.javaArgs(newTermName("value")) match {
annotation.javaArgs(TermName("value")) match {
case ArrayArgument(klasses) => klasses.toList map {
case LiteralArgument(constant) =>
constant.value.asInstanceOf[Type].typeSymbol.asType
Expand Down Expand Up @@ -76,7 +81,7 @@ class Tools[C <: Context](val c: C) {
def isRelevantSubclass(baseSym: Symbol, subSym: Symbol) = {
!blackList(baseSym) && !blackList(subSym) && subSym.isClass && {
val subClass = subSym.asClass
subClass.baseClasses.contains(baseSym) && !subClass.isAbstractClass && !subClass.isTrait
subClass.baseClasses.contains(baseSym) && !subClass.isAbstract && !subClass.isTrait
}
}

Expand Down Expand Up @@ -152,7 +157,7 @@ class Tools[C <: Context](val c: C) {
val pkgMembers = pkg.typeSignature.members
pkgMembers foreach (m => {
def analyze(m: Symbol): Unit = {
if (m.name.decoded.contains("$")) () // SI-7251
if (m.name.decodedName.toString.contains("$")) () // SI-7251
else if (m.isClass) m.asClass.baseClasses foreach (bc => updateCache(bc, m))
else if (m.isModule) analyze(m.asModule.moduleClass)
else ()
Expand Down Expand Up @@ -193,7 +198,7 @@ class Tools[C <: Context](val c: C) {
// NOTE: this is an extremely naïve heuristics
// see http://groups.google.com/group/scala-internals/browse_thread/thread/3a43a6364b97b521 for more information
if (tparamsMatch && targsAreConcrete) appliedType(subSym.toTypeConstructor, baseTargs)
else existentialAbstraction(subSym.typeParams, subSym.toType)
else u.internal.existentialAbstraction(subSym.typeParams, subSym.toType)
})
subTpes
}
Expand Down Expand Up @@ -335,30 +340,30 @@ abstract class Macro extends RichTypes { self =>
}

def syntheticPackageName: String = "scala.pickling.synthetic"
def syntheticBaseName(tpe: Type): TypeName = {
def syntheticBaseName(tpe: Type): String = {
val raw = tpe.toString.split('.').map(_.capitalize).mkString("")
val encoded = newTypeName(raw).encoded
newTypeName(encoded)
val encoded = TypeName(raw).encodedName.toString
encoded
}
def syntheticBaseQualifiedName(tpe: Type): TypeName = newTypeName(syntheticPackageName + "." + syntheticBaseName(tpe).toString)
def syntheticBaseQualifiedName(tpe: Type): String = syntheticPackageName + "." + syntheticBaseName(tpe)

def syntheticPicklerName(tpe: Type): TypeName = syntheticBaseName(tpe) + syntheticPicklerSuffix()
def syntheticPicklerQualifiedName(tpe: Type): TypeName = syntheticBaseQualifiedName(tpe) + syntheticPicklerSuffix()
def syntheticPicklerName(tpe: Type): TypeName = TypeName(syntheticBaseName(tpe) + syntheticPicklerSuffix())
def syntheticPicklerQualifiedName(tpe: Type): TypeName = TypeName(syntheticBaseQualifiedName(tpe) + syntheticPicklerSuffix())
def syntheticPicklerSuffix(): String = "Pickler"

def syntheticUnpicklerName(tpe: Type): TypeName = syntheticBaseName(tpe) + syntheticUnpicklerSuffix()
def syntheticUnpicklerQualifiedName(tpe: Type): TypeName = syntheticBaseQualifiedName(tpe) + syntheticUnpicklerSuffix()
def syntheticUnpicklerName(tpe: Type): TypeName = TypeName(syntheticBaseName(tpe) + syntheticUnpicklerSuffix())
def syntheticUnpicklerQualifiedName(tpe: Type): TypeName = TypeName(syntheticBaseQualifiedName(tpe) + syntheticUnpicklerSuffix())
def syntheticUnpicklerSuffix(): String = "Unpickler"

def syntheticPicklerUnpicklerName(tpe: Type): TypeName = syntheticBaseName(tpe) + syntheticPicklerUnpicklerSuffix()
def syntheticPicklerUnpicklerQualifiedName(tpe: Type): TypeName = syntheticBaseQualifiedName(tpe) + syntheticPicklerUnpicklerSuffix()
def syntheticPicklerUnpicklerName(tpe: Type): TypeName = TypeName(syntheticBaseName(tpe) + syntheticPicklerUnpicklerSuffix())
def syntheticPicklerUnpicklerQualifiedName(tpe: Type): TypeName = TypeName(syntheticBaseQualifiedName(tpe) + syntheticPicklerUnpicklerSuffix())
def syntheticPicklerUnpicklerSuffix(): String = "PicklerUnpickler"

private var reflectivePrologueEmitted = false // TODO: come up with something better
def reflectively(target: String, fir: FieldIR)(body: Tree => Tree): List[Tree] = reflectively(newTermName(target), fir)(body)
def reflectively(target: String, fir: FieldIR)(body: Tree => Tree): List[Tree] = reflectively(TermName(target), fir)(body)

def reflectivelyWithoutGetter(target: String, fir: FieldIR)(body: Tree => Tree): List[Tree] = {
val pickleeName = newTermName(target)
val pickleeName = TermName(target)
val getFieldValue = q"""
val clazz = $pickleeName.getClass
scala.util.Try(clazz.getDeclaredField(${fir.name})).map { javaField =>
Expand Down Expand Up @@ -389,8 +394,8 @@ abstract class Macro extends RichTypes { self =>
// val field = fir.field.get
val owner = if (fir.param.nonEmpty) fir.param.get.owner
else fir.accessor.get.owner
val ownerSymbol = c.fresh(newTermName(fir.name + "Owner"))
val firSymbol = c.fresh(newTermName(fir.name + "Symbol"))
val ownerSymbol = c.freshName(TermName(fir.name + "Owner"))
val firSymbol = c.freshName(TermName(fir.name + "Symbol"))
// TODO: make sure this works for:
// 1) private[this] fields
// 2) inherited private[this] fields
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/scala/pickling/binary/Util.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package scala.pickling.binary

object UnsafeMemory {
import sun.misc.Unsafe
private[pickling] val unsafe: Unsafe =
scala.concurrent.util.Unsafe.instance
import scala.pickling.Tools
private[pickling] val unsafe: Unsafe = Tools.unsafe
private[pickling] val byteArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Byte]])
private[pickling] val shortArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Short]])
private[pickling] val intArrayOffset: Long = unsafe.arrayBaseOffset(classOf[Array[Int]])
Expand Down
3 changes: 1 addition & 2 deletions core/src/main/scala/scala/pickling/generator/Compat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ package generator
import scala.language.experimental.macros
import scala.language.existentials
import scala.pickling.Pickler

import scala.reflect.macros.Context
import scala.reflect.macros.whitebox.Context
import scala.reflect.runtime.{universe => ru}

private[pickling] object Compat {
Expand Down
36 changes: 19 additions & 17 deletions core/src/main/scala/scala/pickling/generator/ScalaSymbols.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package generator

import HasCompat._
import scala.reflect.api.Universe
import scala.reflect.macros.Context
import scala.reflect.macros.whitebox.Context


private[pickling] class UnclosedSubclassesException(errors: Seq[String]) extends Exception(errors.mkString("\n")) {
Expand Down Expand Up @@ -68,13 +68,13 @@ private[pickling] class IrScalaSymbols[U <: Universe with Singleton, C <: Contex
override def className: String = classSymbol.fullName
override def isTrait: Boolean = classSymbol.isTrait
override def isAbstract: Boolean = {
classSymbol.isAbstractType
// NOte: This doesn't exist on scala 2.10
classSymbol.isAbstract
// Note: This doesn't exist on scala 2.10
//classSymbol.isAbstract
classSymbol.isAbstractClass
classSymbol.isAbstract
}
override def primaryConstructor: Option[IrConstructor] = {
tpe.declaration(nme.CONSTRUCTOR) match {
tpe.decl(termNames.CONSTRUCTOR) match {
// NOTE: primary ctor is always the first in the list
case overloaded: TermSymbol => Some(new ScalaIrConstructor(overloaded.alternatives.head.asMethod, this))
case primaryCtor: MethodSymbol => Some(new ScalaIrConstructor(primaryCtor, this))
Expand All @@ -90,7 +90,7 @@ private[pickling] class IrScalaSymbols[U <: Universe with Singleton, C <: Contex
}.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
val declaredVars = (tpe.decls).collect { case meth: MethodSymbol => meth }.toList
// NOTE - There can be duplication between 'constructor args' and 'declared vars' we'd like to avoid.
declaredVars
}
Expand All @@ -111,13 +111,15 @@ private[pickling] class IrScalaSymbols[U <: Universe with Singleton, C <: Contex
def isConstructorArg(x: TermSymbol): Boolean = {
// Note available in scala 2.10
// x.owner.isConstructor
x.owner.name == nme.CONSTRUCTOR
x.owner.name == termNames.CONSTRUCTOR
}
tpe.members.filter(_.isTerm).map(_.asTerm).filter(x => x.isVal || x.isVar).map(x => new ScalaIrField(x, this)).toList
}
override def companion: Option[IrClass] = {
if(tpe.typeSymbol.isType) {
val tmp = tpe.typeSymbol.asType.companionSymbol
// method companionSymbol in trait SymbolApi is deprecated:
// Use `companion` instead, but beware of possible changes in behavior
val tmp = tpe.typeSymbol.asType.companion
if(tmp.isType) {
val cp = tmp.asType.toType
if (cp != NoType) Some(new ScalaIrClass(cp, quantified, rawType))
Expand Down Expand Up @@ -173,7 +175,7 @@ private[pickling] class IrScalaSymbols[U <: Universe with Singleton, C <: Contex
//System.err.println(s"baseSymTpe: ${baseSymTpe.toString}")

val rawSymTpe = baseSymTpe match { case NullaryMethodType(ntpe) => ntpe; case ntpe => ntpe }
val result = existentialAbstraction(quantified, rawSymTpe)
val result = internal.existentialAbstraction(quantified, rawSymTpe)
//System.err.println(s"result = ${result.toString}")
result

Expand All @@ -189,9 +191,9 @@ private[pickling] class IrScalaSymbols[U <: Universe with Singleton, C <: Contex

override def isMarkedTransient: 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]))
((field.accessed != NoSymbol) && field.accessed.annotations.exists(_.tree.tpe =:= typeOf[scala.transient])) ||
((field.getter != NoSymbol) && field.getter.annotations.exists(_.tree.tpe =:= typeOf[scala.transient])) ||
(field.annotations.exists(_.tree.tpe =:= typeOf[scala.transient]))
}
// Here we wrokaround a scala symbol issue where the field is never annotated with transient.
val isSameNameAsTransientVar = owner.transientArgNames(fieldName)
Expand Down Expand Up @@ -229,18 +231,18 @@ private[pickling] class IrScalaSymbols[U <: Universe with Singleton, C <: Contex
private class ScalaIrMethod(mthd: MethodSymbol, override val owner: ScalaIrClass) extends IrMethod {
import owner.fillParameters
override def parameterNames: List[List[String]] =
mthd.paramss.map(_.map(_.name.toString))
mthd.paramLists.map(_.map(_.name.toString))

override def parameterTypes[U <: Universe with Singleton](u: U): List[List[u.Type]] = {
mthd.paramss.map(_.map(x => fillParameters(x).asSeenFrom(owner.tpe, owner.tpe.typeSymbol)).map(_.asInstanceOf[u.Type]))
mthd.paramLists.map(_.map(x => fillParameters(x).asSeenFrom(owner.tpe, owner.tpe.typeSymbol)).map(_.asInstanceOf[u.Type]))
}

override def isMarkedTransient: 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]))
((mthd.accessed != NoSymbol) && mthd.accessed.annotations.exists(_.tree.tpe =:= typeOf[scala.transient])) ||
((mthd.getter != NoSymbol) && mthd.getter.annotations.exists(_.tree.tpe =:= typeOf[scala.transient])) ||
(mthd.annotations.exists(_.tree.tpe =:= typeOf[scala.transient]))
}
tr.getOrElse(false)
}
Expand Down
Loading