diff options
-rw-r--r-- | src/compiler/scala/reflect/macros/util/Traces.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Macros.scala | 42 | ||||
-rw-r--r-- | src/library/scala/PartialFunction.scala | 2 | ||||
-rw-r--r-- | src/reflect/scala/reflect/runtime/ReflectionUtils.scala | 12 | ||||
-rw-r--r-- | test/files/run/macro-system-properties.check | 26 | ||||
-rw-r--r-- | test/files/run/macro-system-properties.scala | 16 |
6 files changed, 68 insertions, 32 deletions
diff --git a/src/compiler/scala/reflect/macros/util/Traces.scala b/src/compiler/scala/reflect/macros/util/Traces.scala index d16916b753..2dffc68745 100644 --- a/src/compiler/scala/reflect/macros/util/Traces.scala +++ b/src/compiler/scala/reflect/macros/util/Traces.scala @@ -6,8 +6,6 @@ trait Traces { val macroDebugLite = globalSettings.YmacrodebugLite.value val macroDebugVerbose = globalSettings.YmacrodebugVerbose.value - val macroTraceLite = scala.tools.nsc.util.trace when (macroDebugLite || macroDebugVerbose) - val macroTraceVerbose = scala.tools.nsc.util.trace when macroDebugVerbose @inline final def macroLogLite(msg: => Any) { if (macroDebugLite || macroDebugVerbose) println(msg) } @inline final def macroLogVerbose(msg: => Any) { if (macroDebugVerbose) println(msg) } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 25091562b3..5ad568b1e6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -341,11 +341,14 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { } import SigGenerator._ - macroTraceVerbose("generating macroImplSigs for: ")(macroDef) - macroTraceVerbose("tparams are: ")(tparams) - macroTraceVerbose("vparamss are: ")(vparamss) - macroTraceVerbose("retTpe is: ")(retTpe) - macroTraceVerbose("macroImplSig is: ")((paramss, implRetTpe)) + macroLogVerbose(sm""" + |generating macroImplSigs for: $macroDef + |tparams are: $tparams + |vparamss are: $vparamss + |retTpe is: $retTpe + |macroImplSig is: $paramss, $implRetTpe + """.trim) + (paramss, implRetTpe) } /** Verifies that the body of a macro def typechecks to a reference to a static public non-overloaded method, @@ -507,7 +510,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { type MacroRuntime = MacroArgs => Any private val macroRuntimesCache = perRunCaches.newWeakMap[Symbol, MacroRuntime] private def macroRuntime(macroDef: Symbol): MacroRuntime = { - macroTraceVerbose("looking for macro implementation: ")(macroDef) + macroLogVerbose(s"looking for macro implementation: $macroDef") if (fastTrack contains macroDef) { macroLogVerbose("macro expansion is serviced by a fast track") fastTrack(macroDef) @@ -524,18 +527,18 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { // upd. my latest experiments show that everything's okay // it seems that in 2.10.1 we can easily switch to Scala reflection try { - macroTraceVerbose("loading implementation class: ")(className) - macroTraceVerbose("classloader is: ")(ReflectionUtils.show(macroClassloader)) + macroLogVerbose(s"loading implementation class: $className") + macroLogVerbose(s"classloader is: ${ReflectionUtils.show(macroClassloader)}") val implObj = ReflectionUtils.staticSingletonInstance(macroClassloader, className) // relies on the fact that macro impls cannot be overloaded // so every methName can resolve to at maximum one method val implMeths = implObj.getClass.getDeclaredMethods.find(_.getName == methName) val implMeth = implMeths getOrElse { throw new NoSuchMethodException(s"$className.$methName") } - macroLogVerbose("successfully loaded macro impl as (%s, %s)".format(implObj, implMeth)) + macroLogVerbose(s"successfully loaded macro impl as ($implObj, $implMeth)") args => implMeth.invoke(implObj, ((args.c +: args.others) map (_.asInstanceOf[AnyRef])): _*) } catch { case ex: Exception => - macroTraceVerbose(s"macro runtime failed to load: ")(ex.toString) + macroLogVerbose(s"macro runtime failed to load: ${ex.toString}") macroDef setFlag IS_ERROR null } @@ -579,8 +582,8 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { if (argcDoesntMatch && !nullaryArgsEmptyParams) { typer.TyperErrorGen.MacroPartialApplicationError(expandee) } val argss: List[List[Any]] = exprArgs.toList - macroTraceVerbose("context: ")(context) - macroTraceVerbose("argss: ")(argss) + macroLogVerbose(s"context: $context") + macroLogVerbose(s"argss: $argss") val preparedArgss: List[List[Any]] = if (fastTrack contains macroDef) { @@ -604,7 +607,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { // whereas V won't be resolved by asSeenFrom and need to be loaded directly from `expandee` which needs to contain a TypeApply node // also, macro implementation reference may contain a regular type as a type argument, then we pass it verbatim val binding = loadMacroImplBinding(macroDef) - macroTraceVerbose("binding: ")(binding) + macroLogVerbose(s"binding: $binding") val tags = binding.signature filter (_ != -1) map (paramPos => { val targ = binding.targs(paramPos).tpe.typeSymbol val tpe = if (targ.isTypeParameterOrSkolem) { @@ -622,7 +625,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { targ.tpe context.WeakTypeTag(tpe) }) - macroTraceVerbose("tags: ")(tags) + macroLogVerbose(s"tags: $tags") // transforms argss taking into account varargness of paramss // note that typetag context bounds are only declared on macroImpls @@ -639,7 +642,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { } else as }) } - macroTraceVerbose("preparedArgss: ")(preparedArgss) + macroLogVerbose(s"preparedArgss: $preparedArgss") MacroArgs(context, preparedArgss.flatten) } @@ -697,7 +700,8 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { val numErrors = reporter.ERROR.count def hasNewErrors = reporter.ERROR.count > numErrors val result = typer.context.withImplicitsEnabled(typer.typed(tree, EXPRmode, pt)) - macroTraceVerbose(s"""${if (hasNewErrors) "failed to typecheck" else "successfully typechecked"} against $phase $pt:\n$result\n""")(result) + macroLogVerbose(s"""${if (hasNewErrors) "failed to typecheck" else "successfully typechecked"} against $phase $pt:\n$result""") + result } var expectedTpe = expandee.tpe @@ -774,7 +778,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { withInfoLevel(nodePrinters.InfoLevel.Quiet) { if (expandee.symbol.isErroneous || (expandee exists (_.isErroneous))) { val reason = if (expandee.symbol.isErroneous) "not found or incompatible macro implementation" else "erroneous arguments" - macroTraceVerbose("cancelled macro expansion because of %s: ".format(reason))(expandee) + macroLogVerbose(s"cancelled macro expansion because of $reason: $expandee") return Cancel(typer.infer.setError(expandee)) } @@ -848,7 +852,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { private def macroExpandWithoutRuntime(typer: Typer, expandee: Tree): MacroExpansionResult = { import typer.TyperErrorGen._ val fallbackSym = expandee.symbol.nextOverriddenSymbol orElse MacroImplementationNotFoundError(expandee) - macroTraceLite("falling back to: ")(fallbackSym) + macroLogLite(s"falling back to: $fallbackSym") def mkFallbackTree(tree: Tree): Tree = { tree match { @@ -900,7 +904,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { undetparams --= undetNoMore map (_.id) if (undetparams.isEmpty) { hasPendingMacroExpansions = true - macroTraceVerbose("macro expansion is pending: ")(expandee) + macroLogVerbose(s"macro expansion is pending: $expandee") } case _ => // do nothing diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala index 7ff5a33586..9ff648a05a 100644 --- a/src/library/scala/PartialFunction.scala +++ b/src/library/scala/PartialFunction.scala @@ -81,7 +81,7 @@ trait PartialFunction[-A, +B] extends (A => B) { self => override def andThen[C](k: B => C): PartialFunction[A, C] = new AndThen[A, B, C] (this, k) - /** Turns this partial function into an plain function returning an `Option` result. + /** Turns this partial function into a plain function returning an `Option` result. * @see Function.unlift * @return a function that takes an argument `x` to `Some(this(x))` if `this` * is defined for `x`, and to `None` otherwise. diff --git a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala index 7b093e0e80..33ad6d2430 100644 --- a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala +++ b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala @@ -28,15 +28,6 @@ private[scala] object ReflectionUtils { case ex if pf isDefinedAt unwrapThrowable(ex) => pf(unwrapThrowable(ex)) } - private def systemProperties: Iterator[(String, String)] = { - import scala.collection.JavaConverters._ - System.getProperties.asScala.iterator - } - - private def inferBootClasspath: String = ( - systemProperties find (_._1 endsWith ".boot.class.path") map (_._2) getOrElse "" - ) - def show(cl: ClassLoader): String = { import scala.language.reflectiveCalls @@ -51,7 +42,8 @@ private[scala] object ReflectionUtils { case cl if cl != null && isAbstractFileClassLoader(cl.getClass) => cl.asInstanceOf[{val root: scala.reflect.io.AbstractFile}].root.canonicalPath case null => - inferBootClasspath + val loadBootCp = (flavor: String) => scala.util.Properties.propOrNone(flavor + ".boot.class.path") + loadBootCp("sun") orElse loadBootCp("java") getOrElse "<unknown>" case _ => "<unknown>" } diff --git a/test/files/run/macro-system-properties.check b/test/files/run/macro-system-properties.check new file mode 100644 index 0000000000..dce976df02 --- /dev/null +++ b/test/files/run/macro-system-properties.check @@ -0,0 +1,26 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> + +scala> import language.experimental._, reflect.macros.Context +import language.experimental._ +import reflect.macros.Context + +scala> object GrabContext { + def lastContext = Option(System.getProperties.get("lastContext").asInstanceOf[reflect.macros.runtime.Context]) + // System.properties lets you stash true globals (unlike statics which are classloader scoped) + def impl(c: Context)() = { System.getProperties.put("lastContext", c); c.literalUnit } + def grab() = macro impl + } +defined module GrabContext + +scala> object Test { class C(implicit a: Any) { GrabContext.grab } } +defined module Test + +scala> object Test { class C(implicit a: Any) { GrabContext.grab } } +defined module Test + +scala> + +scala> diff --git a/test/files/run/macro-system-properties.scala b/test/files/run/macro-system-properties.scala new file mode 100644 index 0000000000..e182defc81 --- /dev/null +++ b/test/files/run/macro-system-properties.scala @@ -0,0 +1,16 @@ +import scala.tools.nsc._ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + def code = """ + import language.experimental._, reflect.macros.Context + object GrabContext { + def lastContext = Option(System.getProperties.get("lastContext").asInstanceOf[reflect.macros.runtime.Context]) + // System.properties lets you stash true globals (unlike statics which are classloader scoped) + def impl(c: Context)() = { System.getProperties.put("lastContext", c); c.literalUnit } + def grab() = macro impl + } + object Test { class C(implicit a: Any) { GrabContext.grab } } + object Test { class C(implicit a: Any) { GrabContext.grab } } + """ +} |