From 499c5e722843e7941e891ed8092483e3a169bc29 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Fri, 6 Nov 2015 11:27:40 +0100 Subject: [PATCH] Correct fix against SO and macros problem --- .../src/main/scala/xsbt/Compat.scala | 26 +++++++++++++++++++ .../src/main/scala/xsbt/ExtractAPI.scala | 13 +++++----- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/compile/interface/src/main/scala/xsbt/Compat.scala b/compile/interface/src/main/scala/xsbt/Compat.scala index 3b007d252..472858380 100644 --- a/compile/interface/src/main/scala/xsbt/Compat.scala +++ b/compile/interface/src/main/scala/xsbt/Compat.scala @@ -87,6 +87,8 @@ abstract class Compat { def enclosingTopLevelClass: Symbol = sym.toplevelClass def toplevelClass: Symbol = sourceCompatibilityOnly def isMacro: Boolean = false + def orElse(alt: => Symbol) = alt + def asType: TypeSymbol = sym.asInstanceOf[TypeSymbol] } val DummyValue = 0 @@ -101,6 +103,30 @@ abstract class Compat { private[this] final implicit def miscCompat(n: AnyRef): MiscCompat = new MiscCompat + object DetectMacroImpls { + + private implicit def withRootMirror(x: Any): WithRootMirror = new WithRootMirror(x) + private class DummyMirror { + def getClassIfDefined(x: String): Symbol = NoSymbol + } + 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) + + // 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) + def isContextCompatible(sym: Symbol) = { + sym.isNonBottomSubClass(BlackboxContextClass) || sym.isNonBottomSubClass(WhiteboxContextClass) + } + + } + object MacroExpansionOf { def unapply(tree: Tree): Option[Tree] = { diff --git a/compile/interface/src/main/scala/xsbt/ExtractAPI.scala b/compile/interface/src/main/scala/xsbt/ExtractAPI.scala index efea1af20..ea198111c 100644 --- a/compile/interface/src/main/scala/xsbt/ExtractAPI.scala +++ b/compile/interface/src/main/scala/xsbt/ExtractAPI.scala @@ -178,15 +178,14 @@ class ExtractAPI[GlobalType <: CallbackGlobal](val global: GlobalType, private def viewer(s: Symbol) = (if (s.isModule) s.moduleClass else s).thisType private def printMember(label: String, in: Symbol, t: Type) = println(label + " in " + in + " : " + t + " (debug: " + debugString(t) + " )") + private def defDef(in: Symbol, s: Symbol): List[xsbti.api.Def] = { - def collectAll(acc: Set[Symbol], s: Symbol): Set[Symbol] = - if (acc contains s) acc - else - ((s.info.members.sorted ++ s.children) foldLeft (acc + s)) { - case (acc, sym) => collectAll(acc, sym) - } - val inspectPostErasure = !collectAll(Set.empty, in.enclosingTopLevelClass).exists(_.isMacro) + import DetectMacroImpls._ + def hasContextAsParameter(meth: MethodSymbol): Boolean = + meth.paramss.flatten exists (p => isContextCompatible(p.info.typeSymbol)) + + val inspectPostErasure = !hasContextAsParameter(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 =