diff options
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 +} |