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