summaryrefslogtreecommitdiff
path: root/sources/scala/tools/nsc/typechecker/Namers.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-11-24 14:22:54 +0000
committerMartin Odersky <odersky@gmail.com>2005-11-24 14:22:54 +0000
commitd8e21c31629b27b6ec5f764d2d06da63fa7602be (patch)
tree938c8da2a2364c0bdac4a3ba78f0cc1d111cf491 /sources/scala/tools/nsc/typechecker/Namers.scala
parenta47b13bd5f8687b6a415dc55257d01a5f1882f6a (diff)
downloadscala-d8e21c31629b27b6ec5f764d2d06da63fa7602be.tar.gz
scala-d8e21c31629b27b6ec5f764d2d06da63fa7602be.tar.bz2
scala-d8e21c31629b27b6ec5f764d2d06da63fa7602be.zip
*** empty log message ***
Diffstat (limited to 'sources/scala/tools/nsc/typechecker/Namers.scala')
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Namers.scala82
1 files changed, 65 insertions, 17 deletions
diff --git a/sources/scala/tools/nsc/typechecker/Namers.scala b/sources/scala/tools/nsc/typechecker/Namers.scala
index a836e0b0f6..ae41a3067b 100755
--- a/sources/scala/tools/nsc/typechecker/Namers.scala
+++ b/sources/scala/tools/nsc/typechecker/Namers.scala
@@ -28,6 +28,30 @@ trait Namers: Analyzer {
sym
}
+ /** Convert to corresponding type parameters all skolems which satisfy one of the
+ * following two conditions:
+ * 1. The skolem is a parameter of a class or alias type
+ * 2. The skolem is a method parameter which appears in parameter `tparams'
+ */
+ class DeSkolemizeMap(tparams: List[Symbol]) extends TypeMap {
+ def apply(tp: Type): Type = tp match {
+ case TypeRef(pre, sym, args) =>
+ val tparam = sym.deSkolemize;
+ mapOver(
+ if (tparam == sym || !(tparams contains tparam)) tp
+ else rawTypeRef(NoPrefix, tparam, args))
+ case SingleType(pre, sym) if (sym.isThisSkolem) =>
+ ThisType(sym.deSkolemize)
+ case PolyType(tparams1, restpe) =>
+ new DeSkolemizeMap(tparams1 ::: tparams).mapOver(tp)
+ case ClassInfoType(parents, decls, clazz) =>
+ val parents1 = List.mapConserve(parents)(this);
+ if (parents1 eq parents) tp else ClassInfoType(parents1, decls, clazz);
+ case _ =>
+ mapOver(tp)
+ }
+ }
+
class Namer(val context: Context) {
private def isTemplateContext(context: Context): boolean = context.tree match {
@@ -112,6 +136,27 @@ trait Namers: Analyzer {
def enterSyms(trees: List[Tree]): Namer =
(this /: trees) ((namer, tree) => namer.enterSym(tree));
+ 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);
+ }
+ tskolems foreach (.setInfo(ltp));
+ tskolems
+ }
+
+ def skolemize(tparams: List[AbsTypeDef]): unit = if (settings.Xgadt.value) {
+ val tskolems = newTypeSkolems(tparams map (.symbol));
+ for (val Pair(tparam, tskolem) <- tparams zip tskolems) tparam.symbol = tskolem
+ }
+
+ def applicableTypeParams(owner: Symbol): List[Symbol] =
+ if (owner.isTerm || owner.isPackageClass) List()
+ else applicableTypeParams(owner.owner) ::: owner.unsafeTypeParams;
+
+ def deSkolemize: TypeMap = new DeSkolemizeMap(applicableTypeParams(context.owner));
+
def enterSym(tree: Tree): Namer = {
def finishWith(tparams: List[AbsTypeDef]): unit = {
@@ -120,16 +165,12 @@ trait Namers: Analyzer {
if (!tparams.isEmpty) {
new Namer(context.makeNewScope(tree, tree.symbol)).enterSyms(tparams);
ltype = new LazyPolyType(tparams map (.symbol), ltype);
+ skolemize(tparams);
}
tree.symbol.setInfo(ltype);
}
def finish = finishWith(List());
- def skolemize(tparams: List[AbsTypeDef]): unit = {
- val tskolems = newTypeSkolems(tparams map (.symbol));
- for (val Pair(tparam, tskolem) <- tparams zip tskolems) tparam.symbol = tskolem
- }
-
if (tree.symbol == NoSymbol) {
val owner = context.owner;
tree match {
@@ -180,11 +221,9 @@ trait Namers: Analyzer {
tree.symbol = enterInScope(owner.newConstructor(tree.pos))
.setFlag(mods | owner.getFlag(ConstrFlags));
finishWith(tparams);
- skolemize(tparams);
case DefDef(mods, name, tparams, _, _, _) =>
tree.symbol = enterInScope(owner.newMethod(tree.pos, name)).setFlag(mods);
finishWith(tparams);
- skolemize(tparams);
case AbsTypeDef(mods, name, _, _) =>
tree.symbol = enterInScope(owner.newAbstractType(tree.pos, name)).setFlag(mods);
finish
@@ -211,7 +250,9 @@ trait Namers: Analyzer {
def typeCompleter(tree: Tree) = new TypeCompleter(tree) {
override def complete(sym: Symbol): unit = {
if (settings.debug.value) log("defining " + sym);
- sym.setInfo(typeSig(tree));
+ val tp = typeSig(tree);
+ sym.setInfo(tp);
+ if (settings.Xgadt.value) System.out.println("" + sym + ":" + tp);
if (settings.debug.value) log("defined " + sym);
validate(sym);
}
@@ -308,11 +349,10 @@ trait Namers: Analyzer {
if (!vparams.isEmpty && vparams.head.hasFlag(IMPLICIT)) ImplicitMethodType(formals, restpe)
else MethodType(formals, restpe);
}
- deSkolemize(
- makePolyType(
- tparamSyms,
- if (vparamSymss.isEmpty) PolyType(List(), restype)
- else (vparamSymss :\ restype)(mkMethodType)))
+ makePolyType(
+ tparamSyms,
+ if (vparamSymss.isEmpty) PolyType(List(), restype)
+ else (vparamSymss :\ restype)(mkMethodType))
}
/** If `sym' is an implicit value, check that its type signature `tp' is contractive.
@@ -354,7 +394,7 @@ trait Namers: Analyzer {
private def aliasTypeSig(tpsym: Symbol, tparams: List[AbsTypeDef], rhs: Tree): Type =
makePolyType(typer.reenterTypeParams(tparams), typer.typedType(rhs).tpe);
- private def typeSig(tree: Tree): Type =
+ private def typeSig(tree: Tree): Type = deSkolemize {
try {
val sym: Symbol = tree.symbol;
tree match {
@@ -368,10 +408,8 @@ trait Namers: Analyzer {
clazz.tpe;
case DefDef(_, _, tparams, vparamss, tpt, rhs) =>
- if (sym.isConstructor) sym.owner.setFlag(INCONSTRUCTOR);
val result =
new Namer(context.makeNewScope(tree, sym)).methodSig(tparams, vparamss, tpt, rhs);
- if (sym.isConstructor) sym.owner.resetFlag(INCONSTRUCTOR);
checkContractive(sym, result)
case ValDef(_, _, tpt, rhs) =>
@@ -383,7 +421,16 @@ trait Namers: Analyzer {
tpt.tpe = deconstIfNotFinal(sym, newTyper(context.make(tree, sym)).computeType(rhs));
tpt.tpe
}
- else typer.typedType(tpt).tpe
+ else {
+ val typer1 =
+ if (false && sym.hasFlag(PARAM) && sym.owner.isConstructor && !phase.erasedTypes) {
+ //todo: find out instead why Template contexts can be nested in Template contexts?
+ var c = context.enclClass;
+ while (c.tree.isInstanceOf[Template]) c = c.outer;
+ newTyper(c)
+ } else typer;
+ typer1.typedType(tpt).tpe
+ }
case AliasTypeDef(_, _, tparams, rhs) =>
new Namer(context.makeNewScope(tree, sym)).aliasTypeSig(sym, tparams, rhs)
@@ -416,6 +463,7 @@ trait Namers: Analyzer {
typer.reportTypeError(tree.pos, ex);
ErrorType
}
+ }
/** Check that symbol's definition is well-formed. This means:
* - no conflicting modifiers