Make sure AnyVal is involved before checking post erasure

This commit is contained in:
Martin Duhem 2015-11-07 09:06:26 +01:00
parent d41fda6584
commit bfc27f1179
2 changed files with 14 additions and 24 deletions

View File

@ -86,9 +86,6 @@ abstract class Compat {
def enclosingTopLevelClass: Symbol = sym.toplevelClass
def toplevelClass: Symbol = sourceCompatibilityOnly
def isMacro: Boolean = false
def orElse(alt: => Symbol) = if (sym ne NoSymbol) sym else alt
def asType: TypeSymbol = sym.asInstanceOf[TypeSymbol]
def asMethod: MethodSymbol = sym.asInstanceOf[MethodSymbol]
}
@ -104,7 +101,7 @@ abstract class Compat {
private[this] final implicit def miscCompat(n: AnyRef): MiscCompat = new MiscCompat
object DetectMacroImpls {
object MirrorHelper {
private implicit def withRootMirror(x: Any): WithRootMirror = new WithRootMirror(x)
private class DummyMirror {
@ -113,23 +110,9 @@ abstract class Compat {
private class WithRootMirror(x: Any) {
def rootMirror = new DummyMirror
}
private class WithIsScala211(x: Any) {
def isScala211 = false
}
private[this] implicit def withIsScala211(x: Any): WithIsScala211 = new WithIsScala211(x)
lazy val AnyValClass = global.rootMirror.getClassIfDefined("scala.AnyVal")
// Copied from scala/scala since these methods do not exists in Scala < 2.11.x
private def Context_210 = if (settings.isScala211) NoSymbol else global.rootMirror.getClassIfDefined("scala.reflect.macros.Context")
lazy val BlackboxContextClass = global.rootMirror.getClassIfDefined("scala.reflect.macros.blackbox.Context").orElse(Context_210)
lazy val WhiteboxContextClass = global.rootMirror.getClassIfDefined("scala.reflect.macros.whitebox.Context").orElse(Context_210)
/**
* Determines whether a symbol may be compatible with Scala macros' `Context` (e.g. could it be
* the `c: Context` parameter of a macro implementation?). In such cases, we should treat the
* method whose parameter this symbol is as a potential macro implementation.
*/
def isContextCompatible(sym: Symbol) = {
sym.isNonBottomSubClass(BlackboxContextClass) || sym.isNonBottomSubClass(WhiteboxContextClass)
}
def isAnyValSubtype(sym: Symbol): Boolean = sym.isNonBottomSubClass(AnyValClass)
}

View File

@ -181,11 +181,18 @@ class ExtractAPI[GlobalType <: CallbackGlobal](val global: GlobalType,
private def defDef(in: Symbol, s: Symbol): List[xsbti.api.Def] =
{
import DetectMacroImpls._
def hasContextAsParameter(meth: MethodSymbol): Boolean =
meth.paramss.flatten exists (p => isContextCompatible(p.info.typeSymbol))
import MirrorHelper._
val inspectPostErasure = !hasContextAsParameter(s.asMethod)
// Here we must be careful to also consider the type parameters, because a tuple (Foo, Int)
// may become (Int, Int) for instance.
def hasValueClassAsParameter(meth: MethodSymbol): Boolean =
meth.paramss.flatten map (_.info) exists (t => isAnyValSubtype(t.typeSymbol))
// Here too we must care for the type parameters (see above comment).
def hasValueClassAsReturnType(meth: MethodSymbol): Boolean =
isAnyValSubtype(meth.returnType.typeSymbol)
val inspectPostErasure = hasValueClassAsParameter(s.asMethod) || hasValueClassAsReturnType(s.asMethod)
def build(t: Type, typeParams: Array[xsbti.api.TypeParameter], valueParameters: List[xsbti.api.ParameterList]): List[xsbti.api.Def] =
{
def parameterList(syms: List[Symbol]): xsbti.api.ParameterList =