OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 // Test that hidden native exception classes can be marked as existing. | |
6 // | |
7 // To infer which native hidden types exist, we need | |
8 // (1) return types of native methods and getters | |
9 // (2) argument types of callbacks | |
10 // (3) exceptions thrown by the operation. | |
11 // | |
12 // (1) and (2) can be achieved by having nicely typed native methods, but there | |
13 // is no place in the Dart language to communicate (3). So we use the following | |
14 // fake body technique. | |
15 | |
16 | |
17 // The exception type. | |
18 class E native "*E" { | |
19 E._used() native; // Bogus native constructor, called only from fake body. | |
20 | |
21 final int code; | |
22 } | |
23 | |
24 // Type with exception-throwing methods. | |
25 class A native "*A" { | |
26 op(int x) native { | |
27 // Fake body calls constructor to mark the exception class (E) as used. | |
28 throw new E._used(); | |
29 } | |
30 } | |
31 | |
32 // This class is here just so that a dynamic context is polymorphic. | |
33 class B { | |
34 int get code() => 666; | |
35 op(String x) => 123; | |
36 } | |
37 | |
38 makeA() native; | |
39 | |
40 void setup1() native """ | |
41 // Ensure we are not relying on global names 'A' and 'E'. | |
42 A = null; | |
43 E = null; | |
44 """; | |
45 | |
46 void setup2() native """ | |
47 // This code is all inside 'setup2' and so not accesible from the global scope. | |
48 function E(x){ this.code = x; } | |
49 | |
50 function A(){} | |
51 A.prototype.op = function (x) { | |
52 if (x & 1) throw new E(100); | |
53 return x / 2; | |
54 }; | |
55 makeA = function(){return new A}; | |
56 """; | |
57 | |
58 int inscrutable(int x) => x == 0 ? 0 : x | inscrutable(x & (x - 1)); | |
59 | |
60 main() { | |
61 setup1(); | |
62 setup2(); | |
63 | |
64 var things = [makeA(), new B()]; | |
65 var a = things[inscrutable(0)]; | |
66 var b = things[inscrutable(1)]; | |
67 | |
68 Expect.equals(25, a.op(50)); | |
69 Expect.equals(123, b.op('hello')); | |
70 Expect.equals(666, b.code); | |
71 | |
72 bool threw = false; | |
73 try { | |
74 var x = a.op(51); | |
75 } catch (var e) { | |
76 threw = true; | |
77 Expect.equals(100, e.code); | |
78 Expect.isTrue(e is E); | |
79 } | |
80 Expect.isTrue(threw); | |
81 | |
82 // Again, but with statically typed receivers. | |
83 A aa = a; | |
84 B bb = b; | |
85 | |
86 Expect.equals(25, aa.op(50)); | |
87 Expect.equals(123, bb.op('hello')); | |
88 Expect.equals(666, bb.code); | |
89 | |
90 threw = false; | |
91 try { | |
92 var x = aa.op(51); | |
93 } catch (E e) { | |
94 threw = true; | |
95 Expect.equals(100, e.code); | |
96 Expect.isTrue(e is E); | |
97 } | |
98 Expect.isTrue(threw); | |
99 } | |
OLD | NEW |