summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2014-01-22 14:01:01 +0300
committerEugene Burmako <xeno.by@gmail.com>2014-02-10 09:16:35 +0100
commitd2a1dd59c264947137669f4dbda20d89b26743af (patch)
treed3f590d4ce04ba83b25d1fb81a0cb599d285516a
parentc32dee8c304973835129bf394e11e34d9ab70a89 (diff)
downloadscala-d2a1dd59c264947137669f4dbda20d89b26743af.tar.gz
scala-d2a1dd59c264947137669f4dbda20d89b26743af.tar.bz2
scala-d2a1dd59c264947137669f4dbda20d89b26743af.zip
introduces -Yshow-symowners
This facility, along with -Yshow-syms, has proven to be very useful when debugging problems caused by corrupt owner chains when hacking on named/default argument transformation.
-rw-r--r--src/compiler/scala/tools/nsc/ast/Printers.scala6
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala1
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala17
-rw-r--r--src/reflect/scala/reflect/api/Printers.scala16
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala49
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala7
-rw-r--r--src/reflect/scala/reflect/internal/settings/MutableSettings.scala1
-rw-r--r--src/reflect/scala/reflect/runtime/Settings.scala1
8 files changed, 58 insertions, 40 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/Printers.scala b/src/compiler/scala/tools/nsc/ast/Printers.scala
index c64b18207a..f3def3c80c 100644
--- a/src/compiler/scala/tools/nsc/ast/Printers.scala
+++ b/src/compiler/scala/tools/nsc/ast/Printers.scala
@@ -178,9 +178,9 @@ trait Printers extends scala.reflect.internal.Printers { this: Global =>
}
}
- def asString(t: Tree): String = render(t, newStandardTreePrinter, settings.printtypes, settings.uniqid, settings.Yshowsymkinds)
- def asCompactString(t: Tree): String = render(t, newCompactTreePrinter, settings.printtypes, settings.uniqid, settings.Yshowsymkinds)
- def asCompactDebugString(t: Tree): String = render(t, newCompactTreePrinter, true, true, true)
+ def asString(t: Tree): String = render(t, newStandardTreePrinter, settings.printtypes, settings.uniqid, settings.Yshowsymowners, settings.Yshowsymkinds)
+ def asCompactString(t: Tree): String = render(t, newCompactTreePrinter, settings.printtypes, settings.uniqid, settings.Yshowsymowners, settings.Yshowsymkinds)
+ def asCompactDebugString(t: Tree): String = render(t, newCompactTreePrinter, true, true, true, true)
def newStandardTreePrinter(writer: PrintWriter): TreePrinter = new TreePrinter(writer)
def newCompactTreePrinter(writer: PrintWriter): CompactTreePrinter = new CompactTreePrinter(writer)
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index a3114a3d7b..a385a31165 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -168,6 +168,7 @@ trait ScalaSettings extends AbsScalaSettings
= BooleanSetting ("-Yshow-trees-stringified", "(Requires -Xprint:) Print stringifications along with detailed ASTs.")
val Yshowsyms = BooleanSetting ("-Yshow-syms", "Print the AST symbol hierarchy after each phase.")
val Yshowsymkinds = BooleanSetting ("-Yshow-symkinds", "Print abbreviated symbol kinds next to symbol names.")
+ val Yshowsymowners = BooleanSetting ("-Yshow-symowners", "Print owner identifiers next to symbol names.")
val skip = PhasesSetting ("-Yskip", "Skip")
val Ygenjavap = StringSetting ("-Ygen-javap", "dir", "Generate a parallel output directory of .javap files.", "")
val Ygenasmp = StringSetting ("-Ygen-asmp", "dir", "Generate a parallel output directory of .asmp files (ie ASM Textifier output).", "")
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index 541a915adb..e7927e2d37 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -174,7 +174,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
def typecheck(expr: Tree, pt: Type, silent: Boolean, withImplicitViewsDisabled: Boolean, withMacrosDisabled: Boolean): Tree =
transformDuringTyper(expr, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)(
(currentTyper, expr) => {
- trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymkinds.value))
+ trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymowners.value, settings.Yshowsymkinds.value))
currentTyper.silent(_.typed(expr, pt), reportAmbiguousErrors = false) match {
case analyzer.SilentResultValue(result) =>
trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value))
@@ -189,7 +189,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
def inferImplicit(tree: Tree, pt: Type, isView: Boolean, silent: Boolean, withMacrosDisabled: Boolean, pos: Position): Tree =
transformDuringTyper(tree, withImplicitViewsDisabled = false, withMacrosDisabled = withMacrosDisabled)(
(currentTyper, tree) => {
- trace("inferring implicit %s (macros = %s): ".format(if (isView) "view" else "value", !withMacrosDisabled))(showAttributed(pt, true, true, settings.Yshowsymkinds.value))
+ trace("inferring implicit %s (macros = %s): ".format(if (isView) "view" else "value", !withMacrosDisabled))(showAttributed(pt, true, true, settings.Yshowsymowners.value, settings.Yshowsymkinds.value))
analyzer.inferImplicit(tree, pt, isView, currentTyper.context, silent, withMacrosDisabled, pos, (pos, msg) => throw ToolBoxError(msg))
})
@@ -234,10 +234,10 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
List(),
List(methdef),
NoPosition))
- trace("wrapped: ")(showAttributed(moduledef, true, true, settings.Yshowsymkinds.value))
+ trace("wrapped: ")(showAttributed(moduledef, true, true, settings.Yshowsymowners.value, settings.Yshowsymkinds.value))
val cleanedUp = resetAttrs(moduledef)
- trace("cleaned up: ")(showAttributed(cleanedUp, true, true, settings.Yshowsymkinds.value))
+ trace("cleaned up: ")(showAttributed(cleanedUp, true, true, settings.Yshowsymowners.value, settings.Yshowsymkinds.value))
cleanedUp.asInstanceOf[ModuleDef]
}
@@ -285,19 +285,22 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
tree
}
- def showAttributed(artifact: Any, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String = {
+ def showAttributed(artifact: Any, printTypes: Boolean = true, printIds: Boolean = true, printOwners: Boolean = false, printKinds: Boolean = false): String = {
val saved1 = settings.printtypes.value
val saved2 = settings.uniqid.value
- val saved3 = settings.Yshowsymkinds.value
+ val saved3 = settings.Yshowsymowners.value
+ val saved4 = settings.Yshowsymkinds.value
try {
settings.printtypes.value = printTypes
settings.uniqid.value = printIds
+ settings.Yshowsymowners.value = printOwners
settings.Yshowsymkinds.value = printKinds
artifact.toString
} finally {
settings.printtypes.value = saved1
settings.uniqid.value = saved2
- settings.Yshowsymkinds.value = saved3
+ settings.Yshowsymowners.value = saved3
+ settings.Yshowsymkinds.value = saved4
}
}
diff --git a/src/reflect/scala/reflect/api/Printers.scala b/src/reflect/scala/reflect/api/Printers.scala
index 5bc92d3893..637fcd782e 100644
--- a/src/reflect/scala/reflect/api/Printers.scala
+++ b/src/reflect/scala/reflect/api/Printers.scala
@@ -142,6 +142,7 @@ trait Printers { self: Universe =>
def print(args: Any*)
protected var printTypes = false
protected var printIds = false
+ protected var printOwners = false
protected var printKinds = false
protected var printMirrors = false
protected var printPositions = false
@@ -149,6 +150,8 @@ trait Printers { self: Universe =>
def withoutTypes: this.type = { printTypes = false; this }
def withIds: this.type = { printIds = true; this }
def withoutIds: this.type = { printIds = false; this }
+ def withOwners: this.type = { printOwners = true; this }
+ def withoutOwners: this.type = { printOwners = false; this }
def withKinds: this.type = { printKinds = true; this }
def withoutKinds: this.type = { printKinds = false; this }
def withMirrors: this.type = { printMirrors = true; this }
@@ -169,12 +172,13 @@ trait Printers { self: Universe =>
}
/** @group Printers */
- protected def render(what: Any, mkPrinter: PrintWriter => TreePrinter, printTypes: BooleanFlag = None, printIds: BooleanFlag = None, printKinds: BooleanFlag = None, printMirrors: BooleanFlag = None, printPositions: BooleanFlag = None): String = {
+ protected def render(what: Any, mkPrinter: PrintWriter => TreePrinter, printTypes: BooleanFlag = None, printIds: BooleanFlag = None, printOwners: BooleanFlag = None, printKinds: BooleanFlag = None, printMirrors: BooleanFlag = None, printPositions: BooleanFlag = None): String = {
val buffer = new StringWriter()
val writer = new PrintWriter(buffer)
val printer = mkPrinter(writer)
printTypes.value.map(printTypes => if (printTypes) printer.withTypes else printer.withoutTypes)
printIds.value.map(printIds => if (printIds) printer.withIds else printer.withoutIds)
+ printOwners.value.map(printOwners => if (printOwners) printer.withOwners else printer.withoutOwners)
printKinds.value.map(printKinds => if (printKinds) printer.withKinds else printer.withoutKinds)
printMirrors.value.map(printMirrors => if (printMirrors) printer.withMirrors else printer.withoutMirrors)
printPositions.value.map(printPositions => if (printPositions) printer.withPositions else printer.withoutPositions)
@@ -193,8 +197,8 @@ trait Printers { self: Universe =>
*
* @group Printers
*/
- def show(any: Any, printTypes: BooleanFlag = None, printIds: BooleanFlag = None, printKinds: BooleanFlag = None, printMirrors: BooleanFlag = None, printPositions: BooleanFlag = None): String =
- render(any, newTreePrinter(_), printTypes, printIds, printKinds, printMirrors, printPositions)
+ def show(any: Any, printTypes: BooleanFlag = None, printIds: BooleanFlag = None, printOwners: BooleanFlag = None, printKinds: BooleanFlag = None, printMirrors: BooleanFlag = None, printPositions: BooleanFlag = None): String =
+ render(any, newTreePrinter(_), printTypes, printIds, printOwners, printKinds, printMirrors, printPositions)
/** Hook to define what `show(...)` means.
* @group Printers
@@ -219,14 +223,14 @@ trait Printers { self: Universe =>
* @group Printers
*/
protected def newCodePrinter(out: PrintWriter): TreePrinter
-
+
/** Renders internal structure of a reflection artifact as the
* visualization of a Scala syntax tree.
*
* @group Printers
*/
- def showRaw(any: Any, printTypes: BooleanFlag = None, printIds: BooleanFlag = None, printKinds: BooleanFlag = None, printMirrors: BooleanFlag = None, printPositions: BooleanFlag = None): String =
- render(any, newRawTreePrinter(_), printTypes, printIds, printKinds, printMirrors, printPositions)
+ def showRaw(any: Any, printTypes: BooleanFlag = None, printIds: BooleanFlag = None, printOwners: BooleanFlag = None, printKinds: BooleanFlag = None, printMirrors: BooleanFlag = None, printPositions: BooleanFlag = None): String =
+ render(any, newRawTreePrinter(_), printTypes, printIds, printOwners, printKinds, printMirrors, printPositions)
/** Hook to define what `showRaw(...)` means.
* @group Printers
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index 519d1047a6..21cf9578af 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -65,6 +65,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
printTypes = settings.printtypes.value
printIds = settings.uniqid.value
+ printOwners = settings.Yshowsymowners.value
printKinds = settings.Yshowsymkinds.value
printMirrors = false // typically there's no point to print mirrors inside the compiler, as there is only one mirror there
printPositions = settings.Xprintpos.value
@@ -128,10 +129,10 @@ trait Printers extends api.Printers { self: SymbolTable =>
body
if (condition) print(")")
}
-
- protected def printImplicitInParamsList(vds: List[ValDef]) =
+
+ protected def printImplicitInParamsList(vds: List[ValDef]) =
if (vds.nonEmpty) printFlags(vds.head.mods.flags & IMPLICIT, "")
-
+
def printValueParams(ts: List[ValDef], inParentheses: Boolean = true): Unit =
parenthesize(inParentheses){
printImplicitInParamsList(ts)
@@ -191,7 +192,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
private var currentOwner: Symbol = NoSymbol
private var selectorType: Type = NoType
-
+
protected def printPackageDef(tree: PackageDef, separator: String) = {
val PackageDef(packaged, stats) = tree
printAnnotations(tree)
@@ -275,6 +276,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
printValueParams
print(" => ", body, ")")
if (printIds && tree.symbol != null) print("#" + tree.symbol.id)
+ if (printOwners && tree.symbol != null) print("@" + tree.symbol.owner.id)
}
protected def printSuper(tree: Super, resultName: => String) = {
@@ -511,7 +513,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
out.print(if (arg == null) "null" else arg.toString)
}
}
-
+
// it's the printer for trees after parser and before typer phases
class ParsedTreePrinter(out: PrintWriter) extends TreePrinter(out) {
override def withTypes = this
@@ -537,13 +539,13 @@ trait Printers extends api.Printers { self: SymbolTable =>
import Chars._
val decName = name.decoded
val bslash = '\\'
- val brackets = List('[',']','(',')','{','}')
+ val brackets = List('[',']','(',')','{','}')
def addBackquotes(s: String) =
- if (decoded && (decName.exists(ch => brackets.contains(ch) || isWhitespace(ch)) ||
+ if (decoded && (decName.exists(ch => brackets.contains(ch) || isWhitespace(ch)) ||
(name.isOperatorName && decName.exists(isOperatorPart) && decName.exists(isScalaLetter) && !decName.contains(bslash))))
s"`$s`" else s
-
+
if (name == nme.CONSTRUCTOR) "this"
else addBackquotes(quotedName(name, decoded))
}
@@ -556,7 +558,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
qualIsIntLit && name.isOperatorName
}
- protected def needsParentheses(parent: Tree)(insideIf: Boolean = true, insideMatch: Boolean = true,
+ protected def needsParentheses(parent: Tree)(insideIf: Boolean = true, insideMatch: Boolean = true,
insideTry: Boolean = true, insideAnnotated: Boolean = true, insideBlock: Boolean = true, insideLabelDef: Boolean = true) = {
parent match {
case _: If => insideIf
@@ -572,10 +574,10 @@ trait Printers extends api.Printers { self: SymbolTable =>
protected def checkForBlank(cond: Boolean) = if (cond) " " else ""
protected def blankForOperatorName(name: Name) = checkForBlank(name.isOperatorName)
protected def blankForName(name: Name) = checkForBlank(name.isOperatorName || name.endsWith("_"))
-
+
protected def resolveSelect(t: Tree): String = {
t match {
- // case for: 1) (if (a) b else c).meth1.meth2 or 2) 1 + 5 should be represented as (1).+(5)
+ // case for: 1) (if (a) b else c).meth1.meth2 or 2) 1 + 5 should be represented as (1).+(5)
case Select(qual, name) if (name.isTermName && needsParentheses(qual)(insideLabelDef = false)) || isIntLitWithDecodedOp(qual, name) => s"(${resolveSelect(qual)}).${printedName(name)}"
case Select(qual, name) if name.isTermName => s"${resolveSelect(qual)}.${printedName(name)}"
case Select(qual, name) if name.isTypeName => s"${resolveSelect(qual)}#${blankForOperatorName(name)}%${printedName(name)}"
@@ -591,7 +593,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
trees match {
case Nil => trees
case init :+ last => last match {
- case Select(Ident(sc), name) if traitsToRemove.contains(name) && sc == nme.scala_ =>
+ case Select(Ident(sc), name) if traitsToRemove.contains(name) && sc == nme.scala_ =>
removeDefaultTraitsFromList(init, traitsToRemove)
case _ => trees
}
@@ -637,7 +639,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
val mutableOrOverride = mods.isOverride || mods.isMutable
val hideCtorMods = mods.isParamAccessor && mods.isPrivateLocal && !mutableOrOverride
val hideCaseCtorMods = mods.isCaseAccessor && mods.isPublic && !mutableOrOverride
-
+
if (primaryCtorParam && !(hideCtorMods || hideCaseCtorMods)) {
printModifiers(mods, primaryCtorParam)
print(if (mods.isMutable) "var " else "val ");
@@ -657,14 +659,14 @@ trait Printers extends api.Printers { self: SymbolTable =>
printParam(tree, primaryCtorParam = false)
}
- protected def printArgss(argss: List[List[Tree]]) =
+ protected def printArgss(argss: List[List[Tree]]) =
argss foreach {x: List[Tree] => if (!(x.isEmpty && argss.size == 1)) printRow(x, "(", ", ", ")")}
-
+
override def printAnnotations(tree: MemberDef) = {
val annots = tree.mods.annotations
annots foreach {annot => printAnnot(annot); print(" ")}
}
-
+
protected def printAnnot(tree: Tree) = {
tree match {
case treeInfo.Applied(core, _, argss) =>
@@ -675,10 +677,10 @@ trait Printers extends api.Printers { self: SymbolTable =>
}
printArgss(argss)
case _ => super.printTree(tree)
- }
+ }
}
- override def printTree(tree: Tree): Unit = {
+ override def printTree(tree: Tree): Unit = {
parentsStack.push(tree)
tree match {
case cl @ ClassDef(mods, name, tparams, impl) =>
@@ -809,15 +811,15 @@ trait Printers extends api.Printers { self: SymbolTable =>
}
case _ => None
}
-
+
if (printedParents.nonEmpty) {
val (clParent :: traits) = printedParents
print(clParent)
val constrArgss = ap match {
case Some(treeInfo.Applied(_, _, argss)) => argss
- case _ => Nil
- }
+ case _ => Nil
+ }
printArgss(constrArgss)
if (traits.nonEmpty) {
printRow(traits, " with ", " with ", "")
@@ -907,7 +909,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
case Apply(fun, vargs) =>
tree match {
// processing methods ending on colons (x \: list)
- case Apply(Block(l1 @ List(sVD: ValDef), a1 @ Apply(Select(_, methodName), l2 @ List(Ident(iVDName)))), l3)
+ case Apply(Block(l1 @ List(sVD: ValDef), a1 @ Apply(Select(_, methodName), l2 @ List(Ident(iVDName)))), l3)
if sVD.mods.isSynthetic && treeInfo.isLeftAssoc(methodName) && sVD.name == iVDName =>
val printBlock = Block(l1, Apply(a1, l3))
print(printBlock)
@@ -972,7 +974,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
case AppliedTypeTree(tp, args) =>
// it's possible to have (=> String) => String type but Function1[=> String, String] is not correct
val containsByNameTypeParam = args exists treeInfo.isByNameParamType
-
+
if (containsByNameTypeParam) {
print("(")
printRow(args.init, "(", ", ", ")")
@@ -1139,6 +1141,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
else if (sym.isStatic && (sym.isClass || sym.isModule)) print(sym.fullName)
else print(sym.name)
if (printIds) print("#", sym.id)
+ if (printOwners) print("@", sym.owner.id)
if (printKinds) print("#", sym.abbreviatedKindString)
if (printMirrors) print("%M", footnotes.put[scala.reflect.api.Mirror[_]](mirrorThatLoaded(sym)))
case tag: TypeTag[_] =>
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index b363123542..17691fe085 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -2472,6 +2472,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* If !settings.debug translates expansions of operators back to operator symbol.
* E.g. $eq => =.
* If settings.uniqid, adds id.
+ * If settings.Yshowsymowners, adds owner's id
* If settings.Yshowsymkinds, adds abbreviated symbol kind.
*/
def nameString: String = {
@@ -2492,7 +2493,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
/** If settings.uniqid is set, the symbol's id, else "" */
- final def idString = if (settings.uniqid.value) "#"+id else ""
+ final def idString = {
+ val id_s = if (settings.uniqid.value) "#"+id else ""
+ val owner_s = if (settings.Yshowsymowners.value) "@"+owner.id else ""
+ id_s + owner_s
+ }
/** String representation, including symbol's kind e.g., "class Foo", "method Bar".
* If hasMeaninglessName is true, uses the owner's name to disambiguate identity.
diff --git a/src/reflect/scala/reflect/internal/settings/MutableSettings.scala b/src/reflect/scala/reflect/internal/settings/MutableSettings.scala
index 816916787e..048fe9ef37 100644
--- a/src/reflect/scala/reflect/internal/settings/MutableSettings.scala
+++ b/src/reflect/scala/reflect/internal/settings/MutableSettings.scala
@@ -39,6 +39,7 @@ abstract class MutableSettings extends AbsSettings {
def Xprintpos: BooleanSetting
def Yposdebug: BooleanSetting
def Yrangepos: BooleanSetting
+ def Yshowsymowners: BooleanSetting
def Yshowsymkinds: BooleanSetting
def breakCycles: BooleanSetting
def debug: BooleanSetting
diff --git a/src/reflect/scala/reflect/runtime/Settings.scala b/src/reflect/scala/reflect/runtime/Settings.scala
index de5ba99900..d46846fc21 100644
--- a/src/reflect/scala/reflect/runtime/Settings.scala
+++ b/src/reflect/scala/reflect/runtime/Settings.scala
@@ -36,6 +36,7 @@ private[reflect] class Settings extends MutableSettings {
val Xprintpos = new BooleanSetting(false)
val Yposdebug = new BooleanSetting(false)
val Yrangepos = new BooleanSetting(false)
+ val Yshowsymowners = new BooleanSetting(false)
val Yshowsymkinds = new BooleanSetting(false)
val breakCycles = new BooleanSetting(false)
val debug = new BooleanSetting(false)