diff options
author | Paul Phillips <paulp@improving.org> | 2011-02-20 00:11:23 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-02-20 00:11:23 +0000 |
commit | 801c5cd82e1a7feb1f9515785ad36e0f0d2b993e (patch) | |
tree | 75718703f656ed1fc3005c4d7c2a2220c5c7b5b2 | |
parent | 3f96a415e123e5fc99c24e68ff5a9a53dc56e1fc (diff) | |
download | scala-801c5cd82e1a7feb1f9515785ad36e0f0d2b993e.tar.gz scala-801c5cd82e1a7feb1f9515785ad36e0f0d2b993e.tar.bz2 scala-801c5cd82e1a7feb1f9515785ad36e0f0d2b993e.zip |
Based on the frequency with which I hear questi...
Based on the frequency with which I hear questions about it and similar,
this error message assumes too much understanding.
scala> scala.collection.mutable.MultiMap(1, 2, 3) <console>:8: error:
value MultiMap is not a member of package scala.collection.mutable
Now it says:
scala> scala.collection.mutable.MultiMap(1, 2, 3) <console>:8: error:
object MultiMap is not a member of package scala.collection.mutable
Note: trait MultiMap exists, but it has no companion object.
No review.
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Namers.scala | 10 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala | 52 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 2 | ||||
-rw-r--r-- | test/files/neg/bug639.check | 2 | ||||
-rw-r--r-- | test/files/neg/noMember1.check | 5 | ||||
-rw-r--r-- | test/files/neg/noMember1.scala | 3 | ||||
-rw-r--r-- | test/files/neg/noMember2.check | 5 | ||||
-rw-r--r-- | test/files/neg/noMember2.scala | 3 |
8 files changed, 59 insertions, 23 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 4b888f5a76..b578759c85 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -1239,13 +1239,13 @@ trait Namers { self: Analyzer => isValidSelector(from) { if (currentRun.compileSourceFor(expr, from)) return typeSig(tree) + + def notMember = context.error(tree.pos, from.decode + " is not a member of " + expr) // for Java code importing Scala objects - if (from.endsWith(nme.raw.DOLLAR)) - isValidSelector(from.subName(0, from.length -1)) { - context.error(tree.pos, from.decode + " is not a member of " + expr) - } + if (from endsWith nme.raw.DOLLAR) + isValidSelector(from stripEnd "$")(notMember) else - context.error(tree.pos, from.decode + " is not a member of " + expr) + notMember } if (checkNotRedundant(tree.pos, from, to)) diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index 8e7563d9c7..b0547cb2e2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -74,8 +74,12 @@ trait TypeDiagnostics { def withAddendum(pos: Position) = (_: String) + addendums.getOrElse(pos, () => "")() - def decodeWithNamespace(name: Name): String = { - val prefix = if (name.isTypeName) "type " else "value " + def decodeWithKind(name: Name, owner: Symbol): String = { + val prefix = ( + if (name.isTypeName) "type " + else if (owner.isPackageClass) "object " + else "value " + ) prefix + name.decode } @@ -84,21 +88,37 @@ trait TypeDiagnostics { def linePrecedes(t1: Tree, t2: Tree) = t1.pos.isDefined && t1.pos.isDefined && t1.pos.line < t2.pos.line def notAMember(sel: Tree, qual: Tree, name: Name) = { - def decoded = decodeWithNamespace(name) - - def msg: String = name match { - case nme.CONSTRUCTOR => qual.tpe.widen+" does not have a constructor" - case _ => - def memberOf = if (qual.tpe.typeSymbol.isTypeParameterOrSkolem) "type parameter " else "" - def possibleCause = - if (linePrecedes(qual, sel)) - "\npossible cause: maybe a semicolon is missing before `"+decoded+"'?" - else - "" - - decoded+" is not a member of "+ memberOf + qual.tpe.widen + possibleCause + val owner = qual.tpe.typeSymbol + val target = qual.tpe.widen + def targetKindString = if (owner.isTypeParameterOrSkolem) "type parameter " else "" + def nameString = decodeWithKind(name, owner) + /** Illuminating some common situations and errors a bit further. */ + def addendum = { + val companion = { + if (name.isTermName && owner.isPackageClass) { + target.member(name.toTypeName) match { + case NoSymbol => "" + case sym => "\nNote: %s exists, but it has no companion object.".format(sym) + } + } + else "" + } + val semicolon = ( + if (linePrecedes(qual, sel)) + "\npossible cause: maybe a semicolon is missing before `"+nameString+"'?" + else + "" + ) + companion + semicolon } - inferError(sel.pos, withAddendum(qual.pos)(msg)) + + inferError( + sel.pos, + withAddendum(qual.pos)( + if (name == nme.CONSTRUCTOR) target + " does not have a constructor" + else nameString + " is not a member of " + targetKindString + target + addendum + ) + ) } /** Only prints the parameter names if they're not synthetic, diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index d805a33940..4d282a4e7d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3695,7 +3695,7 @@ trait Typers extends Modes { log(context.imports)//debug } if (inaccessibleSym eq NoSymbol) { - error(tree.pos, "not found: "+decodeWithNamespace(name)) + error(tree.pos, "not found: "+decodeWithKind(name, context.owner)) } else accessError( tree, inaccessibleSym, context.enclClass.owner.thisType, diff --git a/test/files/neg/bug639.check b/test/files/neg/bug639.check index 2c6055cb96..30a93518a9 100644 --- a/test/files/neg/bug639.check +++ b/test/files/neg/bug639.check @@ -1,4 +1,4 @@ -bug639.scala:3: error: not found: value a +bug639.scala:3: error: not found: object a import a._ ^ one error found diff --git a/test/files/neg/noMember1.check b/test/files/neg/noMember1.check new file mode 100644 index 0000000000..846574bef9 --- /dev/null +++ b/test/files/neg/noMember1.check @@ -0,0 +1,5 @@ +noMember1.scala:1: error: object MultiMap is not a member of package scala.collection.mutable +Note: trait MultiMap exists, but it has no companion object. +import scala.collection.mutable.MultiMap._ + ^ +one error found diff --git a/test/files/neg/noMember1.scala b/test/files/neg/noMember1.scala new file mode 100644 index 0000000000..0aee7bff7f --- /dev/null +++ b/test/files/neg/noMember1.scala @@ -0,0 +1,3 @@ +import scala.collection.mutable.MultiMap._ + +class A diff --git a/test/files/neg/noMember2.check b/test/files/neg/noMember2.check new file mode 100644 index 0000000000..f65571bdc9 --- /dev/null +++ b/test/files/neg/noMember2.check @@ -0,0 +1,5 @@ +noMember2.scala:2: error: object MultiMap is not a member of package scala.collection.mutable +Note: trait MultiMap exists, but it has no companion object. + val m = scala.collection.mutable.MultiMap(1, 2, 3) + ^ +one error found diff --git a/test/files/neg/noMember2.scala b/test/files/neg/noMember2.scala new file mode 100644 index 0000000000..bf72d4f471 --- /dev/null +++ b/test/files/neg/noMember2.scala @@ -0,0 +1,3 @@ +object Test { + val m = scala.collection.mutable.MultiMap(1, 2, 3) +} |