abstract
class
Compat extends AnyRef
Instance Constructors
-
new
Compat()
Abstract Value Members
-
abstract
val
global: Global
Concrete Value Members
-
final
def
!=(arg0: AnyRef): Boolean
-
final
def
!=(arg0: Any): Boolean
-
final
def
##(): Int
-
final
def
==(arg0: AnyRef): Boolean
-
final
def
==(arg0: Any): Boolean
-
val
DummyValue: Int
-
val
LocalChild: scala.reflect.internal.StdNames.tpnme.NameType
-
-
val
Nullary: scala.tools.nsc.Global.NullaryMethodType.type
-
-
val
ScalaObjectClass: scala.tools.nsc.Global.ClassSymbol
-
final
def
asInstanceOf[T0]: T0
-
def
clone(): AnyRef
-
final
def
devWarning(msg: ⇒ String): Unit
-
final
def
enteringPhase[T](ph: Phase)(op: ⇒ T): T
-
final
def
eq(arg0: AnyRef): Boolean
-
def
equals(arg0: Any): Boolean
-
def
finalize(): Unit
-
final
def
getClass(): Class[_]
-
def
hasMacro(s: scala.tools.nsc.Global.Symbol): Boolean
-
def
hashCode(): Int
-
final
def
isInstanceOf[T0]: Boolean
-
def
moduleSuffix(s: scala.tools.nsc.Global.Symbol): String
-
final
def
ne(arg0: AnyRef): Boolean
-
final
def
notify(): Unit
-
final
def
notifyAll(): Unit
-
implicit
def
symbolCompat(sym: scala.tools.nsc.Global.Symbol): SymbolCompat
-
final
def
synchronized[T0](arg0: ⇒ T0): T0
-
def
toString(): String
-
final
def
wait(): Unit
-
final
def
wait(arg0: Long, arg1: Int): Unit
-
final
def
wait(arg0: Long): Unit
Collection of hacks that make it possible for the compiler interface to stay source compatible with Scala compiler 2.9, 2.10 and 2.11.
One common technique used in
Compat
class is use of implicit conversions to deal with methods that got renamed or moved between different Scala compiler versions.Let's pick a specific example. In Scala 2.9 and 2.10 there was a method called
toplevelClass
defined onSymbol
. In 2.10 that method has been deprecated andenclosingTopLevelClass
method has been introduce as a replacement. In Scala 2.11 the oldtoplevelClass
method has been removed. How can we pick the right version based on availability of those two methods?We define an implicit conversion from Symbol to a class that contains both method definitions:
implicit def symbolCompat(sym: Symbol): SymbolCompat = new SymbolCompat(sym) class SymbolCompat(sym: Symbol) { def enclosingTopLevelClass: Symbol = sym.toplevelClass def toplevelClass: Symbol = throw new RuntimeException("For source compatibility only: should not get here.") }
We assume that client code (code in compiler interface) should always call
enclosingTopLevelClass
method. If we compile that code against 2.11 it will just directly link against method provided by Symbol. However, if we compile against 2.9 or 2.10enclosingTopLevelClass
won't be found so the implicit conversion defined above will kick in. That conversion will provideenclosingTopLevelClass
that simply forwards to the oldtoplevelClass
method that is available in 2.9 and 2.10 so that method will be called in the end. There's one twist: sinceenclosingTopLevelClass
forwards totoplevelClass
which doesn't exist in 2.11! Therefore, we need to also definetoplevelClass
that will be provided by an implicit conversion as well. However, we should never reach that method at runtime if eitherenclosingTopLevelClass
ortoplevelClass
is available on Symbol so this is purely source compatibility stub.The technique described above is used in several places below.