summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2006-11-09 16:06:18 +0000
committerIulian Dragos <jaguarul@gmail.com>2006-11-09 16:06:18 +0000
commitf7e5d9d0af7a5af7b7caabef75dcea0e2b27971e (patch)
treecf0ae0265d87016c5e3c590651990ab67ccc3303 /src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
parentaa93e6f3b8686f20e6d16e177e5ec1e24d588096 (diff)
downloadscala-f7e5d9d0af7a5af7b7caabef75dcea0e2b27971e.tar.gz
scala-f7e5d9d0af7a5af7b7caabef75dcea0e2b27971e.tar.bz2
scala-f7e5d9d0af7a5af7b7caabef75dcea0e2b27971e.zip
Fixed bugs in protected accessors.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala60
1 files changed, 34 insertions, 26 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 1e7244e8d2..e41da55549 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -172,6 +172,13 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
val Select(qual, name) = tree
val sym = tree.symbol
val clazz = hostForAccessorOf(sym, currentOwner.enclClass)
+
+ /** Return a list of list of types of all value parameter sections. */
+ def allParamTypes(tpe: Type): List[List[Type]] = tpe match {
+ case MethodType(pts, res) => pts :: allParamTypes(res)
+ case _ => Nil
+ }
+
assert(clazz != NoSymbol, sym)
if (settings.debug.value)
log("Decided for host class: " + clazz)
@@ -179,29 +186,19 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
var protAcc = clazz.info.decl(accName)
val hasArgs = sym.tpe.paramTypes != Nil
if (protAcc == NoSymbol) {
- val resTpe = tree.tpe
- val argTypes =
- if (hasArgs)
- MethodType(
- sym.tpe.paramTypes map {t =>
-// Console.print("Transforming " + t + "(sym=" + t.symbol +") to ")
-// Console.println("" + clazz.typeOfThis + ".memberType = " + clazz.typeOfThis.memberType(t.symbol))
-
- if (!t.symbol.isAbstractType || t.symbol.isTypeParameter)
- clazz.typeOfThis.memberType(t.symbol)
- else
- t
- },
- resTpe.resultType /*sym.tpe.resultType*/)
- else
- resTpe.resultType /*sym.tpe.resultType*/
+ val argTypes = tree.tpe // transform(sym.tpe)
protAcc = clazz.newMethod(tree.pos, nme.protName(sym.originalName))
.setInfo(MethodType(List(clazz.typeOfThis),argTypes))
clazz.info.decls.enter(protAcc);
- val code = DefDef(protAcc, vparamss =>
- vparamss.tail.foldRight(Select(gen.mkAttributedRef(vparamss.head.head), sym): Tree) (
- (vparams, fun) => Apply(fun, (vparams map { v => makeArg(v, vparamss.head.head) } ))))
+ val code = DefDef(protAcc, vparamss => {
+ val obj = vparamss.head.head
+ vparamss.tail.zip(allParamTypes(sym.tpe)).foldLeft(Select(Ident(obj), sym): Tree) (
+ (fun, pvparams) => {
+ Apply(fun, (List.map2(pvparams._1, pvparams._2) { (v, origTpe) => makeArg(v, obj, origTpe) } ))
+ })
+ })
+
if (settings.debug.value)
log(code)
accDefBuf(clazz) += typers(clazz).typed(code)
@@ -212,16 +209,27 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
if (hasArgs) typer.typedOperator(res) else typer.typed(res)
}
- private def makeArg(v: Symbol, obj: Symbol): Tree = {
-// Console.println("" + v + ".tpe = " + v.tpe + " .symbol = "
-// + v.tpe.symbol + " isAbstractType = " + v.tpe.symbol.isAbstractType);
+ /** Adapt the given argument in call to protected member.
+ * Adaptation means adding a cast to a path-dependent type, for instance
+ *
+ * def prot$m(obj: Outer)(x: Inner) = obj.m(x.asInstanceOf[obj.Inner]).
+ *
+ * such a cast might be necessary when m expects an Outer.this.Inner (the
+ * outer of 'obj' and 'x' have to be the same). This restriction can't be
+ * expressed in the type system (but is implicit when defining method m).
+ */
+ private def makeArg(v: Symbol, obj: Symbol, expectedTpe: Type): Tree = {
val res = Ident(v)
+ val sym = v.tpe.symbol
- if (v.tpe.symbol.isAbstractType && !v.tpe.symbol.isTypeParameter) {
+ val isDependentType = expectedTpe match {
+ case TypeRef(ThisType(outerSym), _, _) if (obj.isSubClass(outerSym)) => true
+ case _ => false
+ }
+ if (isDependentType) {
val preciseTpe = typeRef(singleType(NoPrefix, obj), v.tpe.symbol, List())
- Console.println("precise tpe: " + preciseTpe)
- TypeApply(Select(res, definitions.Any_asInstanceOf),
- List(TypeTree(preciseTpe)))
+ TypeApply(Select(res, definitions.Any_asInstanceOf),
+ List(TypeTree(preciseTpe)))
}
else
res