diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Definitions.scala | 4 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/StdNames.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/CleanUp.scala | 10 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 46 | ||||
-rw-r--r-- | src/library/scala/Dynamic.scala | 18 |
5 files changed, 64 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index 659b7e80d2..e38f626932 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -152,6 +152,8 @@ trait Definitions extends reflect.generic.StandardDefinitions { lazy val StringModule = StringClass.linkedClassOfClass lazy val ClassClass = getClass(sn.Class) def Class_getMethod = getMember(ClassClass, nme.getMethod_) + lazy val DynamicClass = getClass("scala.Dynamic") + val Dynamic_OptInvokeMaxArgCount = 7 // fundamental modules lazy val PredefModule: Symbol = getModule("scala.Predef") @@ -160,6 +162,7 @@ trait Definitions extends reflect.generic.StandardDefinitions { def Predef_error = getMember(PredefModule, nme.error) def Predef_identity = getMember(PredefModule, nme.identity) def Predef_conforms = getMember(PredefModule, nme.conforms) + def Predef_wrapRefArray = getMember(PredefModule, nme.wrapRefArray) lazy val ConsoleModule: Symbol = getModule("scala.Console") lazy val ScalaRunTimeModule: Symbol = getModule("scala.runtime.ScalaRunTime") lazy val SymbolModule: Symbol = getModule("scala.Symbol") @@ -244,6 +247,7 @@ trait Definitions extends reflect.generic.StandardDefinitions { // arrays and their members lazy val ArrayModule = getModule("scala.Array") + def ArrayModule_overloadedApply = getMember(ArrayModule, nme.apply) lazy val ArrayClass = getClass("scala.Array") def Array_apply = getMember(ArrayClass, nme.apply) def Array_update = getMember(ArrayClass, nme.update) diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala index 0e28ac54e1..04f71470f8 100644 --- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala +++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala @@ -235,6 +235,7 @@ trait StdNames extends reflect.generic.StdNames with NameManglers { val view_ : NameType = "view" val wait_ : NameType = "wait" val withFilter: NameType = "withFilter" + val wrapRefArray: NameType = "wrapRefArray" val zip: NameType = "zip" // unencoded operators diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index 66c22fb1ef..3c9e701ee9 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -595,6 +595,16 @@ abstract class CleanUp extends Transform with ast.TreeDSL { val ntree = typedWithPos(symapp.pos)(REF(staticFieldSym)) super.transform(ntree) + + // This transform replaces Array(Predef.wrapArray(Array(...)), <manifest>) + // with just Array(...) + case Apply(appMeth, List(Apply(wrapRefArrayMeth, List(array)), _)) + if (wrapRefArrayMeth.symbol == Predef_wrapRefArray && + appMeth.symbol == ArrayModule_overloadedApply.suchThat { + _.tpe.resultType.dealias.typeSymbol == ObjectClass + }) => + super.transform(array) + case _ => super.transform(tree) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 2b6bf6080c..9085affd62 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3443,21 +3443,21 @@ trait Typers extends Modes { adaptToName(qual, name) } catch { case ex: TypeError => - // this happens if implicits are ambiguous; try again with more context info. - // println("last ditch effort: "+qual+" . "+name) // DEBUG - context.tree match { - case Apply(tree1, args) if tree1 eq tree => // try handling the arguments - // println("typing args: "+args) // DEBUG - silent(_.typedArgs(args, mode)) match { - case args: List[_] => - adaptToArguments(qual, name, args.asInstanceOf[List[Tree]], WildcardType) - case _ => - throw ex - } - case _ => - // println("not in an apply: "+context.tree+"/"+tree) // DEBUG - throw ex - } + // this happens if implicits are ambiguous; try again with more context info. + // println("last ditch effort: "+qual+" . "+name) + context.tree match { + case Apply(tree1, args) if tree1 eq tree => // try handling the arguments + // println("typing args: "+args) + silent(_.typedArgs(args, mode)) match { + case args: List[_] => + adaptToArguments(qual, name, args.asInstanceOf[List[Tree]], WildcardType) + case _ => + throw ex + } + case _ => + // println("not in an apply: "+context.tree+"/"+tree) + throw ex + } } if (qual1 ne qual) return typed(treeCopy.Select(tree, qual1, name), mode, pt) } @@ -3468,6 +3468,22 @@ trait Typers extends Modes { if (tree1 != EmptyTree) return typed1(tree1, mode, pt) } + // try to expand according to Dynamic rules. + + if (qual.tpe.widen.typeSymbol isNonBottomSubClass DynamicClass) { + val op = context.tree match { + case Apply(tree1, args) if tree1 eq tree => + "_invoke_" + + (if (args.length <= Dynamic_OptInvokeMaxArgCount) args.length.toString + else "") + case _ => + "_select_" + } + return typed1( + util.trace("dynatype: ")(Apply(Select(qual, op), List(Literal(Constant(name.toString))))), + mode, pt) + } + if (settings.debug.value) { log( "qual = "+qual+":"+qual.tpe+ diff --git a/src/library/scala/Dynamic.scala b/src/library/scala/Dynamic.scala new file mode 100644 index 0000000000..502084949a --- /dev/null +++ b/src/library/scala/Dynamic.scala @@ -0,0 +1,18 @@ +package scala + +trait Dynamic { + def _select_ (name: String): Dynamic + def _invoke_ (name: String)(args: Any*): Dynamic + + def _invoke_0(name: String)(): Dynamic = _invoke_ (name)() + def _invoke_1(name: String)(arg1: Any): Dynamic = _invoke_ (name) (arg1) + def _invoke_2(name: String)(arg1: Any, arg2: Any): Dynamic = _invoke_ (name)(arg1, arg2) + def _invoke_3(name: String)(arg1: Any, arg2: Any, arg3: Any): Dynamic = _invoke_ (name)(arg1, arg2, arg3) + def _invoke_4(name: String)(arg1: Any, arg2: Any, arg3: Any, arg4: Any): Dynamic = _invoke_ (name)(arg1, arg2, arg3, arg4) + def _invoke_5(name: String)(arg1: Any, arg2: Any, arg3: Any, arg4: Any, arg5: Any): Dynamic = _invoke_ (name)(arg1, arg2, arg3, arg4, arg5) + def _invoke_6(name: String)(arg1: Any, arg2: Any, arg3: Any, arg4: Any, arg5: Any, arg6: Any): Dynamic = _invoke_ (name)(arg1, arg2, arg3, arg4, arg5, arg6) + def _invoke_7(name: String)(arg1: Any, arg2: Any, arg3: Any, arg4: Any, arg5: Any, arg6: Any, arg7: Any): Dynamic = _invoke_ (name)(arg1, arg2, arg3, arg4, arg5, arg6, arg7) + + def typed[T]: T = asInstanceOf[T] +} + |