// Copyright (c) 2011, 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. import 'native_testing.dart'; // Test that hidden native exception classes can be marked as existing. // // To infer which native hidden types exist, we need // (1) return types of native methods and getters // (2) argument types of callbacks // (3) exceptions thrown by the operation. // // (1) and (2) can be achieved by having nicely typed native methods, but there // is no place in the Dart language to communicate (3). So we use the following // fake body technique. // The exception type. @Native("E") class E { E._used() native; // Bogus native constructor, called only from fake body. int get code native; } // Type with exception-throwing methods. @Native("A") class A { // Exception class E is created. @Creates("E") @Returns('int') op(int x) native; } // This class is here just so that a dynamic context is polymorphic. class B { int get code => 666; op(String x) => 123; } makeA() native; void setup1() { JS('', r""" (function(){ // Ensure we are not relying on global names 'A' and 'E'. A = null; E = null; })()"""); applyTestExtensions(['E', 'A']); } void setup2() { JS('', r""" (function(){ // This code is all inside 'setup2' and so not accessible from the global scope. function E(x){ this.code = x; } function A(){} A.prototype.op = function (x) { if (x & 1) throw new E(100); return x / 2; }; self.makeA = function(){return new A()}; self.nativeConstructor(E); self.nativeConstructor(A); })()"""); } int inscrutable(int x) => x == 0 ? 0 : x | inscrutable(x & (x - 1)); main() { nativeTesting(); setup1(); setup2(); var things = [makeA(), new B()]; var a = things[inscrutable(0)]; var b = things[inscrutable(1)]; Expect.equals(25, a.op(50)); Expect.equals(123, b.op('hello')); Expect.equals(666, b.code); bool threw = false; try { var x = a.op(51); } catch (e) { threw = true; Expect.isTrue(e is E); Expect.equals(100, (e as E).code); } Expect.isTrue(threw); // Again, but with statically typed receivers. A aa = a; B bb = b; Expect.equals(25, aa.op(50)); Expect.equals(123, bb.op('hello')); Expect.equals(666, bb.code); threw = false; try { var x = aa.op(51); } on E catch (e) { threw = true; Expect.equals(100, e.code); Expect.isTrue(e is E); } Expect.isTrue(threw); }