summaryrefslogtreecommitdiff
path: root/src/compiler/scala/reflect/internal/Symbols.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-10-03 01:28:04 +0000
committerPaul Phillips <paulp@improving.org>2011-10-03 01:28:04 +0000
commitbeadafa2d83a539dae8f969b9789f896346484ec (patch)
tree90c69a49397cdb59120d59307b843c54c8f68908 /src/compiler/scala/reflect/internal/Symbols.scala
parent55109d0d253c7e89660f1b61d17408648c0c53a4 (diff)
downloadscala-beadafa2d83a539dae8f969b9789f896346484ec.tar.gz
scala-beadafa2d83a539dae8f969b9789f896346484ec.tar.bz2
scala-beadafa2d83a539dae8f969b9789f896346484ec.zip
Selective dealiasing when printing errors.
*** Important note for busy commit log skimmers *** Symbol method "fullName" has been trying to serve the dual role of "how to print a symbol" and "how to find a class file." It cannot serve both these roles simultaneously, primarily because of package objects but other little things as well. Since in the majority of situations we want the one which corresponds to the idealized scala world, not the grubby bytecode, I went with that for fullName. When you require the path to a class (e.g. you are calling Class.forName) you should use javaClassName. package foo { package object bar { class Bippy } } If sym is Bippy's symbol, then sym.fullName == foo.bar.Bippy sym.javaClassName == foo.bar.package.Bippy *** End important note *** There are many situations where we (until now) forewent revealing everything we knew about a type mismatch. For instance, this isn't very helpful of scalac (at least in those more common cases where you didn't define type X on the previous repl line.) scala> type X = Int defined type alias X scala> def f(x: X): Byte = x <console>:8: error: type mismatch; found : X required: Byte def f(x: X): Byte = x ^ Now it says: found : X (which expands to) Int required: Byte def f(x: X): Byte = x ^ In addition I rearchitected a number of methods involving: - finding a symbol's owner - calculating a symbol's name - determining whether to print a prefix No review.
Diffstat (limited to 'src/compiler/scala/reflect/internal/Symbols.scala')
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala86
1 files changed, 48 insertions, 38 deletions
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 82706d7265..aebe4184f4 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -395,22 +395,24 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME)
final def isAnonOrRefinementClass = isAnonymousClass || isRefinementClass
- final def isPackageObject = isModule && name == nme.PACKAGEkw && owner.isPackageClass
- final def isPackageObjectClass = isModuleClass && name.toTermName == nme.PACKAGEkw && owner.isPackageClass
- final def definedInPackage = owner.isPackageClass || owner.isPackageObjectClass
+ def isPackageObjectOrClass = (name.toTermName == nme.PACKAGEkw) && owner.isPackageClass
+ final def isPackageObject = isModule && isPackageObjectOrClass
+ final def isPackageObjectClass = isModuleClass && isPackageObjectOrClass
+ final def isDefinedInPackage = effectiveOwner.isPackageClass
final def isJavaInterface = isJavaDefined && isTrait
final def needsFlatClasses: Boolean = phase.flatClasses && rawowner != NoSymbol && !rawowner.isPackageClass
- // not printed as prefixes
- final def isPredefModule = this == PredefModule
- final def isScalaPackage = (this == ScalaPackage) || (isPackageObject && owner == ScalaPackageClass)
- final def isScalaPackageClass = skipPackageObject == ScalaPackageClass
- def inDefaultNamespace = owner.isPredefModule || owner.isScalaPackageClass
+ // In java.lang, Predef, or scala package/package object
+ def isInDefaultNamespace = UnqualifiedOwners(effectiveOwner)
/** If this is a package object or package object class, its owner: otherwise this.
*/
final def skipPackageObject: Symbol = if (isPackageObjectClass) owner else this
+ /** The owner, skipping package objects.
+ */
+ def effectiveOwner = owner.skipPackageObject
+
/** If this is a constructor, its owner: otherwise this.
*/
final def skipConstructor: Symbol = if (isConstructor) owner else this
@@ -418,11 +420,15 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Conditions where we omit the prefix when printing a symbol, to avoid
* unpleasantries like Predef.String, $iw.$iw.Foo and <empty>.Bippy.
*/
- final def printWithoutPrefix = !settings.debug.value && (
- isScalaPackageClass || isPredefModule || isEffectiveRoot || isAnonOrRefinementClass ||
- nme.isReplWrapperName(name) // not isInterpreterWrapper due to nesting
+ final def isOmittablePrefix = !settings.debug.value && (
+ UnqualifiedOwners(skipPackageObject)
+ || isEmptyPrefix
+ )
+ def isEmptyPrefix = (
+ isEffectiveRoot // has no prefix for real, <empty> or <root>
+ || isAnonOrRefinementClass // has uninteresting <anon> or <refinement> prefix
+ || nme.isReplWrapperName(name) // has ugly $iw. prefix (doesn't call isInterpreterWrapper due to nesting)
)
-
def isFBounded = info.baseTypeSeq exists (_ contains this)
/** Is symbol a monomorphic type?
@@ -723,7 +729,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** The decoded name of the symbol, e.g. `==` instead of `\$eq\$eq`.
*/
- def decodedName: String = stripLocalSuffix(NameTransformer.decode(encodedName))
+ def decodedName: String = stripNameString(NameTransformer.decode(encodedName))
def moduleSuffix: String = (
if (hasModuleFlag && !isMethod && !isImplClass && !isJavaDefined) nme.MODULE_SUFFIX_STRING
@@ -732,22 +738,32 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** These should be moved somewhere like JavaPlatform.
*/
- def javaSimpleName = stripLocalSuffix("" + simpleName) + moduleSuffix
- def javaBinaryName = fullName('/') + moduleSuffix
- def javaClassName = fullName('.') + moduleSuffix
+ def javaSimpleName = ("" + simpleName).trim + moduleSuffix
+ def javaBinaryName = fullNameInternal('/') + moduleSuffix
+ def javaClassName = fullNameInternal('.') + moduleSuffix
/** The encoded full path name of this symbol, where outer names and inner names
* are separated by `separator` characters.
* Never translates expansions of operators back to operator symbol.
* Never adds id.
+ * Drops package objects.
+ */
+ final def fullName(separator: Char): String = stripNameString(fullNameInternal(separator))
+
+ /** Doesn't drop package objects, for those situations (e.g. classloading)
+ * where the true path is needed.
*/
- final def fullName(separator: Char): String = stripLocalSuffix {
+ private def fullNameInternal(separator: Char): String = (
if (isRoot || isRootPackage || this == NoSymbol) this.toString
else if (owner.isEffectiveRoot) encodedName
- else owner.enclClass.fullName(separator) + separator + encodedName
- }
+ else effectiveOwner.enclClass.fullName(separator) + separator + encodedName
+ )
- private def stripLocalSuffix(s: String) = s stripSuffix nme.LOCAL_SUFFIX_STRING
+ /** Strip package objects and any local suffix.
+ */
+ private def stripNameString(s: String) =
+ if (settings.debug.value) s
+ else s.replaceAllLiterally(".package", "").trim
/** The encoded full path name of this symbol, where outer names and inner names
* are separated by periods.
@@ -1358,11 +1374,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** The package containing this symbol, or NoSymbol if there
* is not one. */
- def enclosingPackage: Symbol = {
- val packSym = enclosingPackageClass
- if (packSym != NoSymbol) packSym.companionModule
- else packSym
- }
+ def enclosingPackage: Symbol = enclosingPackageClass.companionModule
/** Return the original enclosing method of this symbol. It should return
* the same thing as enclMethod when called before lambda lift,
@@ -1420,8 +1432,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Is this symbol defined in the same scope and compilation unit as `that` symbol? */
def isCoDefinedWith(that: Symbol) = (
(this.rawInfo ne NoType) &&
- (this.owner == that.owner) && {
- !this.owner.isPackageClass ||
+ (this.effectiveOwner == that.effectiveOwner) && {
+ !this.effectiveOwner.isPackageClass ||
(this.sourceFile eq null) ||
(that.sourceFile eq null) ||
(this.sourceFile == that.sourceFile) || {
@@ -1784,11 +1796,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* to the name of the owner.
*/
def hasMeaninglessName = (
- isSetterParameter // x$1
- || isClassConstructor // this
- || isPackageObject // package
- || isPackageObjectClass // package$
- || isRefinementClass // <refinement>
+ isSetterParameter // x$1
+ || isClassConstructor // this
+ || isPackageObjectOrClass // package
+ || isRefinementClass // <refinement>
)
/** String representation of symbol's simple name.
@@ -1812,9 +1823,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** String representation of location.
*/
def ownsString = {
- val owns = owner.skipPackageObject
- if (owns.isClass && !owns.printWithoutPrefix && !isScalaPackageClass) "" + owns
- else ""
+ val owns = effectiveOwner
+ if (owns.isClass && !owns.isEmptyPrefix) "" + owns else ""
}
/** String representation of location, plus a preposition. Doesn't do much,
@@ -1963,7 +1973,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
protected def doCookJavaRawInfo() {
def cook(sym: Symbol) {
- require(sym hasFlag JAVA)
+ require(sym.isJavaDefined, sym)
// @M: I think this is more desirable, but Martin prefers to leave raw-types as-is as much as possible
// object rawToExistentialInJava extends TypeMap {
// def apply(tp: Type): Type = tp match {
@@ -1985,9 +1995,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
if (isJavaDefined)
cook(this)
- else if (hasFlag(OVERLOADED))
+ else if (isOverloaded)
for (sym2 <- alternatives)
- if (sym2 hasFlag JAVA)
+ if (sym2.isJavaDefined)
cook(sym2)
}
}