@@ -2,8 +2,8 @@ package dotty.tools
2
2
package dotc
3
3
package typer
4
4
5
- import dotty .tools .dotc .ast .Trees .NamedArg
6
- import dotty .tools .dotc .ast .tpd . _
5
+ import dotty .tools .dotc .ast .Trees ._
6
+ import dotty .tools .dotc .ast .tpd
7
7
import dotty .tools .dotc .ast .untpd
8
8
import dotty .tools .dotc .core .Constants .Constant
9
9
import dotty .tools .dotc .core .Contexts .Context
@@ -27,28 +27,43 @@ object Dynamic {
27
27
* The first matching rule of is applied.
28
28
*/
29
29
trait Dynamic { self : Typer with Applications =>
30
+ import Dynamic ._
31
+ import tpd ._
30
32
31
33
/** Translate selection that does not typecheck according to the normal rules into a applyDynamic/applyDynamicNamed.
32
34
* foo.bar(baz0, baz1, ...) ~~> foo.applyDynamic(bar)(baz0, baz1, ...)
33
35
* foo.bar[T0, ...](baz0, baz1, ...) ~~> foo.applyDynamic[T0, ...](bar)(baz0, baz1, ...)
34
36
* foo.bar(x = bazX, y = bazY, baz, ...) ~~> foo.applyDynamicNamed("bar")(("x", bazX), ("y", bazY), ("", baz), ...)
35
37
* foo.bar[T0, ...](x = bazX, y = bazY, baz, ...) ~~> foo.applyDynamicNamed[T0, ...]("bar")(("x", bazX), ("y", bazY), ("", baz), ...)
36
38
*/
37
- def typedDynamicApply (qual : untpd.Tree , name : Name , targsOpt : Option [List [untpd.Tree ]], args : List [untpd.Tree ], pt : Type )(original : untpd.Apply )(
38
- implicit ctx : Context ): Tree = {
39
- def isNamedArg (arg : untpd.Tree ): Boolean = arg match { case NamedArg (_, _) => true ; case _ => false }
40
- val dynName = if (args.exists(isNamedArg)) nme.applyDynamicNamed else nme.applyDynamic
41
- if (dynName == nme.applyDynamicNamed && untpd.isWildcardStarArgList(args)) {
42
- ctx.error(" applyDynamicNamed does not support passing a vararg parameter" , original.pos)
43
- original.withType(ErrorType )
44
- } else {
45
- def namedArgTuple (name : String , arg : untpd.Tree ) = untpd.Tuple (List (Literal (Constant (name)), arg))
46
- def namedArgs = args.map {
47
- case NamedArg (argName, arg) => namedArgTuple(argName.toString, arg)
48
- case arg => namedArgTuple(" " , arg)
39
+ def typedDynamicApply (tree : untpd.Apply , pt : Type )(implicit ctx : Context ): Tree = {
40
+ def typedDynamicApply (qual : untpd.Tree , name : Name , targs : List [untpd.Tree ]): Tree = {
41
+ def isNamedArg (arg : untpd.Tree ): Boolean = arg match { case NamedArg (_, _) => true ; case _ => false }
42
+ val args = tree.args
43
+ val dynName = if (args.exists(isNamedArg)) nme.applyDynamicNamed else nme.applyDynamic
44
+ if (dynName == nme.applyDynamicNamed && untpd.isWildcardStarArgList(args)) {
45
+ ctx.error(" applyDynamicNamed does not support passing a vararg parameter" , tree.pos)
46
+ tree.withType(ErrorType )
47
+ } else {
48
+ def namedArgTuple (name : String , arg : untpd.Tree ) = untpd.Tuple (List (Literal (Constant (name)), arg))
49
+ def namedArgs = args.map {
50
+ case NamedArg (argName, arg) => namedArgTuple(argName.toString, arg)
51
+ case arg => namedArgTuple(" " , arg)
52
+ }
53
+ val args1 = if (dynName == nme.applyDynamic) args else namedArgs
54
+ typedApply(untpd.Apply (coreDynamic(qual, dynName, name, targs), args1), pt)
49
55
}
50
- val args1 = if (dynName == nme.applyDynamic) args else namedArgs
51
- typedApply(untpd.Apply (coreDynamic(qual, dynName, name, targsOpt), args1), pt)
56
+ }
57
+
58
+ tree.fun match {
59
+ case Select (qual, name) if ! isDynamicMethod(name) =>
60
+ typedDynamicApply(qual, name, Nil )
61
+ case TypeApply (Select (qual, name), targs) if ! isDynamicMethod(name) =>
62
+ typedDynamicApply(qual, name, targs)
63
+ case TypeApply (fun, targs) =>
64
+ typedDynamicApply(fun, nme.apply, targs)
65
+ case fun =>
66
+ typedDynamicApply(fun, nme.apply, Nil )
52
67
}
53
68
}
54
69
@@ -59,21 +74,31 @@ trait Dynamic { self: Typer with Applications =>
59
74
* Note: inner part of translation foo.bar(baz) = quux ~~> foo.selectDynamic(bar).update(baz, quux) is achieved
60
75
* through an existing transformation of in typedAssign [foo.bar(baz) = quux ~~> foo.bar.update(baz, quux)].
61
76
*/
62
- def typedDynamicSelect (qualifier : untpd.Tree , name : Name , targsOpt : Option [ List [Tree ] ], pt : Type )(implicit ctx : Context ): Tree =
63
- typedApply(coreDynamic(qualifier, nme.selectDynamic, name, targsOpt ), pt)
77
+ def typedDynamicSelect (tree : untpd.Select , targs : List [Tree ], pt : Type )(implicit ctx : Context ): Tree =
78
+ typedApply(coreDynamic(tree. qualifier, nme.selectDynamic, tree. name, targs ), pt)
64
79
65
80
/** Translate selection that does not typecheck according to the normal rules into a updateDynamic.
66
81
* foo.bar = baz ~~> foo.updateDynamic(bar)(baz)
67
82
*/
68
- def typedDynamicAssign (qual : untpd.Tree , name : Name , targsOpt : Option [List [untpd.Tree ]], rhs : untpd.Tree , pt : Type )(implicit ctx : Context ): Tree =
69
- typedApply(untpd.Apply (coreDynamic(qual, nme.updateDynamic, name, targsOpt), rhs), pt)
83
+ def typedDynamicAssign (tree : untpd.Assign , pt : Type )(implicit ctx : Context ): Tree = {
84
+ def typedDynamicAssign (qual : untpd.Tree , name : Name , targs : List [untpd.Tree ]): Tree =
85
+ typedApply(untpd.Apply (coreDynamic(qual, nme.updateDynamic, name, targs), tree.rhs), pt)
86
+ tree.lhs match {
87
+ case Select (qual, name) if ! isDynamicMethod(name) =>
88
+ typedDynamicAssign(qual, name, Nil )
89
+ case TypeApply (Select (qual, name), targs) if ! isDynamicMethod(name) =>
90
+ typedDynamicAssign(qual, name, targs)
91
+ case _ =>
92
+ ctx.error(" reassignment to val" , tree.pos)
93
+ tree.withType(ErrorType )
94
+ }
95
+ }
70
96
71
- private def coreDynamic (qual : untpd.Tree , dynName : Name , name : Name , targsOpt : Option [ List [untpd.Tree ] ])(implicit ctx : Context ): untpd.Apply = {
97
+ private def coreDynamic (qual : untpd.Tree , dynName : Name , name : Name , targs : List [untpd.Tree ])(implicit ctx : Context ): untpd.Apply = {
72
98
val select = untpd.Select (qual, dynName)
73
- val selectWithTypes = targsOpt match {
74
- case Some (targs) => untpd.TypeApply (select, targs)
75
- case None => select
76
- }
99
+ val selectWithTypes =
100
+ if (targs.isEmpty) select
101
+ else untpd.TypeApply (select, targs)
77
102
untpd.Apply (selectWithTypes, Literal (Constant (name.toString)))
78
103
}
79
104
}
0 commit comments