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_ci// test transformation of trailing lambda
173af6ab5fSopenharmony_cilet x: int = 1;
183af6ab5fSopenharmony_ciconst y: int = 3;
193af6ab5fSopenharmony_ci
203af6ab5fSopenharmony_cifunction f1(callback: ()=>void) {
213af6ab5fSopenharmony_ci    callback();
223af6ab5fSopenharmony_ci}
233af6ab5fSopenharmony_ci
243af6ab5fSopenharmony_cifunction f2() {
253af6ab5fSopenharmony_ci    x = x + 1
263af6ab5fSopenharmony_ci}
273af6ab5fSopenharmony_ci
283af6ab5fSopenharmony_cifunction f3(callback: ()=>void) :int {
293af6ab5fSopenharmony_ci    callback();
303af6ab5fSopenharmony_ci    return y;
313af6ab5fSopenharmony_ci}
323af6ab5fSopenharmony_ci
333af6ab5fSopenharmony_cifunction test_transform() {
343af6ab5fSopenharmony_ci    x = 1
353af6ab5fSopenharmony_ci    f1() {  // Test '{' at the same line as call expression, block statement can be transformed to trailing lambda
363af6ab5fSopenharmony_ci        x++
373af6ab5fSopenharmony_ci    }
383af6ab5fSopenharmony_ci    assert x == 2: "expected: " + 2 + " actual: " + x;
393af6ab5fSopenharmony_ci
403af6ab5fSopenharmony_ci    f1()
413af6ab5fSopenharmony_ci    {  // Test '{' not the same line as call expression, block statement can be transformed to trailing lambda
423af6ab5fSopenharmony_ci        x++
433af6ab5fSopenharmony_ci    }
443af6ab5fSopenharmony_ci    assert x == 3: "expected: " + 3 + " actual: " + x;
453af6ab5fSopenharmony_ci
463af6ab5fSopenharmony_ci    f2()
473af6ab5fSopenharmony_ci    {  // Test this block run as a standalone code block
483af6ab5fSopenharmony_ci        x++
493af6ab5fSopenharmony_ci    }
503af6ab5fSopenharmony_ci    assert x == 5: "expected: " + 5 + " actual: " + x;
513af6ab5fSopenharmony_ci
523af6ab5fSopenharmony_ci    let b = f3()
533af6ab5fSopenharmony_ci    { x++ }
543af6ab5fSopenharmony_ci    assert x == 6: "expected: " + 6 + " actual: " + x;
553af6ab5fSopenharmony_ci    assert b == y: "expected: " + y + " actual: " + b;
563af6ab5fSopenharmony_ci
573af6ab5fSopenharmony_ci    let a = f3() { x++ }
583af6ab5fSopenharmony_ci    assert x == 7: "expected: " + 7 + " actual: " + x;
593af6ab5fSopenharmony_ci    assert a == y: "expected: " + y + " actual: " + a;
603af6ab5fSopenharmony_ci
613af6ab5fSopenharmony_ci    assert y == f3(){}
623af6ab5fSopenharmony_ci    assert y == f3(()=>{})
633af6ab5fSopenharmony_ci    {
643af6ab5fSopenharmony_ci    }
653af6ab5fSopenharmony_ci}
663af6ab5fSopenharmony_ci
673af6ab5fSopenharmony_ci// test signature matches of trailing lambda
683af6ab5fSopenharmony_cifunction f_overload(num: Int, callback: ()=>void): Int {
693af6ab5fSopenharmony_ci    return 0;
703af6ab5fSopenharmony_ci}
713af6ab5fSopenharmony_ci
723af6ab5fSopenharmony_cifunction f_overload(num: Int): Int {
733af6ab5fSopenharmony_ci    return num;
743af6ab5fSopenharmony_ci}
753af6ab5fSopenharmony_ci
763af6ab5fSopenharmony_cifunction test_overload() {
773af6ab5fSopenharmony_ci    let num = f_overload(1)
783af6ab5fSopenharmony_ci    {
793af6ab5fSopenharmony_ci        // This block will be transform to a trailing lambda
803af6ab5fSopenharmony_ci    }
813af6ab5fSopenharmony_ci    assert num == 0: "expected: " + 0 + " actual: " + num;
823af6ab5fSopenharmony_ci}
833af6ab5fSopenharmony_ci
843af6ab5fSopenharmony_ci// test class methods using trailing lambda
853af6ab5fSopenharmony_ciclass A {
863af6ab5fSopenharmony_ci    set_n(callback: ()=>void) {
873af6ab5fSopenharmony_ci        callback();
883af6ab5fSopenharmony_ci    }
893af6ab5fSopenharmony_ci
903af6ab5fSopenharmony_ci    public static set_n_static(callback: ()=>void): void {
913af6ab5fSopenharmony_ci        callback();
923af6ab5fSopenharmony_ci    }
933af6ab5fSopenharmony_ci
943af6ab5fSopenharmony_ci    static n: int = 1;
953af6ab5fSopenharmony_ci}
963af6ab5fSopenharmony_ci
973af6ab5fSopenharmony_cifunction test_class_method() {
983af6ab5fSopenharmony_ci    let a = new A();
993af6ab5fSopenharmony_ci    A.n = 1;
1003af6ab5fSopenharmony_ci    a.set_n() {
1013af6ab5fSopenharmony_ci        A.n++;
1023af6ab5fSopenharmony_ci    }
1033af6ab5fSopenharmony_ci    assert A.n == 2: "expected: " + 2 + " actual: " + A.n;
1043af6ab5fSopenharmony_ci
1053af6ab5fSopenharmony_ci    A.set_n_static() {
1063af6ab5fSopenharmony_ci        A.n++;
1073af6ab5fSopenharmony_ci    }
1083af6ab5fSopenharmony_ci    assert A.n == 3: "expected: " + 3 + " actual: " + A.n;
1093af6ab5fSopenharmony_ci}
1103af6ab5fSopenharmony_ci
1113af6ab5fSopenharmony_ci// test scenarios involving scope
1123af6ab5fSopenharmony_cifunction foo(c: () => void): void {
1133af6ab5fSopenharmony_ci    c();
1143af6ab5fSopenharmony_ci}
1153af6ab5fSopenharmony_ci
1163af6ab5fSopenharmony_cifunction foo2(a: int) : int {
1173af6ab5fSopenharmony_ci    a++;
1183af6ab5fSopenharmony_ci    return a;
1193af6ab5fSopenharmony_ci}
1203af6ab5fSopenharmony_ci
1213af6ab5fSopenharmony_ciclass B {
1223af6ab5fSopenharmony_ci    constructor (b: int) {
1233af6ab5fSopenharmony_ci        this.b = b;
1243af6ab5fSopenharmony_ci    }
1253af6ab5fSopenharmony_ci
1263af6ab5fSopenharmony_ci    get_b(): int {
1273af6ab5fSopenharmony_ci        return this.b
1283af6ab5fSopenharmony_ci    }
1293af6ab5fSopenharmony_ci
1303af6ab5fSopenharmony_ci    b: int = 0;
1313af6ab5fSopenharmony_ci}
1323af6ab5fSopenharmony_ci
1333af6ab5fSopenharmony_cifunction test_scope(): void {
1343af6ab5fSopenharmony_ci    foo() {
1353af6ab5fSopenharmony_ci       let num: int = 3;
1363af6ab5fSopenharmony_ci       assert num == 3: "expected: " + 3 + " actual: " + num;
1373af6ab5fSopenharmony_ci       {
1383af6ab5fSopenharmony_ci            num++;
1393af6ab5fSopenharmony_ci            assert num == 4: "expected: " + 4 + " actual: " + num;
1403af6ab5fSopenharmony_ci            {
1413af6ab5fSopenharmony_ci                num++;
1423af6ab5fSopenharmony_ci                assert num == 5: "expected: " + 5 + " actual: " + num;
1433af6ab5fSopenharmony_ci            }
1443af6ab5fSopenharmony_ci       }
1453af6ab5fSopenharmony_ci
1463af6ab5fSopenharmony_ci       let a = foo2(num);
1473af6ab5fSopenharmony_ci       assert a == 6: "expected: " + 6 + " actual: " + a;
1483af6ab5fSopenharmony_ci
1493af6ab5fSopenharmony_ci       let b = new B(num);
1503af6ab5fSopenharmony_ci       assert b.get_b() == 5: "expected: " + 5 + " actual: " + b.get_b();
1513af6ab5fSopenharmony_ci
1523af6ab5fSopenharmony_ci       foo() {
1533af6ab5fSopenharmony_ci          let k = 1
1543af6ab5fSopenharmony_ci          assert k == 1: "expected: " + 1 + " actual: " + k;
1553af6ab5fSopenharmony_ci       }
1563af6ab5fSopenharmony_ci    };
1573af6ab5fSopenharmony_ci}
1583af6ab5fSopenharmony_ci
1593af6ab5fSopenharmony_ci// test recovery of trailing block
1603af6ab5fSopenharmony_cifunction test_recover_trailing_block() {
1613af6ab5fSopenharmony_ci    let a = 100;
1623af6ab5fSopenharmony_ci    foo(()=>{})
1633af6ab5fSopenharmony_ci    {
1643af6ab5fSopenharmony_ci        let k = a;
1653af6ab5fSopenharmony_ci        let b = new B(k);
1663af6ab5fSopenharmony_ci        assert b.get_b() == k: "expected: " + k + " actual: " + b.get_b();
1673af6ab5fSopenharmony_ci
1683af6ab5fSopenharmony_ci        a++;
1693af6ab5fSopenharmony_ci    };
1703af6ab5fSopenharmony_ci    assert a == 101: "expected: " + 101 + " actual: " + a;
1713af6ab5fSopenharmony_ci}
1723af6ab5fSopenharmony_ci
1733af6ab5fSopenharmony_cifunction main() {
1743af6ab5fSopenharmony_ci    test_transform();
1753af6ab5fSopenharmony_ci    test_recover_trailing_block();
1763af6ab5fSopenharmony_ci    test_overload();
1773af6ab5fSopenharmony_ci    test_class_method();
1783af6ab5fSopenharmony_ci    test_scope();
1793af6ab5fSopenharmony_ci}
180