From bfc27f117915077481ddd3b719c4985a3493432a Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Sat, 7 Nov 2015 09:06:26 +0100 Subject: [PATCH] Make sure AnyVal is involved before checking post erasure --- .../src/main/scala/xsbt/Compat.scala | 23 +++---------------- .../src/main/scala/xsbt/ExtractAPI.scala | 15 ++++++++---- 2 files changed, 14 insertions(+), 24 deletions(-) diff --git a/compile/interface/src/main/scala/xsbt/Compat.scala b/compile/interface/src/main/scala/xsbt/Compat.scala index 18214ee3a..8a5ca6a3d 100644 --- a/compile/interface/src/main/scala/xsbt/Compat.scala +++ b/compile/interface/src/main/scala/xsbt/Compat.scala @@ -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) } diff --git a/compile/interface/src/main/scala/xsbt/ExtractAPI.scala b/compile/interface/src/main/scala/xsbt/ExtractAPI.scala index ea198111c..b3227376d 100644 --- a/compile/interface/src/main/scala/xsbt/ExtractAPI.scala +++ b/compile/interface/src/main/scala/xsbt/ExtractAPI.scala @@ -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 =