summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
authormihaylov <mihaylov@epfl.ch>2007-02-06 16:06:34 +0000
committermihaylov <mihaylov@epfl.ch>2007-02-06 16:06:34 +0000
commitf54efe4dc3d13ffab28e6c1e7b0fced4b79eb8d0 (patch)
treeedc177727863228bfaa809ecb7c9dee89c6bc4fb /src/compiler/scala/tools/nsc/typechecker/Typers.scala
parent89e9d67df8a1cfa075808da59238b20f406f7f51 (diff)
downloadscala-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.scala50
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 _ =>