From 5e23a6ac32394130dd72458c7efe38dbd1ddb116 Mon Sep 17 00:00:00 2001 From: Denys Shabalin Date: Mon, 17 Mar 2014 13:59:08 +0100 Subject: SI-8411 match desugared partial functions --- src/reflect/scala/reflect/api/Internals.scala | 2 +- .../reflect/internal/ReificationSupport.scala | 22 +++++++++++++++++++--- test/files/pos/t8411/Macros_1.scala | 10 ++++++++++ test/files/pos/t8411/Test_2.scala | 4 ++++ .../scalacheck/quasiquotes/TypecheckedProps.scala | 5 +++++ 5 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 test/files/pos/t8411/Macros_1.scala create mode 100644 test/files/pos/t8411/Test_2.scala diff --git a/src/reflect/scala/reflect/api/Internals.scala b/src/reflect/scala/reflect/api/Internals.scala index 9faba7efd7..7788dba63e 100644 --- a/src/reflect/scala/reflect/api/Internals.scala +++ b/src/reflect/scala/reflect/api/Internals.scala @@ -765,7 +765,7 @@ trait Internals { self: Universe => val SyntacticPartialFunction: SyntacticPartialFunctionExtractor trait SyntacticPartialFunctionExtractor { def apply(cases: List[Tree]): Match - def unapply(tree: Match): Option[List[CaseDef]] + def unapply(tree: Tree): Option[List[CaseDef]] } val SyntacticMatch: SyntacticMatchExtractor diff --git a/src/reflect/scala/reflect/internal/ReificationSupport.scala b/src/reflect/scala/reflect/internal/ReificationSupport.scala index 9a130337b4..f9f93fbff0 100644 --- a/src/reflect/scala/reflect/internal/ReificationSupport.scala +++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala @@ -6,7 +6,7 @@ import Flags._ import util._ trait ReificationSupport { self: SymbolTable => - import definitions.{TupleClass, FunctionClass, ScalaPackage, UnitClass} + import definitions._ import internal._ class ReificationSupportImpl extends ReificationSupportApi { @@ -852,9 +852,25 @@ trait ReificationSupport { self: SymbolTable => object SyntacticPartialFunction extends SyntacticPartialFunctionExtractor { def apply(cases: List[Tree]): Match = Match(EmptyTree, mkCases(cases)) - def unapply(tree: Match): Option[List[CaseDef]] = tree match { + def unapply(tree: Tree): Option[List[CaseDef]] = tree match { case Match(EmptyTree, cases) => Some(cases) - case _ => None + case Typed( + Block( + List(ClassDef(clsMods, tpnme.ANON_FUN_NAME, Nil, Template( + List(abspf: TypeTree, ser: TypeTree), noSelfType, List( + DefDef(_, nme.CONSTRUCTOR, _, _, _, _), + DefDef(_, nme.applyOrElse, _, _, _, + Match(_, cases :+ + CaseDef(Bind(nme.DEFAULT_CASE, Ident(nme.WILDCARD)), _, _))), + DefDef(_, nme.isDefinedAt, _, _, _, _))))), + Apply(Select(New(Ident(tpnme.ANON_FUN_NAME)), termNames.CONSTRUCTOR), List())), + pf: TypeTree) + if pf.tpe != null && pf.tpe.typeSymbol.eq(PartialFunctionClass) && + abspf.tpe != null && abspf.tpe.typeSymbol.eq(AbstractPartialFunctionClass) && + ser.tpe != null && ser.tpe.typeSymbol.eq(SerializableClass) && + clsMods.hasFlag(FINAL) && clsMods.hasFlag(SYNTHETIC) => + Some(cases) + case _ => None } } diff --git a/test/files/pos/t8411/Macros_1.scala b/test/files/pos/t8411/Macros_1.scala new file mode 100644 index 0000000000..c5319c559c --- /dev/null +++ b/test/files/pos/t8411/Macros_1.scala @@ -0,0 +1,10 @@ +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context + +object Macros { + def defaultZeroCase(pf: PartialFunction[Int, Int]): PartialFunction[Int, Int] = macro impl + def impl(c: Context)(pf: c.Tree) = { import c.universe._ + val q"{ case ..$cases }" = pf + q"{ case ..$cases case _ => 0 }" + } +} diff --git a/test/files/pos/t8411/Test_2.scala b/test/files/pos/t8411/Test_2.scala new file mode 100644 index 0000000000..a0ad30f0f5 --- /dev/null +++ b/test/files/pos/t8411/Test_2.scala @@ -0,0 +1,4 @@ +object Test extends App { + val pf = Macros.defaultZeroCase { case 1 => 2 } + assert(pf(2) == 0) +} diff --git a/test/files/scalacheck/quasiquotes/TypecheckedProps.scala b/test/files/scalacheck/quasiquotes/TypecheckedProps.scala index 7c4cb0306e..fb2eb69321 100644 --- a/test/files/scalacheck/quasiquotes/TypecheckedProps.scala +++ b/test/files/scalacheck/quasiquotes/TypecheckedProps.scala @@ -152,4 +152,9 @@ object TypecheckedProps extends QuasiquoteProperties("typechecked") { assert(name == defName) assert(rhs ≈ defRhs) } + + property("partial function") = test { + val q"{ case ..$cases }: $ascr" = typecheck(q"{ case 1 => () }: PartialFunction[Int, Unit]") + assert(cases ≈ q"{ case 1 => () }".cases) + } } -- cgit v1.2.3