Skip to content

Commit 5c87d7d

Browse files
committed
Fix #2
1 parent 1584de8 commit 5c87d7d

File tree

3 files changed

+183
-1
lines changed

3 files changed

+183
-1
lines changed

src/async/library/scala/async/ExprBuilder.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,12 +267,16 @@ class ExprBuilder[C <: Context with Singleton](val c: C) extends AsyncUtils {
267267
mkHandlerTree(state, Block((stats :+ mkOnCompleteStateTree(nextState)): _*))
268268
}
269269

270-
//TODO: complete for other primitive types, how to handle value classes?
271270
override def varDefForResult: Option[c.Tree] = {
272271
val rhs =
273272
if (resultType <:< definitions.IntTpe) Literal(Constant(0))
274273
else if (resultType <:< definitions.LongTpe) Literal(Constant(0L))
275274
else if (resultType <:< definitions.BooleanTpe) Literal(Constant(false))
275+
else if (resultType <:< definitions.FloatTpe) Literal(Constant(0.0f))
276+
else if (resultType <:< definitions.DoubleTpe) Literal(Constant(0.0d))
277+
else if (resultType <:< definitions.CharTpe) Literal(Constant(0.toChar))
278+
else if (resultType <:< definitions.ShortTpe) Literal(Constant(0.toShort))
279+
else if (resultType <:< definitions.ByteTpe) Literal(Constant(0.toByte))
276280
else Literal(Constant(null))
277281
Some(
278282
ValDef(Modifiers(Flag.MUTABLE), resultName, TypeTree(resultType), rhs)
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import language.reflectiveCalls
2+
import language.postfixOps
3+
import language.implicitConversions
4+
5+
import scala.reflect.{ ClassTag, classTag }
6+
7+
import scala.collection.mutable
8+
import scala.concurrent.{ Future, Awaitable, CanAwait }
9+
import java.util.concurrent.{ TimeoutException, CountDownLatch, TimeUnit }
10+
import scala.concurrent.duration.Duration
11+
12+
13+
14+
trait Output {
15+
val buffer = new StringBuilder
16+
17+
def bufferPrintln(a: Any): Unit = buffer.synchronized {
18+
buffer.append(a.toString + "\n")
19+
}
20+
}
21+
22+
23+
trait MinimalScalaTest extends Output {
24+
25+
val throwables = mutable.ArrayBuffer[Throwable]()
26+
27+
def check() {
28+
if (throwables.nonEmpty) println(buffer.toString)
29+
}
30+
31+
implicit def stringops(s: String) = new {
32+
33+
def should[U](snippets: =>U): U = {
34+
bufferPrintln(s + " should:")
35+
snippets
36+
}
37+
38+
def in[U](snippet: =>U): Unit = {
39+
try {
40+
bufferPrintln("- " + s)
41+
snippet
42+
bufferPrintln("[OK] Test passed.")
43+
} catch {
44+
case e: Throwable =>
45+
bufferPrintln("[FAILED] " + e)
46+
bufferPrintln(e.getStackTrace().mkString("\n"))
47+
throwables += e
48+
}
49+
}
50+
51+
}
52+
53+
implicit def objectops(obj: Any) = new {
54+
55+
def mustBe(other: Any) = assert(obj == other, obj + " is not " + other)
56+
def mustEqual(other: Any) = mustBe(other)
57+
58+
}
59+
60+
def intercept[T <: Throwable: ClassTag](body: =>Any): T = {
61+
try {
62+
body
63+
throw new Exception("Exception of type %s was not thrown".format(classTag[T]))
64+
} catch {
65+
case t: Throwable =>
66+
if (classTag[T].runtimeClass != t.getClass) throw t
67+
else t.asInstanceOf[T]
68+
}
69+
}
70+
71+
def checkType[T: ClassTag, S](in: Future[T], refclasstag: ClassTag[S]): Boolean = classTag[T] == refclasstag
72+
}
73+
74+
75+
object TestLatch {
76+
val DefaultTimeout = Duration(5, TimeUnit.SECONDS)
77+
78+
def apply(count: Int = 1) = new TestLatch(count)
79+
}
80+
81+
82+
class TestLatch(count: Int = 1) extends Awaitable[Unit] {
83+
private var latch = new CountDownLatch(count)
84+
85+
def countDown() = latch.countDown()
86+
def isOpen: Boolean = latch.getCount == 0
87+
def open() = while (!isOpen) countDown()
88+
def reset() = latch = new CountDownLatch(count)
89+
90+
@throws(classOf[TimeoutException])
91+
def ready(atMost: Duration)(implicit permit: CanAwait) = {
92+
val opened = latch.await(atMost.toNanos, TimeUnit.NANOSECONDS)
93+
if (!opened) throw new TimeoutException("Timeout of %s." format (atMost.toString))
94+
this
95+
}
96+
97+
@throws(classOf[Exception])
98+
def result(atMost: Duration)(implicit permit: CanAwait): Unit = {
99+
ready(atMost)
100+
}
101+
102+
}

test/files/run/await0/await0.scala

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* Copyright (C) 2012 Typesafe Inc. <http://www.typesafe.com>
3+
*/
4+
5+
import language.{ reflectiveCalls, postfixOps }
6+
7+
import scala.concurrent.{ Future, ExecutionContext, future, Await }
8+
import scala.concurrent.duration._
9+
import scala.async.Async.{ async, await }
10+
11+
object Test extends App {
12+
13+
Await0Spec.check()
14+
15+
}
16+
17+
class Await0Class {
18+
import ExecutionContext.Implicits.global
19+
20+
def m1(x: Double): Future[Double] = future {
21+
Thread.sleep(200)
22+
x + 2.0
23+
}
24+
25+
def m2(x: Float): Future[Float] = future {
26+
Thread.sleep(200)
27+
x + 2.0f
28+
}
29+
30+
def m3(x: Char): Future[Char] = future {
31+
Thread.sleep(200)
32+
(x.toInt + 2).toChar
33+
}
34+
35+
def m4(x: Short): Future[Short] = future {
36+
Thread.sleep(200)
37+
(x + 2).toShort
38+
}
39+
40+
def m5(x: Byte): Future[Byte] = future {
41+
Thread.sleep(200)
42+
(x + 2).toByte
43+
}
44+
45+
def m0(y: Int): Future[Double] = async {
46+
val f1 = m1(y.toDouble)
47+
val x1: Double = await(f1)
48+
49+
val f2 = m2(y.toFloat)
50+
val x2: Float = await(f2)
51+
52+
val f3 = m3(y.toChar)
53+
val x3: Char = await(f3)
54+
55+
val f4 = m4(y.toShort)
56+
val x4: Short = await(f4)
57+
58+
val f5 = m5(y.toByte)
59+
val x5: Byte = await(f5)
60+
61+
x1 + x2 + 2.0
62+
}
63+
}
64+
65+
object Await0Spec extends MinimalScalaTest {
66+
67+
"An async method" should {
68+
"support a simple await" in {
69+
val o = new Await0Class
70+
val fut = o.m0(10)
71+
val res = Await.result(fut, 10 seconds)
72+
res mustBe(26.0)
73+
}
74+
}
75+
76+
}

0 commit comments

Comments
 (0)