From c0a4e5acdc23bbfae3d4035b7922f3f3841cc822 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Tue, 4 Jan 2011 01:17:52 +0000 Subject: Added some more debugging tools for printing ty... Added some more debugging tools for printing types. Squirrelled it away in a type debugging trait. No review. --- .../scala/tools/nsc/symtab/SymbolTable.scala | 1 + .../scala/tools/nsc/symtab/TypeDebugging.scala | 66 ++++++++++++++++++++++ src/compiler/scala/tools/nsc/symtab/Types.scala | 44 ++++++--------- .../scala/tools/nsc/typechecker/Analyzer.scala | 2 - 4 files changed, 83 insertions(+), 30 deletions(-) create mode 100644 src/compiler/scala/tools/nsc/symtab/TypeDebugging.scala (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala index 97b7ce03bf..38c630f0ec 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala @@ -27,6 +27,7 @@ abstract class SymbolTable extends reflect.generic.Universe with TreePrinters with Positions with DocComments + with TypeDebugging { def settings: Settings def rootLoader: LazyType diff --git a/src/compiler/scala/tools/nsc/symtab/TypeDebugging.scala b/src/compiler/scala/tools/nsc/symtab/TypeDebugging.scala new file mode 100644 index 0000000000..f822c9ff24 --- /dev/null +++ b/src/compiler/scala/tools/nsc/symtab/TypeDebugging.scala @@ -0,0 +1,66 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2010 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.nsc +package symtab + +trait TypeDebugging { + self: SymbolTable => + + import definitions._ + + // @M toString that is safe during debugging (does not normalize, ...) + object TypeDebugStrings { + object str { + def brackets(xs: List[_]): String = xs.mkString("[", ", ", "]") + def tparams(tparams: List[Type]): String = brackets(tparams map debug) + def parents(ps: List[Type]): String = (ps map debug).mkString(" with ") + def refine(defs: Scope): String = defs.toList.mkString("{", " ;\n ", "}") + } + + def dump(tp: Type): Unit = { + println("** " + tp + " **") + import tp._ + + println("typeSymbol = " + typeSymbol) + println("termSymbol = " + termSymbol) + println("widen = " + widen) + println("deconst = " + deconst) + println("typeOfThis = " + typeOfThis) + println("bounds = " + bounds) + println("parents = " + parents) + println("prefixChain = " + prefixChain) + println("typeConstructor = " + typeConstructor) + println(" .. typeConstructor.typeParams = " + typeConstructor.typeParams) + println(" .. _.variance = " + (typeConstructor.typeParams map (_.variance))) + println("typeArgs = " + typeArgs) + println("resultType = " + resultType) + println("finalResultType = " + finalResultType) + println("paramss = " + paramss) + println("paramTypes = " + paramTypes) + println("typeParams = " + typeParams) + println("boundSyms = " + boundSyms) + println("baseTypeSeq = " + baseTypeSeq) + println("baseClasses = " + baseClasses) + println("toLongString = " + toLongString) + } + + def debug(tp: Type): String = tp match { + case TypeRef(pre, sym, args) => debug(pre) + "." + sym.nameString + str.tparams(args) + case ThisType(sym) => sym.nameString + ".this" + case SingleType(pre, sym) => debug(pre) +"."+ sym.nameString +".type" + case RefinedType(parents, defs) => str.parents(parents) + str.refine(defs) + case ClassInfoType(parents, defs, clazz) => "class "+ clazz.nameString + str.parents(parents) + str.refine(defs) + case PolyType(tparams, result) => str.brackets(tparams) + " " + debug(result) + case TypeBounds(lo, hi) => ">: "+ debug(lo) +" <: "+ debug(hi) + case tv @ TypeVar(_, _) => tv.toString + case ExistentialType(tparams, qtpe) => "forSome "+ str.brackets(tparams) + " " + debug(qtpe) + case _ => tp.toString + } + } + + def debugString(tp: Type) = TypeDebugStrings.debug(tp) +} + diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index e20c6c3075..9e97fa7aa7 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -104,7 +104,6 @@ trait Types extends reflect.generic.Types { self: SymbolTable => object undoLog { private type UndoLog = List[(TypeVar, TypeConstraint)] private[nsc] var log: UndoLog = List() - private[nsc] def size() = log.size /** Undo all changes to constraints to type variables upto `limit' */ @@ -116,29 +115,32 @@ trait Types extends reflect.generic.Types { self: SymbolTable => } } - private[Types] def record(tv: TypeVar) = {log = (tv, tv.constr.cloneInternal) :: log} - private[nsc] def clear() { log = List() } + private[Types] def record(tv: TypeVar) = { + log ::= (tv, tv.constr.cloneInternal) + } + private[nsc] def clear() { + if (settings.debug.value) + self.log("Clearing " + log.size + " entries from the undoLog.") + + log = Nil + } // `block` should not affect constraints on typevars def undo[T](block: => T): T = { val before = log - val result = try { - block - } finally { - undoTo(before) - } - result + + try block + finally undoTo(before) } // if `block` evaluates to false, it should not affect constraints on typevars def undoUnless(block: => Boolean): Boolean = { val before = log var result = false - try { - result = block - } finally { - if(!result) undoTo(before) - } + + try result = block + finally if (!result) undoTo(before) + result } } @@ -156,20 +158,6 @@ trait Types extends reflect.generic.Types { self: SymbolTable => import gen._ - // @M toString that is safe during debugging (does not normalize, ...) - def debugString(tp: Type): String = tp match { - case TypeRef(pre, sym, args) => debugString(pre) +"."+ sym.nameString + (args map debugString).mkString("[",", ","]") - case ThisType(sym) => sym.nameString+".this" - case SingleType(pre, sym) => debugString(pre) +"."+ sym.nameString +".type" - case RefinedType(parents, defs) => (parents map debugString).mkString("", " with ", "") + defs.toList.mkString(" {", " ;\n ", "}") - case ClassInfoType(parents, defs, clazz) => "class "+ clazz.nameString + (parents map debugString).mkString("", " with ", "") + defs.toList.mkString("{", " ;\n ", "}") - case PolyType(tparams, result) => tparams.mkString("[", ", ", "] ") + debugString(result) - case TypeBounds(lo, hi) => ">: "+ debugString(lo) +" <: "+ debugString(hi) - case tv @ TypeVar(_, _) => tv.toString - case ExistentialType(tparams, qtpe) => "forsome "+ tparams.mkString("[", ", ", "] ") + debugString(qtpe) - case _ => tp.toString - } - /** A proxy for a type (identified by field `underlying') that forwards most * operations to it (for exceptions, see WrappingProxy, which forwards even more operations). * every operation that is overridden for some kind of types should be forwarded. diff --git a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala index 6e969d07a4..56f1fd4c53 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala @@ -84,8 +84,6 @@ trait Analyzer extends AnyRef val start = startTimer(typerNanos) global.echoPhaseSummary(this) currentRun.units foreach applyPhase - if (global.opt.debug) - log("Clearing " + undoLog.size() + " entries from the undoLog.") undoLog.clear() // need to clear it after as well or 10K+ accumulated entries are // uncollectable the rest of the way. -- cgit v1.2.3