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>2012-09-26 12:24:45 -0700
commite6f10b07d44f0ddde26246b4a41527a84eede81c (patch)
tree2268de6b9dccf22e3355b0ee1bcf63d7e7f10738 /src
parent83b5d4c0c9af462fc562c571f17dfcd00f47255d (diff)
downloadscala-e6f10b07d44f0ddde26246b4a41527a84eede81c.tar.gz
scala-e6f10b07d44f0ddde26246b4a41527a84eede81c.tar.bz2
scala-e6f10b07d44f0ddde26246b4a41527a84eede81c.zip
Fixed SI-5604, selections on package objects.
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