using compat._ to plug source compatibility breakages

This commit makes the code source compatible across Scala 2.10.3
and https://github.com/scala/scala/pull/3452, which is proposed
for inclusion in Scala 2.11.0-RC1.

We only strictly need the incremental compiler to build on Scala
2.11, as that is integrated into the IDE. But we gain valuable
insight into compiler regressions by building *all* of SBT with
2.11.

We only got there recently (the 0.13 branch of SBT now fully cross
compiles with 2.10.3 and 2.11.0-SNAPSHOT), and this aims to keep
things that way.

Once 2.10 support is dropped, SBT macros will be able to exploit
the new reflection APIs in 2.11 to avoid the need for casting
to compiler internals, which aren't governed by binary compatibility.
This has been prototyped by @xeno-by: https://github.com/sbt/sbt/pull/1121
This commit is contained in:
Jason Zaugg 2014-02-15 12:59:03 +01:00
parent 9428bb3344
commit bd943b8e83
5 changed files with 20 additions and 0 deletions

View File

@ -59,6 +59,9 @@ object InputWrapper
private[std] def wrapPrevious[T: c.WeakTypeTag](c: Context)(ts: c.Expr[Any], pos: c.Position): c.Expr[Option[T]] =
wrapImpl[Option[T],InputWrapper.type](c, InputWrapper, WrapPreviousName)(ts, pos)
// TODO 2.11 Remove this after dropping 2.10.x support.
private object HasCompat { val compat = ??? }; import HasCompat._
/** Wraps an arbitrary Tree in a call to the `<s>.<wrapName>` method of this module for later processing by an enclosing macro.
* The resulting Tree is the manually constructed version of:
*
@ -67,6 +70,7 @@ object InputWrapper
def wrapImpl[T: c.WeakTypeTag, S <: AnyRef with Singleton](c: Context, s: S, wrapName: String)(ts: c.Expr[Any], pos: c.Position)(implicit it: c.TypeTag[s.type]): c.Expr[T] =
{
import c.universe.{Apply=>ApplyTree,_}
import compat._
val util = new ContextUtil[c.type](c)
val iw = util.singleton(s)
val tpe = c.weakTypeOf[T]

View File

@ -281,9 +281,13 @@ object TaskMacro
private[this] def iTaskMacro[T: c.WeakTypeTag](c: Context)(t: c.Expr[T]): c.Expr[Task[T]] =
Instance.contImpl[T,Id](c, TaskInstance, TaskConvert, MixedBuilder)(Left(t), Instance.idTransform)
// TODO 2.11 Remove this after dropping 2.10.x support.
private object HasCompat { val compat = ??? }; import HasCompat._
private[this] def inputTaskDynMacro0[T: c.WeakTypeTag](c: Context)(t: c.Expr[Initialize[Task[T]]]): c.Expr[Initialize[InputTask[T]]] =
{
import c.universe.{Apply=>ApplyTree,_}
import compat._
val tag = implicitly[c.WeakTypeTag[T]]
val util = ContextUtil[c.type](c)

View File

@ -32,12 +32,16 @@ object ContextUtil {
def unexpectedTree[C <: Context](tree: C#Tree): Nothing = sys.error("Unexpected macro application tree (" + tree.getClass + "): " + tree)
}
// TODO 2.11 Remove this after dropping 2.10.x support.
private object HasCompat { val compat = ??? }; import HasCompat._
/** Utility methods for macros. Several methods assume that the context's universe is a full compiler (`scala.tools.nsc.Global`).
* This is not thread safe due to the underlying Context and related data structures not being thread safe.
* Use `ContextUtil[c.type](c)` to construct. */
final class ContextUtil[C <: Context](val ctx: C)
{
import ctx.universe.{Apply=>ApplyTree,_}
import compat._
val powerContext = ctx.asInstanceOf[reflect.macros.runtime.Context]
val global: powerContext.universe.type = powerContext.universe

View File

@ -9,11 +9,15 @@ package appmacro
/** A `TupleBuilder` that uses a KList as the tuple representation.*/
object KListBuilder extends TupleBuilder
{
// TODO 2.11 Remove this after dropping 2.10.x support.
private object HasCompat { val compat = ??? }; import HasCompat._
def make(c: Context)(mt: c.Type, inputs: Inputs[c.universe.type]): BuilderResult[c.type] = new BuilderResult[c.type]
{
val ctx: c.type = c
val util = ContextUtil[c.type](c)
import c.universe.{Apply=>ApplyTree,_}
import compat._
import util._
val knilType = c.typeOf[KNil]

View File

@ -14,10 +14,14 @@ object TupleNBuilder extends TupleBuilder
final val MaxInputs = 11
final val TupleMethodName = "tuple"
// TODO 2.11 Remove this after dropping 2.10.x support.
private object HasCompat { val compat = ??? }; import HasCompat._
def make(c: Context)(mt: c.Type, inputs: Inputs[c.universe.type]): BuilderResult[c.type] = new BuilderResult[c.type]
{
val util = ContextUtil[c.type](c)
import c.universe.{Apply=>ApplyTree,_}
import compat._
import util._
val global: Global = c.universe.asInstanceOf[Global]