From 2113259af4f54dc09f92799992f1a8d77954d570 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 28 Jan 2008 18:39:05 +0000 Subject: minor clean ups of Sean's commit; prepareing fo... minor clean ups of Sean's commit; prepareing for virtual classes. --- src/compiler/scala/tools/nsc/Global.scala | 4 ++ src/compiler/scala/tools/nsc/Phase.scala | 1 + .../scala/tools/nsc/symtab/IdeSupport.scala | 12 +--- src/compiler/scala/tools/nsc/symtab/Symbols.scala | 78 +++++++++++----------- src/compiler/scala/tools/nsc/symtab/Types.scala | 15 +++-- .../scala/tools/nsc/typechecker/Contexts.scala | 3 +- .../scala/tools/nsc/typechecker/IdeSupport.scala | 2 +- .../scala/tools/nsc/typechecker/Namers.scala | 12 ++-- .../scala/tools/nsc/typechecker/Typers.scala | 14 ++-- 9 files changed, 70 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 8304a38e4b..5adc669fb3 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -233,10 +233,14 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable def run { currentRun.units foreach applyPhase } def apply(unit: CompilationUnit): Unit + + private val isDevirtualized = prev.name == "devirtualize" || prev.devirtualized + override def devirtualized = isDevirtualized private val isErased = prev.name == "erasure" || prev.erasedTypes override def erasedTypes: Boolean = isErased private val isFlat = prev.name == "flatten" || prev.flatClasses override def flatClasses: Boolean = isFlat + final def applyPhase(unit: CompilationUnit) { if (settings.debug.value) inform("[running phase " + name + " on " + unit + "]") val unit0 = currentRun.currentUnit diff --git a/src/compiler/scala/tools/nsc/Phase.scala b/src/compiler/scala/tools/nsc/Phase.scala index 679c7c8823..7ecce6b3f3 100644 --- a/src/compiler/scala/tools/nsc/Phase.scala +++ b/src/compiler/scala/tools/nsc/Phase.scala @@ -26,6 +26,7 @@ abstract class Phase(val prev: Phase) { def name: String def description: String = name + def devirtualized: Boolean = false def erasedTypes: Boolean = false def flatClasses: Boolean = false def run: Unit diff --git a/src/compiler/scala/tools/nsc/symtab/IdeSupport.scala b/src/compiler/scala/tools/nsc/symtab/IdeSupport.scala index a9d4e90098..015a4ffd36 100644 --- a/src/compiler/scala/tools/nsc/symtab/IdeSupport.scala +++ b/src/compiler/scala/tools/nsc/symtab/IdeSupport.scala @@ -147,7 +147,7 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. } if (sym.isModuleClass) { assert(sym.name.isTypeName) - if (sym.rawInfoSafe.isDefined) + if (sym.hasRawInfo) if (sym.linkedModuleOfClass != NoSymbol) f(sym.linkedModuleOfClass) } else { assert(sym.name.isTypeName) @@ -297,7 +297,7 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. super.enter(symbol) } def reuse(existing : Symbol) : Symbol = { - def record(existing : Symbol) = if (existing.rawInfoSafe.isDefined && + def record(existing : Symbol) = if (existing.hasRawInfo && existing.rawInfo.isComplete && existing.rawInfo != NoType && !hasError(existing.rawInfo)) { tracedTypes(existing) = existing.info } @@ -305,13 +305,7 @@ trait IdeSupport extends SymbolTable { // added to global, not analyzers. if (existing.isMonomorphicType) existing.resetFlag(Flags.MONOMORPHIC) assert(!existing.isPackage) existing.attributes = Nil // reset attributes, we don't look at these. - existing.setInfo(other.rawInfoSafe match { - case Some(info) => - assert(true) - assert(true) - info - case _ => NoType - }) + existing.setInfo(if (other.hasRawInfo) other.rawInfo else NoType) if (existing.isModule && existing.moduleClass != NoSymbol) f(existing.moduleClass,symbol.moduleClass) } diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index 2083eccc0a..3a323aa5a6 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -246,6 +246,15 @@ trait Symbols { final def isStable = isTerm && !hasFlag(MUTABLE) && (!hasFlag(METHOD | BYNAMEPARAM) || hasFlag(STABLE)) + def isDeferred = + hasFlag(DEFERRED) && !isClass + + def isVirtualClass = + hasFlag(DEFERRED) && isClass + + def isVirtualSubClass = + info.baseClasses exists (_.isVirtualClass) + /** Is this symbol a public */ final def isPublic: Boolean = !hasFlag(PRIVATE | PROTECTED) && privateWithin == NoSymbol @@ -339,13 +348,12 @@ trait Symbols { * @param base ... * @return ... */ - final def isIncompleteIn(base: Symbol): Boolean = ( - (this hasFlag DEFERRED) || + final def isIncompleteIn(base: Symbol): Boolean = + this.isDeferred || (this hasFlag ABSOVERRIDE) && { val supersym = superSymbol(base) supersym == NoSymbol || supersym.isIncompleteIn(base) } - ) final def exists: Boolean = this != NoSymbol && (!owner.isPackageClass || { rawInfo.load(this); rawInfo != NoType }) @@ -479,10 +487,7 @@ trait Symbols { cnt += 1 // allow for two completions: // one: sourceCompleter to LazyType, two: LazyType to completed type - if (cnt == 3) { - assert(true) - throw new Error("no progress in completing " + this + ":" + tp) - } + if (cnt == 3) throw new Error("no progress in completing " + this + ":" + tp) } val result = rawInfo result @@ -491,10 +496,6 @@ trait Symbols { /** Set initial info. */ def setInfo(info: Type): this.type = { assert(info ne null) - if (name.toString == "Either") { - assert(true) - assert(true) - } infos = TypeHistory(currentPeriod, info, null) if (info.isComplete) { rawflags = rawflags & ~LOCKED @@ -514,8 +515,7 @@ trait Symbols { this } - /** check if info has been set before, used in the IDE */ - def rawInfoSafe : Option[Type] = if (infos == null) None else Some(rawInfo) + def hasRawInfo: Boolean = infos ne null /** Return info without checking for initialization or completing */ def rawInfo: Type = { @@ -920,8 +920,7 @@ trait Symbols { var sym: Symbol = NoSymbol while (!bcs.isEmpty && sym == NoSymbol) { if (!bcs.head.isImplClass) - sym = matchingSymbol(bcs.head, base.thisType).suchThat( - sym => !sym.hasFlag(DEFERRED)) + sym = matchingSymbol(bcs.head, base.thisType).suchThat(!_.isDeferred) bcs = bcs.tail } sym @@ -963,7 +962,7 @@ trait Symbols { final def makeNotPrivate(base: Symbol) { if (this hasFlag PRIVATE) { setFlag(notPRIVATE) - if (!hasFlag(DEFERRED) && isTerm) setFlag(lateFINAL) + if (isTerm && !isDeferred) setFlag(lateFINAL) if (!isStaticModule && !isClassConstructor) { expandName(base) if (isModule) moduleClass.makeNotPrivate(base) @@ -977,7 +976,7 @@ trait Symbols { def expandName(base: Symbol) { if (this.isTerm && this != NoSymbol && !hasFlag(EXPANDEDNAME)) { setFlag(EXPANDEDNAME) - if (hasFlag(ACCESSOR) && !hasFlag(DEFERRED)) { + if (hasFlag(ACCESSOR) && !isDeferred) { accessed.expandName(base) } else if (hasGetter) { getter(owner).expandName(base) @@ -1092,9 +1091,6 @@ trait Symbols { final def fullNameString: String = fullNameString('.') - - - /** If settings.uniqid is set, the symbol's id, else "" */ final def idString: String = if (settings.uniqid.value) "#"+id else "" @@ -1120,9 +1116,7 @@ trait Symbols { " in " + owner else "" /** String representation of symbol's definition following its name */ - final def infoString(tp: Option[Type]): String = tp match { - case None => "<_>" - case Some(tp) => + final def infoString(tp: Type): String = { def typeParamsString: String = tp match { case PolyType(tparams, _) if (tparams.length != 0) => (tparams map (_.defString)).mkString("[", ",", "]") @@ -1144,13 +1138,13 @@ trait Symbols { } } else if (isModule) - moduleClass.infoString(Some(tp)) + moduleClass.infoString(tp) else tp match { case PolyType(tparams, res) => - typeParamsString + infoString(Some(res)) + typeParamsString + infoString(res) case MethodType(pts, res) => - pts.mkString("(", ",", ")") + infoString(Some(res)) + pts.mkString("(", ",", ")") + infoString(res) case _ => ": " + tp } @@ -1169,7 +1163,8 @@ trait Symbols { val f = if (settings.debug.value) flags else if (owner.isRefinementClass) flags & ExplicitFlags & ~OVERRIDE else flags & ExplicitFlags - compose(List(flagsToString(f), keyString, varianceString + nameString + infoString(rawInfoSafe))) + compose(List(flagsToString(f), keyString, varianceString + nameString + + (if (hasRawInfo) infoString(rawInfo) else "<_>"))) } /** Concatenate strings separated by spaces */ @@ -1281,8 +1276,8 @@ trait Symbols { override def isType = true override def isTypeMember = true - override def isAbstractType = hasFlag(DEFERRED) - override def isAliasType = !hasFlag(DEFERRED) + override def isAbstractType = isDeferred + override def isAliasType = !isDeferred override def tpe: Type = { if (tpeCache eq NoType) throw CyclicReference(this, typeConstructor) @@ -1317,11 +1312,11 @@ trait Symbols { override def setInfo(tp: Type): this.type = { tpePeriod = NoPeriod tyconCache = null - if (tp.isComplete && tp != NoType) - if (tp.isInstanceOf[PolyType]) resetFlag(MONOMORPHIC) - else if (!tp.isInstanceOf[AnnotatedType]) { - assert(true) - setFlag(MONOMORPHIC) + if (tp.isComplete) + tp match { + case PolyType(_, _) => resetFlag(MONOMORPHIC) + case NoType | AnnotatedType(_, _, _) => ; + case _ => setFlag(MONOMORPHIC) } super.setInfo(tp) this @@ -1385,9 +1380,9 @@ trait Symbols { } private var thissym: Symbol = this - override def isClass: Boolean = true - override def isTypeMember = false - override def isAbstractType = false + override def isClass: Boolean = hasFlag(DEFERRED) || !phase.devirtualized + override def isTypeMember = !isClass + override def isAbstractType = !isClass override def isAliasType = false override def reset(completer: Type) { @@ -1418,16 +1413,19 @@ trait Symbols { val period = thisTypePeriod if (period != currentPeriod) { thisTypePeriod = currentPeriod - if (!isValid(period)) thisTypeCache = mkThisType(this) + if (!isValid(period)) + thisTypeCache = if (isClass) mkThisType(this) else NoPrefix } thisTypeCache } /** A symbol carrying the self type of the class as its type */ - override def thisSym: Symbol = thissym + override def thisSym: Symbol = + if (isClass) thissym else this override def typeOfThis: Type = - if (getFlag(MODULE | IMPLCLASS) == MODULE && owner != NoSymbol) + if (!isClass) tpe + else if (getFlag(MODULE | IMPLCLASS) == MODULE && owner != NoSymbol) singleType(owner.thisType, sourceModule) else thissym.tpe diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 460a7a1f46..41cfc86f5c 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -840,6 +840,15 @@ trait Types { override def kind = "WildcardType" } + /** An object representing a missing type; + * used only for IDE. Todo: Merge with WildcardType? + */ + case object MissingType extends Type { + override def toString: String = "<_>" + // override def isNullable: Boolean = true + override def kind = "MissingType" + } + case class BoundedWildcardType(override val bounds: TypeBounds) extends Type { override def toString: String = "?" + bounds override def kind = "BoundedWildcardType" @@ -1844,7 +1853,7 @@ A type's typeSymbol should never be inspected directly. */ private def removeSuper(tp: Type, sym: Symbol): Type = tp match { case SuperType(thistp, _) => - if (sym.isFinal || sym.hasFlag(DEFERRED)) thistp + if (sym.isFinal || sym.isDeferred) thistp else tp case _ => tp @@ -3591,10 +3600,6 @@ A type's typeSymbol should never be inspected directly. skolemizationLevel -= 1 } case (_, et: ExistentialType) => -// println("<<< "+tp1+" with "+tp2) -// settings.explaintypes.value = true -// et.withTypeVars { x => explainTypes(tp1, x); true } -// settings.explaintypes.value = false et.withTypeVars(tp1 <:< _) case (RefinedType(parents1, ref1), _) => parents1 exists (_ <:< tp2) diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 82cbbb30ab..fc5d2a9e50 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -36,7 +36,7 @@ trait Contexts { self: Analyzer => * a root context. This list is sensitive to the * compiler settings. */ - protected def rootImports(unit: CompilationUnit, tree: Tree) :List[Symbol] = { + protected def rootImports(unit: CompilationUnit, tree: Tree): List[Symbol] = { import definitions._ val imps = new ListBuffer[Symbol] if (!settings.noimports.value) { @@ -276,7 +276,6 @@ trait Contexts { self: Analyzer => make(unit, tree, owner, scope, imports) } - def makeNewScope(tree: Tree, owner: Symbol)(implicit kind : ScopeKind): Context = make(tree, owner, scopeFor(scope, tree, kind)) // IDE stuff: distinguish between scopes created for typing and scopes created for naming. diff --git a/src/compiler/scala/tools/nsc/typechecker/IdeSupport.scala b/src/compiler/scala/tools/nsc/typechecker/IdeSupport.scala index c2e0bd3b67..7b42a4c7c1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/IdeSupport.scala +++ b/src/compiler/scala/tools/nsc/typechecker/IdeSupport.scala @@ -25,7 +25,7 @@ trait IdeSupport extends Analyzer { override def newNamer(context : Context) : Namer = new Namer(context) class Namer(context: Context) extends super.Namer(context) { override protected def setInfo[Sym <: Symbol](sym : Sym)(tpe : LazyType) : Sym = { - assert(!sym.rawInfoSafe.isDefined || sym.rawInfo == NoType) // type information has already been reset. + assert(!sym.hasRawInfo || sym.rawInfo == NoType) // type information has already been reset. if (currentClient.makeNoChanges) { sym.setInfo(tpe) sym.info // force completion. diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 0bb30f7b3e..3a6d08b0e2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -150,7 +150,7 @@ trait Namers { self: Analyzer => var guess = prev while ((guess ne null) && (guess.sym ne sym)) guess = context.scope.lookupNextEntry(guess) if (guess != null) prev = guess - while (prev != null && (prev.sym.rawInfoSafe.isEmpty || !prev.sym.rawInfo.isComplete || + while (prev != null && (!prev.sym.hasRawInfo || !prev.sym.rawInfo.isComplete || (prev.sym.sourceFile == null && sym.getClass == prev.sym.getClass))) { if (prev.sym.rawInfo.isComplete) { Console.println("DITCHING: " + prev.sym) @@ -186,7 +186,7 @@ trait Namers { self: Analyzer => val cowner = if (context.owner == EmptyPackageClass) RootClass else context.owner val pkg = cowner.newPackage(pos, name) // IDE: newScope should be ok because packages are never destroyed. - if (inIDE) assert(pkg.moduleClass.rawInfoSafe.isEmpty || !pkg.moduleClass.rawInfo.isComplete) + if (inIDE) assert(!pkg.moduleClass.hasRawInfo || !pkg.moduleClass.rawInfo.isComplete) pkg.moduleClass.setInfo(new PackageClassInfoType(newScope, pkg.moduleClass, null)) pkg.setInfo(pkg.moduleClass.tpe) enterInScope(pkg) @@ -478,7 +478,7 @@ trait Namers { self: Analyzer => setFlag(param.mods.flags & (BYNAMEPARAM | IMPLICIT)) setPrivateWithin(param, sym, param.mods) sym = enterInScope(sym).asInstanceOf[TermSymbol] - if (!sym.rawInfoSafe.isDefined || sym.rawInfo.isComplete) + if (!sym.hasRawInfo || sym.rawInfo.isComplete) setInfo(sym)(typeCompleter(param)) sym } else param.symbol = setInfo( @@ -916,7 +916,7 @@ trait Namers { self: Analyzer => if (sym.info.typeSymbol == FunctionClass(0) && sym.isValueParameter && sym.owner.isClass && sym.owner.hasFlag(CASE)) context.error(sym.pos, "pass-by-name arguments not allowed for case class parameters"); - if ((sym.flags & DEFERRED) != 0) { + if (sym hasFlag DEFERRED) { // virtual classes count, too if (sym.hasAttribute(definitions.NativeAttr)) sym.resetFlag(DEFERRED) else if (!sym.isValueParameter && !sym.isTypeParameterOrSkolem && @@ -932,7 +932,7 @@ trait Namers { self: Analyzer => checkNoConflict(PRIVATE, PROTECTED) checkNoConflict(PRIVATE, OVERRIDE) checkNoConflict(DEFERRED, FINAL) -// checkNoConflict(ABSTRACT, CASE) + checkNoConflict(DEFERRED, CASE) // case classes cannot be virtual } } @@ -1005,7 +1005,7 @@ trait Namers { self: Analyzer => * and getters */ def underlying(member: Symbol): Symbol = if (member hasFlag ACCESSOR) { - if (member hasFlag DEFERRED) { + if (member.isDeferred) { val getter = if (member.isSetter) member.getter(member.owner) else member if (inIDE && getter == NoSymbol) return NoSymbol; val result = getter.owner.newValue(getter.pos, getter.name) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index dfafb8abe0..6696a5cf7b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -416,9 +416,10 @@ trait Typers { self: Analyzer => } } - def reenterValueParams(vparamss: List[List[ValDef]]): Unit = { - for (vparams <- vparamss) for (vparam <- vparams) - vparam.symbol = context.scope enter vparam.symbol + def reenterValueParams(vparamss: List[List[ValDef]]) { + for (vparams <- vparamss) + for (vparam <- vparams) + vparam.symbol = context.scope enter vparam.symbol } def reenterTypeParams(tparams: List[TypeDef]): List[Symbol] = @@ -1222,7 +1223,7 @@ trait Typers { self: Analyzer => alias = NoSymbol if (alias != NoSymbol) { var ownAcc = clazz.info.decl(name).suchThat(_.hasFlag(PARAMACCESSOR)) - if ((ownAcc hasFlag ACCESSOR) && !(ownAcc hasFlag DEFERRED)) + if ((ownAcc hasFlag ACCESSOR) && !ownAcc.isDeferred) ownAcc = ownAcc.accessed if (!ownAcc.isVariable && !alias.accessed.isVariable) { if (settings.debug.value) @@ -1353,10 +1354,6 @@ trait Typers { self: Analyzer => block.stats foreach enterLabelDef val stats1 = typedStats(block.stats, context.owner) val expr1 = typed(block.expr, mode & ~(FUNmode | QUALmode), pt) - if (expr1.tpe == null) { - assert(true) - assert(true) - } val block1 = copy.Block(block, stats1, expr1) .setType(if (treeInfo.isPureExpr(block)) expr1.tpe else expr1.tpe.deconst) //checkNoEscaping.locals(context.scope, pt, block1) @@ -3119,6 +3116,7 @@ trait Typers { self: Analyzer => val lo1 = typedType(lo) val hi1 = typedType(hi) copy.TypeBoundsTree(tree, lo1, hi1) setType mkTypeBounds(lo1.tpe, hi1.tpe) + case etpt @ ExistentialTypeTree(_, _) => newTyper(context.makeNewScope(tree, context.owner)).typedExistentialTypeTree(etpt) -- cgit v1.2.3