diff options
Diffstat (limited to 'src/compiler/scala/reflect/internal/Types.scala')
-rw-r--r-- | src/compiler/scala/reflect/internal/Types.scala | 101 |
1 files changed, 64 insertions, 37 deletions
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index e062e875cd..5afa5343ed 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -904,6 +904,12 @@ trait Types extends api.Types { self: SymbolTable => else str } + /** The string representation of this type when the direct object in a sentence. + * Normally this is no different from the regular representation, but modules + * read better as "object Foo" here and "Foo.type" the rest of the time. + */ + def directObjectString = safeToString + /** A test whether a type contains any unification type variables. */ def isGround: Boolean = this match { case TypeVar(_, constr) => @@ -1224,8 +1230,7 @@ trait Types extends api.Types { self: SymbolTable => else if (sym.isModuleClass) sym.fullNameString + "." else sym.nameString + ".this." override def safeToString: String = - if (sym.isRoot) "<root>" - else if (sym.isEmptyPackageClass) "<empty>" + if (sym.isEffectiveRoot) "" + sym.name else super.safeToString override def narrow: Type = this override def kind = "ThisType" @@ -1851,6 +1856,35 @@ trait Types extends api.Types { self: SymbolTable => // advantage to call TypeRef directly. override def typeConstructor = TypeRef(pre, sym, Nil) } + + class ModuleTypeRef(pre0: Type, sym0: Symbol) extends NoArgsTypeRef(pre0, sym0) with ClassTypeRef { + require(sym.isModuleClass, sym) + private[this] var narrowedCache: Type = _ + override def isStable = true + override def narrow = { + if (narrowedCache eq null) + narrowedCache = singleType(pre, sym.sourceModule) + + narrowedCache + } + final override def isNotNull = true + override protected def finishPrefix(rest: String) = objectPrefix + rest + override def directObjectString = super.safeToString + override def toLongString = toString + override def safeToString = narrow.toString + } + class PackageTypeRef(pre0: Type, sym0: Symbol) extends ModuleTypeRef(pre0, sym0) { + require(sym.isPackageClass, sym) + override protected def finishPrefix(rest: String) = packagePrefix + rest + } + class RefinementTypeRef(sym0: Symbol) extends NoArgsTypeRef(NoType, sym0) with ClassTypeRef { + require(sym.isRefinementClass, sym) + + // I think this is okay, but see #1241 (r12414), #2208, and typedTypeConstructor in Typers + override protected def normalizeImpl: Type = sym.info.normalize + override protected def finishPrefix(rest: String) = "" + thisInfo + } + class NoArgsTypeRef(pre0: Type, sym0: Symbol) extends TypeRef(pre0, sym0, Nil) with UniqueType { // A reference (in a Scala program) to a type that has type parameters, but where the reference // does not include type arguments. Note that it doesn't matter whether the symbol refers @@ -1898,10 +1932,6 @@ trait Types extends api.Types { self: SymbolTable => // !!! There are scaladoc-created symbols arriving which violate this require. // require(sym.isClass, sym) - override protected def normalizeImpl: Type = - if (sym.isRefinementClass) sym.info.normalize // I think this is okay, but see #1241 (r12414), #2208, and typedTypeConstructor in Typers - else super.normalizeImpl - override def baseType(clazz: Symbol): Type = if (sym == clazz) this else transform(sym.info.baseType(clazz)) @@ -2147,12 +2177,15 @@ trait Types extends api.Types { self: SymbolTable => } } - private def preString = ( - // ensure that symbol is not a local copy with a name coincidence - if (!settings.debug.value && shorthands(sym.fullName) && sym.ownerChain.forall(_.isClass)) "" - else pre.prefixString + // ensure that symbol is not a local copy with a name coincidence + private def needsPreString = ( + settings.debug.value + || !shorthands(sym.fullName) + || sym.ownerChain.exists(s => !s.isClass) ) + private def preString = if (needsPreString) pre.prefixString else "" private def argsString = if (args.isEmpty) "" else args.mkString("[", ",", "]") + def refinementString = ( if (sym.isStructuralRefinement) ( decls filter (sym => sym.isPossibleInRefinement && sym.isPublic) @@ -2162,12 +2195,9 @@ trait Types extends api.Types { self: SymbolTable => else "" ) - private def finishPrefix(rest: String) = ( - if (sym.isPackageClass) packagePrefix + rest - else if (sym.isModuleClass) objectPrefix + rest - else if (!sym.isInitialized) rest - else if (sym.isAnonymousClass && !phase.erasedTypes) parentsString(thisInfo.parents) + refinementString - else if (sym.isRefinementClass) "" + thisInfo + protected def finishPrefix(rest: String) = ( + if (sym.isInitialized && sym.isAnonymousClass && !phase.erasedTypes) + parentsString(thisInfo.parents) + refinementString else rest ) private def customToString = this match { @@ -2227,6 +2257,9 @@ trait Types extends api.Types { self: SymbolTable => else { if (sym.isAliasType) new NoArgsTypeRef(pre, sym) with AliasTypeRef else if (sym.isAbstractType) new NoArgsTypeRef(pre, sym) with AbstractTypeRef + else if (sym.isRefinementClass) new RefinementTypeRef(sym) + else if (sym.isPackageClass) new PackageTypeRef(pre, sym) + else if (sym.isModuleClass) new ModuleTypeRef(pre, sym) else new NoArgsTypeRef(pre, sym) with ClassTypeRef } }) @@ -4603,31 +4636,22 @@ trait Types extends api.Types { self: SymbolTable => object adaptToNewRunMap extends TypeMap { private def adaptToNewRun(pre: Type, sym: Symbol): Symbol = { - if (phase.flatClasses) { + if (phase.flatClasses || sym.isRootSymbol || (pre eq NoPrefix) || (pre eq NoType) || sym.isPackageClass) sym - } else if (sym == definitions.RootClass) { - definitions.RootClass - } else if (sym == definitions.RootPackage) { - definitions.RootPackage - } else if (sym.isModuleClass) { + else if (sym.isModuleClass) { val sourceModule1 = adaptToNewRun(pre, sym.sourceModule) - var result = sourceModule1.moduleClass - if (result == NoSymbol) result = sourceModule1.initialize.moduleClass - if (result != NoSymbol) result - else { + + sourceModule1.moduleClass orElse sourceModule1.initialize.moduleClass orElse { val msg = "Cannot adapt module class; sym = %s, sourceModule = %s, sourceModule.moduleClass = %s => sourceModule1 = %s, sourceModule1.moduleClass = %s" debuglog(msg.format(sym, sym.sourceModule, sym.sourceModule.moduleClass, sourceModule1, sourceModule1.moduleClass)) sym } - } else if ((pre eq NoPrefix) || (pre eq NoType) || sym.isPackageClass) { - sym - } else { - var rebind0 = pre.findMember(sym.name, BRIDGE, 0, true) - if (rebind0 == NoSymbol) { + } + else { + var rebind0 = pre.findMember(sym.name, BRIDGE, 0, true) orElse { if (sym.isAliasType) throw missingAliasException debugwarn(pre+"."+sym+" does no longer exist, phase = "+phase) throw new MissingTypeControl // For build manager and presentation compiler purposes - //assert(false, pre+"."+sym+" does no longer exist, phase = "+phase) } /** The two symbols have the same fully qualified name */ def corresponds(sym1: Symbol, sym2: Symbol): Boolean = @@ -4646,12 +4670,10 @@ trait Types extends api.Types { self: SymbolTable => ", rebind = " + rebind0.fullLocationString ) } - val rebind = rebind0.suchThat(sym => sym.isType || sym.isStable) - if (rebind == NoSymbol) { + rebind0.suchThat(sym => sym.isType || sym.isStable) orElse { debuglog("" + phase + " " +phase.flatClasses+sym.owner+sym.name+" "+sym.isType) throw new MalformedType(pre, sym.nameString) } - rebind } } def apply(tp: Type): Type = tp match { @@ -5472,9 +5494,14 @@ trait Types extends api.Types { self: SymbolTable => case _: ClassSymbol => if (isRaw(sym1, tr1.args)) isSubType(rawToExistential(tp1), tp2, depth) - else - sym1.name == tpnme.REFINE_CLASS_NAME && + else if (sym1.isModuleClass) tp2 match { + case SingleType(_, sym2) => sym1 == sym2 + case _ => false + } + else if (sym1.isRefinementClass) isSubType(sym1.info, tp2, depth) + else false + case _: TypeSymbol => if (sym1 hasFlag DEFERRED) { val tp1a = tp1.bounds.hi |