From 880a614b4125fffc010907699572da8f9033b51d Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Mon, 24 Nov 2014 09:10:18 +0200 Subject: [PATCH 1/2] created branch and test template for checking work with generic types in futures inside async blocks. --- .../scala/async/internal/AsyncBase.scala | 1 + .../scala/async/internal/TransformUtils.scala | 6 ++++ .../scala/async/run/gen0/AsyncSpec.scala | 32 +++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 src/test/scala/scala/async/run/gen0/AsyncSpec.scala diff --git a/src/main/scala/scala/async/internal/AsyncBase.scala b/src/main/scala/scala/async/internal/AsyncBase.scala index 7464c42d..f08cf290 100644 --- a/src/main/scala/scala/async/internal/AsyncBase.scala +++ b/src/main/scala/scala/async/internal/AsyncBase.scala @@ -43,6 +43,7 @@ abstract class AsyncBase { (body: c.Expr[T]) (execContext: c.Expr[futureSystem.ExecContext]): c.Expr[futureSystem.Fut[T]] = { import c.universe._, c.internal._, decorators._ + System.err.println("async receive:"+body) val asyncMacro = AsyncMacro(c, self) val code = asyncMacro.asyncTransform[T](body.tree, execContext.tree)(c.weakTypeTag[T]) diff --git a/src/main/scala/scala/async/internal/TransformUtils.scala b/src/main/scala/scala/async/internal/TransformUtils.scala index 9ae48ed2..7109e8ea 100644 --- a/src/main/scala/scala/async/internal/TransformUtils.scala +++ b/src/main/scala/scala/async/internal/TransformUtils.scala @@ -120,6 +120,12 @@ private[async] trait TransformUtils { private def isByName(fun: Tree): ((Int, Int) => Boolean) = { if (Boolean_ShortCircuits contains fun.symbol) (i, j) => true else { + if (fun eq null) { + System.err.println(s"fun == null") + } + if (fun.tpe eq null) { + System.err.println(s"fun.tpe == null, fun=${fun}") + } val paramss = fun.tpe.paramss val byNamess = paramss.map(_.map(_.asTerm.isByNameParam)) (i, j) => util.Try(byNamess(i)(j)).getOrElse(false) diff --git a/src/test/scala/scala/async/run/gen0/AsyncSpec.scala b/src/test/scala/scala/async/run/gen0/AsyncSpec.scala new file mode 100644 index 00000000..c79031ee --- /dev/null +++ b/src/test/scala/scala/async/run/gen0/AsyncSpec.scala @@ -0,0 +1,32 @@ +package scala.async +package run +package gen0 + +import language.{reflectiveCalls, postfixOps} +import scala.concurrent.{Future, ExecutionContext, future, Await} +import scala.concurrent.duration._ +import scala.async.Async.{async, await} +import org.junit.Test + + +class Test1Class { + + import ExecutionContext.Implicits.global + +} + + +class AsyncSpec { + + @Test + def `generic`() { + /* + val o = new Test1Class + val fut = o.m2(10) + val res = Await.result(fut, 2 seconds) + res mustBe (14) + */ + 1 mustBe (1) + } + +} From 41fad2783b2ce56bd83feff7ff1443cfa79663e6 Mon Sep 17 00:00:00 2001 From: Ruslan Shevchenko Date: Mon, 24 Nov 2014 09:50:19 +0200 Subject: [PATCH 2/2] fixed compilation error when async use future with type parameters and added appropriative test. --- .../scala/async/internal/AsyncBase.scala | 1 - .../scala/async/internal/TransformUtils.scala | 8 +---- .../scala/async/run/gen0/AsyncSpec.scala | 32 +++++++++++++------ 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/main/scala/scala/async/internal/AsyncBase.scala b/src/main/scala/scala/async/internal/AsyncBase.scala index f08cf290..7464c42d 100644 --- a/src/main/scala/scala/async/internal/AsyncBase.scala +++ b/src/main/scala/scala/async/internal/AsyncBase.scala @@ -43,7 +43,6 @@ abstract class AsyncBase { (body: c.Expr[T]) (execContext: c.Expr[futureSystem.ExecContext]): c.Expr[futureSystem.Fut[T]] = { import c.universe._, c.internal._, decorators._ - System.err.println("async receive:"+body) val asyncMacro = AsyncMacro(c, self) val code = asyncMacro.asyncTransform[T](body.tree, execContext.tree)(c.weakTypeTag[T]) diff --git a/src/main/scala/scala/async/internal/TransformUtils.scala b/src/main/scala/scala/async/internal/TransformUtils.scala index 7109e8ea..0c12f95c 100644 --- a/src/main/scala/scala/async/internal/TransformUtils.scala +++ b/src/main/scala/scala/async/internal/TransformUtils.scala @@ -120,12 +120,6 @@ private[async] trait TransformUtils { private def isByName(fun: Tree): ((Int, Int) => Boolean) = { if (Boolean_ShortCircuits contains fun.symbol) (i, j) => true else { - if (fun eq null) { - System.err.println(s"fun == null") - } - if (fun.tpe eq null) { - System.err.println(s"fun.tpe == null, fun=${fun}") - } val paramss = fun.tpe.paramss val byNamess = paramss.map(_.map(_.asTerm.isByNameParam)) (i, j) => util.Try(byNamess(i)(j)).getOrElse(false) @@ -337,7 +331,7 @@ private[async] trait TransformUtils { (cls.info.decls.find(sym => sym.isMethod && sym.asTerm.isParamAccessor) getOrElse NoSymbol) def mkZero(tp: Type): Tree = { - if (tp.typeSymbol.asClass.isDerivedValueClass) { + if (tp.typeSymbol.isClass && tp.typeSymbol.asClass.isDerivedValueClass) { val argZero = mkZero(derivedValueClassUnbox(tp.typeSymbol).infoIn(tp).resultType) val baseType = tp.baseType(tp.typeSymbol) // use base type here to dealias / strip phantom "tagged types" etc. diff --git a/src/test/scala/scala/async/run/gen0/AsyncSpec.scala b/src/test/scala/scala/async/run/gen0/AsyncSpec.scala index c79031ee..4335f91b 100644 --- a/src/test/scala/scala/async/run/gen0/AsyncSpec.scala +++ b/src/test/scala/scala/async/run/gen0/AsyncSpec.scala @@ -8,25 +8,39 @@ import scala.concurrent.duration._ import scala.async.Async.{async, await} import org.junit.Test +class TestS[A](a:A) +{ -class Test1Class { + def awrite(v:A): Future[A] = + Future successful v + + def aread: Future[A] = + Future successful a + +} + +class Test1GenAsyncOp[A] { import ExecutionContext.Implicits.global + def testfun[A](a1:A,a2:A): Future[Boolean] = async { + val ts = new TestS(a1) + val s1 = await(ts.awrite(a2)) + val s2 = await(ts.aread) + s1 == s2 + } + } class AsyncSpec { @Test - def `generic`() { - /* - val o = new Test1Class - val fut = o.m2(10) - val res = Await.result(fut, 2 seconds) - res mustBe (14) - */ - 1 mustBe (1) + def `operation with futures generic`() { + val op = new Test1GenAsyncOp[Int] + val f = op.testfun(1,2) + val res = Await.result(f, 2 seconds) + res mustBe (false) } }