aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-03-07 10:57:58 +0100
committerMartin Odersky <odersky@gmail.com>2013-03-07 10:57:58 +0100
commit0a6bddc34dbfc9a667c7d63c1dc4de6ae04d7343 (patch)
treec0d1086447b374bc426de5bde0deb0f96215a732 /src/dotty
parent519942ae5bf4bc6b1ba8f6e4a52447ddb974dad1 (diff)
downloaddotty-0a6bddc34dbfc9a667c7d63c1dc4de6ae04d7343.tar.gz
dotty-0a6bddc34dbfc9a667c7d63c1dc4de6ae04d7343.tar.bz2
dotty-0a6bddc34dbfc9a667c7d63c1dc4de6ae04d7343.zip
Some refinements for prining
Made trees printable in plain mode (refined mode still missing).
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/core/Constants.scala2
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala9
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala3
-rw-r--r--src/dotty/tools/dotc/core/Names.scala11
-rw-r--r--src/dotty/tools/dotc/core/Phases.scala6
-rw-r--r--src/dotty/tools/dotc/core/Printers.scala70
-rw-r--r--src/dotty/tools/dotc/core/Scopes.scala6
-rw-r--r--src/dotty/tools/dotc/core/Showable.scala9
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala2
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala2
-rw-r--r--src/dotty/tools/dotc/core/Trees.scala7
-rw-r--r--src/dotty/tools/dotc/core/Types.scala2
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala2
13 files changed, 84 insertions, 47 deletions
diff --git a/src/dotty/tools/dotc/core/Constants.scala b/src/dotty/tools/dotc/core/Constants.scala
index 825ce60f1..9dd5a2627 100644
--- a/src/dotty/tools/dotc/core/Constants.scala
+++ b/src/dotty/tools/dotc/core/Constants.scala
@@ -21,7 +21,7 @@ object Constants {
// For supporting java enumerations inside java annotations (see ClassfileParser)
final val EnumTag = 13
- case class Constant(value: Any) {
+ case class Constant(value: Any) extends Showable {
import java.lang.Double.doubleToRawLongBits
import java.lang.Float.floatToRawIntBits
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index 05188fb78..d33c93a3a 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -197,7 +197,6 @@ object Contexts {
*/
abstract class FreshContext extends CondensedContext {
def withPeriod(period: Period): this.type = { this.period = period; this }
- def withPhase(pid: PhaseId): this.type = withPeriod(Period(runId, pid))
def withConstraints(constraints: Constraints): this.type = { this.constraints = constraints; this }
def withPosition(position: Position): this.type = { this.position = position; this }
def withPlainPrinter(printer: Context => Printer): this.type = { this.plainPrinter = printer; this }
@@ -207,6 +206,14 @@ object Contexts {
def withTree(tree: Tree): this.type = { this.tree = tree; this }
def withReporter(reporter: Reporter): this.type = { this.reporter = reporter; this }
def withDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this }
+
+ def withPhase(pid: PhaseId): this.type = withPeriod(Period(runId, pid))
+
+ def withSetting[T](setting: Setting[T], value: T): this.type =
+ withSettings(setting.updateIn(sstate, value))
+
+ def withDebug = withSetting(base.settings.debug, true)
+
}
/** A class defining the initial context with given context base
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index 878cec877..bdc95ff16 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -172,11 +172,12 @@ class Definitions(implicit ctx: Context) {
if (ctx.phase.erasedTypes) ctype else ctype.appliedTo(arg)
}
+ /** The enumeration type, goven a value of the enumeration */
def EnumType(sym: Symbol)(implicit ctx: Context) =
// given (in java): "class A { enum E { VAL1 } }"
// - sym: the symbol of the actual enumeration value (VAL1)
// - .owner: the ModuleClassSymbol of the enumeration (object E)
- // - .linkedClassOfClass: the ClassSymbol of the enumeration (class E)
+ // - .linkedClass: the ClassSymbol of the enumeration (class E)
sym.owner.linkedClass.typeConstructor
def FunctionType(args: List[Type], resultType: Type) =
diff --git a/src/dotty/tools/dotc/core/Names.scala b/src/dotty/tools/dotc/core/Names.scala
index 3b9a78dc5..8a345fcc8 100644
--- a/src/dotty/tools/dotc/core/Names.scala
+++ b/src/dotty/tools/dotc/core/Names.scala
@@ -4,6 +4,7 @@ package core
import scala.io.Codec
import util.NameTransformer
import Decorators._
+import Contexts.Context
import collection.IndexedSeqOptimized
import collection.generic.CanBuildFrom
import collection.mutable.{ Builder, StringBuilder }
@@ -32,6 +33,7 @@ object Names {
*/
abstract class Name extends DotClass
with PreName
+ with Showable
with Seq[Char]
with IndexedSeqOptimized[Char, Name] {
@@ -80,14 +82,7 @@ object Names {
override def toString = new String(chrs, start, length)
- /** Show name with namespace suffix: /L for local names,
- * /V for other term names, /T for type names
- */
- def showDetailed: String = toString + {
- (if (isLocalName) "/L"
- else if (isTypeName) "/T"
- else "/V")
- }
+ def show(implicit ctx: Context): String = ctx.show(this)
/** Write to UTF8 representation of this name to given character array.
* Start copying to index `to`. Return index of next free byte in array.
diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala
index 02d9c9749..039bba164 100644
--- a/src/dotty/tools/dotc/core/Phases.scala
+++ b/src/dotty/tools/dotc/core/Phases.scala
@@ -33,12 +33,12 @@ object Phases {
def name = "<no phase>"
def run() { throw new Error("NoPhase.run") }
}
-/*
- object SomePhase extends Phase {
+
+ object SomePhase extends Phase(initialCtx) {
def name = "<some phase>"
def run() { throw new Error("SomePhase.run") }
}
-*/
+
def phaseNamed(name: String) =
allPhases.find(_.name == name).getOrElse(NoPhase)
diff --git a/src/dotty/tools/dotc/core/Printers.scala b/src/dotty/tools/dotc/core/Printers.scala
index 761900c5c..25fa2ca01 100644
--- a/src/dotty/tools/dotc/core/Printers.scala
+++ b/src/dotty/tools/dotc/core/Printers.scala
@@ -2,7 +2,7 @@ package dotty.tools.dotc
package core
import Types._, Symbols._, Contexts._, Scopes._, Names._, NameOps._, Flags._
-import Constants._, Annotations._, StdNames._, Denotations._
+import Constants._, Annotations._, StdNames._, Denotations._, Trees._
import java.lang.Integer.toOctalString
import scala.annotation.switch
@@ -30,12 +30,11 @@ object Printers {
abstract class Printer {
- /** Show name, same as name.toString + kind suffix if plain printer */
+ /** Show name with namespace suffix: /L for local names,
+ * /V for other term names, /T for type names
+ */
def show(name: Name): String
- /** Show name with "type" or "term" prefix */
- def showDetailed(name: Name): String
-
/** Show type in context with given precedence */
def show(tp: Type, precedence: Precedence): String
@@ -61,7 +60,7 @@ object Printers {
/** Show symbol's declaration */
def showDcl(sym: Symbol): String
- /** If symbol's owner is printable class C, the string "in C", otherwise "" */
+ /** If symbol's owner is a printable class C, the string "in C", otherwise "" */
def showLocation(sym: Symbol): String
/** Show symbol and its location */
@@ -71,16 +70,19 @@ object Printers {
def show(denot: Denotation): String
/** Show constant */
- def show(const: Constant)
+ def show(const: Constant): String
/** Show annotation */
def show(annot: Annotation): String
/** Show all symbols in given list separated by `sep`, using `showDcl` for each */
- def show(syms: List[Symbol], sep: String): String
+ def showDcls(syms: List[Symbol], sep: String): String
- /** Show all definitions in a scope usng `showDcl` for each */
+ /** Show all definitions in a scope using `showDcl` for each */
def show(sc: Scope): String
+
+ /** Show tree */
+ def show[T](tree: Tree[T]): String
}
class PlainPrinter(_ctx: Context) extends Printer {
@@ -105,7 +107,7 @@ object Printers {
}
/** Concatenate strings separated by spaces */
- protected def compose(ss: String*) = ss filter (_.nonEmpty) mkString " "
+ protected def compose(ss: String*) = ss.filter(_.nonEmpty).mkString(" ")
/** If the name of the symbol's owner should be used when you care about
* seeing an interesting name: in such cases this symbol is e.g. a method
@@ -119,10 +121,11 @@ object Printers {
|| (sym.name == nme.PACKAGE) // package
)
- def show(name: Name): String = name.showDetailed
-
- def showDetailed(name: Name): String =
- (if (name.isTypeName) "type " else "term ") + name
+ def show(name: Name): String = name.toString + {
+ (if (name.isLocalName) "/L"
+ else if (name.isTypeName) "/T"
+ else "/V")
+ }
/** String representation of a name used in a refinement
* In refined printing this undoes type parameter expansion
@@ -133,7 +136,7 @@ object Printers {
protected def showRefinement(rt: RefinedType) =
showRefinementName(rt) + showRHS(rt.refinedInfo)
- /** The longest sequence refinement types, starting at given type
+ /** The longest sequence of refinement types, starting at given type
* and following parents.
*/
private def refinementChain(tp: Type): List[Type] =
@@ -149,7 +152,7 @@ object Printers {
case tp: SingletonType =>
val str = showPrefix(tp)
if (str.endsWith(".")) str + "type"
- else showFullName(tp.underlying.typeSymbol.skipPackageObject) + ".type"
+ else showFullName(tp.typeSymbol.skipPackageObject) + ".type"
case TypeRef(pre, name) =>
showPrefix(pre) + showName(tp.typeSymbol)
case tp: RefinedType =>
@@ -225,12 +228,6 @@ object Printers {
protected def trimPrefix(str: String) =
str.stripPrefix(objectPrefix).stripPrefix(packagePrefix)
- protected def isOmittablePrefix(sym: Symbol) =
- (defn.UnqualifiedOwners contains sym) || isEmptyPrefix(sym)
-
- protected def isEmptyPrefix(sym: Symbol) =
- sym.isEffectiveRoot || sym.isAnonymousClass || sym.name.isReplWrapperName
-
/** The string representation of this type used as a prefix */
protected def showPrefix(tp: Type): String = controlled {
tp match {
@@ -253,6 +250,12 @@ object Printers {
}
}
+ protected def isOmittablePrefix(sym: Symbol) =
+ (defn.UnqualifiedOwners contains sym) || isEmptyPrefix(sym)
+
+ protected def isEmptyPrefix(sym: Symbol) =
+ sym.isEffectiveRoot || sym.isAnonymousClass || sym.name.isReplWrapperName
+
/** String representation of a definition's type following its name */
protected def showRHS(tp: Type): String = controlled {
tp match {
@@ -270,7 +273,7 @@ object Printers {
val parentsStr = cparents.map(show(_, WithPrec)).mkString(" with ")
val declsStr =
if (decls.isEmpty) ""
- else "\n " + show(decls.toList, "\n ")
+ else "\n " + showDcls(decls.toList, "\n ")
s"""$parentsStr { $selfStr$declsStr
|} at $preStr""".stripMargin
case _ => ": " + showGlobal(tp)
@@ -367,11 +370,28 @@ object Printers {
def show(annot: Annotation): String = s"@${annot.symbol.name}" // for now
- def show(syms: List[Symbol], sep: String): String =
+ def showDcls(syms: List[Symbol], sep: String): String =
syms map (_.showDcl) mkString sep
def show(sc: Scope): String =
- "Scope{\n" + show(sc.toList, ";\n ") + "\n}"
+ "Scope{\n" + showDcls(sc.toList, ";\n ") + "\n}"
+
+ def show[T](tree: Tree[T]): String = tree match {
+ case node: Product =>
+ def showElem(elem: Any) = elem match {
+ case elem: Showable => elem.show
+ case elem => elem.toString
+ }
+ val nodeName = node.productPrefix
+ val elems = node.productIterator.map(showElem).mkString(", ")
+ val tpSuffix =
+ if (ctx.settings.printtypes.value && tree.hasType) s" | ${tree.tpe}"
+ else ""
+
+ s"$nodeName($elems$tpSuffix)"
+ case _ =>
+ tree.toString
+ } // todo: override in refined printer
}
class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
diff --git a/src/dotty/tools/dotc/core/Scopes.scala b/src/dotty/tools/dotc/core/Scopes.scala
index 0253cd60b..f8a125a3b 100644
--- a/src/dotty/tools/dotc/core/Scopes.scala
+++ b/src/dotty/tools/dotc/core/Scopes.scala
@@ -48,7 +48,7 @@ object Scopes {
* or to delete them. These methods are provided by subclass
* MutableScope.
*/
- abstract class Scope extends Iterable[Symbol] {
+ abstract class Scope extends Showable with Iterable[Symbol] {
/** The last scope-entry from which all others are reachable via `prev` */
private[dotc] def lastEntry: ScopeEntry
@@ -109,6 +109,8 @@ object Scopes {
/** Cast this scope to a mutable scope */
final def openForMutations: MutableScope = this.asInstanceOf[MutableScope]
+
+ final def show(implicit ctx: Context): String = ctx.show(this)
}
/** A subclass of Scope that defines methods for entering and
@@ -293,8 +295,6 @@ object Scopes {
if (filtered eq unfiltered) this
else newScopeWith(filtered: _*)
}
-
- final def show(implicit ctx: Context): String = ctx.show(this)
}
/** Create a new scope */
diff --git a/src/dotty/tools/dotc/core/Showable.scala b/src/dotty/tools/dotc/core/Showable.scala
new file mode 100644
index 000000000..770b3c818
--- /dev/null
+++ b/src/dotty/tools/dotc/core/Showable.scala
@@ -0,0 +1,9 @@
+package dotty.tools.dotc.core
+
+import Contexts._
+
+trait Showable {
+
+ def show(implicit ctx: Context): String
+
+} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 8ad63229e..2b20e4c16 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -947,7 +947,7 @@ object SymDenotations {
if (file != null) (s" in $file", file.toString)
else ("", "the signature")
cctx.error(
- s"""|bad symbolic reference. A signature$location refers to ${cctx.showDetailed(denot.name)}
+ s"""|bad symbolic reference. A signature$location refers to ${cctx.fresh.withDebug.show(denot.name)}
|in ${denot.owner.showKind} ${denot.owner.showFullName} which is not available.
|It may be completely missing from the current classpath, or the version on
|the classpath might be incompatible with the version used when compiling $src.""".stripMargin)
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index e307328e1..fa4e6f75d 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -267,7 +267,7 @@ object Symbols {
/** A Symbol represents a Scala definition/declaration or a package.
*/
- class Symbol private[Symbols] (val coord: Coord) extends DotClass {
+ class Symbol private[Symbols] (val coord: Coord) extends DotClass with Showable {
type ThisName <: Name
diff --git a/src/dotty/tools/dotc/core/Trees.scala b/src/dotty/tools/dotc/core/Trees.scala
index 8d297d5df..1140eb088 100644
--- a/src/dotty/tools/dotc/core/Trees.scala
+++ b/src/dotty/tools/dotc/core/Trees.scala
@@ -30,7 +30,7 @@ object Trees {
* - Type checking an untyped tree will remove all embedded `TypedSplice`
* nodes.
*/
- abstract class Tree[T] extends DotClass {
+ abstract class Tree[T] extends DotClass with Showable {
/** The tree's position. Except
* for SharedTree nodes, it is always ensured that a tree's position
@@ -71,6 +71,9 @@ object Trees {
tree.asInstanceOf[ThisTree[Type]]
}
+ /** Does the tree have it's type field set? */
+ def hasType: Boolean = _tpe != null
+
/** The denotation referred to by this tree, NoDenotation where not applicable */
def denot(implicit ctx: Context): Denotation = NoDenotation
@@ -92,6 +95,8 @@ object Trees {
/** Is this tree either the empty tree or the empty ValDef? */
def isEmpty: Boolean = false
+ override def show(implicit ctx: Context) = ctx.show(this)
+
override def hashCode(): Int = System.identityHashCode(this)
override def equals(that: Any) = this eq that.asInstanceOf[AnyRef]
}
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 45a8ad157..ab43a793d 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -60,7 +60,7 @@ object Types {
* +- ErrorType
* +- WildcardType
*/
- abstract class Type extends DotClass {
+ abstract class Type extends DotClass with Showable {
// ----- Tests -----------------------------------------------------
diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
index b036a8170..27cc10ee6 100644
--- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
@@ -457,7 +457,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleRoot: Clas
if (tp1 exists isBound) {
val tp2 = tp1.subst(boundSyms, boundSyms map (_ => defn.AnyType))
cctx.warning(s"""failure to eliminate existential
- |original type : $tp forSome {${cctx.show(boundSyms, "; ")}}
+ |original type : $tp forSome {${cctx.showDcls(boundSyms, "; ")}}
|reduces to : $tp1
|type used instead: $tp2
|proceed at own risk.""".stripMargin)