1/*
2 * Copyright (c) 2024 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
16interface B<T> {
17  f2(v: B<T>): B<T>; 
18}
19
20class C<T extends Numeric|string> implements B<T> {
21  f1(v: T): T { return v; }
22
23  f2(v: C<T>): C<T> { return new C<T>(); }
24  f2(v: B<T>): B<T> {
25     return this.f2(v as C<T>);
26  }
27
28  f5(x: T, y: T): string {return "C.f5"; }
29
30  f6(x: C<T>, y: C<T>): string { return "C.f6"; }
31  f7(x: T, y: C<T>): string { return "C.f7"; }
32}
33
34class D extends C<string> {
35  f1(v: string): string { return "oh"; }
36  f1(v: Int): Int { return 7; }
37
38  f2(v: D): D { return new D(); }
39
40  f3(){}
41  f4 (x: int, y: int): int { return x + y; }
42
43  f6(): string { return "D.f6"; }
44  f7(x: string, y: D): string { return "D.f7"; }
45}
46
47class F extends D {}
48
49class G<U extends Numeric|string> extends C<U> {}
50
51class E<U extends Integral> extends C<U> {
52  f1(v: U): Integral { 
53    if (v instanceof Int) {
54      return new Int(7);
55    } else if (v instanceof Long) {
56      return new Long(8);
57    } else {
58      return new Int(-1);
59    }
60  }
61
62  f2(v: E<U>): E<U> { return new E<U>(); }
63
64  f3(){}
65  f4(x:int, y: int): int { return x + y; }
66}
67
68
69function foo1(c: C<Int>) {
70 assert (c.f1(0) == 7);
71 assert (c.f2(c).f1(0) == 7);
72 assert (c.f5(1, 2) == "C.f5"); 
73 assert (c.f6(c, c) == "C.f6");
74}
75
76function foo2(c: C<Long>) {
77 assert (c.f1(0) == 8);
78 assert (c.f2(c).f1(0) == 8);
79 assert (c.f5(3, 4) == "C.f5");
80 assert (c.f7(3, c) == "C.f7");
81}
82
83
84function ttt(c: C<string>): void {
85  assert (c.f1("ah") == "oh"); 
86  assert (c.f2(c).f1("ah") == "oh");
87
88  let a: Object = "ah";
89  assert (c.f1(a) == "oh");
90  assert (c.f2(c).f1(a) == "oh");
91
92  assert (c.f5("ah", "ah") == "C.f5");
93  assert (c.f6(c, c) == "C.f6");;
94  assert ((c as D).f6() == "D.f6");
95  assert (c.f7("ah", c) == "D.f7");
96}
97
98function main() {
99  ttt(new D())
100  let c: C<Int> = new E<Int>();
101  foo1(c);
102  foo2(new E<Long>());
103}
104