summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-09-26 12:14:13 -0700
committerPaul Phillips <paulp@improving.org>2013-01-30 03:50:35 -0800
commitd4437aaa4bd28dc41da13ca28a752e14b5b8e30c (patch)
treebb3efbfd35539890387226ff0aaf6b18f6fef6c5 /src
parente156cd13a37048b6ea822fdc8caaee40bb6a70a4 (diff)
downloadscala-d4437aaa4bd28dc41da13ca28a752e14b5b8e30c.tar.gz
scala-d4437aaa4bd28dc41da13ca28a752e14b5b8e30c.tar.bz2
scala-d4437aaa4bd28dc41da13ca28a752e14b5b8e30c.zip
SI-5604, selections on package objects.
[backport] mkAttributedSelect, which creates a Select tree based on a symbol, has been a major source of package object bugs, because it has not been accurately identifying selections on package objects. When selecting foo.bar, if foo turns out to be a package object, the created Select tree must be foo.`package`.bar However mkAttributedSelect was only examining the owner of the symbol, which means it would work if the package object defined bar directly, but not if it inherited it.
Diffstat (limited to 'src')
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index ebf0998573..c1753fc5a1 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -172,10 +172,29 @@ abstract class TreeGen extends macros.TreeBuilder {
if (qual.symbol != null && (qual.symbol.isEffectiveRoot || qual.symbol.isEmptyPackage))
mkAttributedIdent(sym)
else {
+ // Have to recognize anytime a selection is made on a package
+ // so it can be rewritten to foo.bar.`package`.name rather than
+ // foo.bar.name if name is in the package object.
+ // TODO - factor out the common logic between this and
+ // the Typers method "isInPackageObject", used in typedIdent.
+ val qualsym = (
+ if (qual.tpe ne null) qual.tpe.typeSymbol
+ else if (qual.symbol ne null) qual.symbol
+ else NoSymbol
+ )
+ val needsPackageQualifier = (
+ (sym ne null)
+ && qualsym.isPackage
+ && !sym.isDefinedInPackage
+ )
val pkgQualifier =
- if (sym != null && sym.owner.isPackageObjectClass && sym.effectiveOwner == qual.tpe.typeSymbol) {
- val obj = sym.owner.sourceModule
- Select(qual, nme.PACKAGE) setSymbol obj setType singleType(qual.tpe, obj)
+ if (needsPackageQualifier) {
+ // The owner of a symbol which requires package qualification may be the
+ // package object iself, but it also could be any superclass of the package
+ // object. In the latter case, we must go through the qualifier's info
+ // to obtain the right symbol.
+ val packageObject = if (sym.owner.isModuleClass) sym.owner.sourceModule else qual.tpe member nme.PACKAGE
+ Select(qual, nme.PACKAGE) setSymbol packageObject setType singleType(qual.tpe, packageObject)
}
else qual