343682c4ac
An earlier cl fixed the test in web_2, this is just backporting that fix. earlier cl: https://dart-review.googlesource.com/c/sdk/+/200020 Change-Id: Id34bfbc77b5d7774f0e464170c65fd84fa5e9d17 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/203827 Reviewed-by: Sigmund Cherem <sigmund@google.com> Commit-Queue: Joshua Litt <joshualitt@google.com>
118 lines
2.6 KiB
Dart
118 lines
2.6 KiB
Dart
// 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'.
|
|
self.A = null;
|
|
self.E = null;
|
|
})()""");
|
|
applyTestExtensions(['E', 'A']);
|
|
}
|
|
|
|
void setup2() {
|
|
JS('', r"""
|
|
(function(){
|
|
// Confirm A and B are null.
|
|
console.assert(self.A == null);
|
|
console.assert(self.B == null);
|
|
|
|
// 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);
|
|
}
|