summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/reflect/scala/reflect/api/Printers.scala7
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala51
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala33
-rw-r--r--test/files/run/reflection-allmirrors-tostring.check18
-rw-r--r--test/files/run/reflection-magicsymbols-invoke.check12
-rw-r--r--test/files/run/showdecl.check34
-rw-r--r--test/files/run/showdecl/Macros_1.scala30
-rw-r--r--test/files/run/showdecl/Test_2.scala32
8 files changed, 149 insertions, 68 deletions
diff --git a/src/reflect/scala/reflect/api/Printers.scala b/src/reflect/scala/reflect/api/Printers.scala
index 5bc92d3893..ae1ad30527 100644
--- a/src/reflect/scala/reflect/api/Printers.scala
+++ b/src/reflect/scala/reflect/api/Printers.scala
@@ -219,7 +219,7 @@ 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.
*
@@ -252,4 +252,9 @@ trait Printers { self: Universe =>
* @group Printers
*/
def showRaw(flags: FlagSet): String = flags.toString
+
+ /** Renders a string that represents a declaration of this symbol written in Scala.
+ * @group Printers
+ */
+ def showDeclaration(sym: Symbol): String
}
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index 519d1047a6..b287a3884a 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -128,10 +128,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 +191,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)
@@ -511,7 +511,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 +537,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 +556,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 +572,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 +591,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 +637,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 +657,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 +675,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 +809,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 +907,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 +972,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, "(", ", ", ")")
@@ -1237,4 +1237,9 @@ trait Printers extends api.Printers { self: SymbolTable =>
s_flags mkString " | "
}
}
+
+ def showDeclaration(sym: Symbol): String = {
+ if (!isCompilerUniverse) definitions.fullyInitializeSymbol(sym)
+ sym.defString
+ }
}
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index bf8a3f0ae2..1e64b805e9 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -292,32 +292,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
jfield.set(receiver, if (isDerivedValueClass) unboxer.invoke(value) else value)
}
- override def toString = s"field mirror for ${symbol.fullName} (bound to $receiver)"
- }
-
- private def showMethodSig(symbol: MethodSymbol): String = {
- var sig = s"${symbol.fullName}"
- if (symbol.typeParams.nonEmpty) {
- def showTparam(tparam: Symbol) =
- tparam.typeSignature match {
- case tpe @ TypeBounds(_, _) => s"${tparam.name}$tpe"
- case _ => tparam.name
- }
- def showTparams(tparams: List[Symbol]) = "[" + (tparams map showTparam mkString ", ") + "]"
- sig += showTparams(symbol.typeParams)
- }
- if (symbol.paramss.nonEmpty) {
- def showParam(param: Symbol) = s"${param.name}: ${param.typeSignature}"
- def showParams(params: List[Symbol]) = {
- val s_mods = if (params.nonEmpty && params(0).hasFlag(IMPLICIT)) "implicit " else ""
- val s_params = params map showParam mkString ", "
- "(" + s_mods + s_params + ")"
- }
- def showParamss(paramss: List[List[Symbol]]) = paramss map showParams mkString ""
- sig += showParamss(symbol.paramss)
- }
- sig += s": ${symbol.returnType}"
- sig
+ override def toString = s"field mirror for ${showDeclaration(symbol)} (bound to $receiver)"
}
// the "symbol == Any_getClass || symbol == Object_getClass" test doesn't cut it
@@ -372,7 +347,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
override def toString = {
val what = if (symbol.isConstructor) "constructor mirror" else "method mirror"
- s"$what for ${showMethodSig(symbol)} (bound to $receiver)"
+ s"$what for ${showDeclaration(symbol)} (bound to $receiver)"
}
}
@@ -468,7 +443,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
private class BytecodelessMethodMirror[T: ClassTag](val receiver: T, val symbol: MethodSymbol)
extends MethodMirror {
def bind(newReceiver: Any) = new BytecodelessMethodMirror(newReceiver.asInstanceOf[T], symbol)
- override def toString = s"bytecodeless method mirror for ${showMethodSig(symbol)} (bound to $receiver)"
+ override def toString = s"bytecodeless method mirror for ${showDeclaration(symbol)} (bound to $receiver)"
def apply(args: Any*): Any = {
// checking type conformance is too much of a hassle, so we don't do it here
@@ -482,7 +457,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
if (!perfectMatch && !varargMatch) {
val n_arguments = if (isVarArgsList(params)) s"${params.length - 1} or more" else s"${params.length}"
val s_arguments = if (params.length == 1 && !isVarArgsList(params)) "argument" else "arguments"
- abort(s"${showMethodSig(symbol)} takes $n_arguments $s_arguments")
+ abort(s"${showDeclaration(symbol)} takes $n_arguments $s_arguments")
}
def objReceiver = receiver.asInstanceOf[AnyRef]
diff --git a/test/files/run/reflection-allmirrors-tostring.check b/test/files/run/reflection-allmirrors-tostring.check
index 2a3be29402..3003cce6c0 100644
--- a/test/files/run/reflection-allmirrors-tostring.check
+++ b/test/files/run/reflection-allmirrors-tostring.check
@@ -1,14 +1,14 @@
class mirror for C (bound to null)
module mirror for M (bound to null)
instance mirror for an instance of C
-field mirror for C.f1 (bound to an instance of C)
-field mirror for C.f2 (bound to an instance of C)
-method mirror for C.m1: Int (bound to an instance of C)
-method mirror for C.m2(): Int (bound to an instance of C)
-method mirror for C.m3[T >: String <: Int]: T (bound to an instance of C)
-method mirror for C.m4[A, B <: A[Int]](x: A[B])(implicit y: Int): Nothing (bound to an instance of C)
-method mirror for C.m5(x: => Int, y: Int*): String (bound to an instance of C)
+field mirror for private[this] val f1: Int (bound to an instance of C)
+field mirror for private[this] var f2: Int (bound to an instance of C)
+method mirror for def m1: Int (bound to an instance of C)
+method mirror for def m2(): Int (bound to an instance of C)
+method mirror for def m3[T >: String <: Int]: T (bound to an instance of C)
+method mirror for def m4[A[_], B <: A[Int]](x: A[B])(implicit y: Int): Nothing (bound to an instance of C)
+method mirror for def m5(x: => Int,y: Int*): String (bound to an instance of C)
class mirror for C.C (bound to an instance of C)
module mirror for C.M (bound to an instance of C)
-constructor mirror for C.<init>(): C (bound to null)
-constructor mirror for C.C.<init>(): C.this.C (bound to an instance of C)
+constructor mirror for def <init>(): C (bound to null)
+constructor mirror for def <init>(): C.this.C (bound to an instance of C)
diff --git a/test/files/run/reflection-magicsymbols-invoke.check b/test/files/run/reflection-magicsymbols-invoke.check
index b153ae0470..f580296ae7 100644
--- a/test/files/run/reflection-magicsymbols-invoke.check
+++ b/test/files/run/reflection-magicsymbols-invoke.check
@@ -15,12 +15,12 @@ testing Any.!=: false
testing Any.##: 50
testing Any.==: true
testing Any.asInstanceOf: class scala.ScalaReflectionException: Any.asInstanceOf requires a type argument, it cannot be invoked with mirrors
-testing Any.asInstanceOf: class scala.ScalaReflectionException: scala.Any.asInstanceOf[T0]: T0 takes 0 arguments
+testing Any.asInstanceOf: class scala.ScalaReflectionException: final def asInstanceOf[T0]: T0 takes 0 arguments
testing Any.equals: true
testing Any.getClass: class java.lang.String
testing Any.hashCode: 50
testing Any.isInstanceOf: class scala.ScalaReflectionException: Any.isInstanceOf requires a type argument, it cannot be invoked with mirrors
-testing Any.isInstanceOf: class scala.ScalaReflectionException: scala.Any.isInstanceOf[T0]: Boolean takes 0 arguments
+testing Any.isInstanceOf: class scala.ScalaReflectionException: final def isInstanceOf[T0]: Boolean takes 0 arguments
testing Any.toString: 2
============
AnyVal
@@ -28,7 +28,7 @@ it's important to print the list of AnyVal's members
if some of them change (possibly, adding and/or removing magic symbols), we must update this test
constructor AnyVal: ()AnyVal
method getClass: ()Class[_ <: AnyVal]
-testing AnyVal.<init>: class scala.ScalaReflectionException: unsupported symbol constructor AnyVal when invoking bytecodeless method mirror for scala.AnyVal.<init>(): AnyVal (bound to null)
+testing AnyVal.<init>: class scala.ScalaReflectionException: unsupported symbol constructor AnyVal when invoking bytecodeless method mirror for def <init>(): AnyVal (bound to null)
testing AnyVal.getClass: class scala.ScalaReflectionException: expected a member of class Integer, you provided method scala.AnyVal.getClass
============
AnyRef
@@ -59,9 +59,9 @@ method wait: (x$1: Long, x$2: Int)Unit
testing Object.!=: false
testing Object.##: 50
testing Object.$asInstanceOf: class scala.ScalaReflectionException: AnyRef.$asInstanceOf is an internal method, it cannot be invoked with mirrors
-testing Object.$asInstanceOf: class scala.ScalaReflectionException: java.lang.Object.$asInstanceOf[T0](): T0 takes 0 arguments
+testing Object.$asInstanceOf: class scala.ScalaReflectionException: final def $asInstanceOf[T0](): T0 takes 0 arguments
testing Object.$isInstanceOf: class scala.ScalaReflectionException: AnyRef.$isInstanceOf is an internal method, it cannot be invoked with mirrors
-testing Object.$isInstanceOf: class scala.ScalaReflectionException: java.lang.Object.$isInstanceOf[T0](): Boolean takes 0 arguments
+testing Object.$isInstanceOf: class scala.ScalaReflectionException: final def $isInstanceOf[T0](): Boolean takes 0 arguments
testing Object.==: true
testing Object.clone: class java.lang.CloneNotSupportedException: java.lang.String
testing Object.eq: true
@@ -115,5 +115,5 @@ testing String.+: 23
============
CTM
testing Predef.classOf: class scala.ScalaReflectionException: Predef.classOf is a compile-time function, it cannot be invoked with mirrors
-testing Predef.classOf: class scala.ScalaReflectionException: scala.Predef.classOf[T]: Class[T] takes 0 arguments
+testing Predef.classOf: class scala.ScalaReflectionException: def classOf[T]: Class[T] takes 0 arguments
testing Universe.reify: class scala.ScalaReflectionException: scala.reflect.api.Universe.reify is a macro, i.e. a compile-time function, it cannot be invoked with mirrors
diff --git a/test/files/run/showdecl.check b/test/files/run/showdecl.check
new file mode 100644
index 0000000000..b8d7f94c57
--- /dev/null
+++ b/test/files/run/showdecl.check
@@ -0,0 +1,34 @@
+compile-time
+uninitialized D: class D extends
+initialized D: class D extends C
+uninitialized x: val x: <?>
+initialized x: val x: Int
+uninitialized y: lazy val y: <?>
+initialized y: lazy val y: Int
+uninitialized z: def z: <?>
+initialized z: def z: Int
+uninitialized t: def t: <?>
+initialized t: def t[T <: Int](x: D)(y: x.W): Int
+uninitialized W: type W = String
+initialized W: type W = String
+uninitialized C: class C extends
+initialized C: class C extends D
+uninitialized O: object O
+initialized O: object O
+runtime
+autoinitialized D: class D extends C
+autoinitialized D: class D extends C
+autoinitialized x: val x: Int
+autoinitialized x: val x: Int
+autoinitialized y: lazy val y: Int
+autoinitialized y: lazy val y: Int
+autoinitialized z: def z: Int
+autoinitialized z: def z: Int
+autoinitialized t: def t[T <: Int](x: D)(y: x.W): Int
+autoinitialized t: def t[T <: Int](x: D)(y: x.W): Int
+autoinitialized W: type W = String
+autoinitialized W: type W = String
+autoinitialized C: class C extends D
+autoinitialized C: class C extends D
+autoinitialized O: object O
+autoinitialized O: object O
diff --git a/test/files/run/showdecl/Macros_1.scala b/test/files/run/showdecl/Macros_1.scala
new file mode 100644
index 0000000000..d0493fb97f
--- /dev/null
+++ b/test/files/run/showdecl/Macros_1.scala
@@ -0,0 +1,30 @@
+import scala.reflect.macros.whitebox._
+import scala.language.experimental.macros
+
+object Macros {
+ def impl(c: Context) = {
+ var messages = List[String]()
+ def println(msg: String) = messages :+= msg
+
+ import c.universe._
+ def test(sym: Symbol): Unit = {
+ println(s"uninitialized ${sym.name}: ${showDeclaration(sym)}")
+ sym.typeSignature
+ println(s"initialized ${sym.name}: ${showDeclaration(sym)}")
+ }
+
+ println("compile-time")
+ test(c.mirror.staticClass("D"))
+ test(c.mirror.staticClass("D").typeSignature.member(TermName("x")))
+ test(c.mirror.staticClass("D").typeSignature.member(TermName("y")))
+ test(c.mirror.staticClass("D").typeSignature.member(TermName("z")))
+ test(c.mirror.staticClass("D").typeSignature.member(TermName("t")))
+ test(c.mirror.staticClass("D").typeSignature.member(TypeName("W")))
+ test(c.mirror.staticClass("D").typeSignature.member(TypeName("C")))
+ test(c.mirror.staticClass("D").typeSignature.member(TermName("O")))
+
+ q"..${messages.map(msg => q"println($msg)")}"
+ }
+
+ def foo: Any = macro impl
+} \ No newline at end of file
diff --git a/test/files/run/showdecl/Test_2.scala b/test/files/run/showdecl/Test_2.scala
new file mode 100644
index 0000000000..65ab2f147c
--- /dev/null
+++ b/test/files/run/showdecl/Test_2.scala
@@ -0,0 +1,32 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+
+object Test extends App {
+ def test(sym: Symbol): Unit = {
+ println(s"autoinitialized ${sym.name}: ${showDeclaration(sym)}")
+ sym.typeSignature
+ println(s"autoinitialized ${sym.name}: ${showDeclaration(sym)}")
+ }
+
+ Macros.foo
+ println("runtime")
+ test(symbolOf[D])
+ test(typeOf[D].member(TermName("x")))
+ test(typeOf[D].member(TermName("y")))
+ test(typeOf[D].member(TermName("z")))
+ test(typeOf[D].member(TermName("t")))
+ test(typeOf[D].member(TypeName("W")))
+ test(typeOf[D].member(TypeName("C")))
+ test(typeOf[D].member(TermName("O")))
+}
+
+class C
+class D extends C {
+ val x = 2
+ lazy val y = 3
+ var z = 4
+ def t[T <: Int](x: D)(y: x.W) = 5
+ type W = String
+ class C extends D
+ object O extends C
+}