summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2005-05-27 16:08:52 +0000
committerMartin Odersky <odersky@gmail.com>2005-05-27 16:08:52 +0000
commit4c593d00f6959e2d753fcb365150921258d9b760 (patch)
treeac5248895f41b0c9e40413c1a8be458eac9fff04 /sources
parent22dc160a9f4cb6f28a2a58c3ec8298e2d90f749a (diff)
downloadscala-4c593d00f6959e2d753fcb365150921258d9b760.tar.gz
scala-4c593d00f6959e2d753fcb365150921258d9b760.tar.bz2
scala-4c593d00f6959e2d753fcb365150921258d9b760.zip
*** empty log message ***
Diffstat (limited to 'sources')
-rwxr-xr-xsources/scala/tools/nsc/symtab/Types.scala48
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Infer.scala5
-rwxr-xr-xsources/scala/tools/nsc/typechecker/Typers.scala2
3 files changed, 43 insertions, 12 deletions
diff --git a/sources/scala/tools/nsc/symtab/Types.scala b/sources/scala/tools/nsc/symtab/Types.scala
index b1027c77b1..614f054c13 100755
--- a/sources/scala/tools/nsc/symtab/Types.scala
+++ b/sources/scala/tools/nsc/symtab/Types.scala
@@ -32,6 +32,7 @@ abstract class Types: SymbolTable {
import definitions._;
private var explainSwitch = false;
+ private var checkMalformedSwitch = true;
val emptyTypeArray = new Array[Type](0);
@@ -180,6 +181,9 @@ abstract class Types: SymbolTable {
def substThis(from: Symbol, to: Type): Type =
new SubstThisMap(from, to) apply this;
+ def substSuper(from: Type, to: Type): Type =
+ new SubstSuperMap(from, to) apply this;
+
/** Does this type contain a reference to this symbol? */
def contains(sym: Symbol): boolean =
new ContainsTraverser(sym).traverse(this).result;
@@ -310,11 +314,13 @@ abstract class Types: SymbolTable {
}
def findMember(name: Name, excludedFlags: int, requiredFlags: int): Symbol = {
- //System.out.println("find member " + name.decode + " in " + this.baseClasses);//DEBUG
+ //System.out.println("find member " + name.decode + " in " + this + ":" + this.baseClasses);//DEBUG
var members: Scope = null;
var member: Symbol = NoSymbol;
var excluded = excludedFlags | DEFERRED;
var continue = true;
+ var savedCheckMalformedSwitch = checkMalformedSwitch;
+ checkMalformedSwitch = false;
while (continue) {
continue = false;
var bcs = baseClasses;
@@ -328,13 +334,14 @@ abstract class Types: SymbolTable {
val excl = sym.getFlag(excluded);
if (excl == 0) {
if (name.isTypeName) {
+ checkMalformedSwitch = savedCheckMalformedSwitch;
return sym
} else if (member == NoSymbol) {
member = sym
} else if (members == null) {
if (member.name != sym.name ||
member != sym && !memberType(member).matches(memberType(sym)))
- members = new Scope(List(member, sym))
+ members = new Scope(List(member, sym));
} else {
var prevEntry = members lookupEntry sym.name;
while (prevEntry != null &&
@@ -358,6 +365,7 @@ abstract class Types: SymbolTable {
} // while (!bcs.isEmpty)
excluded = excludedFlags
} // while (continue)
+ checkMalformedSwitch = savedCheckMalformedSwitch;
if (members == null) member
else baseClasses.head.newOverloaded(this, members.toList)
}
@@ -452,7 +460,16 @@ abstract class Types: SymbolTable {
override def prefixString: String =
if (sym.isEmptyPackage && !settings.debug.value) ""
else pre.prefixString + sym.nameString + ".";
- assert(prefixString != "Nil.");//debug
+ }
+
+ case class SuperType(thistpe: Type, supertp: Type) extends SingletonType {
+ override def symbol = thistpe.symbol;
+ override def singleDeref = supertp;
+ override def prefixString =
+ if (thistpe.prefixString.endsWith("this."))
+ thistpe.prefixString.substring(0, thistpe.prefixString.length() - 5) + "super."
+ else thistpe.prefixString;
+ override def narrow: Type = thistpe.narrow
}
/** A class for the bounds of abstract types and type parameters
@@ -757,15 +774,17 @@ abstract class Types: SymbolTable {
/** The canonical creator for single-types */
def singleType(pre: Type, sym: Symbol): SingleType = {
- if (!pre.isStable && !pre.isError)
+ if (checkMalformedSwitch && !pre.isStable && !pre.isError) {
+ System.out.println("malformed: " + pre + "." + sym.name + checkMalformedSwitch);//debug
throw new MalformedType(pre, sym.name.toString());
+ }
new SingleType(pre, rebind(pre, sym)) {}
}
/** The canonical creator for typerefs */
def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type = {
val sym1 = if (sym.isAbstractType) rebind(pre, sym) else sym;
- if (sym1.isAbstractType && !pre.isStable && !pre.isError)
+ if (checkMalformedSwitch && sym1.isAbstractType && !pre.isStable && !pre.isError)
throw new MalformedType(pre, sym.nameString);
if (sym1.isAliasType && sym1.info.typeParams.length == args.length) {
// note: we require that object is initialized,
@@ -850,6 +869,11 @@ abstract class Types: SymbolTable {
if (pre1 eq pre) tp
else singleType(pre1, sym)
}
+ case SuperType(thistp, supertp) =>
+ val thistp1 = this(thistp);
+ val supertp1 = this(supertp);
+ if ((thistp1 eq thistp) && (supertp1 eq supertp)) tp
+ else SuperType(thistp1, supertp1)
case ConstantType(base, value) =>
val base1 = this(base);
if (base1 eq base) tp
@@ -944,13 +968,13 @@ abstract class Types: SymbolTable {
else toPrefix(pre.baseType(clazz).prefix, clazz.owner);
toPrefix(pre, clazz)
case SingleType(pre, sym) =>
- if (sym.isPackageClass) tp // fast path
+ if (sym.isPackageClass) tp // fast path // todo remove this case; it is redundant
else
- try {
+// try {
mapOver(tp)
- } catch {
- case ex: MalformedType => apply(tp.singleDeref) // todo: try needed?
- }
+// } catch {
+// case ex: MalformedType => apply(tp.singleDeref) // todo: try needed?
+// }
case TypeRef(prefix, sym, args) if (sym.isTypeParameter) =>
def toInstance(pre: Type, clazz: Symbol): Type =
if (pre == NoType || pre == NoPrefix || !clazz.isClass) tp
@@ -1030,6 +1054,10 @@ abstract class Types: SymbolTable {
}
}
+ class SubstSuperMap(from: Type, to: Type) extends TypeMap {
+ def apply(tp: Type): Type = if (tp eq from) to else mapOver(tp);
+ }
+
/** A map to convert every occurrence of a wildcard type to a fresh
* type variable */
object wildcardToTypeVarMap extends TypeMap {
diff --git a/sources/scala/tools/nsc/typechecker/Infer.scala b/sources/scala/tools/nsc/typechecker/Infer.scala
index 6807223bba..96e4909557 100755
--- a/sources/scala/tools/nsc/typechecker/Infer.scala
+++ b/sources/scala/tools/nsc/typechecker/Infer.scala
@@ -220,7 +220,10 @@ abstract class Infer: Analyzer {
if (sym1 == NoSymbol) {
errorTree(tree, sym.toString() + " cannot be accessed in " + pre.widen)
} else {
- tree setSymbol sym1 setType pre.memberType(sym1)
+ var owntype = pre.memberType(sym1);
+ if (pre.isInstanceOf[SuperType])
+ owntype = owntype.substSuper(pre, site.symbol.thisType);
+ tree setSymbol sym1 setType owntype
}
}
diff --git a/sources/scala/tools/nsc/typechecker/Typers.scala b/sources/scala/tools/nsc/typechecker/Typers.scala
index 07cc5f37cc..61f5272e7d 100755
--- a/sources/scala/tools/nsc/typechecker/Typers.scala
+++ b/sources/scala/tools/nsc/typechecker/Typers.scala
@@ -1037,7 +1037,7 @@ abstract class Typers: Analyzer {
ErrorType
} else ps.head
}
- tree setSymbol clazz setType owntype
+ tree setSymbol clazz setType SuperType(clazz.thisType, owntype)
}
case This(qual) =>