• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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