summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
diff options
context:
space:
mode:
authorHubert Plociniczak <hubert.plociniczak@epfl.ch>2011-09-07 12:17:54 +0000
committerHubert Plociniczak <hubert.plociniczak@epfl.ch>2011-09-07 12:17:54 +0000
commit620f339bbaadad57daa696007660bb887372e927 (patch)
treee9bf93cfa9d93a299f24cab28577900c36260438 /src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
parent596be479f1e527230f92db320642f77bae7e386d (diff)
downloadscala-620f339bbaadad57daa696007660bb887372e927.tar.gz
scala-620f339bbaadad57daa696007660bb887372e927.tar.bz2
scala-620f339bbaadad57daa696007660bb887372e927.zip
First refactoring related to Error trees.
There are no more direct calls to context.error from Typers and Infer, so more work needs to be done to finish it for Implicits and Namers. I am pushing it to trunk so that all of you can share my pain (and complain). Please do not add any more context.error randomly in that code, instead deal with it appropriately (by creating specific error tree). I was trying to be as informative when it comes to error tree names as possible, but if you feel like changing names to something more appropriate then feel free to do so. When it comes to printing error messages I tried to follow test suite as closily as possible but obviously there were few changes to some tests (mostly positive, I believe). On my machine performance drawback was neglible but I am working on more aggressive caching to reduce the penalty of containsError() calls even more. Any suggestions welcome. At the moment the code supports both styles i.e. throwing type errors for the cases that are not yet handled and generating error trees. But in the future we will drop the former completely (apart from cyclic errors which can pop up almost everywhere). Review by odersky, extempore and anyone who feels like it.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala73
1 files changed, 21 insertions, 52 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index 6e0e78e8e2..0b84e67447 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -135,21 +135,6 @@ trait TypeDiagnostics {
def alternativesString(tree: Tree) =
alternatives(tree) map (x => " " + methodTypeErrorString(x)) mkString ("", " <and>\n", "\n")
- def missingParameterTypeMsg(fun: Tree, vparam: ValDef, pt: Type) = {
- def anonMessage = (
- "\nThe argument types of an anonymous function must be fully known. (SLS 8.5)" +
- "\nExpected type was: " + pt.toLongString
- )
- val suffix =
- if (!vparam.mods.isSynthetic) ""
- else " for expanded function" + (fun match {
- case Function(_, Match(_, _)) => anonMessage
- case _ => " " + fun
- })
-
- "missing parameter type" + suffix
- }
-
def treeSymTypeMsg(tree: Tree): String = {
val sym = tree.symbol
def hasParams = tree.tpe.paramSectionCount > 0
@@ -168,34 +153,6 @@ trait TypeDiagnostics {
else defaultMessage
}
- def notEnoughArgumentsMsg(fun: Tree, missing: List[Symbol]): String = {
- val suffix = {
- if (missing.isEmpty) ""
- else {
- val keep = missing take 3 map (_.name)
- ".\nUnspecified value parameter%s %s".format(
- if (missing.tail.isEmpty) "" else "s",
- if (missing drop 3 nonEmpty) (keep :+ "...").mkString(", ")
- else keep.mkString("", ", ", ".")
- )
- }
- }
-
- "not enough arguments for " + treeSymTypeMsg(fun) + suffix
- }
-
- def applyErrorMsg(tree: Tree, msg: String, argtpes: List[Type], pt: Type) = {
- def asParams(xs: List[Any]) = xs.mkString("(", ", ", ")")
-
- def resType = if (pt isWildcard) "" else " with expected result type " + pt
- def allTypes = (alternatives(tree) flatMap (_.paramTypes)) ++ argtpes :+ pt
- def locals = alternatives(tree) flatMap (_.typeParams)
-
- withDisambiguation(locals, allTypes: _*) {
- treeSymTypeMsg(tree) + msg + asParams(argtpes) + resType
- }
- }
-
def disambiguate(ss: List[String]) = ss match {
case Nil => Nil
case s :: ss => s :: (ss map { case `s` => "(some other)"+s ; case x => x })
@@ -405,8 +362,10 @@ trait TypeDiagnostics {
trait TyperDiagnostics {
self: Typer =>
- private def contextError(pos: Position, msg: String) = context.error(pos, msg)
- private def contextError(pos: Position, err: Throwable) = context.error(pos, err)
+ private def contextError(pos: Position, msg: String) { contextError(context, pos, msg) }
+ private def contextError(context0: Analyzer#Context, pos: Position, msg: String) { context0.error(pos, msg) }
+ private def contextError(pos: Position, err: Throwable) { contextError(context, pos, err) }
+ private def contextError(context0: Analyzer#Context, pos: Position, err: Throwable) { context0.error(pos, err) }
object checkDead {
private var expr: Symbol = NoSymbol
@@ -440,36 +399,46 @@ trait TypeDiagnostics {
}
}
- def symWasOverloaded(sym: Symbol) = sym.owner.isClass && sym.owner.info.member(sym.name).isOverloaded
- def cyclicAdjective(sym: Symbol) = if (symWasOverloaded(sym)) "overloaded" else "recursive"
+ private def symWasOverloaded(sym: Symbol) = sym.owner.isClass && sym.owner.info.member(sym.name).isOverloaded
+ private def cyclicAdjective(sym: Symbol) = if (symWasOverloaded(sym)) "overloaded" else "recursive"
/** Returns Some(msg) if the given tree is untyped apparently due
* to a cyclic reference, and None otherwise.
*/
- def cyclicReferenceMessage(sym: Symbol, tree: Tree) = condOpt(tree) {
+ private def cyclicReferenceMessage(sym: Symbol, tree: Tree) = condOpt(tree) {
case ValDef(_, _, tpt, _) if tpt.tpe == null => "recursive "+sym+" needs type"
case DefDef(_, _, _, _, tpt, _) if tpt.tpe == null => List(cyclicAdjective(sym), sym, "needs result type") mkString " "
}
+ def reportTypeError(pos: Position, ex: TypeError) {
+ reportTypeError(context, pos, ex)
+ }
+
/** Report a type error.
*
* @param pos0 The position where to report the error
* @param ex The exception that caused the error
*/
- def reportTypeError(pos: Position, ex: TypeError) {
+ def reportTypeError(context0: Analyzer#Context, pos: Position, ex: TypeError) {
if (ex.pos == NoPosition) ex.pos = pos
- if (!context.reportGeneralErrors) throw ex
+ if (!context0.reportGeneralErrors) throw ex
if (settings.debug.value) ex.printStackTrace()
ex match {
case CyclicReference(sym, info: TypeCompleter) =>
- contextError(ex.pos, cyclicReferenceMessage(sym, info.tree) getOrElse ex.getMessage())
+ contextError(context0, ex.pos, cyclicReferenceMessage(sym, info.tree) getOrElse ex.getMessage())
if (sym == ObjectClass)
throw new FatalError("cannot redefine root "+sym)
case _ =>
- contextError(ex.pos, ex)
+ contextError(context0, ex.pos, ex)
}
}
+
+ def emitAllErrorTrees(tree: Tree, context: Context) =
+ errorTreesFinder(tree).foreach(_.emit(context))
+
+ def findAllNestedErrors(trees: List[Tree]): List[ErrorTree] =
+ trees.map(errorTreesFinder(_)).flatten
}
}