diff options
Diffstat (limited to 'src/compiler/scala')
10 files changed, 113 insertions, 76 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index a46b7d6bc7..1d0ed2442e 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -142,12 +142,13 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val EmptyPackage = RootClass.newPackage(NoPosition, nme.EMPTY_PACKAGE_NAME).setFlag(FINAL) lazy val EmptyPackageClass = EmptyPackage.moduleClass - lazy val JavaLangPackage = getModule(sn.JavaLang) - lazy val ScalaPackage = getModule("scala") - lazy val ScalaPackageClass = ScalaPackage.tpe.typeSymbol + lazy val JavaLangPackage = getModule(sn.JavaLang) + lazy val JavaLangPackageClass = JavaLangPackage.moduleClass + lazy val ScalaPackage = getModule(nme.scala_) + lazy val ScalaPackageClass = ScalaPackage.moduleClass lazy val RuntimePackage = getModule("scala.runtime") - lazy val RuntimePackageClass = RuntimePackage.tpe.typeSymbol + lazy val RuntimePackageClass = RuntimePackage.moduleClass // convenient one-argument parameter lists lazy val anyparam = List(AnyClass.typeConstructor) @@ -221,7 +222,7 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val BridgeClass = getClass("scala.annotation.bridge") // fundamental reference classes - lazy val ScalaObjectClass = getClass("scala.ScalaObject") + lazy val ScalaObjectClass = getMember(ScalaPackageClass, tpnme.ScalaObject) lazy val PartialFunctionClass = getClass("scala.PartialFunction") lazy val SymbolClass = getClass("scala.Symbol") lazy val StringClass = getClass(sn.String) @@ -233,9 +234,17 @@ trait Definitions extends reflect.api.StandardDefinitions { // fundamental modules lazy val SysPackage = getPackageObject("scala.sys") def Sys_error = getMember(SysPackage, nme.error) + + // Modules whose members are in the default namespace + lazy val UnqualifiedModules = List(PredefModule, ScalaPackage, JavaLangPackage) + // Those modules and their module classes + lazy val UnqualifiedOwners = UnqualifiedModules.toSet ++ UnqualifiedModules.map(_.moduleClass) + lazy val PredefModule: Symbol = getModule("scala.Predef") - lazy val PredefModuleClass = PredefModule.tpe.typeSymbol - def Predef_AnyRef = getMember(PredefModule, "AnyRef") // used by the specialization annotation + lazy val PredefModuleClass = PredefModule.moduleClass + // Note: this is not the type alias AnyRef, it's a val defined in Predef + // used by the @specialize annotation. + def Predef_AnyRef = getMember(PredefModule, tpnme.AnyRef.toTermName) def Predef_classOf = getMember(PredefModule, nme.classOf) def Predef_identity = getMember(PredefModule, nme.identity) def Predef_conforms = getMember(PredefModule, nme.conforms) 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) } } diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 34c6570c2a..43168190a3 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -1157,7 +1157,7 @@ trait Types extends api.Types { self: SymbolTable => override def prefixString = if (settings.debug.value) sym.nameString + ".this." else if (sym.isAnonOrRefinementClass) "this." - else if (sym.printWithoutPrefix) "" + else if (sym.isOmittablePrefix) "" else if (sym.isModuleClass) sym.fullName + "." else sym.nameString + ".this." override def safeToString: String = @@ -1220,8 +1220,9 @@ trait Types extends api.Types { self: SymbolTable => override def termSymbol = sym override def prefix: Type = pre - override def prefixString: String = - if ((sym.isEmptyPackage || sym.isInterpreterWrapper || sym.isPredefModule || sym.isScalaPackage) && !settings.debug.value) "" + override def prefixString = + if (sym.isPackageObjectOrClass) pre.prefixString + else if (sym.isOmittablePrefix) "" else pre.prefixString + sym.nameString + "." override def kind = "SingleType" } @@ -2050,8 +2051,10 @@ A type's typeSymbol should never be inspected directly. override def prefixString = "" + ( if (settings.debug.value) super.prefixString - else if (sym.printWithoutPrefix) + else if (sym.isOmittablePrefix) "" + else if (sym.isPackageObjectOrClass) + sym.owner.fullName + "." else if (sym.isPackageClass) sym.fullName + "." else if (isStable && nme.isSingletonName(sym.name)) @@ -4080,7 +4083,7 @@ A type's typeSymbol should never be inspected directly. def corresponds(sym1: Symbol, sym2: Symbol): Boolean = sym1.name == sym2.name && (sym1.isPackageClass || corresponds(sym1.owner, sym2.owner)) if (!corresponds(sym.owner, rebind0.owner)) { - debuglog("ADAPT1 pre = "+pre+", sym = "+sym+sym.locationString+", rebind = "+rebind0+rebind0.locationString) + debuglog("ADAPT1 pre = "+pre+", sym = "+sym.fullLocationString+", rebind = "+rebind0.fullLocationString) val bcs = pre.baseClasses.dropWhile(bc => !corresponds(bc, sym.owner)); if (bcs.isEmpty) assert(pre.typeSymbol.isRefinementClass, pre) // if pre is a refinementclass it might be a structural type => OK to leave it in. @@ -4089,11 +4092,8 @@ A type's typeSymbol should never be inspected directly. debuglog( "ADAPT2 pre = " + pre + ", bcs.head = " + bcs.head + - ", sym = " + sym+sym.locationString + - ", rebind = " + rebind0 + ( - if (rebind0 == NoSymbol) "" - else rebind0.locationString - ) + ", sym = " + sym.fullLocationString + + ", rebind = " + rebind0.fullLocationString ) } val rebind = rebind0.suchThat(sym => sym.isType || sym.isStable) diff --git a/src/compiler/scala/reflect/runtime/Loaders.scala b/src/compiler/scala/reflect/runtime/Loaders.scala index e16431df99..46ee176b0f 100644 --- a/src/compiler/scala/reflect/runtime/Loaders.scala +++ b/src/compiler/scala/reflect/runtime/Loaders.scala @@ -35,7 +35,7 @@ trait Loaders { self: SymbolTable => assert(sym == clazz || sym == module || sym == module.moduleClass) // try { atPhaseNotLaterThan(picklerPhase) { - unpickleClass(clazz, module, javaClass(clazz.fullName)) + unpickleClass(clazz, module, javaClass(clazz.javaClassName)) // } catch { // case ex: ClassNotFoundException => makePackage() // case ex: NoClassDefFoundError => makePackage() diff --git a/src/compiler/scala/reflect/runtime/ScalaToJava.scala b/src/compiler/scala/reflect/runtime/ScalaToJava.scala index db8658d30c..b1e4d6224c 100644 --- a/src/compiler/scala/reflect/runtime/ScalaToJava.scala +++ b/src/compiler/scala/reflect/runtime/ScalaToJava.scala @@ -43,7 +43,7 @@ trait ScalaToJava extends ConversionUtil { self: SymbolTable => else if (clazz == ArrayClass) noClass else if (clazz.owner.isPackageClass) - javaClass(clazz.fullName) + javaClass(clazz.javaClassName) else if (clazz.owner.isClass) classToJava(clazz.owner) .getDeclaredClasses diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala index 2a7f11325c..d735044e07 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala @@ -39,7 +39,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { "memberSym " + memberSym + " templateSym " + templateSym + " encls = " + closestPackage(memberSym) + ", " + closestPackage(templateSym) ) - memberSym.inDefaultNamespace || (closestPackage(memberSym) == closestPackage(templateSym)) + memberSym.isOmittablePrefix || (closestPackage(memberSym) == closestPackage(templateSym)) } private lazy val noSubclassCache = Set(AnyClass, AnyRefClass, ObjectClass, ScalaObjectClass) diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 169295e5c9..660999eb64 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -335,8 +335,8 @@ trait Implicits { pre1: String, pre2: String, trailer: String) = if (!info1.tpe.isErroneous && !info2.tpe.isErroneous) { val coreMsg = - pre1+" "+info1.sym+info1.sym.locationString+" of type "+info1.tpe+"\n "+ - pre2+" "+info2.sym+info2.sym.locationString+" of type "+info2.tpe+"\n "+ + pre1+" "+info1.sym.fullLocationString+" of type "+info1.tpe+"\n "+ + pre2+" "+info2.sym.fullLocationString+" of type "+info2.tpe+"\n "+ trailer error(tree.pos, if (isView) { @@ -408,7 +408,7 @@ trait Implicits { if (!(pt.isErroneous)) context.unit.error( tree.pos, "diverging implicit expansion for type "+pt+"\nstarting with "+ - info.sym+info.sym.locationString) + info.sym.fullLocationString) SearchFailure } else { throw DivergentImplicit @@ -545,7 +545,7 @@ trait Implicits { SearchFailure else if (!hasMatchingSymbol(itree1)) fail("candidate implicit %s is shadowed by other implicit %s".format( - info.sym + info.sym.locationString, itree1.symbol + itree1.symbol.locationString)) + info.sym.fullLocationString, itree1.symbol.fullLocationString)) else { val tvars = undetParams map freshVar diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 360acbd469..31aaaa36b8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -403,7 +403,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT val isCandidate = ( sym.isProtected && sym.isJavaDefined - && !sym.definedInPackage + && !sym.isDefinedInPackage && !accessibleThroughSubclassing && (sym.owner.enclosingPackageClass != currentOwner.enclosingPackageClass) && (sym.owner.enclosingPackageClass == packageAccessBoundry(sym)) diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index 6e0e78e8e2..6c735a2d44 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -82,6 +82,17 @@ trait TypeDiagnostics { def posPrecedes(p1: Position, p2: Position) = p1.isDefined && p2.isDefined && p1.line < p2.line def linePrecedes(t1: Tree, t2: Tree) = posPrecedes(t1.pos, t2.pos) + private object DealiasedType extends TypeMap { + def apply(tp: Type): Type = tp match { + // Avoid "explaining" that String is really java.lang.String, + // while still dealiasing types from non-default namespaces. + case TypeRef(pre, sym, args) if sym.isAliasType && !sym.isInDefaultNamespace => + mapOver(tp.dealias) + case _ => + mapOver(tp) + } + } + def notAMemberMessage(pos: Position, qual: Tree, name: Name) = { val owner = qual.tpe.typeSymbol val target = qual.tpe.widen @@ -212,12 +223,17 @@ trait TypeDiagnostics { else if (sym.variance == -1) "contravariant" else "invariant" - // I think this should definitely be on by default, but I need to - // play with it a bit longer. For now it's behind -Xlint. - def explainAlias(tp: Type) = ( - if (!settings.lint.value || (tp eq tp.normalize)) "" - else " (which expands to)\n " + tp.normalize - ) + def explainAlias(tp: Type) = { + // Don't automatically normalize standard aliases; they still will be + // expanded if necessary to disambiguate simple identifiers. + if ((tp eq tp.normalize) || tp.typeSymbolDirect.isInDefaultNamespace) "" + else { + // A sanity check against expansion being identical to original. + val s = "" + DealiasedType(tp) + if (s == "" + tp) "" + else "\n (which expands to) " + s + } + } /** Look through the base types of the found type for any which * might have been valid subtypes if given conformant type arguments. @@ -292,7 +308,6 @@ trait TypeDiagnostics { } "" // no elaborable variance situation found } - def foundReqMsg(found: Type, req: Type): String = ( withDisambiguation(Nil, found, req)( ";\n found : " + found.toLongString + existentialContext(found) + explainAlias(found) + @@ -309,8 +324,11 @@ trait TypeDiagnostics { def modifyName(f: String => String) = sym.name = newTypeName(f(sym.name.toString)) - def scalaQualify() = { - val intersect = Set(trueOwner, aliasOwner) intersect Set(ScalaPackageClass, PredefModuleClass) + /** Prepend java.lang, scala., or Predef. if this type originated + * in one of those. + */ + def qualifyDefaultNamespaces() = { + val intersect = Set(trueOwner, aliasOwner) intersect UnqualifiedOwners if (intersect.nonEmpty) preQualify() } @@ -320,8 +338,8 @@ trait TypeDiagnostics { def typeQualify() = if (sym.isTypeParameterOrSkolem) postQualify() def nameQualify() = if (trueOwner.isPackageClass) preQualify() else postQualify() - def trueOwner = tp.typeSymbol.owner.skipPackageObject - def aliasOwner = tp.typeSymbolDirect.owner.skipPackageObject + def trueOwner = tp.typeSymbol.effectiveOwner + def aliasOwner = tp.typeSymbolDirect.effectiveOwner def sym_==(other: TypeDiag) = tp.typeSymbol == other.tp.typeSymbol def owner_==(other: TypeDiag) = trueOwner == other.trueOwner @@ -385,7 +403,7 @@ trait TypeDiagnostics { // scala package or predef, qualify with scala so it is not confusing why // e.g. java.util.Iterator and Iterator are different types. if (td1 name_== td2) - tds foreach (_.scalaQualify()) + tds foreach (_.qualifyDefaultNamespaces()) // If they still print identically: // a) If they are type parameters with different owners, append (in <owner>) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 5bd936bfb7..deff4c10a2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3848,7 +3848,7 @@ trait Typers extends Modes with Adaptations { if (defSym.exists && impSym.exists) { // imported symbols take precedence over package-owned symbols in different // compilation units. Defined symbols take precedence over erroneous imports. - if (defSym.definedInPackage && + if (defSym.isDefinedInPackage && (!currentRun.compiles(defSym) || context.unit.exists && defSym.sourceFile != context.unit.source.file)) defSym = NoSymbol |