1/*
2 * Copyright (c) 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
16@Sendable
17class SC1 {};
18class NC1 {};
19@Sendable
20class SC2 {};
21class NC2 {};
22@Sendable
23class SCT1<T> {};
24class NCT1<T> {};
25@Sendable
26class SCT2<T> {};
27class NCT2<T> {};
28
29const sc1:SC1 = new SC1();
30const nc1:NC1 = new NC1();
31const sc2:SC2 = new SC2();
32const nc2:NC2 = new NC2();
33const sct1:SCT1<number> = new SCT1();
34const nct1:NCT1<number> = new NCT1();
35const sct2:SCT2<number> = new SCT2();
36const nct2:NCT2<number> = new NCT2();
37
38type TSS<T> = SCT1<number> |  SCT2<T>;
39type TSN<T> = SCT1<number> |  NCT1<T>;
40
41let a1: SC1 = new NC1(); // ERROR
42a1 = new NC1();// ERROR
43function handle(p: SC1):void{};
44handle(new NC1());// ERROR
45class Main1 {
46    constructor(param:SC1) {};
47}
48new Main1(new NC1());// ERROR
49interface IProxy {map: SC1;};
50const proxy: IProxy = {map: new NC1()};// ERROR
51const proxies: IProxy[] = [{map: new NC1()}];// ERROR
52
53
54
55let b1: SC1 = new SC1(); // OK
56let b2: SC1 = new NC1(); // ERROR
57let b3: SCT1<string> = new SCT1<string>(); // OK
58let b4: SCT1<string> = new NCT1<string>(); // ERROR
59let b5: SC1 | NC1 = new SC1(); // OK
60let b6: SC1 | NC1 = new SC2(); // ERROR
61let b7: SC1 | NC1 = new NC1(); // OK
62let b8: SC1 | NC1 = new NC2(); // ERROR
63let b9: SC1 | NC1 = 1 ? new SC1() : new NC1(); // OK
64let b10: SC1 | NC1 = 1 ? new SC1() : new NC2(); // ERROR
65let b11: SC1 | NC1 = 1 ? new SC2() : new NC1(); // ERROR
66let b12: SC1 | NC1 = 1 ? new SC2() : new NC2(); // ERROR
67let b13: TSS<number> = new SCT1<number>(); // OK
68let b14: TSS<number> = new SCT2<number>(); // OK
69let b15: TSS<number> = new NCT1<number>(); // ERROR
70let b16: TSS<number> = new NCT2<number>(); // ERROR
71let b17: TSS<number> = 1 ? new SCT1<number>() : new NCT1<number>(); // ERROR
72let b18: TSS<number> = 1 ? new SCT1<number>() : new NCT2<number>(); // ERROR
73let b19: TSS<number> = 1 ? new SCT2<number>() : new NCT1<number>(); // ERROR
74let b20: TSS<number> = 1 ? new SCT2<number>() : new NCT2<number>(); // ERROR
75// For compatibility, if both sendable, no strict check
76let b21: SCT1<number> = new SCT2<number>();// OK
77let b22: TSN<number> = new SCT1<number>(); // OK
78let b23: TSN<number> = new SCT2<number>(); // OK
79let b24: TSN<number> = new NCT1<number>(); // OK
80let b25: TSN<number> = new NCT2<number>(); // OK
81let b26: TSN<number> = 1 ? new SCT1<number>() : new NCT1<number>(); // OK
82let b27: TSN<number> = 1 ? new SCT1<number>() : new NCT2<number>(); // OK
83let b28: TSN<number> = 1 ? new SCT2<number>() : new NCT1<number>(); // OK
84let b29: TSN<number> = 1 ? new SCT2<number>() : new NCT2<number>(); // OK
85
86
87
88// add check in PropertyDeclaration 
89class Main {
90    p1: SC1 = new SC1(); // OK
91    p2: SC1 = new NC1(); // ERROR
92    p3: SCT1<string> = new SCT1<string>(); // OK
93    p4: SCT1<string> = new NCT1<string>(); // ERROR
94    p5: SC1 | NC1 = new SC1(); // OK
95    p6: SC1 | NC1 = new SC2(); // OK
96    p7: SC1 | NC1 = new NC1(); // OK
97    p8: SC1 | NC1 = new NC2(); // OK
98    p9: SC1 | NC1 = 1 ? new SC1() : new NC1(); // OK
99    p10: SC1 | NC1 = 1 ? new SC1() : new NC2(); // OK
100    p11: SC1 | NC1 = 1 ? new SC2() : new NC1(); // OK
101    p12: SC1 | NC1 = 1 ? new SC2() : new NC2(); // OK
102    p13: TSS<number> = new SCT1<number>(); // OK
103    p14: TSS<number> = new SCT2<number>(); // OK
104    p15: TSS<number> = new NCT1<number>(); // ERROR
105    p16: TSS<number> = new NCT2<number>(); // ERROR
106    p17: TSS<number> = 1 ? new SCT1<number>() : new NCT1<number>(); // ERROR
107    p18: TSS<number> = 1 ? new SCT1<number>() : new NCT2<number>(); // ERROR
108    p19: TSS<number> = 1 ? new SCT2<number>() : new NCT1<number>(); // ERROR
109    p20: TSS<number> = 1 ? new SCT2<number>() : new NCT2<number>(); // ERROR
110} 
111
112// add check in ArrayLiteralExpression
113const l1: [SC1] = [sc1]; // OK
114const l2: [SC1] = [nc1]; // ERROR
115const l3: SC1[] = [sc1]; // OK
116const l4: SC1[] = [nc1]; // ERROR
117const l5: SCT1<string>[] = [sct1]; // OK
118const l6: SCT1<string>[] = [nct1]; // ERROR
119const l7: (SC1 | NC1)[] = [
120    sc1, // OK
121    sc2, // OK
122    nc1, // OK
123    nc2, // OK
124    1 ? sc1 : nc1, // OK
125    1 ? sc1 : nc2, // OK
126    1 ? sc2 : nc1, // OK
127    1 ? sc2 : nc2 // OK
128];
129const l8: TSS<number>[] = [
130    sct1, // OK
131    sct2, // OK
132    nct1, // ERROR
133    nct2, // ERROR
134    1 ? sct1 : nct1, // ERROR
135    1 ? sct1 : nct2, // ERROR
136    1 ? sct2 : nct1, // ERROR
137    1 ? sct2 : nct2 // ERROR
138];
139
140// add check in ReturnStatement
141function f1(): SC1 {
142    if(1) return new NC1(); // ERROR
143    return new SC1(); // OK
144}
145
146function f2(): SCT1<number> {
147    if(1) return new NCT1<number>(); // ERROR
148    return new SCT1<number>(); // OK
149}
150
151function f3():(SC1 | NC1) {
152    if(1) return new SC1(); // OK
153    if(1) return new SC2(); // OK
154    if(1) return new NC1(); // OK
155    if(1) return new NC2(); // OK
156    if(1) return 1 ? new SC1() : new NC1(); // OK
157    if(1) return 1 ? new SC1() : new NC2(); // OK
158    if(1) return 1 ? new SC2() : new NC1(); // OK
159    if(1) return 1 ? new SC2() : new NC2(); // OK
160    return new SC1(); // OK
161}
162
163
164function f4():(TSS<number>) {
165    if(1) return new SCT1<number>(); // OK
166    if(1) return new SCT2<number>(); // OK
167    if(1) return new NCT1<number>(); // ERROR
168    if(1) return new NCT2<number>(); // ERROR
169    if(1) return 1 ? new SCT1<number>() : new NCT1<number>(); // ERROR
170    if(1) return 1 ? new SCT1<number>() : new NCT2<number>(); // ERROR
171    if(1) return 1 ? new SCT2<number>() : new NCT1<number>(); // ERROR
172    if(1) return 1 ? new SCT2<number>() : new NCT2<number>(); // ERROR
173    return new SCT1<number>(); // OK
174}