| Index: test/codegen/lib/mirrors/proxy_type_test.dart | 
| diff --git a/test/codegen/lib/mirrors/proxy_type_test.dart b/test/codegen/lib/mirrors/proxy_type_test.dart | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..c64c86236988b29baad56d0b3644b181af292448 | 
| --- /dev/null | 
| +++ b/test/codegen/lib/mirrors/proxy_type_test.dart | 
| @@ -0,0 +1,82 @@ | 
| +// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file | 
| +// for details. All rights reserved. Use of this source code is governed by a | 
| +// BSD-style license that can be found in the LICENSE file. | 
| + | 
| +library test.proxy_type; | 
| + | 
| +import 'dart:mirrors'; | 
| +import 'package:expect/expect.dart'; | 
| + | 
| +// This test is much longer that is strictly necessary to test | 
| +// InstanceMirror.type in the face of a reflectee overriding runtimeType, but | 
| +// shows a case where one might have legimate reason to override runtimeType. | 
| +// See section 2.2 in Mark Miller's Robust Composition: Towards a Unfied | 
| +// Approach to Access Control and Concurrency Control. | 
| + | 
| +class Alice { | 
| +  Bob bob = new Bob(); | 
| +  Carol carol = new Carol(); | 
| +  sayFooUnattenuated() { | 
| +    bob.foo(carol); | 
| +  } | 
| +  sayFooAttenuated() { | 
| +    bool enabled = true; | 
| +    bool gate() => enabled; | 
| +    bob.foo(new CarolCaretaker(carol, gate)); | 
| +    enabled = false;  // Attenuate a capability | 
| +  } | 
| +  sayBar() { | 
| +    bob.bar(); | 
| +  } | 
| +} | 
| + | 
| +class Bob { | 
| +  Carol savedCarol; | 
| +  foo(Carol carol) { | 
| +    savedCarol = carol;  // Store a capability | 
| +    carol.foo(); | 
| +  } | 
| +  bar() { | 
| +    savedCarol.foo(); | 
| +  } | 
| +} | 
| + | 
| +class Carol { | 
| +  foo() => 'c'; | 
| +} | 
| + | 
| +typedef bool Gate(); | 
| + | 
| +class CarolCaretaker implements Carol { | 
| +  final Carol _carol; | 
| +  final Gate _gate; | 
| +  CarolCaretaker(this._carol, this._gate); | 
| + | 
| +  foo() { | 
| +    if (!_gate()) throw new NoSuchMethodError(this, #foo, [], {}); | 
| +    return _carol.foo(); | 
| +  } | 
| + | 
| +  Type get runtimeType => Carol; | 
| +} | 
| + | 
| +main() { | 
| +  Alice alice1 = new Alice(); | 
| +  alice1.sayFooUnattenuated(); | 
| +  alice1.sayBar();  // Bob still has authority to use Carol | 
| + | 
| +  Alice alice2 = new Alice(); | 
| +  alice2.sayFooAttenuated(); | 
| +  Expect.throws(() => alice2.sayBar(), | 
| +                (e) => e is NoSuchMethodError, | 
| +                'Authority should have been attenuated'); | 
| + | 
| +  // At the base level, a caretaker for a Carol masquerades as a Carol. | 
| +  CarolCaretaker caretaker = new CarolCaretaker(new Carol(), ()=>true); | 
| +  Expect.isTrue(caretaker is Carol); | 
| +  Expect.equals(Carol, caretaker.runtimeType); | 
| + | 
| +  // At the reflective level, the caretaker is distinguishable. | 
| +  Expect.equals(reflectClass(CarolCaretaker), | 
| +                reflect(caretaker).type); | 
| +} | 
|  |