From fef6649b31d58e2cc239518cb031d39e1ac58b70 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 17 Sep 2011 17:26:31 +0000 Subject: More work on error trees. extempore can't live with that level of duplication. I eliminated 400 lines. I could eliminate more: there are distinctions which seem unimportant, but I'm not sure so I left them in place. Example, is a "ContextError" something meaningful other than "an error which one emits by calling context.error"? Review by plocinic. --- .../scala/tools/nsc/typechecker/ErrorTrees.scala | 1007 ++++++-------------- .../tools/nsc/typechecker/NamesDefaults.scala | 2 +- .../scala/tools/nsc/typechecker/Typers.scala | 12 +- 3 files changed, 312 insertions(+), 709 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/ErrorTrees.scala b/src/compiler/scala/tools/nsc/typechecker/ErrorTrees.scala index 92903aabb0..9b679276af 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ErrorTrees.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ErrorTrees.scala @@ -10,6 +10,10 @@ package typechecker * @author Hubert Plociniczak * @version 1.0 */ + +import scala.collection.{ mutable, immutable } +import scala.tools.util.StringOps.{ countElementsAsString, countAsString } + trait ErrorTrees { self: Analyzer => @@ -23,57 +27,52 @@ trait ErrorTrees { def exception: TypeError = null // Once we get rid of all thrown type errors (apart from cyclic), remove var reported = false override def tpe = ErrorType - printName(this) + + // Debugging option + if (settings.errortrees.value) + println("[ErrorTree instance] " + this.getClass) } - protected trait ContextError { + trait ErrorPosAndMsg { def errMsg: String def errPos: Position - def emit(context: Context) = context.error(errPos, errMsg) + def shouldEmit: Boolean + def emit(context: Context): Unit } + protected trait ContextError extends ErrorPosAndMsg { } - // Debugging option - @inline private def printName(t: ErrorTree) { - if (settings.errortrees.value) - println("[ErrorTree instance] " + t.getClass) + trait ErrorTreeWithContext extends ErrorTree with ContextError { + def shouldEmit = true + def emit(context: Context) = if (shouldEmit) context.error(errPos, errMsg) } - object errorTreesFinder extends Traverser { - import scala.collection.mutable - var trees: mutable.ListBuffer[ErrorTree] = _ - override def traverse(t: Tree) { - t match { - case e: ErrorTree if !e.reported => - trees += e - case e: ErrorTree => - case _ => + /** Traverses a tree, collecting subtrees for which the first argument is + * defined. A given tree's children are traversed only if the keepTraversing + * predicate returns true for that tree. + */ + def pruningCollect[T](pf: PartialFunction[Tree, T])(keepTraversing: Tree => Boolean): Tree => List[T] = { + class Collector extends Traverser { + val trees = mutable.ListBuffer[T]() + override def traverse(t: Tree) { + if (pf.isDefinedAt(t)) + trees += pf(t) + if (keepTraversing(t)) super.traverse(t) } } - def apply(t: Tree) = { - trees = new mutable.ListBuffer() - traverse(t) - trees + tree => { + val c = new Collector + c traverse tree + c.trees.toList } } - object quickErrorTreeFinder extends Traverser { - import scala.collection.mutable - private var found: Option[ErrorTree] = None - override def traverse(t: Tree) { - if (!found.isDefined) - t match { - case e: ErrorTree => - found = Some(e) - case _ => - super.traverse(t) - } - } - def apply(t: Tree): ErrorTree = { - found = None - traverse(t) - found.get - } + def errorTreesFinder(tree: Tree): List[ErrorTree] = + pruningCollect({ case e: ErrorTree if !e.reported => e })(!_.isInstanceOf[ErrorTree])(tree) + + def quickErrorTreeFinder(tree: Tree): ErrorTree = tree find (_.isInstanceOf[ErrorTree]) match { + case Some(x: ErrorTree) => x + case _ => NullErrorTree } protected abstract class TreeForwarder(forwardTo: Tree) extends Tree { @@ -82,38 +81,58 @@ trait ErrorTrees { override def symbol = forwardTo.symbol override def symbol_=(x: Symbol) = forwardTo.symbol = x } + abstract class PositionedErrorTree(tree: Tree) extends ErrorTree with ErrorPosAndMsg { + def errPos = tree.pos + def shouldEmit = !tree.isErroneous + def emit(context: Context) = if (shouldEmit) context.error(errPos, errMsg) + } + abstract class ContextErrorTree(tree: Tree) extends PositionedErrorTree(tree) with ContextError { } + abstract class ErrorTreeForwarder(tree: Tree) extends TreeForwarder(tree) with ErrorTree with ErrorPosAndMsg { + def errPos = tree.pos + def shouldEmit = !tree.isErroneous + def emit(context: Context) = if (shouldEmit) context.error(errPos, errMsg) + } + abstract class ContextErrorTreeForwarder(tree: Tree) extends ErrorTreeForwarder(tree) with ContextError { } // create trees for specific error trees trait TyperErrorTrees { self: Typer => - import infer.setError - - case class UnstableTreeError(tree: Tree) - extends TreeForwarder(tree) with ErrorTree { - + trait TypeErrorTrait extends ErrorTree with ErrorPosAndMsg { + def errMsg = "type error" // not used def emit(context: Context) { - val msg = "stable identifier required, but "+tree+" found."+ - (if (isStableExceptVolatile(tree)) { - val tpe = tree.symbol.tpe match { - case PolyType(_, rtpe) => rtpe - case t => t - } - "\n Note that "+tree.symbol+" is not stable because its type, "+tree.tpe+", is volatile." - } else "") - - if (!tree.isErroneous) - context.error(tree.pos, msg) + reportTypeError(context, errPos, exception) + } + } + abstract class TypeErrorTreeForwarder(tree: Tree) extends ErrorTreeForwarder(tree) with TypeErrorTrait { + override def emit(context: Context) { + super[TypeErrorTrait].emit(context) } } - case class NoImplicitFoundError(fun: Tree, param: Symbol) - extends TreeForwarder(fun) with ErrorTree with ContextError { + import infer.setError + case class UnstableTreeError(tree: Tree) extends ErrorTreeForwarder(tree) { + private def addendum = { + // !!! unused + // val tpe = tree.symbol.tpe match { + // case PolyType(_, rtpe) => rtpe + // case t => t + // } + "\n Note that "+tree.symbol+" is not stable because its type, "+tree.tpe+", is volatile." + } + def errMsg = ( + "stable identifier required, but "+tree+" found." + ( + if (isStableExceptVolatile(tree)) addendum else "" + ) + ) + } + + case class NoImplicitFoundError(tree: Tree, param: Symbol) extends ContextErrorTreeForwarder(tree) { def errMsg = { val paramName = param.name - val paramTp = param.tpe + val paramTp = param.tpe paramTp.typeSymbol match { case ImplicitNotFoundMsg(msg) => msg.format(paramName, paramTp) case _ => @@ -122,266 +141,161 @@ trait ErrorTrees { else "parameter "+paramName+": ")+paramTp } } - def errPos = fun.pos - } - - case class TypeErrorTree(tree: Tree, pt: Type, override val exception: TypeError) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - reportTypeError(context, tree.pos, exception) - } } - case class AdaptToMemberWithArgsError(tree: Tree, override val exception: TypeError) - extends TreeForwarder(tree) with ErrorTree { + case class TypeErrorTree(tree: Tree, pt: Type, override val exception: TypeError) extends TypeErrorTreeForwarder(tree) { } - def emit(context: Context) { - reportTypeError(context, tree.pos, exception) - } - } + case class AdaptToMemberWithArgsError(tree: Tree, override val exception: TypeError) extends TypeErrorTreeForwarder(tree) { } - case class WithFilterError(tree0: Tree, override val exception: TypeError) - extends TreeForwarder(tree0) with ErrorTree { - - def emit(context: Context) { - reportTypeError(context, tree0.pos, exception) - setError(tree0) + case class WithFilterError(tree: Tree, override val exception: TypeError) extends TypeErrorTreeForwarder(tree) { + override def emit(context: Context) { + super.emit(context) + setError(tree) } } - case class ParentTypesError(templ: Template, override val exception: TypeError) - extends ErrorTree { - - def emit(context: Context) { + case class ParentTypesError(templ: Template, override val exception: TypeError) extends TypeErrorTrait { + def errPos = templ.pos + def shouldEmit = !templ.isErroneous + override def emit(context: Context) { templ.tpe = null - reportTypeError(context, templ.pos, exception) + super.emit(context) } } // additional parentTypes errors - - case class ConstrArgsInTraitParentTpeError(arg: Tree, parent: Symbol) - extends ErrorTree with ContextError { - + case class ConstrArgsInTraitParentTpeError(arg: Tree, parent: Symbol) extends ContextErrorTree(arg) { def errMsg = parent + " is a trait; does not take constructor arguments" - def errPos = arg.pos } - case class MissingTypeArgumentsParentTpeError(supertpt: Tree) - extends ErrorTree with ContextError { - + case class MissingTypeArgumentsParentTpeError(supertpt: Tree) extends ContextErrorTree(supertpt) { def errMsg = "missing type arguments" - def errPos = supertpt.pos } - case class SilentTypeError(tree: Tree, override val exception: TypeError) - extends ErrorTree { - - def emit(context: Context) { - reportTypeError(context, tree.pos, exception) - } + case class SilentTypeError(tree: Tree, override val exception: TypeError) extends TypeErrorTrait { + def shouldEmit = false // !!! correct? + def errPos = tree.pos } - case class TypedApplyError(tree: Tree, override val exception: TypeError) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - reportTypeError(context, tree.pos, exception) - } - + case class TypedApplyError(tree: Tree, override val exception: TypeError) extends TypeErrorTreeForwarder(tree) { override def pos = exception.pos } - case class AssignmentTypedApplyError(tree: Tree) - extends TreeForwarder(tree) with ErrorTree with ContextError { - + case class AssignmentTypedApplyError(tree: Tree) extends ContextErrorTreeForwarder(tree) { def errMsg = "reassignment to val" - def errPos = tree.pos } // typedIdent - case class AmbiguousIdentError(tree: Tree, name: Name, msg: String) - extends TreeForwarder(tree) with ErrorTree with ContextError { - + case class AmbiguousIdentError(tree: Tree, name: Name, msg: String) extends ContextErrorTreeForwarder(tree) { def errMsg = "reference to " + name + " is ambiguous;\n" + msg - def errPos = tree.pos } - case class SymbolNotFound(tree: Tree, name: Name, owner: Symbol) - extends TreeForwarder(tree) with ErrorTree with ContextError { - + case class SymbolNotFound(tree: Tree, name: Name, owner: Symbol) extends ContextErrorTreeForwarder(tree) { def errMsg = "not found: "+decodeWithKind(name, owner) - def errPos = tree.pos } // typedAppliedTypeTree - case class AppliedTypeNoParametersError(tree: Tree, errTpe: Type) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, errTpe + " does not take type parameters") - } + case class AppliedTypeNoParametersError(tree: Tree, errTpe: Type) extends ErrorTreeForwarder(tree) { + def errMsg = errTpe + " does not take type parameters" } - case class AppliedTypeWrongNumberOfArgsError(tree: Tree, msg: String) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, msg) - } - } + case class AppliedTypeWrongNumberOfArgsError(tree: Tree, errMsg: String) extends ErrorTreeForwarder(tree) { } // packagedef - case class RefTreeError(tree: Tree, name: Name) - extends ErrorTree with RefTree { - - def emit(context: Context) { - // Error was already reported - } + case class RefTreeError(tree: Tree, name: Name) extends ErrorTree with RefTree { + // Error was already reported + def emit(context: Context) { } } // typedTypeDef - case class LowerBoundError(tree: TypeDef, lowB: Type, highB: Type) - extends ErrorTree with ContextError { - + case class LowerBoundError(tree: TypeDef, lowB: Type, highB: Type) extends ContextErrorTree(tree) { def errMsg = "lower bound "+lowB+" does not conform to upper bound "+highB - def errPos = tree.pos } // check privates - case class HiddenSymbolWithError(tree: Tree) - extends ErrorTree { - - def emit(context: Context) {} + case class HiddenSymbolWithError(tree: Tree) extends ErrorTree { + def emit(context: Context) { } } - case class SymbolEscapesScopeError(tree: Tree, badSymbol: Symbol) - extends ErrorTree with ContextError { - - val treeTpe = tree.tpe - def errMsg = (if (badSymbol.isPrivate) "private " else "") + badSymbol + - " escapes its defining scope as part of type "+treeTpe + case class SymbolEscapesScopeError(tree: Tree, badSymbol: Symbol) extends ErrorTreeWithContext { + private val treeTpe = tree.tpe def errPos = tree.pos + def errMsg = modifierString + badSymbol + " escapes its defining scope as part of type "+treeTpe + private def modifierString = if (badSymbol.isPrivate) "private " else "" } // typedDefDef - case class StarParamNotLastError(param: Tree) - extends ErrorTree with ContextError { - + case class StarParamNotLastError(param: Tree) extends ContextErrorTree(param) { def errMsg = "*-parameter must come last" - def errPos = param.pos } - case class StarWithDefaultError(meth: Symbol) - extends ErrorTree with ContextError { - + case class StarWithDefaultError(meth: Symbol) extends ErrorTreeWithContext { def errMsg = "a parameter section with a `*'-parameter is not allowed to have default arguments" def errPos = meth.pos } - case class InvalidConstructorDefError(ddef: Tree) - extends ErrorTree with ContextError { - + case class InvalidConstructorDefError(ddef: Tree) extends ContextErrorTree(ddef) { def errMsg = "constructor definition not allowed here" - def errPos = ddef.pos } - case class DeprecatedParamNameError(param: Symbol, name: Name) - extends ErrorTree with ContextError { - + case class DeprecatedParamNameError(param: Symbol, name: Name) extends ErrorTreeWithContext { def errMsg = "deprecated parameter name "+ name +" has to be distinct from any other parameter name (deprecated or not)." def errPos = param.pos } // computeParamAliases - case class SuperConstrReferenceError(tree: Tree) - extends ErrorTree with ContextError { - + case class SuperConstrReferenceError(tree: Tree) extends ContextErrorTree(tree) { def errMsg = "super constructor cannot be passed a self reference unless parameter is declared by-name" - def errPos = tree.pos } - case class SuperConstrArgsThisReferenceError(tree: Tree) - extends ErrorTree with ContextError { - + case class SuperConstrArgsThisReferenceError(tree: Tree) extends ContextErrorTree(tree) { def errMsg = "super constructor arguments cannot reference unconstructed `this`" - def errPos = tree.pos } // typedValDef - case class VolatileValueError(vdef: Tree) - extends ErrorTree with ContextError { - + case class VolatileValueError(vdef: Tree) extends ContextErrorTree(vdef) { def errMsg = "values cannot be volatile" - def errPos = vdef.pos } - case class FinalVolatileVarError(vdef: Tree) - extends ErrorTree with ContextError { - + case class FinalVolatileVarError(vdef: Tree) extends ContextErrorTree(vdef) { def errMsg = "final vars cannot be volatile" - def errPos = vdef.pos } - case class LocalVarUninitializedError(vdef: Tree) - extends ErrorTree with ContextError { - + case class LocalVarUninitializedError(vdef: Tree) extends ContextErrorTree(vdef) { def errMsg = "local variables must be initialized" - def errPos = vdef.pos } //typedAssign - case class AssignmentError(tree: Tree, varSym: Symbol) - extends TreeForwarder(tree) with ErrorTree with ContextError { - + case class AssignmentError(tree: Tree, varSym: Symbol) extends ContextErrorTreeForwarder(tree) { def errMsg = if (varSym != null && varSym.isValue) "reassignment to val" else "assignment to non variable" - def errPos = tree.pos } - case class UnexpectedTreeAssignmentConversionError(tree: Tree) - extends TreeForwarder(tree) with ErrorTree with ContextError { - + case class UnexpectedTreeAssignmentConversionError(tree: Tree) extends ContextErrorTreeForwarder(tree) { def errMsg = "Unexpected tree during assignment conversion." - def errPos = tree.pos } - case class MultiDimensionalArrayError(tree: Tree) - extends ErrorTree with ContextError { - + case class MultiDimensionalArrayError(tree: Tree) extends ContextErrorTree(tree) { def errMsg = "cannot create a generic multi-dimensional array of more than "+ definitions.MaxArrayDims+" dimensions" - def errPos = tree.pos } //typedSuper - case class MixinMissingParentClassNameError(tree: Tree, mix: Name, clazz: Symbol) - extends ErrorTree with ContextError { - + case class MixinMissingParentClassNameError(tree: Tree, mix: Name, clazz: Symbol) extends ContextErrorTree(tree) { def errMsg = mix+" does not name a parent class of "+clazz - def errPos = tree.pos } - case class AmbiguousParentClassError(tree: Tree) - extends ErrorTree with ContextError { - + case class AmbiguousParentClassError(tree: Tree) extends ContextErrorTree(tree) { def errMsg = "ambiguous parent class qualifier" - def errPos = tree.pos } //typedSelect - case class NotAMemberErroneous(tree: Tree) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { } + case class NotAMemberErroneous(tree: Tree) extends ErrorTreeForwarder(tree) { + def errMsg = "" + override def emit(context: Context) { } } - case class NotAMemberError(sel: Tree, qual: Tree, name: Name) - extends TreeForwarder(sel) with ErrorTree with ContextError { - + case class NotAMemberError(sel: Tree, qual: Tree, name: Name) extends ContextErrorTreeForwarder(sel) { def errMsg = { val owner = qual.tpe.typeSymbol val target = qual.tpe.widen @@ -411,94 +325,51 @@ trait ErrorTrees { else nameString + " is not a member of " + targetKindString + target + addendum ) } - - def errPos = sel.pos } //typedNew - case class IsAbstractError(tree: Tree, sym: Symbol) - extends ErrorTree with ContextError { - + case class IsAbstractError(tree: Tree, sym: Symbol) extends ContextErrorTree(tree) { def errMsg = sym + " is abstract; cannot be instantiated" - def errPos = tree.pos } - case class DoesNotConformToSelfTypeError(tree: Tree, sym: Symbol, tpe0: Type) - extends ErrorTree with ContextError { - - def errMsg = sym + - " cannot be instantiated because it does not conform to its self-type "+ - tpe0 - def errPos = tree.pos + case class DoesNotConformToSelfTypeError(tree: Tree, sym: Symbol, tpe0: Type) extends ContextErrorTree(tree) { + def errMsg = sym + " cannot be instantiated because it does not conform to its self-type " + tpe0 } //typedEta - case class UnderscoreEtaError(tree: Tree) - extends ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, "_ must follow method; cannot follow " + tree.tpe) - } + case class UnderscoreEtaError(tree: Tree) extends PositionedErrorTree(tree) { + def errMsg = "_ must follow method; cannot follow " + tree.tpe } //typedReturn - case class ReturnOutsideOfDefError(tree: Tree) - extends ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, "return outside method definition") - } + case class ReturnOutsideOfDefError(tree: Tree) extends PositionedErrorTree(tree) { + def errMsg = "return outside method definition" } - case class ReturnWithoutTypeError(tree: Tree, owner: Symbol) - extends ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, owner + " has return statement; needs result type") - } + case class ReturnWithoutTypeError(tree: Tree, owner: Symbol) extends PositionedErrorTree(tree) { + def errMsg = owner + " has return statement; needs result type" } //typedBind - case class VariableInPatternAlternativeError(tree: Tree) - extends ErrorTree with ContextError { - + case class VariableInPatternAlternativeError(tree: Tree) extends ContextErrorTree(tree) { def errMsg = "illegal variable in pattern alternative" - def errPos = tree.pos } //typedCase - case class StarPositionInPatternError(pos0: Position) - extends ErrorTree with ContextError { - + case class StarPositionInPatternError(errPos: Position) extends ErrorTreeWithContext { def errMsg = "_* may only come last" - def errPos = pos0 } //typedFunction - case class MaxFunctionArityError(fun: Tree) - extends TreeForwarder(fun) with ErrorTree { - - def emit(context: Context) { - if (!fun.isErroneous) - context.error(fun.pos,"implementation restricts functions to " + definitions.MaxFunctionArity + " parameters") - } + case class MaxFunctionArityError(fun: Tree) extends ErrorTreeForwarder(fun) { + def errMsg = "implementation restricts functions to " + definitions.MaxFunctionArity + " parameters" } - case class WrongNumberOfParametersError(tree: Tree, argpts: List[Type]) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos,"wrong number of parameters; expected = " + argpts.length) - } + case class WrongNumberOfParametersError(tree: Tree, argpts: List[Type]) extends ErrorTreeForwarder(tree) { + def errMsg = "wrong number of parameters; expected = " + argpts.length } - case class MissingParameterTypeError(fun: Tree, vparam: ValDef, pt: Type) - extends ErrorTree with ContextError { - + case class MissingParameterTypeError(fun: Tree, vparam: ValDef, pt: Type) extends ContextErrorTree(vparam) { def anonMessage = ( "\nThe argument types of an anonymous function must be fully known. (SLS 8.5)" + "\nExpected type was: " + pt.toLongString @@ -512,186 +383,104 @@ trait ErrorTrees { }) def errMsg = "missing parameter type" + suffix - def errPos = vparam.pos } - case class ConstructorsOrderError(tree: Tree) - extends ErrorTree with ContextError { - + case class ConstructorsOrderError(tree: Tree) extends ContextErrorTree(tree) { def errMsg = "called constructor's definition must precede calling constructor's definition" - def errPos = tree.pos } - case class OnlyDeclarationsError(tree: Tree) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, "only declarations allowed here") - } + case class OnlyDeclarationsError(tree: Tree) extends ErrorTreeForwarder(tree) { + def errMsg = "only declarations allowed here" } // typedAnnotation - case class AnnotationNotAConstantError(tree: Tree) - extends ErrorTree with ContextError { - + case class AnnotationNotAConstantError(tree: Tree) extends ContextErrorTree(tree) { def errMsg = "annotation argument needs to be a constant; found: " + tree - def errPos = tree.pos } - case class AnnotationArgNulError(tree: Tree) - extends ErrorTree with ContextError { - + case class AnnotationArgNullError(tree: Tree) extends ContextErrorTree(tree) { def errMsg = "annotation argument cannot be null" - def errPos = tree.pos } - case class ArrayConstantsError(tree: Tree) - extends ErrorTree with ContextError { - + case class ArrayConstantsError(tree: Tree) extends ContextErrorTree(tree) { def errMsg = "Array constants have to be specified using the `Array(...)' factory method" - def errPos = tree.pos } - case class ArrayConstantsTypeMismatchError(tree: Tree, pt: Type) - extends ErrorTree with ContextError { - + case class ArrayConstantsTypeMismatchError(tree: Tree, pt: Type) extends ContextErrorTree(tree) { def errMsg = "found array constant, expected argument of type " + pt - def errPos = tree.pos } - case class UnexpectedTreeAnnotation(tree: Tree) - extends ErrorTree with ContextError { - + case class UnexpectedTreeAnnotation(tree: Tree) extends ContextErrorTree(tree) { def errMsg = "unexpected tree in annotation: "+ tree - def errPos = tree.pos } - case class AnnotationTypeMismatchError(tree: Tree, expected: Type, found: Type) - extends ErrorTree with ContextError { - - def errMsg = "expected annotation of type "+ expected +", found "+ found - def errPos = tree.pos + case class AnnotationTypeMismatchError(tree: Tree, expected: Type, found: Type) extends ContextErrorTree(tree) { + def errMsg = "expected annotation of type " + expected + ", found " + found } - case class MultipleArgumentListForAnnotationError(tree: Tree) - extends ErrorTree with ContextError { - + case class MultipleArgumentListForAnnotationError(tree: Tree) extends ContextErrorTree(tree) { def errMsg = "multiple argument lists on classfile annotation" - def errPos = tree.pos } - case class UnknownAnnotationNameError(tree: Tree, name: Name) - extends ErrorTree with ContextError { - + case class UnknownAnnotationNameError(tree: Tree, name: Name) extends ContextErrorTree(tree) { def errMsg = "unknown annotation argument name: " + name - def errPos = tree.pos } - case class DuplicateValueAnnotationError(tree: Tree, name: Name) - extends ErrorTree with ContextError { - + case class DuplicateValueAnnotationError(tree: Tree, name: Name) extends ContextErrorTree(tree) { def errMsg = "duplicate value for annotation argument " + name - def errPos = tree.pos } - case class ClassfileAnnotationsAsNamedArgsError(tree: Tree) - extends ErrorTree with ContextError { - + case class ClassfileAnnotationsAsNamedArgsError(tree: Tree) extends ContextErrorTree(tree) { def errMsg = "classfile annotation arguments have to be supplied as named arguments" - def errPos = tree.pos } - case class AnnotationMissingArgError(tree: Tree, annType: Type, name: Symbol) - extends ErrorTree with ContextError { - + case class AnnotationMissingArgError(tree: Tree, annType: Type, name: Symbol) extends ContextErrorTree(tree) { def errMsg = "annotation " + annType.typeSymbol.fullName + " is missing argument " + name.name - def errPos = tree.pos } - case class NestedAnnotationError(tree: Tree, annType: Type) - extends ErrorTree with ContextError { - + case class NestedAnnotationError(tree: Tree, annType: Type) extends ContextErrorTree(tree) { def errMsg = "nested classfile annotations must be defined in java; found: "+ annType - def errPos = tree.pos } - case class UnexpectedTreeAnnotationError(tree: Tree, unexpected: Tree) - extends ErrorTree with ContextError { - + case class UnexpectedTreeAnnotationError(tree: Tree, unexpected: Tree) extends ContextErrorTree(tree) { def errMsg = "unexpected tree after typing annotation: "+ unexpected - def errPos = tree.pos } // TODO no test case //typedExistentialTypeTree - case class AbstractionFromVolatileTypeError(vd: ValDef) - extends ErrorTree with ContextError { - + case class AbstractionFromVolatileTypeError(vd: ValDef) extends ContextErrorTree(vd) { def errMsg = "illegal abstraction from value with volatile type "+vd.symbol.tpe - def errPos = vd.pos } - case class TypedApplyWrongNumberOfTpeParametersError(tree: Tree, fun: Tree) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, "wrong number of type parameters for "+treeSymTypeMsg(fun)) - } + case class TypedApplyWrongNumberOfTpeParametersError(tree: Tree, fun: Tree) extends ErrorTreeForwarder(tree) { + def errMsg = "wrong number of type parameters for "+treeSymTypeMsg(fun) } - case class TypedApplyDoesNotTakeTpeParametersError(tree: Tree, fun: Tree) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, treeSymTypeMsg(fun)+" does not take type parameters.") - } + case class TypedApplyDoesNotTakeTpeParametersError(tree: Tree, fun: Tree) extends ErrorTreeForwarder(tree) { + def errMsg = treeSymTypeMsg(fun)+" does not take type parameters." } // doTypeApply //tryNamesDefaults - case class WrongNumberOfArgsError(tree: Tree, fun: Tree) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, "wrong number of arguments for "+ treeSymTypeMsg(fun)) - } + case class WrongNumberOfArgsError(tree: Tree, fun: Tree) extends ErrorTreeForwarder(tree) { + def errMsg = "wrong number of arguments for "+ treeSymTypeMsg(fun) } - case class TooManyArgsNamesDefaultsError(tree: Tree, fun: Tree) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, "too many arguments for "+treeSymTypeMsg(fun)) - } + case class TooManyArgsNamesDefaultsError(tree: Tree, fun: Tree) extends ErrorTreeForwarder(tree) { + def errMsg = "too many arguments for "+treeSymTypeMsg(fun) } - case class MultipleVarargError(tree: Tree) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, "when using named arguments, the vararg parameter "+ - "has to be specified exactly once") - } + case class MultipleVarargError(tree: Tree) extends ErrorTreeForwarder(tree) { + def errMsg = "when using named arguments, the vararg parameter has to be specified exactly once" } - case class ModuleUsingCompanionClassDefaultArgsErrror(tree: Tree) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, "module extending its companion class cannot use default constructor arguments") - } + case class ModuleUsingCompanionClassDefaultArgsErrror(tree: Tree) extends ErrorTreeForwarder(tree) { + def errMsg = "module extending its companion class cannot use default constructor arguments" } - case class NotEnoughArgsError(tree: Tree, fun0: Tree, missing0: List[Symbol]) - extends TreeForwarder(tree) with ErrorTree { - def notEnoughArgumentsMsg(fun: Tree, missing: List[Symbol]): String = { + case class NotEnoughArgsError(tree: Tree, fun0: Tree, missing0: List[Symbol]) extends ErrorTreeForwarder(tree) { + def errMsg = notEnoughArgumentsMsg(fun0, missing0) + def notEnoughArgumentsMsg(fun: Tree, missing: List[Symbol]) = { val suffix = { if (missing.isEmpty) "" else { @@ -704,56 +493,33 @@ trait ErrorTrees { } } - "not enough arguments for " + treeSymTypeMsg(fun) + suffix - } - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, notEnoughArgumentsMsg(fun0, missing0)) + "not enough arguments for " + treeSymTypeMsg(fun) + suffix } } //doTypedApply - ErrorType - case class ErroneousFunInTypeApplyError(fun: Tree, args: List[Tree]) - extends TreeForwarder(fun) with ErrorTree { - - var errorCache: scala.collection.mutable.ListBuffer[ErrorTree] = null + case class ErroneousFunInTypeApplyError(fun: Tree, args: List[Tree]) extends TreeForwarder(fun) with ErrorTree { + private lazy val errorCache = errorTreesFinder(fun) ++ (args flatMap errorTreesFinder) def emit(context: Context) { - if (errorCache == null) - errorCache = errorTreesFinder(fun) ++ args.map(arg => errorTreesFinder(arg)).flatten - errorCache.foreach(_.emit(context)) + errorCache foreach (_ emit context) } } //doTypedApply - patternMode // TODO: missing test case - case class TooManyArgsPatternError(fun: Tree) - extends TreeForwarder(fun) with ErrorTree with ContextError { - + case class TooManyArgsPatternError(fun: Tree) extends ContextErrorTreeForwarder(fun) { def errMsg = "too many arguments for unapply pattern, maximum = "+definitions.MaxTupleArity - def errPos = fun.pos } - case class WrongNumberArgsPatternError(tree: Tree, fun: Tree) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, "wrong number of arguments for "+treeSymTypeMsg(fun)) - } + case class WrongNumberArgsPatternError(tree: Tree, fun: Tree) extends ErrorTreeForwarder(tree) { + def errMsg = "wrong number of arguments for "+treeSymTypeMsg(fun) } // Extends ErrorTreeWithPrettyPrinter to pass presentation/ping-pong test case - case class ApplyWithoutArgsError(tree: Tree, fun: Tree) - extends TreeForwarder(tree) with ErrorTreeWithPrettyPrinter with ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, fun.tpe+" does not take parameters") - } - - override def toString() = tree.toString() + case class ApplyWithoutArgsError(tree: Tree, fun: Tree) extends ErrorTreeForwarder(tree) with ErrorTreeWithPrettyPrinter { + def errMsg = fun.tpe+" does not take parameters" + override def toString = "" + tree } //checkClassType @@ -762,251 +528,164 @@ trait ErrorTrees { // trait BlockingError allows us to distinguish it trait BlockingError - case class TypeNotAStablePrefixError(pre: Type, pos0: Position) - extends ErrorTree with BlockingError with ContextError { - + case class TypeNotAStablePrefixError(pre: Type, errPos: Position) extends ErrorTreeWithContext with BlockingError { def errMsg = "type "+pre+" is not a stable prefix" - def errPos = pos0 } - case class ClassTypeRequiredError(tree: Tree, found: AnyRef) - extends ErrorTree with BlockingError with ContextError { - + case class ClassTypeRequiredError(tree: Tree, found: AnyRef) extends ContextErrorTree(tree) with BlockingError { def errMsg = "class type required but "+found+" found" - def errPos = tree.pos } // validateParentClasses - case class ParentSuperSubclassError(pos0: Position, superclazz: Symbol, + case class ParentSuperSubclassError(errPos: Position, superclazz: Symbol, parentSym: Symbol, mixin: Symbol) - extends ErrorTree with ContextError { + extends ErrorTreeWithContext { def errMsg = "illegal inheritance; super"+superclazz+ "\n is not a subclass of the super"+parentSym+ "\n of the mixin " + mixin - def errPos = pos0 } - case class ParentNotATraitMixinError(pos0: Position, mixin: Symbol) - extends ErrorTree with BlockingError with ContextError { - + case class ParentNotATraitMixinError(errPos: Position, mixin: Symbol) extends ErrorTreeWithContext with BlockingError { def errMsg = mixin+" needs to be a trait to be mixed in" - def errPos = pos0 } - case class ParentFinalInheritanceError(pos0: Position, mixin: Symbol) - extends ErrorTree with BlockingError with ContextError { - + case class ParentFinalInheritanceError(errPos: Position, mixin: Symbol) extends ErrorTreeWithContext with BlockingError { def errMsg = "illegal inheritance from final "+mixin - def errPos = pos0 } - case class ParentSealedInheritanceError(pos0: Position, mixin: Symbol) - extends ErrorTree with BlockingError with ContextError { - + case class ParentSealedInheritanceError(errPos: Position, mixin: Symbol) extends ErrorTreeWithContext with BlockingError { def errMsg = "illegal inheritance from sealed "+mixin - def errPos = pos0 } - case class ParentSelfTypeConformanceError( - pos0: Position, selfType: Type, parent: Tree) - extends ErrorTree with ContextError { - - def errMsg = "illegal inheritance;\n self-type "+ - selfType+" does not conform to "+parent + - "'s selftype "+parent.tpe.typeOfThis - def errPos = pos0 + case class ParentSelfTypeConformanceError(errPos: Position, selfType: Type, parent: Tree) extends ErrorTreeWithContext { + def errMsg = ( + "illegal inheritance;\n self-type "+selfType+" does not conform to "+ + parent +"'s selftype "+parent.tpe.typeOfThis + ) } - case class ParentInheritedTwiceError(pos0: Position, parent: Symbol) - extends ErrorTree with BlockingError with ContextError { - + case class ParentInheritedTwiceError(errPos: Position, parent: Symbol) extends ErrorTreeWithContext with BlockingError { def errMsg = parent+" is inherited twice" - def errPos = pos0 } //adapt - case class MissingArgsForMethodTpeError(tree: Tree, meth: Symbol) - extends ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, "missing arguments for "+meth+meth.locationString+ - (if (meth.isConstructor) "" - else ";\nfollow this method with `_' if you want to treat it as a partially applied function")) - } + case class MissingArgsForMethodTpeError(tree: Tree, meth: Symbol) extends PositionedErrorTree(tree) { + def errMsg = ( + "missing arguments for " + meth.fullLocationString + ( + if (meth.isConstructor) "" + else ";\nfollow this method with `_' if you want to treat it as a partially applied function" + ) + ) } // This is really a workaround for a compiler bug - case class Bug4425Error(tree: Tree) - extends TreeForwarder(tree) with ErrorTree with ContextError { - + case class Bug4425Error(tree: Tree) extends ContextErrorTreeForwarder(tree) { def errMsg = "erroneous or inaccessible type" - def errPos = tree.pos } - case class MissingTypeParametersError(tree: Tree) - extends TreeForwarder(tree) with ErrorTree { + case class MissingTypeParametersError(tree: Tree) extends ErrorTreeForwarder(tree) { + def errMsg = tree.symbol+" takes type parameters" - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, tree.symbol+" takes type parameters") - setError(tree) - } + // !!! Necessary? + // override def emit(context: Context) { + // super.emit(context) + // setError(tree) + // } } - case class KindArityMismatchError(tree: Tree, pt: Type) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - import scala.tools.util.StringOps.{countElementsAsString, countAsString} - if (!tree.isErroneous) - context.error(tree.pos, - tree.tpe+" takes "+countElementsAsString(tree.tpe.typeParams.length, "type parameter")+ - ", expected: "+countAsString(pt.typeParams.length)) - } + case class KindArityMismatchError(tree: Tree, pt: Type) extends ErrorTreeForwarder(tree) { + def errMsg = ( + tree.tpe+" takes "+countElementsAsString(tree.tpe.typeParams.length, "type parameter")+ + ", expected: "+countAsString(pt.typeParams.length) + ) } //case class ParamsNotConvertible - case class CaseClassConstructorError(tree: Tree) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - import scala.tools.util.StringOps.{countElementsAsString, countAsString} - if (!tree.isErroneous) - context.error(tree.pos, - tree.symbol + " is not a case class constructor, nor does it have an unapply/unapplySeq method") - } + case class CaseClassConstructorError(tree: Tree) extends ErrorTreeForwarder(tree) { + def errMsg = tree.symbol + " is not a case class constructor, nor does it have an unapply/unapplySeq method" } //TODO Needs test case - case class ConstructorPrefixError(tree: Tree, restpe: Type) - extends ErrorTree with ContextError { - + case class ConstructorPrefixError(tree: Tree, restpe: Type) extends ContextErrorTree(tree) { def errMsg = restpe.prefix+" is not a legal prefix for a constructor" - def errPos = tree.pos } // SelectFromTypeTree - case class TypeSelectionFromVolatileTypeError(tree: Tree, qual: Tree) - extends ErrorTree with ContextError { - + case class TypeSelectionFromVolatileTypeError(tree: Tree, qual: Tree) extends ContextErrorTree(tree) { def errMsg = "illegal type selection from volatile type "+qual.tpe - def errPos = tree.pos } // packedType - case class InferTypeWithVolatileTypeSelectionError(tree: Tree, pre: Type) - extends ErrorTree with ContextError { - + case class InferTypeWithVolatileTypeSelectionError(tree: Tree, pre: Type) extends ContextErrorTree(tree) { def errMsg = "Inferred type "+tree.tpe+" contains type selection from volatile type "+pre - def errPos = tree.pos } - case class AbstractExistentiallyOverParamerizedTpeError(tree: Tree, tp: Type) - extends ErrorTree with ContextError { - + case class AbstractExistentiallyOverParamerizedTpeError(tree: Tree, tp: Type) extends ContextErrorTree(tree) { def errMsg = "can't existentially abstract over parameterized type " + tp - def errPos = tree.pos } //manifestTreee - case class MissingManifestError(pos0: Position, full: Boolean, tp: Type) - extends ErrorTree with ContextError { - + case class MissingManifestError(errPos: Position, full: Boolean, tp: Type) extends ErrorTreeWithContext { def errMsg = "cannot find "+(if (full) "" else "class ")+"manifest for element type "+tp - def errPos = pos0 } // TODO needs test case // cases where we do not necessairly return trees - case class DependentMethodTpeConversionToFunctionError(pos0: Position, tp: Type) - extends ErrorTree with ContextError { - + case class DependentMethodTpeConversionToFunctionError(errPos: Position, tp: Type) extends ErrorTreeWithContext { def errMsg = "method with dependent type "+tpe+" cannot be converted to function value" - def errPos = pos0 - - override def pos = pos0 + override def pos = errPos } //checkStarPatOK - case class StarPatternWithVarargParametersError(pos0: Position) - extends ErrorTree with ContextError { - + case class StarPatternWithVarargParametersError(errPos: Position) extends ErrorTreeWithContext { def errMsg = "star patterns must correspond with varargs parameters" - def errPos = pos0 } - case class GetterDefinedTwiceError(getter: Symbol) - extends ErrorTree with ContextError { - + case class GetterDefinedTwiceError(getter: Symbol) extends ErrorTreeWithContext { def errMsg = getter+" is defined twice" def errPos = getter.pos } - case class BeanPropertyAnnotationLimitationError(tree: Tree) - extends ErrorTree with ContextError { - + case class BeanPropertyAnnotationLimitationError(tree: Tree) extends ContextErrorTree(tree) { def errMsg = "implementation limitation: the BeanProperty annotation cannot be used in a type alias or renamed import" - def errPos = tree.pos } // TODO missing test case - case class FinitiaryError(tparam: Symbol) - extends ErrorTree with ContextError { - + case class FinitaryError(tparam: Symbol) extends ErrorTreeWithContext { def errMsg = "class graph is not finitary because type parameter "+tparam.name+" is expansively recursive" def errPos = tparam.pos } // TODO missing test case for a second case - case class QualifyingClassError(tree: Tree, qual: Name) - extends ErrorTree with ContextError { - + case class QualifyingClassError(tree: Tree, qual: Name) extends ContextErrorTree(tree) { def errMsg = if (qual.isEmpty) tree + " can be used only in a class, object, or template" else qual + " is not an enclosing class" - def errPos = tree.pos } // def stabilize - case class NotAValueError(tree: Tree, sym: Symbol) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, sym.kindString + " " + sym.fullName + " is not a value") - } + case class NotAValueError(tree: Tree, sym: Symbol) extends ErrorTreeForwarder(tree) { + def errMsg = sym.kindString + " " + sym.fullName + " is not a value" } // checkNoDoubleDefs... - case class DefDefinedTwiceError(sym0: Symbol, sym1: Symbol) - extends ErrorTree with ContextError { - - def errMsg = sym1+" is defined twice"+{if(!settings.debug.value) "" else " in "+context.unit.toString} + case class DefDefinedTwiceError(sym0: Symbol, sym1: Symbol) extends ErrorTreeWithContext { + def errMsg = sym1+" is defined twice"+{if(!settings.debug.value) "" else " in "+context.unit} def errPos = sym0.pos override def pos = sym0.pos - } // cyclic errors - case class CyclicAliasingOrSubtypingError(pos0: Position, sym0: Symbol) - extends ErrorTree with ContextError { - + case class CyclicAliasingOrSubtypingError(errPos: Position, sym0: Symbol) extends ErrorTreeWithContext { def errMsg = "cyclic aliasing or subtyping involving "+sym0 - def errPos = pos0 - - override def pos = pos0 + override def pos = errPos } - case class CyclicReferenceError(pos0: Position, lockedSym: Symbol) - extends ErrorTree with ContextError { - + case class CyclicReferenceError(errPos: Position, lockedSym: Symbol) extends ErrorTreeWithContext { def errMsg = "illegal cyclic reference involving " + lockedSym - def errPos = pos0 - override def pos = pos0 + override def pos = errPos } - } trait InferencerErrorTrees { @@ -1024,106 +703,79 @@ trait ErrorTrees { } } - case class AccessError(tree: Tree, sym: Symbol, pre: Type, - owner0: Symbol, explanation: String) - extends TreeForwarder(tree) with ErrorTree with ContextError { - + case class AccessError(tree: Tree, sym: Symbol, pre: Type, owner0: Symbol, explanation: String) extends ContextErrorTreeForwarder(tree) { def errMsg = { - val realsym = underlying(sym) + val realsym = underlying(sym) val location = if (sym.isClassConstructor) owner0 else pre.widen realsym.fullLocationString + " cannot be accessed in " + location + explanation } - def errPos = tree.pos } - case class NoMethodInstanceError(fn: Tree, args: List[Tree], - msg: String) - extends TreeForwarder(fn) with ErrorTree { - - def emit(context: Context) { - if (!fn.isErroneous) - context.error(fn.pos, "no type parameters for " + - applyErrorMsg(fn, " exist so that it can be applied to arguments ", args map (_.tpe.widen), WildcardType) + - "\n --- because ---\n" + msg) - } + case class NoMethodInstanceError(fn: Tree, args: List[Tree], msg: String) extends ErrorTreeForwarder(fn) { + def errMsg = ( + "no type parameters for " + + applyErrorMsg(fn, " exist so that it can be applied to arguments ", args map (_.tpe.widen), WildcardType) + + "\n --- because ---\n" + msg + ) } // TODO: no test case - case class NoConstructorInstanceError(tree: Tree, restpe: Type, - pt: Type, msg: String) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, "constructor of type " + restpe + - " cannot be uniquely instantiated to expected type " + pt + - "\n --- because ---\n" + msg) - } + case class NoConstructorInstanceError(tree: Tree, restpe: Type, pt: Type, msg: String) extends ErrorTreeForwarder(tree) { + def errMsg = ( + "constructor of type " + restpe + + " cannot be uniquely instantiated to expected type " + pt + + "\n --- because ---\n" + msg + ) } - case class ConstrInstantiationError(tree: Tree, restpe: Type, - pt: Type) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, "constructor cannot be instantiated to expected type" + - foundReqMsg(restpe, pt)) - } + case class ConstrInstantiationError(tree: Tree, restpe: Type, pt: Type) extends ErrorTreeForwarder(tree) { + def errMsg = "constructor cannot be instantiated to expected type" + foundReqMsg(restpe, pt) } - case class NoBestMethodAlternativeError(tree: Tree, argtpes: List[Type], - pt: Type) - extends TreeForwarder(tree) with ErrorTree { - - def emit(context: Context) { - if (!tree.isErroneous) - context.error(tree.pos, applyErrorMsg(tree, " cannot be applied to ", argtpes, pt)) - } + case class NoBestMethodAlternativeError(tree: Tree, argtpes: List[Type], pt: Type) extends ErrorTreeForwarder(tree) { + def errMsg = applyErrorMsg(tree, " cannot be applied to ", argtpes, pt) } case class AmbiguousMethodAlternativeError(tree: Tree, pre: Type, best: Symbol, firstCompeting: Symbol, argtpes: List[Type], pt: Type) - extends TreeForwarder(tree) with ErrorTree { + extends ErrorTreeForwarder(tree) { - def emit(context: Context) { - context.ambiguousError(tree.pos, pre, best, firstCompeting, - "argument types " + argtpes.mkString("(", ",", ")") + - (if (pt == WildcardType) "" else " and expected result type " + pt)) + def errMsg = ( + "argument types " + argtpes.mkString("(", ",", ")") + + (if (pt == WildcardType) "" else " and expected result type " + pt) + ) + override def emit(context: Context) { + context.ambiguousError(tree.pos, pre, best, firstCompeting, errMsg) } } - case class NoBestExprAlternativeError(tree: Tree, pt: Type) - extends TreeForwarder(tree) with ErrorTree with ContextError { - + case class NoBestExprAlternativeError(tree: Tree, pt: Type) extends ContextErrorTreeForwarder(tree) { def errMsg = withAddendum(tree.pos)(typeErrorMsg(tree.symbol.tpe, pt)) - def errPos = tree.pos } - case class AmbiguousExprAlternativeError(tree: Tree, pre: Type, best: Symbol, - firstCompeting: Symbol, pt: Type) - extends TreeForwarder(tree) with ErrorTree { + case class AmbiguousExprAlternativeError(tree: Tree, pre: Type, best: Symbol, firstCompeting: Symbol, pt: Type) + extends ErrorTreeForwarder(tree) { - def emit(context: Context) { - context.ambiguousError(tree.pos, pre, best, firstCompeting, - "expected type " + pt) + def errMsg = "expected type " + pt + override def emit(context: Context) { + context.ambiguousError(tree.pos, pre, best, firstCompeting, errMsg) } } // checkBounds - case class KindBoundErrors(pos0: Position, prefix: String, targs: List[Type], + case class KindBoundErrors(errPos: Position, prefix: String, targs: List[Type], tparams: List[Symbol], kindErrors: List[String]) - extends ErrorTree with ContextError { + extends ErrorTreeWithContext { - def errMsg = - prefix + "kinds of the type arguments " + targs.mkString("(", ",", ")") + - " do not conform to the expected kinds of the type parameters "+ tparams.mkString("(", ",", ")") + tparams.head.locationString+ "." + - kindErrors.toList.mkString("\n", ", ", "") - def errPos = pos0 - - override def pos = pos0 + def errMsg = ( + prefix + "kinds of the type arguments " + targs.mkString("(", ",", ")") + + " do not conform to the expected kinds of the type parameters "+ + tparams.mkString("(", ",", ")") + tparams.head.locationString+ "." + + kindErrors.toList.mkString("\n", ", ", "") + ) + override def pos = errPos } case class NotWithinBounds(pos0: Position, prefix: String, targs: List[Type], @@ -1149,44 +801,30 @@ trait ErrorTrees { } //substExpr - case class PolymorphicExpressionInstantiationError(tree: Tree, undetparams: List[Symbol], - pt: Type) - extends TreeForwarder(tree) with ErrorTree with ContextError { - - def errMsg = + case class PolymorphicExpressionInstantiationError(tree: Tree, undetparams: List[Symbol], pt: Type) extends ContextErrorTreeForwarder(tree) { + def errMsg = ( "polymorphic expression cannot be instantiated to expected type" + foundReqMsg(polyType(undetparams, skipImplicit(tree.tpe)), pt) - def errPos = tree.pos + ) } //checkCheckable - case class TypePatternOrIsInstanceTestError(pos0: Position, tp: Type) - extends ErrorTree with ContextError { - + case class TypePatternOrIsInstanceTestError(errPos: Position, tp: Type) extends ErrorTreeWithContext { def errMsg = "type "+tp+" cannot be used in a type pattern or isInstanceOf test" - def errPos = pos0 - override def pos = pos0 + override def pos = errPos } - case class IncompletePatternTypeError(pos0: Position, pattp: Type, pt: Type) - extends ErrorTree with ContextError { - + case class IncompletePatternTypeError(errPos: Position, pattp: Type, pt: Type) extends ErrorTreeWithContext { def errMsg = "pattern type is incompatible with expected type" + foundReqMsg(pattp, pt) - def errPos = pos0 - override def pos = pos0 + override def pos = errPos } - case class IncompatibleScrutineeTypeError(pos0: Position, pattp: Type, pt: Type) - extends ErrorTree with ContextError { - + case class IncompatibleScrutineeTypeError(errPos: Position, pattp: Type, pt: Type) extends ErrorTreeWithContext { def errMsg = "scrutinee is incompatible with pattern type" + foundReqMsg(pattp, pt) - def errPos = pos0 - override def pos = pos0 + override def pos = errPos } - case class PatternTypeIncompatibleWithPtError(pat: Tree, pt1: Type, pt: Type) - extends TreeForwarder(pat) with ErrorTree with ContextError { - + case class PatternTypeIncompatibleWithPtError(pat: Tree, pt1: Type, pt: Type) extends ContextErrorTreeForwarder(pat) { def errMsg = { val sym = pat.tpe.typeSymbol val clazz = sym.companionClass @@ -1211,24 +849,16 @@ trait ErrorTrees { ) "pattern type is incompatible with expected type"+foundReqMsg(pat.tpe, pt) + addendum } - def errPos = pat.pos } - case class PolyAlternativeError(tree: Tree, msg: String) - extends TreeForwarder(tree) with ErrorTree with ContextError { - - def errMsg = msg - def errPos = tree.pos - } + case class PolyAlternativeError(tree: Tree, errMsg: String) extends ContextErrorTreeForwarder(tree) { } } trait NamerErrorTrees { self: Namer => // Currently too general - case class TypeSigError(tree: Tree, override val exception: TypeError) - extends ErrorTree { - + case class TypeSigError(tree: Tree, override val exception: TypeError) extends ErrorTree { def emit(context: Context) { typer.reportTypeError(context, tree.pos, exception) } @@ -1238,7 +868,7 @@ trait ErrorTrees { // General errors case class PendingErrors(pending0: List[ErrorTree]) extends ErrorTree { - assert(pending0.length != 0, "pending exceptions cannot be empty") + assert(pending0.nonEmpty, "pending exceptions cannot be empty") def emit(context: Context) { // Try to report each, here we dont' care @@ -1252,27 +882,22 @@ trait ErrorTrees { } case object NullErrorTree extends ErrorTree { - def emit(context: Context) {} } case class SetErrorTree(tree: Tree) extends ErrorTree { - def emit(context: Context) { typer.infer.setError(tree) } } //NamesDefaults errors, refactor to their own trait - case class NameClashError(sym: Symbol, arg: Tree) - extends ErrorTree with ContextError { - + case class NameClashError(sym: Symbol, arg: Tree) extends ErrorTreeWithContext { def errMsg = "%s definition needs %s because '%s' is used as a named argument in its body.".format( "variable", // "method" "type", // "result type" sym.name) - def errPos = sym.pos override def emit(context: Context) = { super.emit(context) @@ -1281,46 +906,26 @@ trait ErrorTrees { typer.infer.setError(arg) } + def errPos = sym.pos override def pos = sym.pos } - case class AmbiguousReferenceInNamesDefaultError(arg: Tree, name: Name) - extends TreeForwarder(arg) with ErrorTree { - - def emit(context: Context) { - if (!arg.isErroneous) { - context.error( - arg.pos, - "reference to "+ name +" is ambiguous; it is both, a parameter\n"+ - "name of the method and the name of a variable currently in scope.") - } - } + case class AmbiguousReferenceInNamesDefaultError(arg: Tree, name: Name) extends ErrorTreeForwarder(arg) { + def errMsg = ( + "reference to "+ name +" is ambiguous; it is both, a parameter\n"+ + "name of the method and the name of a variable currently in scope." + ) } - case class UnknwonParameterNameNamesDefaultError(arg: Tree, name: Name) - extends TreeForwarder(arg) with ErrorTree { - - def emit(context: Context) { - if (!arg.isErroneous) - context.error(arg.pos, "unknown parameter name: " + name) - } + case class UnknownParameterNameNamesDefaultError(arg: Tree, name: Name) extends ErrorTreeForwarder(arg) { + def errMsg = "unknown parameter name: " + name } - case class DoubleParamNamesDefaultError(arg: Tree, name: Name) - extends TreeForwarder(arg) with ErrorTree { - - def emit(context: Context) { - if (!arg.isErroneous) - context.error(arg.pos, "parameter specified twice: "+ name) - } + case class DoubleParamNamesDefaultError(arg: Tree, name: Name) extends ErrorTreeForwarder(arg) { + def errMsg = "parameter specified twice: "+ name } - case class PositionalAfterNamedNamesDefaultError(arg: Tree) - extends TreeForwarder(arg) with ErrorTree { - - def emit(context: Context) { - if (!arg.isErroneous) - context.error(arg.pos, "positional after named argument.") - } + case class PositionalAfterNamedNamesDefaultError(arg: Tree) extends ErrorTreeForwarder(arg) { + def errMsg = "positional after named argument." } } diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index cef099e371..729bbf4557 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -457,7 +457,7 @@ trait NamesDefaults { self: Analyzer => // treat the arg as an assignment of type Unit Assign(a.lhs, rhs).setPos(arg.pos) } else { - UnknwonParameterNameNamesDefaultError(arg, name) + UnknownParameterNameNamesDefaultError(arg, name) } } else if (argPos contains pos) { DoubleParamNamesDefaultError(arg, name) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 5106d7a4e6..5dd5b0b6be 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1343,7 +1343,7 @@ trait Typers extends Modes with Adaptations { case _ => newinfo } } - Some(FinitiaryError(tparam)) + Some(FinitaryError(tparam)) } else None ).flatten } @@ -2830,7 +2830,7 @@ trait Typers extends Modes with Adaptations { if (const == null) { Left(AnnotationNotAConstantError(tr)) } else if (const.value == null) - Left(AnnotationArgNulError(tr)) + Left(AnnotationArgNullError(tr)) else Right(LiteralAnnotArg(const)) } @@ -3587,12 +3587,10 @@ trait Typers extends Modes with Adaptations { case _ => Nil }) // Get correct posiition for the error - val (ePos, firstToReport) = { - val firstError = quickErrorTreeFinder(treeWithError) - (firstError.pos, firstError) - } - + val firstToReport = quickErrorTreeFinder(treeWithError) + val ePos = firstToReport.pos def errorInResult(tree: Tree) = treesInResult(tree) exists (_.pos == ePos) + val retry = (ePos != null) && (fun :: tree :: args exists errorInResult) if (settings.errortrees.value) println("[ErrorTree retry] " + retry + " with " + treeWithError + " " + firstToReport.exception) -- cgit v1.2.3