diff options
author | mihaylov <mihaylov@epfl.ch> | 2007-02-06 16:06:34 +0000 |
---|---|---|
committer | mihaylov <mihaylov@epfl.ch> | 2007-02-06 16:06:34 +0000 |
commit | f54efe4dc3d13ffab28e6c1e7b0fced4b79eb8d0 (patch) | |
tree | edc177727863228bfaa809ecb7c9dee89c6bc4fb /src/compiler/scala/tools/nsc/typechecker/Typers.scala | |
parent | 89e9d67df8a1cfa075808da59238b20f406f7f51 (diff) | |
download | scala-f54efe4dc3d13ffab28e6c1e7b0fced4b79eb8d0.tar.gz scala-f54efe4dc3d13ffab28e6c1e7b0fced4b79eb8d0.tar.bz2 scala-f54efe4dc3d13ffab28e6c1e7b0fced4b79eb8d0.zip |
Merged the dotnet-scala branch
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 4328a6b06e..42a3bd1831 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -639,6 +639,14 @@ trait Typers requires Analyzer { // (13); the condition prevents chains of views if (settings.debug.value) log("inferring view from "+tree.tpe+" to "+pt) val coercion = inferView(tree.pos, tree.tpe, pt, true) + // convert forward views of delegate types into closures wrapped around + // the delegate's apply method (the "Invoke" method, which was translated into apply) + if (forMSIL && coercion != null && isCorrespondingDelegate(tree.tpe, pt)) { + val meth: Symbol = tree.tpe.member(nme.apply) + if(settings.debug.value) + log("replacing forward delegate view with: " + meth + ":" + meth.tpe) + return typed(Select(tree, meth), mode, pt) + } if (coercion != EmptyTree) { if (settings.debug.value) log("inferred view from "+tree.tpe+" to "+pt+" = "+coercion+":"+coercion.tpe) return typed(Apply(coercion, List(tree)) setPos tree.pos, mode, pt) @@ -1187,7 +1195,7 @@ trait Typers requires Analyzer { * @return ... */ def typedFunction(fun: Function, mode: int, pt: Type): Tree = { - val codeExpected = !forCLDC && (pt.symbol isNonBottomSubClass CodeClass) + val codeExpected = !forCLDC && !forMSIL && (pt.symbol isNonBottomSubClass CodeClass) def decompose(pt: Type): {Symbol, List[Type], Type} = if (isFunctionType(pt) @@ -1361,6 +1369,28 @@ trait Typers requires Analyzer { case MethodType(_, rtp) if ((mode & PATTERNmode) != 0) => rtp case _ => tp } + + // Replace the Delegate-Chainer methods += and -= with corresponding + // + and - calls, which are translated in the code generator into + // Combine and Remove + if (forMSIL) { + fun match { + case Select(qual, name) => + if (isSubType(qual.tpe, definitions.DelegateClass.tpe) + && (name == encode("+=") || name == encode("-="))) + { + val n = if (name == encode("+=")) nme.PLUS else nme.MINUS + val f = Select(qual, n) + // the compiler thinks, the PLUS method takes only one argument, + // but he thinks it's an instance method -> still two ref's on the stack + // -> translated by backend + val rhs = copy.Apply(tree, f, args) + return typed(Assign(qual, rhs)) + } + case _ => () + } + } + if (fun.symbol == List_apply && args.isEmpty) { atPos(tree.pos) { gen.mkNil setType restpe } } else if ((mode & CONSTmode) != 0 && fun.symbol.owner == PredefModule.tpe.symbol && fun.symbol.name == nme.Array) { @@ -2007,7 +2037,23 @@ trait Typers requires Analyzer { case PolyType(_, MethodType(formals, _)) => adapt(expr1, mode, functionType(formals map (t => WildcardType), WildcardType)) case MethodType(formals, _) => - adapt(expr1, mode, functionType(formals map (t => WildcardType), WildcardType)) + expr1 match { + case Select(qual, name) => + if(forMSIL && pt != WildcardType && pt != ErrorType && isSubType(pt, definitions.DelegateClass.tpe)) { + val scalaCaller = newScalaCaller(pt); + addScalaCallerInfo(scalaCaller, expr1.symbol) + val n: Name = scalaCaller.name + val del = Ident(DelegateClass) setType DelegateClass.tpe + val f = Select(del, n) + //val f1 = TypeApply(f, List(Ident(pt.symbol) setType pt)) + val args: List[Tree] = if(expr1.symbol.isStatic) List(Literal(Constant(null))) + else List(qual) // where the scala-method is located + val rhs = Apply(f, args); + return typed(rhs) + } + case _ => () + } + adapt(expr1, mode, functionType(formals map (t => WildcardType), WildcardType)) case ErrorType => expr1 case _ => |