1/*
2 * Copyright (c) 2022-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
16import {
17  OhosLibC,
18  OhosLibI,
19  OhosLibIC,
20  OhosLibII,
21  OhosLibCC,
22  OhosLibCI
23} from './oh_modules/ohos_lib'
24
25import {
26  DynLibC,
27  DynLibI,
28  DynLibIC,
29  DynLibII,
30  DynLibCC,
31  DynLibCI
32} from './dynamic_lib'
33
34import type { lang } from './@arkts.lang';
35
36class A {
37  getName(): string { return 'A'; }
38  getType(): string { return 'class'; }
39}
40class B {
41  getName(): string { return 'B'; }
42  getType(): string { return 'type'; }
43}
44function foo(a1: A, ...a2: A[]): void {
45}
46foo(new B, new A, new B);
47
48let a =  new A;
49a = new B;
50
51let b: B = new A;
52
53function bar(bArr: B[]): void {
54  bArr[0] = new A;
55}
56
57let name = (new B as A).getName();
58
59class C extends B {
60  getBase(): string { return 'B'; }
61}
62
63function goo(): B {
64  return new B;
65}
66let cl: C = goo() as C;
67
68function zoo(b: B): void {
69}
70zoo(cl as B);
71
72class IdentLibC {}
73interface IdentLibI {}
74interface IdentLibII extends IdentLibI {}
75class IdentLibCC extends IdentLibC {}
76class IdentLibCI implements IdentLibI {}
77
78function fC(a: IdentLibC) {}
79function fI(a: IdentLibI) {}
80
81function fDC(a: DynLibC) {}
82function fDI(a: DynLibI) {}
83
84function fOC(a: OhosLibC) {}
85function fOI(a: OhosLibI) {}
86
87const c: IdentLibC = {};
88const i: IdentLibI = {};
89const ci: IdentLibCI = {};
90const cc: IdentLibCC = {};
91const ii: IdentLibII = {};
92
93const dc: DynLibC = {};
94const di: DynLibI = {};
95const dci: DynLibCI = {};
96const dcc: DynLibCC = {};
97const dii: DynLibII = {};
98const dic: DynLibIC = {};
99
100const oc: OhosLibC = {};
101const oi: OhosLibI = {};
102const oci: OhosLibCI = {};
103const occ: OhosLibCC = {};
104const oii: OhosLibII = {};
105const oic: OhosLibIC = {};
106
107fC(c);    // OK
108fC(i);    // ERR, no inheritance relation
109fC(ci);   // ERR, no inheritance relation
110fC(cc);   // OK
111fC(ii);   // ERR, no inheritance relation
112fI(c);    // ERR, no inheritance relation
113fI(i);    // OK
114fI(ci);   // OK
115fI(cc);   // ERR, no inheritance relation
116fI(ii);   // OK
117fDC(c);   // OK, assignment to dynamic
118fDC(i);   // OK, assignment to dynamic
119fDC(ci);  // OK, assignment to dynamic
120fDC(cc);  // OK, assignment to dynamic
121fDC(ii);  // OK, assignment to dynamic
122fDI(c);   // OK, assignment to dynamic
123fDI(i);   // OK, assignment to dynamic
124fDI(ci);  // OK, assignment to dynamic
125fDI(cc);  // OK, assignment to dynamic
126fDI(ii);  // OK, assignment to dynamic
127fOC(c);   // OK, assignment to dynamic
128fOC(i);   // OK, assignment to dynamic
129fOC(ci);  // OK, assignment to dynamic
130fOC(cc);  // OK, assignment to dynamic
131fOC(ii);  // OK, assignment to dynamic
132fOI(c);   // OK, assignment to dynamic
133fOI(i);   // OK, assignment to dynamic
134fOI(ci);  // OK, assignment to dynamic
135fOI(cc);  // OK, assignment to dynamic
136fOI(ii);  // OK, assignment to dynamic
137
138fC(dc);   // ERR, no inheritance relation
139fC(di);   // ERR, no inheritance relation
140fC(dci);  // ERR, no inheritance relation
141fC(dcc);  // ERR, no inheritance relation
142fC(dii);  // ERR, no inheritance relation
143fC(dic);  // ERR, no inheritance relation
144fI(dc);   // ERR, no inheritance relation
145fI(di);   // ERR, no inheritance relation
146fI(dci);  // ERR, no inheritance relation
147fI(dcc);  // ERR, no inheritance relation
148fI(dii);  // ERR, no inheritance relation
149fI(dic);  // ERR, no inheritance relation
150fDC(dc);  // OK, assignment to dynamic
151fDC(di);  // OK, assignment to dynamic
152fDC(dci); // OK, assignment to dynamic
153fDC(dcc); // OK, assignment to dynamic
154fDC(dii); // OK, assignment to dynamic
155fDC(dic); // OK, assignment to dynamic
156fDI(dc);  // OK, assignment to dynamic
157fDI(di);  // OK, assignment to dynamic
158fDI(dci); // OK, assignment to dynamic
159fDI(dcc); // OK, assignment to dynamic
160fDI(dii); // OK, assignment to dynamic
161fDI(dic); // OK, assignment to dynamic
162fOC(dc);  // OK, assignment to dynamic
163fOC(di);  // OK, assignment to dynamic
164fOC(dci); // OK, assignment to dynamic
165fOC(dcc); // OK, assignment to dynamic
166fOC(dii); // OK, assignment to dynamic
167fOC(dic); // OK, assignment to dynamic
168fOI(dc);  // OK, assignment to dynamic
169fOI(di);  // OK, assignment to dynamic
170fOI(dci); // OK, assignment to dynamic
171fOI(dcc); // OK, assignment to dynamic
172fOI(dii); // OK, assignment to dynamic
173fOI(dic); // OK, assignment to dynamic
174
175fC(oc);   // ERR, no inheritance relation
176fC(oi);   // ERR, no inheritance relation
177fC(oci);  // ERR, no inheritance relation
178fC(occ);  // ERR, no inheritance relation
179fC(oii);  // ERR, no inheritance relation
180fC(oic);  // ERR, no inheritance relation
181fI(oc);   // ERR, no inheritance relation
182fI(oi);   // ERR, no inheritance relation
183fI(oci);  // ERR, no inheritance relation
184fI(occ);  // ERR, no inheritance relation
185fI(oii);  // ERR, no inheritance relation
186fI(oic);  // ERR, no inheritance relation
187fDC(oc);  // OK, assignment to dynamic
188fDC(oi);  // OK, assignment to dynamic
189fDC(oci); // OK, assignment to dynamic
190fDC(occ); // OK, assignment to dynamic
191fDC(oii); // OK, assignment to dynamic
192fDC(oic); // OK, assignment to dynamic
193fDI(oc);  // OK, assignment to dynamic
194fDI(oi);  // OK, assignment to dynamic
195fDI(oci); // OK, assignment to dynamic
196fDI(occ); // OK, assignment to dynamic
197fDI(oii); // OK, assignment to dynamic
198fDI(oic); // OK, assignment to dynamic
199fOC(oc);  // OK, assignment to dynamic
200fOC(oi);  // OK, assignment to dynamic
201fOC(oci); // OK, assignment to dynamic
202fOC(occ); // OK, assignment to dynamic
203fOC(oii); // OK, assignment to dynamic
204fOC(oic); // OK, assignment to dynamic
205fOI(oc);  // OK, assignment to dynamic
206fOI(oi);  // OK, assignment to dynamic
207fOI(oci); // OK, assignment to dynamic
208fOI(occ); // OK, assignment to dynamic
209fOI(oii); // OK, assignment to dynamic
210fOI(oic); // OK, assignment to dynamic
211
212// Structural typing is now relaxed for 'as' expression, all cases are OK
213c as IdentLibC;
214i as IdentLibC;
215ci as IdentLibC;
216cc as IdentLibC;
217ii as IdentLibC;
218c as IdentLibI;
219i as IdentLibI;
220ci as IdentLibI;
221cc as IdentLibI;
222ii as IdentLibI;
223c as DynLibC;
224i as DynLibC;
225ci as DynLibC;
226cc as DynLibC;
227ii as DynLibC;
228c as DynLibI;
229i as DynLibI;
230ci as DynLibI;
231cc as DynLibI;
232ii as DynLibI;
233c as OhosLibC;
234i as OhosLibC;
235ci as OhosLibC;
236cc as OhosLibC;
237ii as OhosLibC;
238c as OhosLibI;
239i as OhosLibI;
240ci as OhosLibI;
241cc as OhosLibI;
242ii as OhosLibI;
243
244dc as IdentLibC;
245di as IdentLibC;
246dci as IdentLibC;
247dcc as IdentLibC;
248dii as IdentLibC;
249dic as IdentLibC;
250dc as IdentLibI;
251di as IdentLibI;
252dci as IdentLibI;
253dcc as IdentLibI;
254dii as IdentLibI;
255dic as IdentLibI;
256dc as DynLibC;
257di as DynLibC;
258dci as DynLibC;
259dcc as DynLibC;
260dii as DynLibC;
261dic as DynLibC;
262dc as DynLibI;
263di as DynLibI;
264dci as DynLibI;
265dcc as DynLibI;
266dii as DynLibI;
267dic as DynLibI;
268dc as OhosLibC;
269di as OhosLibC;
270dci as OhosLibC;
271dcc as OhosLibC;
272dii as OhosLibC;
273dic as OhosLibC;
274dc as OhosLibI;
275di as OhosLibI;
276dci as OhosLibI;
277dcc as OhosLibI;
278dii as OhosLibI;
279dic as OhosLibI;
280
281oc as IdentLibC;
282oi as IdentLibC;
283oci as IdentLibC;
284occ as IdentLibC;
285oii as IdentLibC;
286oic as IdentLibC;
287oc as IdentLibI;
288oi as IdentLibI;
289oci as IdentLibI;
290occ as IdentLibI;
291oii as IdentLibI;
292oic as IdentLibI;
293oc as DynLibC;
294oi as DynLibC;
295oci as DynLibC;
296occ as DynLibC;
297oii as DynLibC;
298oic as DynLibC;
299oc as DynLibI;
300oi as DynLibI;
301oci as DynLibI;
302occ as DynLibI;
303oii as DynLibI;
304oic as DynLibI;
305oc as OhosLibC;
306oi as OhosLibC;
307oci as OhosLibC;
308occ as OhosLibC;
309oii as OhosLibC;
310oic as OhosLibC;
311oc as OhosLibI;
312oi as OhosLibI;
313oci as OhosLibI;
314occ as OhosLibI;
315oii as OhosLibI;
316oic as OhosLibI;
317
318class Ct {
319  a: number = 1
320  b: string = ""
321}
322
323interface I {
324  a: number
325}
326
327class Cz {
328  x: Ct | null = new Ct();
329  y: I = this.x as I
330}
331
332let x: Ct | null = new Ct();
333let y: I = x as I
334
335class X {}
336class Y {}
337class Z {}
338class W extends X {}
339
340function union(x: X, xy: X | Y, xz: X | Z, xyz: X | Y | Z, w: W, xw: X | W, zw: Z | W) {
341  x = xy; // ERR, 'X | Y' assigned to 'X'
342  xy = x; // OK
343
344  xy = xz; // ERR, 'X | Z' assigned to 'X | Y'
345  xz = xy; // ERR, 'X | Y' assigned to 'X | Z'
346
347  xyz = xz; // OK
348  xz = xyz; // ERR, 'X | Y | Z' assigned to 'X | Z'
349  
350  x = w; // OK
351  w = x; // ERR, 'X' assigned to 'W' 
352
353  x = xw; // OK
354  xw = x; // OK
355
356  xw = zw; // ERR, 'Z | W' assigned to 'X | W'
357  zw = xw; // ERR, 'X | W' assigned to 'Z | W'
358  
359  xz = zw; // OK
360  zw = xz; // ERR, 'X | Z' assigned to 'Z | W'
361}
362
363class C0 {}
364class C1 {}
365class C2<T> {}
366
367type U1 = number | string | boolean;
368type U2 = number[] | string[] | boolean[];
369type U3 = C1 | C2<number> | C2<string>;
370type U4 = C1[] | C2<number>[] | C2<string>[];
371
372function testUnionStructuralIdentityNegative(u1: U1, u2: U2, u3: U3, u4: U4) {
373  // no CTE expected
374  u1 as number;
375  u1 as string;
376  u1 as boolean;
377
378  u1 as number | string;
379  u1 as number | boolean;
380  u1 as string | boolean;
381
382  u1 as number | string | boolean;
383  u1 as boolean | number | string;
384  u1 as U1;
385
386  // no CTE expected
387  u2 as number[];
388  u2 as string[];
389  u2 as boolean[];
390
391  u2 as number[] | string[];
392  u2 as number[] | boolean[];
393  u2 as string[] | boolean[];
394
395  u2 as number[] | string[] | boolean[];
396  u2 as boolean[] | number[] | string[];
397  u2 as U2;
398
399  // no CTE expected
400  u3 as C1;
401  u3 as C2<number>;
402  u3 as C2<string>;
403
404  u3 as C1 | C2<number>;
405  u3 as C1 | C2<string>;
406  u3 as C2<number> | C2<string>;
407
408  u3 as C1 | C2<number> | C2<string>;
409  u3 as C2<string> | C2<number> | C1;
410  u3 as U3;
411
412  // no CTE expected
413  u4 as C1[];
414  u4 as C2<number>[];
415  u4 as C2<string>[];
416
417  u4 as C1[] | C2<number>[];
418  u4 as C1[] | C2<string>[];
419  u4 as C2<number>[] | C2<string>[];
420
421  u4 as C1[] | C2<number>[] | C2<string>[];
422  u4 as C2<string>[] | C2<number>[] | C1[];
423  u4 as U4;
424}
425
426function testUnionStructuralIdentityPositive(u1: U1, u2: U2, u3: U3, u4: U4) {
427  u1 as Number;
428  u1 as String;
429  u1 as Boolean;
430
431  u1 as Number | String;
432  u1 as Number | Boolean;
433  u1 as String | Boolean;
434
435  u1 as Number | String | Boolean;
436  u1 as Boolean | Number | String;
437  u1 as U1 | U2;
438
439  u2 as Number[];
440  u2 as String[];
441  u2 as Boolean[];
442
443  u2 as Number[] | String[];
444  u2 as Number[] | Boolean[];
445  u2 as String[] | Boolean[];
446
447  u2 as Number[] | String[] | Boolean[];
448  u2 as Boolean[] | Number[] | String[];
449  u2 as U2 | U1;
450
451  u3 as C1 | C0;
452  u3 as C2<boolean>;
453  u3 as C2<C1>;
454
455  u3 as C1 | C2<number> | C2<string> | C0;
456  u3 as C1 | C2<string> | number;
457  u3 as C2<number> | C2<string> | C2<boolean>;
458
459  u3 as C1 | C2<number> | C2<boolean>;
460  u3 as C2<string> | C2<number> | C0;
461  u3 as U3 | U4;
462
463  u3 as C1[] | C0[];
464  u3 as C2<boolean>[];
465  u3 as C2<C1>[];
466
467  u3 as C1[] | C2<number>[] | C2<string>[] | C0[];
468  u3 as C1[] | C2<string>[] | undefined[];
469  u3 as C2<number>[] | C2<string>[] | C2<boolean>[];
470
471  u3 as C1[] | C2<number>[] | C2<string>[];
472  u3 as C2<string>[] | C2<number>[] | C0[];
473  u3 as U3 | U4;
474}
475
476
477/**
478 * Add the Sendable exception to the [arks-no-struct_typing] rule.
479 */
480@Sendable
481class TC1 implements lang.ISendable {
482  name:string = 'tc1';
483}
484
485@Sendable
486class TC2 {
487  name:string = 'tc2';
488}
489
490class TC3 {
491  name:string = 'tc3';
492}
493const t1 = new TC1();
494const t2 = new TC2();
495const t3 = new TC3();
496
497
498// Appears on SyntaxKind.VariableDeclaration node
499const a1: lang.ISendable = t1; // OK
500const a2: lang.ISendable = t2; // OK , Sendable can be thought of as implement ISendable
501const a3: lang.ISendable = t2 as lang.ISendable; // OK 
502const a4: lang.ISendable = t3; // ERROR
503const a5: lang.ISendable = t3 as lang.ISendable; // ERROR
504
505
506// Appears on SyntaxKind.BinaryExpression node
507let b1:lang.ISendable;
508b1 = t1; // OK
509b1 = t2; // OK , Sendable can be thought of as implement ISendable
510b1 = t2 as lang.ISendable; // OK
511b1 = t3; // ERROR
512b1 = t3 as lang.ISendable; // ERROR
513
514
515// Appears on SyntaxKind.CallExpression node
516function cf(value: lang.ISendable):void {}
517cf(t1); // OK
518cf(t2); // OK , Sendable can be thought of as implement ISendable
519cf(t2 as lang.ISendable); // OK
520cf(t3); // ERROR
521cf(t3 as lang.ISendable); // ERROR
522
523function cfT<T>(value: T):void {}
524cfT<lang.ISendable>(t1); // OK
525cfT<lang.ISendable>(t2); // OK , Sendable can be thought of as implement ISendable
526cfT<lang.ISendable>(t2 as lang.ISendable); // OK
527cfT<lang.ISendable>(t3); // ERROR
528cfT<lang.ISendable>(t3 as lang.ISendable); // ERROR
529
530
531// Appears on SyntaxKind.handleNewExpression node
532class DC1 {
533  name:string;
534
535  constructor(value:lang.ISendable) {
536    this.name = value.name;
537  }
538}
539new DC1(t1); // OK
540new DC1(t2); // OK , Sendable can be thought of as implement ISendable
541new DC1(t2 as lang.ISendable); // OK
542new DC1(t3); // ERROR
543new DC1(t3 as lang.ISendable); // ERROR
544
545
546// Appears on SyntaxKind.ObjectLiteralExpression/SyntaxKind.ArrayLiteralExpression node
547interface EI1 {
548  sendable: lang.ISendable;
549}
550const e1: EI1 = { sendable:t1 }; // OK
551const e2: EI1 = { sendable:t2 }; // OK , Sendable can be thought of as implement ISendable, avoid [arkts-no-untyped-obj-literals] rule
552const e3: EI1 = { sendable:t2 as lang.ISendable }; // OK
553const e4: EI1 = { sendable:t3 }; // ERROR
554const e5: EI1 = { sendable:t3 as lang.ISendable }; // ERROR
555const e1s: EI1[] = [{ sendable:t1 }]; // OK
556const e2s: EI1[] = [{ sendable:t2 }]; // OK , Sendable can be thought of as implement ISendable.  avoid [arkts-no-untyped-obj-literals] rule
557const e3s: EI1[] = [{ sendable:t2 as lang.ISendable }]; // OK
558const e4s: EI1[] = [{ sendable:t3 }]; // ERROR
559const e5s: EI1[] = [{ sendable:t3 as lang.ISendable }]; // ERROR
560
561// // Appears on SyntaxKind.PropertyDeclaration node
562// PropertyDeclaration does not do [arkts-no-structural-typing] check
563// export class FC1 {
564//   prop1: lang.ISendable = t1; // OK
565//   prop2: lang.ISendable = t2; // OK
566//   prop3: lang.ISendable = t3; // OK
567// }
568
569
570// union
571class GC1 { }
572function ff1(value: lang.ISendable):void {}
573function ff2(value: lang.ISendable | GC1):void {}
574function ff3(value: TC1 | TC2): void { ff1(value); } // OK , Sendable can be thought of as implement ISendable
575function ff4(value: TC1 | TC3): void { ff1(value); } // ERROR
576function ff5(value: TC1): void { ff2(value); } // OK
577function ff6(value: TC2): void { ff2(value); } // OK , Sendable can be thought of as implement ISendable
578function ff7(value: TC3): void { ff2(value); } // ERROR
579function ff8(value: TC1 | TC2): void { ff2(value); } // OK , Sendable can be thought of as implement ISendable
580function ff9(value: TC1 | TC3): void { ff2(value); } // ERROR
581
582