OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import "package:expect/expect.dart"; | 5 import "package:expect/expect.dart"; |
6 | 6 |
7 // Test to see if resolving a hidden native class's method interferes with | 7 // Test to see if resolving a hidden native class's method interferes with |
8 // subsequent resolving the subclass's method. This might happen if the | 8 // subsequent resolving the subclass's method. This might happen if the |
9 // superclass caches the method in the prototype, so shadowing the dispatcher | 9 // superclass caches the method in the prototype, so shadowing the dispatcher |
10 // stored on Object.prototype. | 10 // stored on Object.prototype. |
11 | 11 |
12 class A native "A" { | 12 class A native "A" { |
13 foo([a=100]) native; | 13 foo() => 'A.foo ${bar()}'; |
| 14 bar() => 'A.bar'; |
14 } | 15 } |
15 | 16 |
16 class B extends A native "B" { | 17 class B extends A native "B" { |
| 18 bar() => 'B.bar'; |
17 } | 19 } |
18 | 20 |
19 class C extends B native "C" { | 21 class C extends B native "C" { |
20 foo([z=300]) native; | 22 foo() => 'C.foo; super.foo = ${super.foo()}'; |
| 23 bar() => 'C.bar'; |
21 } | 24 } |
22 | 25 |
23 class D extends C native "D" { | 26 class D extends C native "D" { |
| 27 bar() => 'D.bar'; |
24 } | 28 } |
25 | 29 |
26 makeA() native; | 30 makeA() native; |
27 makeB() native; | 31 makeB() native; |
28 makeC() native; | 32 makeC() native; |
29 makeD() native; | 33 makeD() native; |
30 | 34 |
31 void setup() native """ | 35 void setup() native """ |
32 // This code is all inside 'setup' and so not accesible from the global scope. | 36 // This code is all inside 'setup' and so not accesible from the global scope. |
33 function inherits(child, parent) { | 37 function inherits(child, parent) { |
34 if (child.prototype.__proto__) { | 38 if (child.prototype.__proto__) { |
35 child.prototype.__proto__ = parent.prototype; | 39 child.prototype.__proto__ = parent.prototype; |
36 } else { | 40 } else { |
37 function tmp() {}; | 41 function tmp() {}; |
38 tmp.prototype = parent.prototype; | 42 tmp.prototype = parent.prototype; |
39 child.prototype = new tmp(); | 43 child.prototype = new tmp(); |
40 child.prototype.constructor = child; | 44 child.prototype.constructor = child; |
41 } | 45 } |
42 } | 46 } |
43 | 47 |
44 function A(){} | 48 function A(){} |
45 function B(){} | 49 function B(){} |
46 inherits(B, A); | 50 inherits(B, A); |
47 function C(){} | 51 function C(){} |
48 inherits(C, B); | 52 inherits(C, B); |
49 function D(){} | 53 function D(){} |
50 inherits(D, C); | 54 inherits(D, C); |
51 | 55 |
52 A.prototype.foo = function(a){return 'A.foo(' + a + ')';} | |
53 C.prototype.foo = function(z){return 'C.foo(' + z + ')';} | |
54 | |
55 makeA = function(){return new A}; | 56 makeA = function(){return new A}; |
56 makeB = function(){return new B}; | 57 makeB = function(){return new B}; |
57 makeC = function(){return new C}; | 58 makeC = function(){return new C}; |
58 makeD = function(){return new D}; | 59 makeD = function(){return new D}; |
59 """; | 60 """; |
60 | 61 |
61 | 62 |
62 main() { | 63 main() { |
63 setup(); | 64 setup(); |
64 | 65 |
65 var a = makeA(); | 66 var a = makeA(); |
66 var b = makeB(); | 67 var b = makeB(); |
67 var c = makeC(); | 68 var c = makeC(); |
68 var d = makeD(); | 69 var d = makeD(); |
69 | 70 |
70 Expect.equals('A.foo(100)', b.foo()); | 71 Expect.equals('A.foo A.bar', a.foo()); |
71 Expect.equals('C.foo(300)', d.foo()); | 72 Expect.equals('A.foo B.bar', b.foo()); |
72 // If the above line fails with C.foo(100) then the dispatch to fill in the | 73 Expect.equals('C.foo; super.foo = A.foo C.bar', c.foo()); |
73 // default got the wrong one, followed by a second dispatch that resolved to | 74 Expect.equals('C.foo; super.foo = A.foo D.bar', d.foo()); |
74 // the correct native method. | |
75 | |
76 Expect.equals('A.foo(1)', a.foo(1)); | |
77 Expect.equals('A.foo(2)', b.foo(2)); | |
78 Expect.equals('C.foo(3)', c.foo(3)); | |
79 Expect.equals('C.foo(4)', d.foo(4)); | |
80 } | 75 } |
OLD | NEW |