1/* 2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16function assert_ccexc(f: () => void) { 17 try { 18 f(); 19 } catch (e) { 20 assert(e instanceof ClassCastError); 21 return; 22 } 23 assert false : "exception expected"; 24} 25 26class A { } 27class B { } 28class C { } 29class X<T> { } 30 31function erase<T>(x: Object | null | undefined): T { return x as T; } 32 33function test_substitution() { 34 assert_ccexc(() => { erase<Object>(null); }) 35 assert_ccexc(() => { erase<Object>(undefined); }) 36 assert_ccexc(() => { erase<A>(null); }) 37 assert_ccexc(() => { erase<A>(undefined); }) 38 39 assert_ccexc(() => { erase<Object | undefined>(null); }) 40 assert_ccexc(() => { erase<Object | null>(undefined); }) 41 assert_ccexc(() => { erase<A | undefined>(null); }) 42 assert_ccexc(() => { erase<A | null>(undefined); }) 43 44 assert_ccexc(() => { erase<A>(undefined); }) 45 assert_ccexc(() => { erase<A>(new Object()); }) 46 assert_ccexc(() => { erase<A>(new B()); }) 47 48 assert_ccexc(() => { erase<A | B>(undefined); }) 49 assert_ccexc(() => { erase<A | B>(new Object()); }) 50 assert_ccexc(() => { erase<A | B>(new C()); }) 51 52 assert_ccexc(() => { erase<A[]>(new B[0]); }) 53} 54 55class Erased<T> { 56 constructor(x: Object | null | undefined) { this.t = x as T; } 57 t: T; 58} 59 60function test_substitution_memberexpr() { 61 assert_ccexc(() => { new Erased<Object>(null).t; }) 62 assert_ccexc(() => { new Erased<Object>(undefined).t; }) 63 assert_ccexc(() => { new Erased<A>(null).t; }) 64 assert_ccexc(() => { new Erased<A>(undefined).t; }) 65 66 assert_ccexc(() => { new Erased<Object | undefined>(null).t; }) 67 assert_ccexc(() => { new Erased<Object | null>(undefined).t; }) 68 assert_ccexc(() => { new Erased<A | undefined>(null).t; }) 69 assert_ccexc(() => { new Erased<A | null>(undefined).t; }) 70 71 assert_ccexc(() => { new Erased<A>(undefined).t; }) 72 assert_ccexc(() => { new Erased<A>(new Object()).t; }) 73 assert_ccexc(() => { new Erased<A>(new B()).t; }) 74 75 assert_ccexc(() => { new Erased<A | B>(undefined).t; }) 76 assert_ccexc(() => { new Erased<A | B>(new Object()).t; }) 77 assert_ccexc(() => { new Erased<A | B>(new C()).t; }) 78 79 assert_ccexc(() => { new Erased<A[]>(new B[0]).t; }) 80} 81 82function cast_to_tparam<T extends A | B | null>(x: Object | null | undefined) { x as T; } 83 84function test_constraint() { 85 assert_ccexc(() => { cast_to_tparam<A>(undefined); }) 86 assert_ccexc(() => { cast_to_tparam<A>(new Object()); }) 87 assert_ccexc(() => { cast_to_tparam<A>(new C()); }) 88} 89 90function to_basetype<T>(x: Object | null | undefined) { return x as X<T>; } 91 92function test_basetype() { 93 assert_ccexc(() => { to_basetype<A>(null); }) 94 assert_ccexc(() => { to_basetype<A>(undefined); }) 95 assert_ccexc(() => { to_basetype<A>(new Object()); }) 96 assert_ccexc(() => { to_basetype<A>(new C()); }) 97} 98 99function main() { 100 test_substitution(); 101 test_substitution_memberexpr(); 102 test_constraint(); 103 test_basetype(); 104} 105