summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-01-14 00:34:24 -0800
committerJason Zaugg <jzaugg@gmail.com>2014-01-14 00:34:24 -0800
commitef4c5d2f43e912b5562c1372228e9c6ec9f25bb0 (patch)
treebb7385f1971d1b7869eed8678fb0bfef24082e60 /src/compiler
parent4065b5136f2d0d1b6b9bb03f6669c1fd8a2b4e64 (diff)
parentb2f67b5730adccc4cbb24e5b542dc66452869489 (diff)
downloadscala-ef4c5d2f43e912b5562c1372228e9c6ec9f25bb0.tar.gz
scala-ef4c5d2f43e912b5562c1372228e9c6ec9f25bb0.tar.bz2
scala-ef4c5d2f43e912b5562c1372228e9c6ec9f25bb0.zip
Merge pull request #3355 from xeno-by/topic/saturday-night
reshuffles names for blackbox/whitebox contexts, changes bundle notation
Diffstat (limited to 'src/compiler')
-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/runtime/JavaReflectionRuntimes.scala15
-rw-r--r--src/compiler/scala/reflect/macros/runtime/MacroRuntimes.scala6
-rw-r--r--src/compiler/scala/reflect/macros/runtime/ScalaReflectionRuntimes.scala31
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala19
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala16
10 files changed, 40 insertions, 108 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/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 14b0c6baba..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._
@@ -49,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
@@ -63,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: _*)
- }
- }
- }
-}
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 5f079a428b..5492e563dd 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -1710,25 +1710,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
}
}
- /** Create and compile a synthetic compilation unit from the provided tree.
- *
- * This needs to create a virtual file underlying the compilation unit in order to appease SBT.
- * However this file cannot have a randomly generated name, because then SBT 0.13 goes into a vicious loop
- * as described on the mailing list: https://groups.google.com/forum/#!msg/scala-user/r1SgSoVfs0U/Wv4av0LOKukJ
- * Therefore I have introduced an additional parameter that makes everyone specify meaningful file names.
- */
- def compileLate(virtualFileName: String, code: PackageDef) {
- // compatibility with SBT
- // on the one hand, we need to specify some jfile here, otherwise sbt crashes with an NPE (SI-6870)
- // on the other hand, we can't specify the obvious enclosingUnit, because then sbt somehow fails to run tests using type macros
- val fakeJfile = new java.io.File(virtualFileName)
- val virtualFile = new VirtualFile(virtualFileName) { override def file = fakeJfile }
- val sourceFile = new BatchSourceFile(virtualFile, code.toString)
- val unit = new CompilationUnit(sourceFile)
- unit.body = code
- compileLate(unit)
- }
-
/** Reset package class to state at typer (not sure what this
* is needed for?)
*/
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index fdec1edcc0..19fba639e3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -1145,7 +1145,7 @@ trait Implicits {
gen.mkAttributedThis(thisSym)
case _ =>
// if `pre` is not a PDT, e.g. if someone wrote
- // implicitly[scala.reflect.macros.BlackboxContext#TypeTag[Int]]
+ // implicitly[scala.reflect.macros.blackbox.Context#TypeTag[Int]]
// then we need to fail, because we don't know the prefix to use during type reification
// upd. we also need to fail silently, because this is a very common situation
// e.g. quite often we're searching for BaseUniverse#TypeTag, e.g. for a type tag in any universe
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index a1e77515a8..cf82d6baac 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -29,7 +29,7 @@ import Fingerprint._
* Then fooBar needs to point to a static method of the following form:
*
* def fooBar[T: c.WeakTypeTag] // type tag annotation is optional
- * (c: scala.reflect.macros.BlackboxContext)
+ * (c: scala.reflect.macros.blackbox.Context)
* (xs: c.Expr[List[T]])
* : c.Expr[T] = {
* ...
@@ -67,7 +67,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
*
* This solution is very simple, but unfortunately it's also lacking. If we use it, then
* signatures of macro defs become transitively dependent on scala-reflect.jar
- * (because they refer to macro impls, and macro impls refer to scala.reflect.macros.BlackboxContext/WhiteboxContext defined in scala-reflect.jar).
+ * (because they refer to macro impls, and macro impls refer to *box.Context defined in scala-reflect.jar).
* More details can be found in comments to https://issues.scala-lang.org/browse/SI-5940.
*
* Therefore we have to avoid putting macro impls into binding pickles and come up with our own serialization format.
@@ -81,9 +81,9 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
* and various accounting information necessary when composing an argument list for the reflective invocation.
*/
case class MacroImplBinding(
- // Is this macro impl a bundle (a trait extending BlackboxMacro or WhiteboxMacro) or a vanilla def?
+ // Is this macro impl a bundle (a trait extending *box.Macro) or a vanilla def?
val isBundle: Boolean,
- // Is this macro impl blackbox (i.e. having BlackboxContext in its signature)?
+ // Is this macro impl blackbox (i.e. having blackbox.Context in its signature)?
val isBlackbox: Boolean,
// Java class name of the class that contains the macro implementation
// is used to load the corresponding object with Java reflection
@@ -97,8 +97,8 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
// * c.Expr[T] => LiftedTyped
// * c.Tree => LiftedUntyped
// * c.WeakTypeTag[T] => Tagged(index of the type parameter corresponding to that type tag)
- // * everything else (e.g. scala.reflect.macros.BlackboxContext/WhiteboxContext) => Other
- // f.ex. for: def impl[T: WeakTypeTag, U, V: WeakTypeTag](c: BlackboxContext)(x: c.Expr[T], y: c.Tree): (U, V) = ???
+ // * everything else (e.g. *box.Context) => Other
+ // f.ex. for: def impl[T: WeakTypeTag, U, V: WeakTypeTag](c: blackbox.Context)(x: c.Expr[T], y: c.Tree): (U, V) = ???
// `signature` will be equal to List(List(Other), List(LiftedTyped, LiftedUntyped), List(Tagged(0), Tagged(2)))
signature: List[List[Fingerprint]],
// type arguments part of a macro impl ref (the right-hand side of a macro definition)
@@ -116,7 +116,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
* with synthetic content that carries the payload described in `MacroImplBinding`.
*
* For example, for a pair of macro definition and macro implementation:
- * def impl(c: scala.reflect.macros.BlackboxContext): c.Expr[Unit] = ???
+ * def impl(c: scala.reflect.macros.blackbox.Context): c.Expr[Unit] = ???
* def foo: Unit = macro impl
*
* We will have the following annotation added on the macro definition `foo`:
@@ -478,7 +478,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
}
/** Keeps track of macros in-flight.
- * See more informations in comments to `openMacros` in `scala.reflect.macros.WhiteboxContext`.
+ * See more informations in comments to `openMacros` in `scala.reflect.macros.whitebox.Context`.
*/
var _openMacros = List[MacroContext]()
def openMacros = _openMacros