summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2008-01-28 18:39:05 +0000
committerMartin Odersky <odersky@gmail.com>2008-01-28 18:39:05 +0000
commit2113259af4f54dc09f92799992f1a8d77954d570 (patch)
tree525dd4d953e34d597505759c22b8fd0124fe417b /src
parentca0ffaa0ee4f75eaff2989ce4f9049b28aded6a3 (diff)
downloadscala-2113259af4f54dc09f92799992f1a8d77954d570.tar.gz
scala-2113259af4f54dc09f92799992f1a8d77954d570.tar.bz2
scala-2113259af4f54dc09f92799992f1a8d77954d570.zip
minor clean ups of Sean's commit; prepareing fo...
minor clean ups of Sean's commit; prepareing for virtual classes.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala4
-rw-r--r--src/compiler/scala/tools/nsc/Phase.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/IdeSupport.scala12
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala78
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala15
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/IdeSupport.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala12
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala14
9 files changed, 70 insertions, 71 deletions
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)