1/* 2 * Copyright (c) 2023-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 16// test transformation of trailing lambda 17let x: int = 1; 18const y: int = 3; 19 20function f1(callback: ()=>void) { 21 callback(); 22} 23 24function f2() { 25 x = x + 1 26} 27 28function f3(callback: ()=>void) :int { 29 callback(); 30 return y; 31} 32 33function test_transform() { 34 x = 1 35 f1() { // Test '{' at the same line as call expression, block statement can be transformed to trailing lambda 36 x++ 37 } 38 assertEQ(x, 2, "expected: " + 2 + " actual: " + x) 39 40 f1() 41 { // Test '{' not the same line as call expression, block statement can be transformed to trailing lambda 42 x++ 43 } 44 assertEQ(x, 3, "expected: " + 3 + " actual: " + x) 45 46 f2() 47 { // Test this block run as a standalone code block 48 x++ 49 } 50 assertEQ(x, 5, "expected: " + 5 + " actual: " + x) 51 52 let b = f3() 53 { x++ } 54 assertEQ(x, 6, "expected: " + 6 + " actual: " + x) 55 assertEQ(b, y, "expected: " + y + " actual: " + b) 56 57 let a = f3() { x++ } 58 assertEQ(x, 7, "expected: " + 7 + " actual: " + x) 59 assertEQ(a, y, "expected: " + y + " actual: " + a) 60 61 assertEQ(y, f3(){}) 62 assertEQ(y, f3(()=>{})) 63 { 64 } 65} 66 67// test signature matches of trailing lambda 68function f_overload(num: Int, callback: ()=>void): Int { 69 return 0; 70} 71 72function f_overload(num: Int): Int { 73 return num; 74} 75 76function test_overload() { 77 let num = f_overload(1) 78 { 79 // This block will be transform to a trailing lambda 80 } 81 assertEQ(num, 0, "expected: " + 0 + " actual: " + num) 82} 83 84// test class methods using trailing lambda 85class A { 86 set_n(callback: ()=>void) { 87 callback(); 88 } 89 90 public static set_n_static(callback: ()=>void): void { 91 callback(); 92 } 93 94 static n: int = 1; 95} 96 97function test_class_method() { 98 let a = new A(); 99 A.n = 1; 100 a.set_n() { 101 A.n++; 102 } 103 assertEQ(A.n, 2, "expected: " + 2 + " actual: " + A.n) 104 105 A.set_n_static() { 106 A.n++; 107 } 108 assertEQ(A.n, 3, "expected: " + 3 + " actual: " + A.n) 109} 110 111// test scenarios involving scope 112function foo(c: () => void): void { 113 c(); 114} 115 116function foo2(a: int) : int { 117 a++; 118 return a; 119} 120 121class B { 122 constructor (b: int) { 123 this.b = b; 124 } 125 126 get_b(): int { 127 return this.b 128 } 129 130 b: int = 0; 131} 132 133function test_scope(): void { 134 foo() { 135 let num: int = 3; 136 assertEQ(num, 3, "expected: " + 3 + " actual: " + num) 137 { 138 num++; 139 assertEQ(num, 4, "expected: " + 4 + " actual: " + num) 140 { 141 num++; 142 assertEQ(num, 5, "expected: " + 5 + " actual: " + num) 143 } 144 } 145 146 let a = foo2(num); 147 assertEQ(a, 6, "expected: " + 6 + " actual: " + a) 148 149 let b = new B(num); 150 assertEQ(b.get_b(), 5, "expected: " + 5 + " actual: " + b.get_b()) 151 152 foo() { 153 let k = 1 154 assertEQ(k, 1, "expected: " + 1 + " actual: " + k) 155 } 156 }; 157} 158 159// test recovery of trailing block 160function test_recover_trailing_block() { 161 let a = 100; 162 foo(()=>{}) 163 { 164 let k = a; 165 let b = new B(k); 166 assertEQ(b.get_b(), k, "expected: " + k + " actual: " + b.get_b()) 167 168 a++; 169 }; 170 assertEQ(a, 101, "expected: " + 101 + " actual: " + a) 171} 172 173function main() { 174 test_transform(); 175 test_recover_trailing_block(); 176 test_overload(); 177 test_class_method(); 178 test_scope(); 179} 180