summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/internal/Flags.scala10
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/LiftCode.scala57
-rw-r--r--src/library/scala/reflect/api/Modifier.scala4
4 files changed, 70 insertions, 3 deletions
diff --git a/src/compiler/scala/reflect/internal/Flags.scala b/src/compiler/scala/reflect/internal/Flags.scala
index b95042341a..8366c6d63a 100644
--- a/src/compiler/scala/reflect/internal/Flags.scala
+++ b/src/compiler/scala/reflect/internal/Flags.scala
@@ -458,6 +458,7 @@ class Flags extends ModifierFlags {
case Modifier.interface => INTERFACE
case Modifier.mutable => MUTABLE
case Modifier.parameter => PARAM
+ case Modifier.`macro` => MACRO
case Modifier.covariant => COVARIANT
case Modifier.contravariant => CONTRAVARIANT
case Modifier.preSuper => PRESUPER
@@ -471,6 +472,15 @@ class Flags extends ModifierFlags {
case Modifier.paramAccessor => PARAMACCESSOR
case Modifier.bynameParameter => BYNAMEPARAM
}
+
+ def flagsOfModifiers(mods: List[Modifier.Value]): Long =
+ (mods :\ 0L) { (mod, curr) => curr | flagOfModifier(mod) }
+
+ def modifierOfFlag(flag: Long): Option[Modifier.Value] =
+ Modifier.values find { mod => flagOfModifier(mod) == flag }
+
+ def modifiersOfFlags(flags: Long): List[Modifier.Value] =
+ pickledListOrder map (mask => modifierOfFlag(flags & mask)) flatMap { mod => mod }
}
object Flags extends Flags { }
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index b15f338938..6be15e4e98 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -159,6 +159,8 @@ trait ScalaSettings extends AbsScalaSettings
val Ytyperdebug = BooleanSetting ("-Ytyper-debug", "Trace all type assignments.")
val Yinferdebug = BooleanSetting ("-Yinfer-debug", "Trace type inference and implicit search.")
val Ypmatdebug = BooleanSetting ("-Ypmat-debug", "Trace all pattern matcher activity.")
+ val Yreifycopypaste =
+ BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.")
val Yreifydebug = BooleanSetting ("-Yreify-debug", "Trace reification actions.")
val Yreplsync = BooleanSetting ("-Yrepl-sync", "Do not use asynchronous code for repl startup")
val Yrepldebug = BooleanSetting ("-Yrepl-debug", "Trace all repl activity.") .
diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
index f55fe4f75e..b395f9095e 100644
--- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala
+++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
@@ -57,6 +57,59 @@ abstract class LiftCode extends Transform with TypingTransformers {
val reifyDebug = settings.Yreifydebug.value
val debugTrace = util.trace when reifyDebug
+ val reifyCopypaste = settings.Yreifycopypaste.value
+ def printCopypaste(tree: Tree) {
+ import scala.reflect.api.Modifier
+ import scala.reflect.api.Modifier._
+
+ def copypasteModifier(mod: Modifier.Value): String = mod match {
+ case mod @ (
+ `protected` | `private` | `override` |
+ `abstract` | `final` | `sealed` |
+ `implicit` | `lazy` | `macro` |
+ `case` | `trait`) => "`" + mod.toString + "`"
+ case mod => mod.toString
+ }
+
+ for (line <- (tree.toString.split(Properties.lineSeparator) drop 2 dropRight 1)) {
+ var s = line.trim
+ s = s.replace("$mr.", "")
+ s = s.replace(".apply", "")
+ s = s.replace("scala.collection.immutable.", "")
+ s = "List\\[List\\[.*?\\].*?\\]".r.replaceAllIn(s, "List")
+ s = "List\\[.*?\\]".r.replaceAllIn(s, "List")
+ s = s.replace("immutable.this.Nil", "List()")
+ s = s.replace("modifiersFromInternalFlags", "Modifiers")
+ s = s.replace("Modifiers(0L, newTypeName(\"\"), List())", "Modifiers()")
+ s = """Modifiers\((\d+)L, newTypeName\("(.*?)"\), List\((.*?)\)\)""".r.replaceAllIn(s, m => {
+ val buf = new StringBuffer()
+
+ val flags = m.group(1).toLong
+ var s_flags = Flags.modifiersOfFlags(flags) map copypasteModifier
+ buf.append("Set(" + s_flags.mkString(", ") + ")")
+
+ var privateWithin = m.group(2)
+ buf.append(", " + "newTypeName(\"" + privateWithin + "\")")
+
+ var annotations = m.group(3)
+ buf.append(", " + "List(" + annotations + ")")
+
+ var s = buf.toString
+ if (s.endsWith(", Map()")) s = s.substring(0, s.length - ", Map()".length)
+ if (s.endsWith(", newTypeName(\"\")")) s = s.substring(0, s.length - ", newTypeName(\"\")".length)
+ if (s.endsWith("Set()")) s = s.substring(0, s.length - "Set()".length)
+ "Modifiers(" + s + ")"
+ })
+ s = """setInternalFlags\((\d+)L\)""".r.replaceAllIn(s, m => {
+ val flags = m.group(1).toLong
+ val mods = Flags.modifiersOfFlags(flags) map copypasteModifier
+ "setInternalFlags(flagsOfModifiers(List(" + mods.mkString(", ") + ")))"
+ })
+
+ println(s)
+ }
+ }
+
/** Set of mutable local variables that are free in some inner method. */
private val freeMutableVars: mutable.Set[Symbol] = new mutable.HashSet
private val converted: mutable.Set[Symbol] = new mutable.HashSet // debug
@@ -79,7 +132,9 @@ abstract class LiftCode extends Transform with TypingTransformers {
try {
printTypings = reifyDebug
debugTrace("transformed = ") {
- localTyper.typedPos(tree.pos)(codify(super.transform(tree)))
+ val result = localTyper.typedPos(tree.pos)(codify(super.transform(tree)))
+ if (reifyCopypaste) printCopypaste(result)
+ result
}
} finally printTypings = saved
case ValDef(mods, name, tpt, rhs) if (freeMutableVars(sym)) => // box mutable variables that are accessed from a local closure
diff --git a/src/library/scala/reflect/api/Modifier.scala b/src/library/scala/reflect/api/Modifier.scala
index 5992e658c6..8569b103cf 100644
--- a/src/library/scala/reflect/api/Modifier.scala
+++ b/src/library/scala/reflect/api/Modifier.scala
@@ -3,9 +3,9 @@ package scala.reflect.api
object Modifier extends Enumeration {
val `protected`, `private`, `override`, `abstract`, `final`,
- `sealed`, `implicit`, `lazy`, `case`, `trait`,
+ `sealed`, `implicit`, `lazy`, `macro`, `case`, `trait`,
deferred, interface, mutable, parameter, covariant, contravariant,
preSuper, abstractOverride, local, java, static, caseAccessor,
defaultParameter, defaultInit, paramAccessor, bynameParameter = Value
-} \ No newline at end of file
+}