diff options
author | Martin Odersky <odersky@gmail.com> | 2005-11-22 10:02:24 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2005-11-22 10:02:24 +0000 |
commit | 12c007cda6ff4d6b902efbfef18a057370bcd86e (patch) | |
tree | 266dba82490cb6953d1f367ae0007ae73632bcf2 | |
parent | fb67524a831520da47ea29967d2595dced41c323 (diff) | |
download | scala-12c007cda6ff4d6b902efbfef18a057370bcd86e.tar.gz scala-12c007cda6ff4d6b902efbfef18a057370bcd86e.tar.bz2 scala-12c007cda6ff4d6b902efbfef18a057370bcd86e.zip |
*** empty log message ***
-rw-r--r-- | sources/scala/tools/nsc/Settings.scala | 1 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/ast/TreeGen.scala | 16 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/StdNames.scala | 1 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/Symbols.scala | 19 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/symtab/Types.scala | 3 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/Contexts.scala | 24 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/Namers.scala | 2 | ||||
-rwxr-xr-x | sources/scala/tools/nsc/typechecker/Typers.scala | 6 |
8 files changed, 45 insertions, 27 deletions
diff --git a/sources/scala/tools/nsc/Settings.scala b/sources/scala/tools/nsc/Settings.scala index 0143525a67..8e66ee3dac 100644 --- a/sources/scala/tools/nsc/Settings.scala +++ b/sources/scala/tools/nsc/Settings.scala @@ -52,6 +52,7 @@ class Settings(error: String => unit) { val Xshowcls = StringSetting ("-Xshowcls", "class", "Show class info", ""); val Xshowobj = StringSetting ("-Xshowobj", "object", "Show object info", ""); val Xshowicode = BooleanSetting("-Xshowicode", "Print the generated ICode"); + val Xgadt = BooleanSetting("-Xgadt", "enable gadt for classes"); /** A list of all settings */ def allSettings: List[Setting] = allsettings.reverse; diff --git a/sources/scala/tools/nsc/ast/TreeGen.scala b/sources/scala/tools/nsc/ast/TreeGen.scala index 8d2f30bd4d..425cf9eac8 100755 --- a/sources/scala/tools/nsc/ast/TreeGen.scala +++ b/sources/scala/tools/nsc/ast/TreeGen.scala @@ -24,12 +24,16 @@ abstract class TreeGen { case ThisType(clazz) => if (clazz.isRoot || clazz.isEmptyPackageClass) EmptyTree else This(clazz) case SingleType(pre, sym) => - val qual = mkStableRef(pre, sym); - qual.tpe match { - case MethodType(List(), restpe) => - Apply(qual, List()) setType restpe - case _ => - qual + if (sym.isThisSkolem) { + mkQualifier(ThisType(sym.deSkolemize)) + } else { + val qual = mkStableRef(pre, sym); + qual.tpe match { + case MethodType(List(), restpe) => + Apply(qual, List()) setType restpe + case _ => + qual + } } case TypeRef(pre, sym, args) => assert(phase.erasedTypes); diff --git a/sources/scala/tools/nsc/symtab/StdNames.scala b/sources/scala/tools/nsc/symtab/StdNames.scala index a984e9e491..c20843843a 100755 --- a/sources/scala/tools/nsc/symtab/StdNames.scala +++ b/sources/scala/tools/nsc/symtab/StdNames.scala @@ -76,6 +76,7 @@ import scala.tools.nsc.util.NameTransformer; val IMPL_CLASS_SUFFIX = newTermName("$class"); val MODULE_SUFFIX = newTermName("$module"); val LOCALDUMMY_PREFIX = newTermName(LOCALDUMMY_PREFIX_STRING); + val THIS_SUFFIX = newTermName(".this"); def isLocalName(name: Name) = name.endsWith(LOCAL_SUFFIX); def isSetterName(name: Name) = name.endsWith(SETTER_SUFFIX); diff --git a/sources/scala/tools/nsc/symtab/Symbols.scala b/sources/scala/tools/nsc/symtab/Symbols.scala index cc8a907a02..1a0d4017c4 100755 --- a/sources/scala/tools/nsc/symtab/Symbols.scala +++ b/sources/scala/tools/nsc/symtab/Symbols.scala @@ -70,6 +70,9 @@ import Flags._; final def newThisSym(pos: int) = { newValue(pos, nme.this_).setFlag(SYNTHETIC); } + final def newThisSkolem: Symbol = + new ThisSkolem(owner, pos, name, this) + .setFlag(SYNTHETIC | FINAL); final def newImport(pos: int) = newValue(pos, nme.IMPORT).setFlag(SYNTHETIC); final def newOverloaded(pre: Type, alternatives: List[Symbol]): Symbol = @@ -85,7 +88,7 @@ import Flags._; new TypeSymbol(this, pos, name).setFlag(DEFERRED); final def newTypeParameter(pos: int, name: Name) = newAbstractType(pos, name).setFlag(PARAM); - final def newSkolem: Symbol = + final def newTypeSkolem: Symbol = new TypeSkolem(owner, pos, name, this) .setFlag(flags); final def newClass(pos: int, name: Name) = @@ -129,6 +132,7 @@ import Flags._; final def isStaticModule = isModule && isStatic && !isMethod; final def isPackage = isModule && hasFlag(PACKAGE); final def isThisSym = isTerm && name == nme.this_; + final def isThisSkolem = isTerm && deSkolemize != this; final def isError = hasFlag(IS_ERROR); final def isTrait = isClass & hasFlag(TRAIT); final def isAliasType = isType && !isClass && !hasFlag(DEFERRED); @@ -811,6 +815,15 @@ import Flags._; } } + /** A class for type parameters viewed from inside their scopes */ + class ThisSkolem(initOwner: Symbol, initPos: int, initName: Name, clazz: Symbol) extends TermSymbol(initOwner, initPos, initName) { + override def deSkolemize = clazz; + override def cloneSymbolImpl(owner: Symbol): Symbol = { + throw new Error("should not clone a this skolem"); + } + override def nameString: String = clazz.name.toString() + ".this"; + } + /** A class of type symbols. Alias and abstract types are direct instances * of this class. Classes are instances of a subclass. */ @@ -983,8 +996,8 @@ import Flags._; syms1 } - def newSkolems(tparams: List[Symbol]): List[Symbol] = { - val tskolems = tparams map (.newSkolem); + def newTypeSkolems(tparams: List[Symbol]): List[Symbol] = { + val tskolems = tparams map (.newTypeSkolem); val ltp = new LazyType { override def complete(sym: Symbol): unit = sym setInfo sym.deSkolemize.info.substSym(tparams, tskolems); diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala index 3faa808ee3..30f20cd8ff 100755 --- a/sources/scala/tools/nsc/symtab/Types.scala +++ b/sources/scala/tools/nsc/symtab/Types.scala @@ -1311,6 +1311,9 @@ import Flags._; } } def apply(tp: Type): Type = tp match { + case ThisType(sym) if (sym.isModuleClass) => + val sym1 = adaptToNewRun(sym.owner.thisType, sym); + if (sym1 == sym) tp else ThisType(sym1) case SingleType(pre, sym) => if (sym.isPackage) tp else { diff --git a/sources/scala/tools/nsc/typechecker/Contexts.scala b/sources/scala/tools/nsc/typechecker/Contexts.scala index da911ceb78..d6608f3521 100755 --- a/sources/scala/tools/nsc/typechecker/Contexts.scala +++ b/sources/scala/tools/nsc/typechecker/Contexts.scala @@ -63,7 +63,7 @@ import scala.tools.nsc.util.Position; var depth: int = 0; var imports: List[ImportInfo] = List(); - var thisSkolemType: Type = NoPrefix; + var prefix: Type = NoPrefix; var reportAmbiguousErrors = false; var reportGeneralErrors = false; var checking = false; @@ -85,10 +85,10 @@ import scala.tools.nsc.util.Position; tree match { case Template(_, _) | PackageDef(_, _) => c.enclClass = c; - c.thisSkolemType = skolemizedThisType(c.owner) + c.prefix = skolemizedThisType(this.prefix, c.owner) case _ => c.enclClass = this.enclClass; - c.thisSkolemType = this.thisSkolemType + c.prefix = if (c.owner != this.owner && c.owner.isTerm) NoPrefix else this.prefix } c.variance = this.variance; c.depth = if (scope == this.scope) this.depth else this.depth + 1; @@ -129,18 +129,14 @@ import scala.tools.nsc.util.Position; c } - def skolemizedThisType(clazz: Symbol): Type = { - clazz.thisType - /* not yet (GADT) + def skolemizedThisType(pre: Type, clazz: Symbol): Type = if (settings.Xgadt.value) { val tparams = clazz.unsafeTypeParams; - if (tparams.isEmpty) clazz.thisType - else { - val self = clazz.newThisSym(clazz.pos) - setInfo clazz.typeOfThis.substSym(tparams, newSkolems(tparams)); - singleType(clazz.thisType, self) - } - */ - } + if (pre.isInstanceOf[SingleType] || !tparams.isEmpty) { + val self = clazz.newThisSkolem + setInfo clazz.typeOfThis.substSym(tparams, newTypeSkolems(tparams)); + singleType(pre, self) + } else clazz.thisType + } else clazz.thisType; def error(pos: int, msg: String): unit = if (reportGeneralErrors) diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala index 3f7dd81be5..a836e0b0f6 100755 --- a/sources/scala/tools/nsc/typechecker/Namers.scala +++ b/sources/scala/tools/nsc/typechecker/Namers.scala @@ -126,7 +126,7 @@ trait Namers: Analyzer { def finish = finishWith(List()); def skolemize(tparams: List[AbsTypeDef]): unit = { - val tskolems = newSkolems(tparams map (.symbol)); + val tskolems = newTypeSkolems(tparams map (.symbol)); for (val Pair(tparam, tskolem) <- tparams zip tskolems) tparam.symbol = tskolem } diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala index 5ca4feb0b5..267a9ca838 100755 --- a/sources/scala/tools/nsc/typechecker/Typers.scala +++ b/sources/scala/tools/nsc/typechecker/Typers.scala @@ -959,7 +959,7 @@ import collection.mutable.HashMap; var cx = context; while (defSym == NoSymbol && cx != NoContext) { - pre = cx.enclClass.thisSkolemType; + pre = cx.enclClass.prefix; defEntry = cx.scope.lookupEntry(name); if (defEntry != null) { defSym = defEntry.sym; @@ -1240,7 +1240,7 @@ import collection.mutable.HashMap; Pair(tree.symbol, tree.symbol.thisType) } else { val clazzContext = qualifyingClassContext(qual); - Pair(clazzContext.owner, clazzContext.thisSkolemType) + Pair(clazzContext.owner, clazzContext.prefix) } if (clazz == NoSymbol) setError(tree) else { @@ -1265,7 +1265,7 @@ import collection.mutable.HashMap; Pair(tree.symbol, tree.symbol.thisType) } else { val clazzContext = qualifyingClassContext(qual); - Pair(clazzContext.owner, clazzContext.thisSkolemType) + Pair(clazzContext.owner, clazzContext.prefix) } if (clazz == NoSymbol) setError(tree) else { |