13af6ab5fSopenharmony_ci/*
23af6ab5fSopenharmony_ci * Copyright (c) 2023 - 2024 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci * You may obtain a copy of the License at
63af6ab5fSopenharmony_ci *
73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci *
93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci * limitations under the License.
143af6ab5fSopenharmony_ci */
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_cifunction main() {
173af6ab5fSopenharmony_ci    testLocalIdentifier()
183af6ab5fSopenharmony_ci    testArgument()
193af6ab5fSopenharmony_ci    testCallExpression()
203af6ab5fSopenharmony_ci    testNPE()
213af6ab5fSopenharmony_ci    testFieldAccess()
223af6ab5fSopenharmony_ci    testFieldAccess2()
233af6ab5fSopenharmony_ci}
243af6ab5fSopenharmony_ci
253af6ab5fSopenharmony_cifunction typeOf(i : Int) : int {
263af6ab5fSopenharmony_ci    return 1;
273af6ab5fSopenharmony_ci}
283af6ab5fSopenharmony_ci
293af6ab5fSopenharmony_cifunction typeOf(o : Object) : int {
303af6ab5fSopenharmony_ci    return -1;
313af6ab5fSopenharmony_ci}
323af6ab5fSopenharmony_ci
333af6ab5fSopenharmony_cifunction dummy(): Int | null {
343af6ab5fSopenharmony_ci    return 5;
353af6ab5fSopenharmony_ci}
363af6ab5fSopenharmony_ci
373af6ab5fSopenharmony_cifunction testLocalIdentifier() : void {
383af6ab5fSopenharmony_ci    let a : Int | null = dummy();
393af6ab5fSopenharmony_ci    let b = a!;
403af6ab5fSopenharmony_ci
413af6ab5fSopenharmony_ci    assert typeOf(b) == 1: "b must be type Int";
423af6ab5fSopenharmony_ci    assert b == 5 : "b must be 5";
433af6ab5fSopenharmony_ci
443af6ab5fSopenharmony_ci    let c = b + a! * 7;
453af6ab5fSopenharmony_ci
463af6ab5fSopenharmony_ci    assert c == 40: "c should be 40";
473af6ab5fSopenharmony_ci
483af6ab5fSopenharmony_ci    assert a! == (a)!;
493af6ab5fSopenharmony_ci}
503af6ab5fSopenharmony_ci
513af6ab5fSopenharmony_cifunction bar(arg : Int | null) : Int {
523af6ab5fSopenharmony_ci    return arg!;
533af6ab5fSopenharmony_ci}
543af6ab5fSopenharmony_ci
553af6ab5fSopenharmony_cifunction testArgument() : void {
563af6ab5fSopenharmony_ci    let a : Int | null = 7;
573af6ab5fSopenharmony_ci    let b = bar(a);
583af6ab5fSopenharmony_ci
593af6ab5fSopenharmony_ci    assert typeOf(b) == 1: "b must be type Int";
603af6ab5fSopenharmony_ci    assert b == 7;
613af6ab5fSopenharmony_ci}
623af6ab5fSopenharmony_ci
633af6ab5fSopenharmony_cifunction foo() : Double | null {
643af6ab5fSopenharmony_ci    return new Double(3.1415);
653af6ab5fSopenharmony_ci}
663af6ab5fSopenharmony_ci
673af6ab5fSopenharmony_ciclass Foo {
683af6ab5fSopenharmony_ci    foo() : Float | null {
693af6ab5fSopenharmony_ci        return Float.DELTA;
703af6ab5fSopenharmony_ci    }
713af6ab5fSopenharmony_ci}
723af6ab5fSopenharmony_ci
733af6ab5fSopenharmony_cifunction testCallExpression() {
743af6ab5fSopenharmony_ci    let d = foo()!
753af6ab5fSopenharmony_ci
763af6ab5fSopenharmony_ci    assert d instanceof Double : "d must be type Double"
773af6ab5fSopenharmony_ci    assert d == 3.1415 : "d must be 3.1415"
783af6ab5fSopenharmony_ci
793af6ab5fSopenharmony_ci    let sd = foo()!.toString()
803af6ab5fSopenharmony_ci
813af6ab5fSopenharmony_ci    assert "3.1415".equals(sd) : "s must be '3.1415'"
823af6ab5fSopenharmony_ci
833af6ab5fSopenharmony_ci    let f = new Foo().foo()!
843af6ab5fSopenharmony_ci
853af6ab5fSopenharmony_ci    assert f instanceof Float : "f must be type Float"
863af6ab5fSopenharmony_ci    assert f == Float.DELTA : "f must be Float.DELTA"
873af6ab5fSopenharmony_ci}
883af6ab5fSopenharmony_ci
893af6ab5fSopenharmony_cifunction baz() : Byte | null {
903af6ab5fSopenharmony_ci    return null;
913af6ab5fSopenharmony_ci}
923af6ab5fSopenharmony_ci
933af6ab5fSopenharmony_cifunction aux(): Object | null {
943af6ab5fSopenharmony_ci   return null;
953af6ab5fSopenharmony_ci}
963af6ab5fSopenharmony_ci
973af6ab5fSopenharmony_cifunction testNPE() : void {
983af6ab5fSopenharmony_ci    let o : Object | null = aux();
993af6ab5fSopenharmony_ci    let npe_caught = false;
1003af6ab5fSopenharmony_ci
1013af6ab5fSopenharmony_ci    try {
1023af6ab5fSopenharmony_ci        (o as Object | null)!;
1033af6ab5fSopenharmony_ci        assert false : "this must not be executed";
1043af6ab5fSopenharmony_ci    } catch (ex: NullPointerError) {
1053af6ab5fSopenharmony_ci        npe_caught = true;
1063af6ab5fSopenharmony_ci    }
1073af6ab5fSopenharmony_ci
1083af6ab5fSopenharmony_ci    assert npe_caught : "NPE must be caught";
1093af6ab5fSopenharmony_ci
1103af6ab5fSopenharmony_ci    try {
1113af6ab5fSopenharmony_ci        baz()!;
1123af6ab5fSopenharmony_ci        assert false : "this must not be executed";
1133af6ab5fSopenharmony_ci    } catch (ex: NullPointerError) {
1143af6ab5fSopenharmony_ci        npe_caught = true;
1153af6ab5fSopenharmony_ci    }
1163af6ab5fSopenharmony_ci
1173af6ab5fSopenharmony_ci    assert npe_caught : "NPE must be caught";
1183af6ab5fSopenharmony_ci}
1193af6ab5fSopenharmony_ci
1203af6ab5fSopenharmony_ciclass A {
1213af6ab5fSopenharmony_ci    public static c : Char | null = c'C';
1223af6ab5fSopenharmony_ci}
1233af6ab5fSopenharmony_ci
1243af6ab5fSopenharmony_ciclass B {
1253af6ab5fSopenharmony_ci    public a : A | null;
1263af6ab5fSopenharmony_ci
1273af6ab5fSopenharmony_ci    constructor(a : A | null) {
1283af6ab5fSopenharmony_ci        this.a = a;
1293af6ab5fSopenharmony_ci    }
1303af6ab5fSopenharmony_ci
1313af6ab5fSopenharmony_ci    public setA(a : A) {
1323af6ab5fSopenharmony_ci        this.a = a;
1333af6ab5fSopenharmony_ci    }
1343af6ab5fSopenharmony_ci
1353af6ab5fSopenharmony_ci    public getA() : A {
1363af6ab5fSopenharmony_ci        return this.a!;
1373af6ab5fSopenharmony_ci    }
1383af6ab5fSopenharmony_ci}
1393af6ab5fSopenharmony_ci
1403af6ab5fSopenharmony_cifunction testFieldAccess() : void {
1413af6ab5fSopenharmony_ci    let ac = A.c!;
1423af6ab5fSopenharmony_ci    assert ac == c'C' : "ac should be 'C'";
1433af6ab5fSopenharmony_ci
1443af6ab5fSopenharmony_ci    let a_orig = new A();
1453af6ab5fSopenharmony_ci    let b = new B(a_orig);
1463af6ab5fSopenharmony_ci
1473af6ab5fSopenharmony_ci    let a = b.a!;
1483af6ab5fSopenharmony_ci
1493af6ab5fSopenharmony_ci    assert a == a_orig : "a should be the object referenced by a_orig";
1503af6ab5fSopenharmony_ci
1513af6ab5fSopenharmony_ci    let c = b.a!.c!;
1523af6ab5fSopenharmony_ci
1533af6ab5fSopenharmony_ci    assert c == c'C' : "c should be 'C'";
1543af6ab5fSopenharmony_ci}
1553af6ab5fSopenharmony_ci
1563af6ab5fSopenharmony_cifunction testFieldAccess2() : void {
1573af6ab5fSopenharmony_ci    let a = new A();
1583af6ab5fSopenharmony_ci    let b = new B(a);
1593af6ab5fSopenharmony_ci
1603af6ab5fSopenharmony_ci    assert b.getA() == a : "getA should return the same object that was given to the constructor";
1613af6ab5fSopenharmony_ci
1623af6ab5fSopenharmony_ci    let a2 = new A();
1633af6ab5fSopenharmony_ci    b.setA(a2);
1643af6ab5fSopenharmony_ci
1653af6ab5fSopenharmony_ci    assert b.getA() == a2 : "getA should return the same object that was given to setA";
1663af6ab5fSopenharmony_ci}
167