• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022-2025 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);//ERROR
47
48let a =  new A;
49a = new B;//ERROR
50
51let b: B = new A;//ERROR
52
53function bar(bArr: B[]): void {
54  bArr[0] = new A;//ERROR
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/**
583 * More contexts are checked in 'arkts 2.0' mode.
584 */
585class A_20 {}
586class B_20 {}
587
588// Return statement
589function foo_20(): A_20 {
590  return new B_20();// ERROR
591}
592function bar_20(): B_20 {
593  return new A_20();// ERROR
594}
595
596// Array literal expression
597const a_20 = new A_20();
598const b_20 = new B_20();
599const arrA_20: A_20[] = [a_20, b_20];// ERROR
600const arrB_20: B_20[] = [a_20, b_20];// ERROR
601
602// Property declaration
603class C_20 {
604  a: A_20 = new B_20();// ERROR
605  b: B_20 = new A_20();// ERROR
606}
607
608class A_10 {
609  v: number = 0
610 }
611class B_10 {
612  v: number = 0
613}
614let aa: A_10 = new B_10() as A_10; // ERROR
615
616
617class F<T> {
618}
619class D extends B_10 {}
620
621const imageSet: Set<aod.ImageType> = new Set(this.context.triggers?.map((t) => t.imageType));
622const orderedImage: aod.ImageType[] = Array.from(imageSet);
623
624let obj1: A_10 = new A_10();
625let obj2: B_10 = new B_10();
626let obj3: B_10 = obj1; // Not OK
627let obj4: B_10 = obj1 as B_10; // NOT OK
628let obj5: B_10 = new A_10() as B_10; // NOT OK
629let obj6: B_10 = new D() as B_10; // OK
630let obj7: A_10 = test() as A_10; // NOT OK
631
632let bb: F<B_10> = new F<A_10>(); // NOT OK
633let cc1: F<B_10 | string> = new F<A_10>(); // NOT OK
634let cc2: F<B_10 | A_10> = new F<A_10 | D>(); // OK
635let cc3: F<A_10> = new F<A_10 | string>(); // OK
636let arr1: Array<A_10> = [obj2] // NOT OK
637let arr2: Array<A_10> = [obj1, obj2] // obj2 NOT OK
638let arr3: Array<A_10 | string> = [obj1, obj2, 'hello'] // obj2 NOT OK
639let arr4: Array<A_10 | B_10> = [obj1, obj2] // OK
640
641function test(): B_10 {
642  return obj2;
643}
644
645function test1(): B_10 {
646  return obj1; // NOT OK
647}
648
649class D_10 {
650  obj1: A_10 = new A_10();
651  obj2: B_10 = new B_10();
652  obj3: B_10 = obj1; // Not OK
653  obj4: B_10 = obj1 as B_10; // NOT OK
654  obj5: B_10 = new A_10() as B_10; // NOT OK
655  obj6: B_10 = new D() as B_10; // OK
656  arr1: Array<A_10> = [obj2] // NOT OK
657  arr2: Array<A_10> = [obj1, obj2] // NOT OK
658  arr3: Array<A_10 | string> = [obj1, obj2, 'hello'] // obj2 NOT OK
659  b: F<B_10> = new F<A_10>(); // NOT OK
660  c: F<B_10 | string> = new F<A_10>(); // NOT OK
661  cc: F<B_10 | A_10> = new F<A_10 | D>(); // OK
662
663  test(): B_10{
664    let obj1: A_10 = new A_10();
665    return obj1; // NOT OK
666  }
667}
668
669function test_10(): B_10 {
670  let obj1: A_10 = new A_10();
671  return obj1; // NOT OK
672}
673
674class MyObj2 {
675
676}
677class MyObj1 {
678
679}
680class MyObj3 {
681
682}
683interface goodPerson extends IPerson {
684    like: MyObj2,
685    like1: MyObj3
686 }
687
688 let lily:goodPerson = {
689    like: new MyObj1(),
690    name: 'Alice',
691    age: 30,
692    sayHello:()=> {
693       return new MyObj2()
694    }
695 }
696
697 async function foo1(): Promise<boolean>{
698
699  return new Promise<boolean>(()=>{
700
701  });
702}
703
704function foo2(rule:Record<string,string|Object>){
705  let b:Array<string> = rule['123'] as Array<string>
706}