1/* 2 * Copyright (c) 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 16type S = string 17 18function xassert(a: S, b: S) { assertEQ(a, b) } 19 20function p0call(f: () => S, a: S[]) { 21 return f() 22} 23function p1call(f: (p1: S) => S, a: S[]) { 24 return f(a[0]) 25} 26function p2call(f: (p1: S, p2: S) => S, a: S[]) { 27 return f(a[0], a[1]) 28} 29function p012call(f: () => S, a: S[]) { 30 return p0call(f, a) + p1call(f, a) + p2call(f, a) 31} 32function p_12call(f: (p1: S) => S, a: S[]) { 33 return p1call(f, a) + p2call(f, a) 34} 35function p__2call(f: (p1: S, p2: S) => S, a: S[]) { 36 return p2call(f, a) 37} 38 39function r0__call(f: (p1?: S, p2?: S) => S, a: S[]) { 40 return f() + f(a[0]) + f(a[0], a[1]) 41} 42function r_1_call(f: (p1: S, p2?: S) => S, a: S[]) { 43 return f(a[0]) + f(a[0], a[1]) 44} 45 46function testBasicArity() { 47 let args = ["a", "b"] 48 let f0 = () => "/f0:" 49 let f1 = (a1: S) => "/f1:" + a1 50 let f2 = (a1: S, a2: S) => "/f2:" + a1 + a2 51 52 xassert(p012call(f0, args), "/f0:/f0:/f0:") 53 xassert(p_12call(f0, args), "/f0:/f0:") 54 xassert(p_12call(f1, args), "/f1:a/f1:a") 55 xassert(p__2call(f0, args), "/f0:") 56 xassert(p__2call(f1, args), "/f1:a") 57 xassert(p__2call(f2, args), "/f2:ab") 58 59 xassert(r0__call(f0, args), "/f0:/f0:/f0:") 60 xassert(r_1_call(f0, args), "/f0:/f0:") 61 xassert(r_1_call(f1, args), "/f1:a/f1:a") 62} 63testBasicArity(); 64 65function testOptionalArity() { 66 let args = ["a", "b"] 67 let tou = (v?: string) => v ?? "u" 68 let f0 = (a1?: S, a2?: S) => "/f0:" + tou(a1) + tou(a2) 69 let f1 = (a1: S, a2?: S) => "/f1:" + a1 + tou(a2) 70 let f2 = (a1: S, a2: S) => "/f2:" + a1 + a2 71 72 xassert(p012call(f0, args), "/f0:uu/f0:au/f0:ab") 73 xassert(p_12call(f0, args), "/f0:au/f0:ab") 74 xassert(p_12call(f1, args), "/f1:au/f1:ab") 75 xassert(p__2call(f0, args), "/f0:ab") 76 xassert(p__2call(f1, args), "/f1:ab") 77 xassert(p__2call(f2, args), "/f2:ab") 78 79 xassert(r0__call(f0, args), "/f0:uu/f0:au/f0:ab") 80 xassert(r_1_call(f0, args), "/f0:au/f0:ab") 81 xassert(r_1_call(f1, args), "/f1:au/f1:ab") 82} 83testOptionalArity(); 84 85function testDfltArity() { 86 let args = ["a", "b"] 87 let f0 = (a1: S = "x", a2: S = "y") => "/f0:" + a1 + a2 88 let f1 = (a1: S, a2: S = "y") => "/f1:" + a1 + a2 89 let f2 = (a1: S, a2: S) => "/f2:" + a1 + a2 90 91 xassert(p012call(f0, args), "/f0:xy/f0:ay/f0:ab") 92 xassert(p_12call(f0, args), "/f0:ay/f0:ab") 93 xassert(p_12call(f1, args), "/f1:ay/f1:ab") 94 xassert(p__2call(f0, args), "/f0:ab") 95 xassert(p__2call(f1, args), "/f1:ab") 96 xassert(p__2call(f2, args), "/f2:ab") 97 98 xassert(r0__call(f0, args), "/f0:xy/f0:ay/f0:ab") 99 xassert(r_1_call(f0, args), "/f0:ay/f0:ab") 100 xassert(r_1_call(f1, args), "/f1:ay/f1:ab") 101} 102testDfltArity() 103 104function testDfltEvaluation() { 105 let counter = "c" 106 let inc = () => (counter += "x") 107 let f = (a: string = inc()) => a 108 xassert(f("a"), "a") 109 xassert(f(), "cx") 110 xassert(f(), "cxx") 111 xassert(f(undefined), "cxxx") 112} 113testDfltEvaluation() 114 115function testArrowExprCalls() { 116 let x = (a1: S, a2?: S, a3?: S) => a1 + (a2 ?? "u") + (a3 ?? "u") 117 xassert(x("a"), "auu") 118 xassert(x("a", "b"), "abu") 119 xassert(x("a", "b", "c"), "abc") 120 121 xassert(((a?: S) => a ?? "u")(), "u") 122 // xassert(((a?: S) => a ?? "u")("a"), "a") // #22952: broken 123} 124testArrowExprCalls() 125 126class X<T> { 127 constructor(v: (p?: T) => T) { this.fv = v } 128 get f() { return this.fv } 129 fv: (p?: T) => T 130} 131function gcall<T>(x: X<T>, a: T) { 132 (x.f)(); 133 (x.f)(a); 134 (x.fv)(); 135 (x.fv)(a); 136} 137function testGenerics() { 138 let res: string = ":" 139 let fn = (a?: string) => { 140 res += (a ?? "D"); 141 return res; 142 }; 143 gcall(new X<string>(fn), "a") // #22952: inference fails 144 xassert(res, ":DaDa") 145} 146testGenerics(); 147 148function foo(a1: S, a2?: S) { return a1 + (a2 ?? "D") } 149function testFuncRef() { 150 let f = (a1: S, a2?: S) => foo(a1, a2) // #22952: foo is overloaded 151 xassert(f("a"), "aD") 152 xassert(f("a", undefined), "aD") 153 xassert(f("a", "b"), "ab") 154} 155testFuncRef(); 156