summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2014-01-12 12:01:12 +0100
committerEugene Burmako <xeno.by@gmail.com>2014-01-12 18:03:51 +0100
commite36888c3d953048483ccea9a95d5984b54ad6ebc (patch)
treea6ba3268a238acb5310dcfdefcf8234c0b7f6a77 /src/compiler
parent3a689f5c426436aea716567625fd6167e57bef92 (diff)
downloadscala-e36888c3d953048483ccea9a95d5984b54ad6ebc.tar.gz
scala-e36888c3d953048483ccea9a95d5984b54ad6ebc.tar.bz2
scala-e36888c3d953048483ccea9a95d5984b54ad6ebc.zip
prohibits constructor overloading for macro bundles
As per Jason’s feedback, this commit handles overloaded constructors in macro bundles. The backend now checks that we have a constructor of a correct type. The frontend now prohibits multiple constructors altogether.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/macros/compiler/Errors.scala2
-rw-r--r--src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala15
2 files changed, 13 insertions, 4 deletions
diff --git a/src/compiler/scala/reflect/macros/compiler/Errors.scala b/src/compiler/scala/reflect/macros/compiler/Errors.scala
index 6b6d4248aa..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 concrete classes having a single `val c: Context` parameter")
+ 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/runtime/JavaReflectionRuntimes.scala b/src/compiler/scala/reflect/macros/runtime/JavaReflectionRuntimes.scala
index 8ad38ff5f0..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.blackbox.{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.getConstructors().head.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]]: _*)
}