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 assert false : "exception expected"; 20 } catch (e) { 21 assert(e instanceof ClassCastError); 22 } 23} 24 25class A { } 26class B { } 27class C { } 28class X<T> { } 29 30function erase<T>(x: Object | null | undefined): T { return x as T; } 31 32function test_substitution() { 33 assert_ccexc(() => { erase<Object>(null); }) 34 assert_ccexc(() => { erase<Object>(undefined); }) 35 assert_ccexc(() => { erase<A>(null); }) 36 assert_ccexc(() => { erase<A>(undefined); }) 37 38 assert_ccexc(() => { erase<Object | undefined>(null); }) 39 assert_ccexc(() => { erase<Object | null>(undefined); }) 40 assert_ccexc(() => { erase<A | undefined>(null); }) 41 assert_ccexc(() => { erase<A | null>(undefined); }) 42 43 assert_ccexc(() => { erase<A>(undefined); }) 44 assert_ccexc(() => { erase<A>(new Object()); }) 45 assert_ccexc(() => { erase<A>(new B()); }) 46 47 assert_ccexc(() => { erase<A | B>(undefined); }) 48 assert_ccexc(() => { erase<A | B>(new Object()); }) 49 assert_ccexc(() => { erase<A | B>(new C()); }) 50 51 assert_ccexc(() => { erase<A[]>(new B[0]); }) 52} 53 54class Erased<T> { 55 constructor(x: Object | null | undefined) { this.t = x as T; } 56 t: T; 57} 58 59function test_substitution_memberexpr() { 60 assert_ccexc(() => { new Erased<Object>(null).t; }) 61 assert_ccexc(() => { new Erased<Object>(undefined).t; }) 62 assert_ccexc(() => { new Erased<A>(null).t; }) 63 assert_ccexc(() => { new Erased<A>(undefined).t; }) 64 65 assert_ccexc(() => { new Erased<Object | undefined>(null).t; }) 66 assert_ccexc(() => { new Erased<Object | null>(undefined).t; }) 67 assert_ccexc(() => { new Erased<A | undefined>(null).t; }) 68 assert_ccexc(() => { new Erased<A | null>(undefined).t; }) 69 70 assert_ccexc(() => { new Erased<A>(undefined).t; }) 71 assert_ccexc(() => { new Erased<A>(new Object()).t; }) 72 assert_ccexc(() => { new Erased<A>(new B()).t; }) 73 74 assert_ccexc(() => { new Erased<A | B>(undefined).t; }) 75 assert_ccexc(() => { new Erased<A | B>(new Object()).t; }) 76 assert_ccexc(() => { new Erased<A | B>(new C()).t; }) 77 78 assert_ccexc(() => { new Erased<A[]>(new B[0]).t; }) 79} 80 81function cast_to_tparam<T extends A | B | null>(x: Object | null | undefined) { x as T; } 82 83function test_constraint() { 84 assert_ccexc(() => { cast_to_tparam<A>(undefined); }) 85 assert_ccexc(() => { cast_to_tparam<A>(new Object()); }) 86 assert_ccexc(() => { cast_to_tparam<A>(new C()); }) 87} 88 89function to_basetype<T>(x: Object | null | undefined) { return x as X<T>; } 90 91function test_basetype() { 92 assert_ccexc(() => { to_basetype<A>(null); }) 93 assert_ccexc(() => { to_basetype<A>(undefined); }) 94 assert_ccexc(() => { to_basetype<A>(new Object()); }) 95 assert_ccexc(() => { to_basetype<A>(new C()); }) 96} 97 98function main() { 99 test_substitution(); 100 test_substitution_memberexpr(); 101 test_constraint(); 102 test_basetype(); 103} 104