aboutsummaryrefslogtreecommitdiff
path: root/tests/run/finally.scala
blob: 64324abc4b61a1a8e309477b22423a061a0c3779 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
object Test extends dotty.runtime.LegacyApp {


  // test that finally is not covered by any exception handlers.
  def throwCatchFinally: Unit = {
    try {
      bar
    } catch {
      case e: Throwable => println(e)
    }
  }

  // test that finally is not covered by any exception handlers.
  def bar: Unit = {
    try {
      println("hi")
    }
    catch {
      case e: Throwable => println("SHOULD NOT GET HERE")
    }
    finally {
      println("In Finally")
      throw new RuntimeException("ouch")
    }
  }

  // return in catch (finally is executed)
  def retCatch: Unit = {
    try {
      throw new Exception
    } catch {
      case e: Throwable =>
        println(e);
        return
    } finally println("in finally")
  }

  // throw in catch (finally is executed, exception propagated)
  def throwCatch: Unit = {
    try {
      throw new Exception
    } catch {
      case e: Throwable =>
        println(e);
        throw e
    } finally println("in finally")
  }

  // return inside body (finally is executed)
  def retBody: Unit = {
    try {
      return
    } catch {
      case e: Throwable =>
        println(e);
        throw e
    } finally println("in finally")
  }

  // throw inside body (finally and catch are executed)
  def throwBody: Unit = {
    try {
      throw new Exception
    } catch {
      case e: Throwable =>
        println(e);
    } finally println("in finally")
  }

  // return inside finally (each finally is executed once)
  def retFinally: Unit = {
    try {
      try println("body")
      finally {
        println("in finally 1")
        return
      }
    } finally println("in finally 2")
  }


  // throw inside finally (finally is executed once, exception is propagated)
  def throwFinally: Unit = {
    try {
      try println("body")
      finally {
        println("in finally")
        throw new Exception
      }
    } catch {
      case e: Throwable => println(e)
    }
  }

  // nested finallies with return value
  def nestedFinalies: Int =
    try {
      try {
        return 10
      } finally {
        try { () } catch { case _: Throwable => () }
        println("in finally 1")
      }
    } finally {
      println("in finally 2")
    }

  def test[A](m: => A, name: String): Unit = {
    println("Running %s".format(name))
    try {
      m
    } catch {
      case e: Throwable => println("COUGHT: " + e)
    }
    println("-" * 40)
  }

  test(throwCatchFinally, "throwCatchFinally")
  test(retCatch, "retCatch")
  test(throwCatch, "throwCatch")
  test(retBody, "retBody")
  test(throwBody, "throwBody")
  test(retFinally, "retFinally")
  test(throwFinally, "throwFinally")
  test(nestedFinalies, "nestedFinalies")
}