summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-11-22 10:02:24 +0000
committerMartin Odersky <odersky@gmail.com>2005-11-22 10:02:24 +0000
commit12c007cda6ff4d6b902efbfef18a057370bcd86e (patch)
tree266dba82490cb6953d1f367ae0007ae73632bcf2 /sources
parentfb67524a831520da47ea29967d2595dced41c323 (diff)
downloadscala-12c007cda6ff4d6b902efbfef18a057370bcd86e.tar.gz
scala-12c007cda6ff4d6b902efbfef18a057370bcd86e.tar.bz2
scala-12c007cda6ff4d6b902efbfef18a057370bcd86e.zip
*** empty log message ***
Diffstat (limited to 'sources')
-rw-r--r--sources/scala/tools/nsc/Settings.scala1
-rwxr-xr-xsources/scala/tools/nsc/ast/TreeGen.scala16
-rwxr-xr-xsources/scala/tools/nsc/symtab/StdNames.scala1
-rwxr-xr-xsources/scala/tools/nsc/symtab/Symbols.scala19
-rwxr-xr-xsources/scala/tools/nsc/symtab/Types.scala3
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Contexts.scala24
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Namers.scala2
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala6
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 {