diff options
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 28 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Dynamic.scala | 75 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 17 |
3 files changed, 60 insertions, 60 deletions
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 52e80930e..72c971925 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -591,17 +591,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic => fun1.tpe match { case ErrorType => tree.withType(ErrorType) - case TryDynamicCallType => - tree.fun match { - case Select(qual, name) if !isDynamicMethod(name) => - typedDynamicApply(qual, name, None, tree.args, pt)(tree) - case TypeApply(Select(qual, name), targs) if !isDynamicMethod(name) => - typedDynamicApply(qual, name, Some(targs), tree.args, pt)(tree) - case TypeApply(fun, targs) => - typedDynamicApply(fun, nme.apply, Some(targs), tree.args, pt)(tree) - case fun => - typedDynamicApply(fun, nme.apply, None, tree.args, pt)(tree) - } + case TryDynamicCallType => typedDynamicApply(tree, pt) case _ => tryEither { implicit ctx => simpleApply(fun1, proto) @@ -683,18 +673,12 @@ trait Applications extends Compatibility { self: Typer with Dynamic => } case _ => } - if (typedFn.tpe eq TryDynamicCallType) { - (pt, typedFn) match { - case (_: FunProto, _)=> - tree.withType(TryDynamicCallType) - case (_, Select(qual, name)) => - typedDynamicSelect(qual, name, Some(typedArgs), pt) - case _ => - tree.withType(TryDynamicCallType) - } - } else { - assignType(cpy.TypeApply(tree)(typedFn, typedArgs), typedFn, typedArgs) + def tryDynamicTypeApply(): Tree = typedFn match { + case typedFn: Select if !pt.isInstanceOf[FunProto] => typedDynamicSelect(typedFn, typedArgs, pt) + case _ => tree.withType(TryDynamicCallType) } + if (typedFn.tpe eq TryDynamicCallType) tryDynamicTypeApply() + else assignType(cpy.TypeApply(tree)(typedFn, typedArgs), typedFn, typedArgs) } /** Rewrite `new Array[T](....)` if T is an unbounded generic to calls to newGenericArray. diff --git a/src/dotty/tools/dotc/typer/Dynamic.scala b/src/dotty/tools/dotc/typer/Dynamic.scala index f5303b833..b5ace87d3 100644 --- a/src/dotty/tools/dotc/typer/Dynamic.scala +++ b/src/dotty/tools/dotc/typer/Dynamic.scala @@ -2,8 +2,8 @@ package dotty.tools package dotc package typer -import dotty.tools.dotc.ast.Trees.NamedArg -import dotty.tools.dotc.ast.tpd._ +import dotty.tools.dotc.ast.Trees._ +import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.ast.untpd import dotty.tools.dotc.core.Constants.Constant import dotty.tools.dotc.core.Contexts.Context @@ -27,6 +27,8 @@ object Dynamic { * The first matching rule of is applied. */ trait Dynamic { self: Typer with Applications => + import Dynamic._ + import tpd._ /** Translate selection that does not typecheck according to the normal rules into a applyDynamic/applyDynamicNamed. * foo.bar(baz0, baz1, ...) ~~> foo.applyDynamic(bar)(baz0, baz1, ...) @@ -34,21 +36,34 @@ trait Dynamic { self: Typer with Applications => * foo.bar(x = bazX, y = bazY, baz, ...) ~~> foo.applyDynamicNamed("bar")(("x", bazX), ("y", bazY), ("", baz), ...) * foo.bar[T0, ...](x = bazX, y = bazY, baz, ...) ~~> foo.applyDynamicNamed[T0, ...]("bar")(("x", bazX), ("y", bazY), ("", baz), ...) */ - def typedDynamicApply(qual: untpd.Tree, name: Name, targsOpt: Option[List[untpd.Tree]], args: List[untpd.Tree], pt: Type)(original: untpd.Apply)( - implicit ctx: Context): Tree = { - def isNamedArg(arg: untpd.Tree): Boolean = arg match { case NamedArg(_, _) => true; case _ => false } - val dynName = if (args.exists(isNamedArg)) nme.applyDynamicNamed else nme.applyDynamic - if (dynName == nme.applyDynamicNamed && untpd.isWildcardStarArgList(args)) { - ctx.error("applyDynamicNamed does not support passing a vararg parameter", original.pos) - original.withType(ErrorType) - } else { - def namedArgTuple(name: String, arg: untpd.Tree) = untpd.Tuple(List(Literal(Constant(name)), arg)) - def namedArgs = args.map { - case NamedArg(argName, arg) => namedArgTuple(argName.toString, arg) - case arg => namedArgTuple("", arg) + def typedDynamicApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = { + def typedDynamicApply(qual: untpd.Tree, name: Name, targs: List[untpd.Tree]): Tree = { + def isNamedArg(arg: untpd.Tree): Boolean = arg match { case NamedArg(_, _) => true; case _ => false } + val args = tree.args + val dynName = if (args.exists(isNamedArg)) nme.applyDynamicNamed else nme.applyDynamic + if (dynName == nme.applyDynamicNamed && untpd.isWildcardStarArgList(args)) { + ctx.error("applyDynamicNamed does not support passing a vararg parameter", tree.pos) + tree.withType(ErrorType) + } else { + def namedArgTuple(name: String, arg: untpd.Tree) = untpd.Tuple(List(Literal(Constant(name)), arg)) + def namedArgs = args.map { + case NamedArg(argName, arg) => namedArgTuple(argName.toString, arg) + case arg => namedArgTuple("", arg) + } + val args1 = if (dynName == nme.applyDynamic) args else namedArgs + typedApply(untpd.Apply(coreDynamic(qual, dynName, name, targs), args1), pt) } - val args1 = if (dynName == nme.applyDynamic) args else namedArgs - typedApply(untpd.Apply(coreDynamic(qual, dynName, name, targsOpt), args1), pt) + } + + tree.fun match { + case Select(qual, name) if !isDynamicMethod(name) => + typedDynamicApply(qual, name, Nil) + case TypeApply(Select(qual, name), targs) if !isDynamicMethod(name) => + typedDynamicApply(qual, name, targs) + case TypeApply(fun, targs) => + typedDynamicApply(fun, nme.apply, targs) + case fun => + typedDynamicApply(fun, nme.apply, Nil) } } @@ -59,21 +74,31 @@ trait Dynamic { self: Typer with Applications => * Note: inner part of translation foo.bar(baz) = quux ~~> foo.selectDynamic(bar).update(baz, quux) is achieved * through an existing transformation of in typedAssign [foo.bar(baz) = quux ~~> foo.bar.update(baz, quux)]. */ - def typedDynamicSelect(qualifier: untpd.Tree, name: Name, targsOpt: Option[List[Tree]], pt: Type)(implicit ctx: Context): Tree = - typedApply(coreDynamic(qualifier, nme.selectDynamic, name, targsOpt), pt) + def typedDynamicSelect(tree: untpd.Select, targs: List[Tree], pt: Type)(implicit ctx: Context): Tree = + typedApply(coreDynamic(tree.qualifier, nme.selectDynamic, tree.name, targs), pt) /** Translate selection that does not typecheck according to the normal rules into a updateDynamic. * foo.bar = baz ~~> foo.updateDynamic(bar)(baz) */ - def typedDynamicAssign(qual: untpd.Tree, name: Name, targsOpt: Option[List[untpd.Tree]], rhs: untpd.Tree, pt: Type)(implicit ctx: Context): Tree = - typedApply(untpd.Apply(coreDynamic(qual, nme.updateDynamic, name, targsOpt), rhs), pt) + def typedDynamicAssign(tree: untpd.Assign, pt: Type)(implicit ctx: Context): Tree = { + def typedDynamicAssign(qual: untpd.Tree, name: Name, targs: List[untpd.Tree]): Tree = + typedApply(untpd.Apply(coreDynamic(qual, nme.updateDynamic, name, targs), tree.rhs), pt) + tree.lhs match { + case Select(qual, name) if !isDynamicMethod(name) => + typedDynamicAssign(qual, name, Nil) + case TypeApply(Select(qual, name), targs) if !isDynamicMethod(name) => + typedDynamicAssign(qual, name, targs) + case _ => + ctx.error("reassignment to val", tree.pos) + tree.withType(ErrorType) + } + } - private def coreDynamic(qual: untpd.Tree, dynName: Name, name: Name, targsOpt: Option[List[untpd.Tree]])(implicit ctx: Context): untpd.Apply = { + private def coreDynamic(qual: untpd.Tree, dynName: Name, name: Name, targs: List[untpd.Tree])(implicit ctx: Context): untpd.Apply = { val select = untpd.Select(qual, dynName) - val selectWithTypes = targsOpt match { - case Some(targs) => untpd.TypeApply(select, targs) - case None => select - } + val selectWithTypes = + if (targs.isEmpty) select + else untpd.TypeApply(select, targs) untpd.Apply(selectWithTypes, Literal(Constant(name.toString))) } } diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index cce692b42..2cfc5f411 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -317,12 +317,9 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit val qual1 = typedExpr(tree.qualifier, selectionProto(tree.name, pt, this)) if (tree.name.isTypeName) checkStable(qual1.tpe, qual1.pos) val select = typedSelect(tree, pt, qual1) - pt match { - case _ if select.tpe ne TryDynamicCallType => select - case _: FunProto | AssignProto => select - case PolyProto(_,_) => select - case _ => typedDynamicSelect(tree.qualifier, tree.name, None, pt) - } + if (select.tpe ne TryDynamicCallType) select + else if (pt.isInstanceOf[PolyProto] || pt.isInstanceOf[FunProto] || pt == AssignProto) select + else typedDynamicSelect(tree, Nil, pt) } def asJavaSelectFromTypeTree(implicit ctx: Context): Tree = { @@ -518,13 +515,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit reassignmentToVal } case TryDynamicCallType => - tree match { - case Assign(Select(qual, name), rhs) if !isDynamicMethod(name) => - typedDynamicAssign(qual, name, None, rhs, pt) - case Assign(TypeApply(Select(qual, name), targs), rhs) if !isDynamicMethod(name) => - typedDynamicAssign(qual, name, Some(targs), rhs, pt) - case _ => reassignmentToVal - } + typedDynamicAssign(tree, pt) case tpe => reassignmentToVal } |