summaryrefslogtreecommitdiff
path: root/src/compiler/scala/reflect
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/reflect')
-rw-r--r--src/compiler/scala/reflect/macros/compiler/Errors.scala2
-rw-r--r--src/compiler/scala/reflect/macros/compiler/Resolvers.scala35
-rw-r--r--src/compiler/scala/reflect/macros/compiler/Validators.scala18
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Context.scala4
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Enclosures.scala4
-rw-r--r--src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala15
-rw-r--r--src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala14
-rw-r--r--src/compiler/scala/reflect/macros/runtime/ScalaReflectionRuntimes.scala31
8 files changed, 38 insertions, 85 deletions
diff --git a/src/compiler/scala/reflect/macros/compiler/Errors.scala b/src/compiler/scala/reflect/macros/compiler/Errors.scala
index 4c30a9a85c..280baa2a42 100644
--- a/src/compiler/scala/reflect/macros/compiler/Errors.scala
+++ b/src/compiler/scala/reflect/macros/compiler/Errors.scala
@@ -51,7 +51,7 @@ trait Errors extends Traces {
def MacroBundleNonStaticError() = bundleRefError("macro bundles must be static")
- def MacroBundleWrongShapeError() = bundleRefError("macro bundles must be monomorphic traits extending either BlackboxMacro or WhiteboxMacro and not implementing their `val c: BlackboxContext/WhiteboxContext` member")
+ def MacroBundleWrongShapeError() = bundleRefError("macro bundles must be concrete classes having a single constructor with a `val c: Context` parameter")
// compatibility errors
diff --git a/src/compiler/scala/reflect/macros/compiler/Resolvers.scala b/src/compiler/scala/reflect/macros/compiler/Resolvers.scala
index e4851632a5..d35f1c32a9 100644
--- a/src/compiler/scala/reflect/macros/compiler/Resolvers.scala
+++ b/src/compiler/scala/reflect/macros/compiler/Resolvers.scala
@@ -40,36 +40,11 @@ trait Resolvers {
}
val untypedImplRef = typer.silent(_.typedTypeConstructor(maybeBundleRef)) match {
- case SilentResultValue(result) if mightBeMacroBundleType(result.tpe) =>
- val bundleProto = result.tpe.typeSymbol
- val bundlePkg = bundleProto.enclosingPackageClass
- if (!isMacroBundleProtoType(bundleProto.tpe)) MacroBundleWrongShapeError()
- if (!bundleProto.owner.isStaticOwner) MacroBundleNonStaticError()
-
- // synthesize the bundle, i.e. given a static `trait Foo extends Macro { def expand = ... } `
- // create a top-level definition `class Foo$Bundle(val c: BlackboxContext/WhiteboxContext) extends Foo` in a package next to `Foo`
- val bundlePid = gen.mkUnattributedRef(bundlePkg)
- val bundlePrefix =
- if (bundlePkg == EmptyPackageClass) bundleProto.fullName('$')
- else bundleProto.fullName('$').substring(bundlePkg.fullName('$').length + 1)
- val bundleName = TypeName(bundlePrefix + tpnme.MACRO_BUNDLE_SUFFIX)
- val existingBundle = bundleProto.enclosingPackageClass.info.decl(bundleName)
- if (!currentRun.compiles(existingBundle)) {
- val contextType = if (isBlackboxMacroBundleType(bundleProto.tpe)) BlackboxContextClass.tpe else WhiteboxContextClass.tpe
- def mkContextValDef(flags: Long) = ValDef(Modifiers(flags), nme.c, TypeTree(contextType), EmptyTree)
- val contextField = mkContextValDef(PARAMACCESSOR)
- val contextParam = mkContextValDef(PARAM | PARAMACCESSOR)
- val bundleCtor = DefDef(Modifiers(), nme.CONSTRUCTOR, Nil, List(List(contextParam)), TypeTree(), Block(List(pendingSuperCall), Literal(Constant(()))))
- val bundleParent = gen.mkAppliedTypeTree(Ident(bundleProto), bundleProto.typeParams.map(sym => Ident(sym.name)))
- val bundleTemplate = Template(List(bundleParent), noSelfType, List(contextField, bundleCtor))
- val bundle = atPos(bundleProto.pos)(ClassDef(NoMods, bundleName, bundleProto.typeParams.map(TypeDef(_)), bundleTemplate))
- currentRun.compileLate(bundleName + ".scala", PackageDef(bundlePid, List(bundle)))
- }
-
- // synthesize the macro impl reference, which is going to look like:
- // `new FooBundle(???).macroName` plus the optional type arguments
- val bundleInstance = New(Select(bundlePid, bundleName), List(List(Ident(Predef_???))))
- atPos(macroDdef.rhs.pos)(gen.mkTypeApply(Select(bundleInstance, methName), targs))
+ case SilentResultValue(result) if looksLikeMacroBundleType(result.tpe) =>
+ val bundle = result.tpe.typeSymbol
+ if (!isMacroBundleType(bundle.tpe)) MacroBundleWrongShapeError()
+ if (!bundle.owner.isStaticOwner) MacroBundleNonStaticError()
+ atPos(macroDdef.rhs.pos)(gen.mkTypeApply(Select(New(bundle, Ident(Predef_???)), methName), targs))
case _ =>
macroDdef.rhs
}
diff --git a/src/compiler/scala/reflect/macros/compiler/Validators.scala b/src/compiler/scala/reflect/macros/compiler/Validators.scala
index 5936b52890..02c1f7c431 100644
--- a/src/compiler/scala/reflect/macros/compiler/Validators.scala
+++ b/src/compiler/scala/reflect/macros/compiler/Validators.scala
@@ -26,9 +26,9 @@ trait Validators {
if (macroImpl.isOverloaded) MacroImplOverloadedError()
val implicitParams = aparamss.flatten filter (_.isImplicit)
if (implicitParams.nonEmpty) MacroImplNonTagImplicitParameters(implicitParams)
- val declaredInStaticObject = isImplMethod && (macroImplOwner.isStaticOwner || macroImplOwner.moduleClass.isStaticOwner)
- val declaredInTopLevelClass = isImplBundle && macroImplOwner.owner.isPackageClass
- if (!declaredInStaticObject && !declaredInTopLevelClass) MacroImplReferenceWrongShapeError()
+ val effectiveOwner = if (isImplMethod) macroImplOwner else macroImplOwner.owner
+ val declaredInStaticObject = effectiveOwner.isStaticOwner || effectiveOwner.moduleClass.isStaticOwner
+ if (!declaredInStaticObject) MacroImplReferenceWrongShapeError()
}
private def checkMacroDefMacroImplCorrespondence() = {
@@ -93,20 +93,20 @@ trait Validators {
*
* For the following macro impl:
* def fooBar[T: c.WeakTypeTag]
- * (c: scala.reflect.macros.BlackboxContext)
+ * (c: scala.reflect.macros.blackbox.Context)
* (xs: c.Expr[List[T]])
* : c.Expr[T] = ...
*
* This function will return:
- * (c: scala.reflect.macros.BlackboxContext)(xs: c.Expr[List[T]])c.Expr[T]
+ * (c: scala.reflect.macros.blackbox.Context)(xs: c.Expr[List[T]])c.Expr[T]
*
* Note that type tag evidence parameters are not included into the result.
* Type tag context bounds for macro impl tparams are optional.
* Therefore compatibility checks ignore such parameters, and we don't need to bother about them here.
*
* This method cannot be reduced to just macroImpl.info, because macro implementations might
- * come in different shapes. If the implementation is an apply method of a BlackboxMacro/WhiteboxMacro-compatible object,
- * then it won't have (c: BlackboxContext/WhiteboxContext) in its parameters, but will rather refer to BlackboxMacro/WhiteboxMacro.c.
+ * come in different shapes. If the implementation is an apply method of a *box.Macro-compatible object,
+ * then it won't have (c: *box.Context) in its parameters, but will rather refer to *boxMacro.c.
*
* @param macroImpl The macro implementation symbol
*/
@@ -123,8 +123,8 @@ trait Validators {
* def foo[T](xs: List[T]): T = macro fooBar
*
* This function will return:
- * (c: scala.reflect.macros.BlackboxContext)(xs: c.Expr[List[T]])c.Expr[T] or
- * (c: scala.reflect.macros.WhiteboxContext)(xs: c.Expr[List[T]])c.Expr[T]
+ * (c: scala.reflect.macros.blackbox.Context)(xs: c.Expr[List[T]])c.Expr[T] or
+ * (c: scala.reflect.macros.whitebox.Context)(xs: c.Expr[List[T]])c.Expr[T]
*
* Note that type tag evidence parameters are not included into the result.
* Type tag context bounds for macro impl tparams are optional.
diff --git a/src/compiler/scala/reflect/macros/contexts/Context.scala b/src/compiler/scala/reflect/macros/contexts/Context.scala
index 7b79b52a18..87dac18849 100644
--- a/src/compiler/scala/reflect/macros/contexts/Context.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Context.scala
@@ -3,8 +3,8 @@ package contexts
import scala.tools.nsc.Global
-abstract class Context extends scala.reflect.macros.BlackboxContext
- with scala.reflect.macros.WhiteboxContext
+abstract class Context extends scala.reflect.macros.blackbox.Context
+ with scala.reflect.macros.whitebox.Context
with Aliases
with Enclosures
with Names
diff --git a/src/compiler/scala/reflect/macros/contexts/Enclosures.scala b/src/compiler/scala/reflect/macros/contexts/Enclosures.scala
index bb88c8d5e1..5e931817b5 100644
--- a/src/compiler/scala/reflect/macros/contexts/Enclosures.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Enclosures.scala
@@ -8,10 +8,6 @@ trait Enclosures {
import universe._
- type MacroRole = analyzer.MacroRole
- def APPLY_ROLE = analyzer.APPLY_ROLE
- def macroRole: MacroRole
-
private lazy val site = callsiteTyper.context
private lazy val enclTrees = site.enclosingContextChain map (_.tree)
private lazy val enclPoses = enclosingMacros map (_.macroApplication.pos) filterNot (_ eq NoPosition)
diff --git a/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala b/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala
index 450cb4d9ea..ecdd48db22 100644
--- a/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala
+++ b/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala
@@ -2,7 +2,9 @@ package scala.reflect.macros
package runtime
import scala.reflect.runtime.ReflectionUtils
-import scala.reflect.macros.{Context => ApiContext}
+import scala.reflect.macros.blackbox.{Context => BlackboxContext}
+import scala.reflect.macros.whitebox.{Context => WhiteboxContext}
+import java.lang.reflect.{Constructor => jConstructor}
trait JavaReflectionRuntimes {
self: scala.tools.nsc.typechecker.Analyzer =>
@@ -19,8 +21,15 @@ trait JavaReflectionRuntimes {
macroLogVerbose(s"successfully loaded macro impl as ($implClass, $implMeth)")
args => {
val implObj =
- if (isBundle) implClass.getConstructor(classOf[ApiContext]).newInstance(args.c)
- else ReflectionUtils.staticSingletonInstance(implClass)
+ if (isBundle) {
+ def isMacroContext(clazz: Class[_]) = clazz == classOf[BlackboxContext] || clazz == classOf[WhiteboxContext]
+ def isBundleCtor(ctor: jConstructor[_]) = ctor.getParameterTypes match {
+ case Array(param) if isMacroContext(param) => true
+ case _ => false
+ }
+ val Array(bundleCtor) = implClass.getConstructors.filter(isBundleCtor)
+ bundleCtor.newInstance(args.c)
+ } else ReflectionUtils.staticSingletonInstance(implClass)
val implArgs = if (isBundle) args.others else args.c +: args.others
implMeth.invoke(implObj, implArgs.asInstanceOf[Seq[AnyRef]]: _*)
}
diff --git a/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala b/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala
index 7de3341304..5fd9c0db34 100644
--- a/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala
+++ b/src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala
@@ -4,7 +4,7 @@ package runtime
import scala.reflect.internal.Flags._
import scala.reflect.runtime.ReflectionUtils
-trait MacroRuntimes extends JavaReflectionRuntimes with ScalaReflectionRuntimes {
+trait MacroRuntimes extends JavaReflectionRuntimes {
self: scala.tools.nsc.typechecker.Analyzer =>
import global._
@@ -19,8 +19,14 @@ trait MacroRuntimes extends JavaReflectionRuntimes with ScalaReflectionRuntimes
* @return Requested runtime if macro implementation can be loaded successfully from either of the mirrors,
* `null` otherwise.
*/
+ def macroRuntime(expandee: Tree): MacroRuntime = pluginsMacroRuntime(expandee)
+
+ /** Default implementation of `macroRuntime`.
+ * Can be overridden by analyzer plugins (see AnalyzerPlugins.pluginsMacroRuntime for more details)
+ */
private val macroRuntimesCache = perRunCaches.newWeakMap[Symbol, MacroRuntime]
- def macroRuntime(macroDef: Symbol): MacroRuntime = {
+ def standardMacroRuntime(expandee: Tree): MacroRuntime = {
+ val macroDef = expandee.symbol
macroLogVerbose(s"looking for macro implementation: $macroDef")
if (fastTrack contains macroDef) {
macroLogVerbose("macro expansion is serviced by a fast track")
@@ -43,8 +49,7 @@ trait MacroRuntimes extends JavaReflectionRuntimes with ScalaReflectionRuntimes
/** Abstracts away resolution of macro runtimes.
*/
type MacroRuntime = MacroArgs => Any
- class MacroRuntimeResolver(val macroDef: Symbol) extends JavaReflectionResolvers
- with ScalaReflectionResolvers {
+ class MacroRuntimeResolver(val macroDef: Symbol) extends JavaReflectionResolvers {
val binding = loadMacroImplBinding(macroDef).get
val isBundle = binding.isBundle
val className = binding.className
@@ -57,7 +62,6 @@ trait MacroRuntimes extends JavaReflectionRuntimes with ScalaReflectionRuntimes
try {
macroLogVerbose(s"resolving macro implementation as $className.$methName (isBundle = $isBundle)")
macroLogVerbose(s"classloader is: ${ReflectionUtils.show(defaultMacroClassloader)}")
- // resolveScalaReflectionRuntime(defaultMacroClassloader)
resolveJavaReflectionRuntime(defaultMacroClassloader)
} catch {
case ex: Exception =>
diff --git a/src/compiler/scala/reflect/macros/runtime/ScalaReflectionRuntimes.scala b/src/compiler/scala/reflect/macros/runtime/ScalaReflectionRuntimes.scala
deleted file mode 100644
index 50f64310f8..0000000000
--- a/src/compiler/scala/reflect/macros/runtime/ScalaReflectionRuntimes.scala
+++ /dev/null
@@ -1,31 +0,0 @@
-package scala.reflect.macros
-package runtime
-
-import scala.reflect.runtime.{universe => ru}
-
-trait ScalaReflectionRuntimes {
- self: scala.tools.nsc.typechecker.Analyzer =>
-
- trait ScalaReflectionResolvers {
- self: MacroRuntimeResolver =>
-
- def resolveScalaReflectionRuntime(classLoader: ClassLoader): MacroRuntime = {
- val macroMirror: ru.JavaMirror = ru.runtimeMirror(classLoader)
- val implContainerSym = macroMirror.classSymbol(Class.forName(className, true, classLoader))
- val implMethSym = implContainerSym.typeSignature.member(ru.TermName(methName)).asMethod
- macroLogVerbose(s"successfully loaded macro impl as ($implContainerSym, $implMethSym)")
- args => {
- val implContainer =
- if (isBundle) {
- val implCtorSym = implContainerSym.typeSignature.member(ru.nme.CONSTRUCTOR).asMethod
- macroMirror.reflectClass(implContainerSym).reflectConstructor(implCtorSym)(args.c)
- } else {
- macroMirror.reflectModule(implContainerSym.module.asModule).instance
- }
- val implMeth = macroMirror.reflect(implContainer).reflectMethod(implMethSym)
- val implArgs = if (isBundle) args.others else args.c +: args.others
- implMeth(implArgs: _*)
- }
- }
- }
-}