summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-11-15 12:06:45 +0000
committerMartin Odersky <odersky@gmail.com>2005-11-15 12:06:45 +0000
commit0beee8af0cfcc3295a7f2a66cbf615eec2fc2039 (patch)
treefbfd7d9a58830d5842d40d7dfe8fca8958e54f45
parent87f227fedd7374d7513c971cbdedbc2efe7ed53c (diff)
downloadscala-0beee8af0cfcc3295a7f2a66cbf615eec2fc2039.tar.gz
scala-0beee8af0cfcc3295a7f2a66cbf615eec2fc2039.tar.bz2
scala-0beee8af0cfcc3295a7f2a66cbf615eec2fc2039.zip
*** empty log message ***
-rwxr-xr-xsources/scala/tools/nsc/transform/Mixin.scala48
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Contexts.scala2
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala48
3 files changed, 58 insertions, 40 deletions
diff --git a/sources/scala/tools/nsc/transform/Mixin.scala b/sources/scala/tools/nsc/transform/Mixin.scala
index f532cad7fe..8bc4100806 100755
--- a/sources/scala/tools/nsc/transform/Mixin.scala
+++ b/sources/scala/tools/nsc/transform/Mixin.scala
@@ -88,30 +88,37 @@ abstract class Mixin extends InfoTransform {
if (settings.debug.value) log("new defs of " + clazz + " = " + clazz.info.decls);
}
- def addMixedinMembers(clazz: Symbol): unit =
+ def addMixedinMembers(clazz: Symbol): unit = {
if (!(clazz hasFlag MIXEDIN) && (clazz != ObjectClass)) {
assert(!clazz.isTrait, clazz);
clazz setFlag MIXEDIN;
assert(!clazz.info.parents.isEmpty, clazz);
val superclazz = clazz.info.parents.head.symbol;
addMixedinMembers(superclazz);
- for (val bc <- clazz.info.baseClasses.tail.takeWhile(superclazz !=))
- if (bc.hasFlag(lateINTERFACE))
- addLateInterfaceMembers(bc);
- for (val bc <- clazz.info.baseClasses.tail.takeWhile(superclazz !=)) {
- if (bc.isImplClass) {
- for (val member <- bc.info.decls.toList) {
+ //System.out.println("adding members of " + clazz.info.baseClasses.tail.takeWhile(superclazz !=) + " to " + clazz);//DEBUG
+ val mixins = clazz.info.baseClasses.tail.takeWhile(superclazz !=);
+ def mixinMembers(mixin: Symbol, mmap: Symbol => Symbol): unit = {
+ if (mixin.isImplClass) {
+ for (val member <- mixin.info.decls.toList) {
+ //System.out.println("adding forwarded method " + member + member.locationString + " to " + clazz + " " + clazz.info.member(member.name).alternatives);//DEBUG
if (isForwarded(member) && !isStatic(member) &&
- (clazz.info.findMember(member.name, 0, 0).alternatives contains member)) {
- //System.out.println("adding forwarded method " + member + member.locationString + " to " + clazz + " " + clazz.info.member(member.name).alternatives);//DEBUG
- val member1 = addMember(clazz, member.cloneSymbol(clazz) setFlag MIXEDIN resetFlag (DEFERRED | lateDEFERRED));
- member1.asInstanceOf[TermSymbol] setAlias member;
- }
+ (clazz.info.findMember(member.name, 0, 0).alternatives contains mmap(member))) {
+ val member1 = addMember(
+ clazz,
+ member.cloneSymbol(clazz)
+ setFlag MIXEDIN resetFlag (DEFERRED | lateDEFERRED));
+ member1.asInstanceOf[TermSymbol] setAlias member;
+ }
}
- } else if (bc.hasFlag(lateINTERFACE)) {
- for (val member <- bc.info.decls.toList) {
+ } else if (mixin.hasFlag(lateINTERFACE)) {
+ addLateInterfaceMembers(mixin);
+ val impl = implClass(mixin);
+ //System.out.println("late impl " + mixin + " " + impl);//DEBUG
+ if (!(mixins contains impl)) mixinMembers(impl, .overriddenSymbol(mixin));
+ for (val member <- mixin.info.decls.toList) {
if (member hasFlag ACCESSOR) {
- val member1 = addMember(clazz,
+ val member1 = addMember(
+ clazz,
member.cloneSymbol(clazz) setFlag (MIXEDIN | FINAL) resetFlag (DEFERRED | lateDEFERRED));
if (!member.isSetter)
member.tpe match {
@@ -119,14 +126,14 @@ abstract class Mixin extends InfoTransform {
;
case _ =>
addMember(clazz,
- clazz.newValue(member.pos, nme.getterToLocal(member.name))
- setFlag (LOCAL | PRIVATE | MIXEDIN | member.getFlag(MUTABLE))
- setInfo member.tpe.resultType)
+ clazz.newValue(member.pos, nme.getterToLocal(member.name))
+ setFlag (LOCAL | PRIVATE | MIXEDIN | member.getFlag(MUTABLE))
+ setInfo member.tpe.resultType)
}
} else if (member hasFlag SUPERACCESSOR) {
val member1 = addMember(clazz, member.cloneSymbol(clazz)) setFlag MIXEDIN;
assert(member1.alias != NoSymbol, member1);
- val alias1 = rebindSuper(clazz, member.alias, bc);
+ val alias1 = rebindSuper(clazz, member.alias, mixin);
member1.asInstanceOf[TermSymbol] setAlias alias1;
} else if (member.isMethod && member.isModule && !(member hasFlag (LIFTED | BRIDGE))) {
addMember(clazz, member.cloneSymbol(clazz) setFlag MIXEDIN)
@@ -134,8 +141,11 @@ abstract class Mixin extends InfoTransform {
}
}
}
+// for (val mixin <- mixins) if (mixin.hasFlag(lateINTERFACE)) addLateInterfaceMembers(mixin);
+ for (val mixin <- mixins) mixinMembers(mixin, identity);
if (settings.debug.value) log("new defs of " + clazz + " = " + clazz.info.decls);
}
+ }
override def transformInfo(sym: Symbol, tp: Type): Type = tp match {
case ClassInfoType(parents, decls, clazz) =>
diff --git a/sources/scala/tools/nsc/typechecker/Contexts.scala b/sources/scala/tools/nsc/typechecker/Contexts.scala
index a43a45d1f3..4af9f95202 100755
--- a/sources/scala/tools/nsc/typechecker/Contexts.scala
+++ b/sources/scala/tools/nsc/typechecker/Contexts.scala
@@ -63,6 +63,7 @@ import scala.tools.nsc.util.Position;
var depth: int = 0;
var imports: List[ImportInfo] = List();
+ var thisSkolemType: Type = NoPrefix;
var reportAmbiguousErrors = false;
var reportGeneralErrors = false;
var checking = false;
@@ -88,6 +89,7 @@ import scala.tools.nsc.util.Position;
c.variance = this.variance;
c.depth = if (scope == this.scope) this.depth else this.depth + 1;
c.imports = imports;
+ c.thisSkolemType = if (owner.isClass) owner.thisType else thisSkolemType;
c.reportAmbiguousErrors = this.reportAmbiguousErrors;
c.reportGeneralErrors = this.reportGeneralErrors;
c.checking = this.checking;
diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala
index a5ff44a106..72cfaf733e 100755
--- a/sources/scala/tools/nsc/typechecker/Typers.scala
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -2,7 +2,6 @@
* Copyright 2005 LAMP/EPFL
* @author Martin Odersky
*/
-// $Id$
//todo: rewrite or disallow new T where T is a trait (currently: <init> not a member of T)
package scala.tools.nsc.typechecker;
@@ -881,22 +880,16 @@ import collection.mutable.HashMap;
}
/** The qualifying class of a this or super with prefix `qual' */
- def qualifyingClass(qual: Name): Symbol = {
+ def qualifyingClassContext(qual: Name): Context = {
if (qual == nme.EMPTY.toTypeName) {
- val clazz = context.enclClass.owner;
- if (!clazz.isPackageClass) clazz
- else {
+ if (context.enclClass.owner.isPackageClass)
error(tree.pos, "" + tree + " can be used only in a class, object, or template");
- NoSymbol
- }
+ context.enclClass
} else {
var c = context.enclClass;
while (c != NoContext && c.owner.name != qual) c = c.outer.enclClass;
- if (c != NoContext) c.owner
- else {
- error(tree.pos, "" + qual + " is not an enclosing class");
- NoSymbol
- }
+ if (c == NoContext) error(tree.pos, "" + qual + " is not an enclosing class");
+ c
}
}
@@ -963,11 +956,12 @@ import collection.mutable.HashMap;
var cx = context;
while (defSym == NoSymbol && cx != NoContext) {
- pre = cx.enclClass.owner.thisType;
+ pre = cx.enclClass.thisSkolemType;
defEntry = cx.scope.lookupEntry(name);
- if (defEntry != null)
- defSym = defEntry.sym
- else {
+ if (defEntry != null) {
+ defSym = defEntry.sym;
+ assert(pre eq cx.enclClass.owner.thisType, "mismatch " + pre + " " + cx.enclClass.owner + " " + defSym);//debug
+ } else {
cx = cx.enclClass;
defSym = pre.member(name) filter (sym => context.isAccessible(sym, pre, false));
if (defSym == NoSymbol) cx = cx.outer;
@@ -1239,7 +1233,13 @@ import collection.mutable.HashMap;
}
case Super(qual, mix) =>
- val clazz = if (tree.symbol != NoSymbol) tree.symbol else qualifyingClass(qual);
+ val Pair(clazz, selftype) =
+ if (tree.symbol != NoSymbol) {
+ Pair(tree.symbol, tree.symbol.thisType)
+ } else {
+ val clazzContext = qualifyingClassContext(qual);
+ Pair(clazzContext.owner, clazzContext.thisSkolemType)
+ }
if (clazz == NoSymbol) setError(tree)
else {
val owntype =
@@ -1254,15 +1254,21 @@ import collection.mutable.HashMap;
ErrorType
} else ps.head
}
- tree setSymbol clazz setType SuperType(clazz.thisType, owntype)
+ tree setSymbol clazz setType SuperType(selftype, owntype)
}
case This(qual) =>
- val clazz = if (tree.symbol != NoSymbol) tree.symbol else qualifyingClass(qual);
+ val Pair(clazz, selftype) =
+ if (tree.symbol != NoSymbol) {
+ Pair(tree.symbol, tree.symbol.thisType)
+ } else {
+ val clazzContext = qualifyingClassContext(qual);
+ Pair(clazzContext.owner, clazzContext.thisSkolemType)
+ }
if (clazz == NoSymbol) setError(tree)
else {
- val owntype = if (pt.isStable || (mode & QUALmode) != 0) clazz.thisType
- else clazz.typeOfThis;
+ val owntype = if (pt.isStable || (mode & QUALmode) != 0) selftype
+ else selftype.singleDeref;
tree setSymbol clazz setType owntype
}