13af6ab5fSopenharmony_ci/*
23af6ab5fSopenharmony_ci * Copyright (c) 2021-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_cifunction main(): void {
173af6ab5fSopenharmony_ci    let intType: TypeGetter<Int> = new TypeGetter<Int>();
183af6ab5fSopenharmony_ci    let testInt: Int = 2;
193af6ab5fSopenharmony_ci    let testDouble: Double = 3.0;
203af6ab5fSopenharmony_ci    let doubleType: TypeGetter<Double> = new TypeGetter<Double>();
213af6ab5fSopenharmony_ci    intType.SetType(testInt);
223af6ab5fSopenharmony_ci    doubleType.SetType(testDouble);
233af6ab5fSopenharmony_ci    assert intType.GetType() == 2;
243af6ab5fSopenharmony_ci    assert doubleType.GetType() == 3.0;
253af6ab5fSopenharmony_ci
263af6ab5fSopenharmony_ci    let aType: TypeGetter<A> = new TypeGetter<A>();
273af6ab5fSopenharmony_ci    let aClass: A = new A();
283af6ab5fSopenharmony_ci    aType.SetType(aClass);
293af6ab5fSopenharmony_ci    assert aType.GetType().aValue() == 1;
303af6ab5fSopenharmony_ci
313af6ab5fSopenharmony_ci    let ext1Class: Ext1 = new Ext1();
323af6ab5fSopenharmony_ci    let ext2Class: Ext2 = new Ext2();
333af6ab5fSopenharmony_ci    assert bar(ext1Class, ext2Class) == 7;
343af6ab5fSopenharmony_ci    assert bar(ext2Class, ext1Class) == -7;
353af6ab5fSopenharmony_ci
363af6ab5fSopenharmony_ci    let bc: B = new B();
373af6ab5fSopenharmony_ci    let cc : C = new C();
383af6ab5fSopenharmony_ci    let dc: D = new D();
393af6ab5fSopenharmony_ci    assert bc.bMet(cc).cMet() == 17;
403af6ab5fSopenharmony_ci    assert bc.bMet(cc).ifaceMet() == 10;
413af6ab5fSopenharmony_ci    assert bc.bMet(dc).dMet() == 8;
423af6ab5fSopenharmony_ci}
433af6ab5fSopenharmony_ci
443af6ab5fSopenharmony_ciinterface ifaceExt {
453af6ab5fSopenharmony_ci  ifmet(other: Object): int;
463af6ab5fSopenharmony_ci}
473af6ab5fSopenharmony_ci
483af6ab5fSopenharmony_cifunction ifaceType<T extends ifaceExt>(x: T, y: T): int {
493af6ab5fSopenharmony_ci  return x.ifmet(y);
503af6ab5fSopenharmony_ci}
513af6ab5fSopenharmony_ci
523af6ab5fSopenharmony_ciclass TypeGetter<TT> {
533af6ab5fSopenharmony_ci    tVar: TT;
543af6ab5fSopenharmony_ci
553af6ab5fSopenharmony_ci    GetType(): TT{
563af6ab5fSopenharmony_ci        return this.tVar;
573af6ab5fSopenharmony_ci    }
583af6ab5fSopenharmony_ci
593af6ab5fSopenharmony_ci    SetType(a0: TT): void{
603af6ab5fSopenharmony_ci        this.tVar = a0;
613af6ab5fSopenharmony_ci    }
623af6ab5fSopenharmony_ci}
633af6ab5fSopenharmony_ci
643af6ab5fSopenharmony_ciclass A {
653af6ab5fSopenharmony_ci    aValue(): int {
663af6ab5fSopenharmony_ci        return 1;
673af6ab5fSopenharmony_ci    }
683af6ab5fSopenharmony_ci}
693af6ab5fSopenharmony_ci
703af6ab5fSopenharmony_ciclass AConstraint<T extends A>{
713af6ab5fSopenharmony_ci    cVar: T;
723af6ab5fSopenharmony_ci
733af6ab5fSopenharmony_ci    getVal(): void {
743af6ab5fSopenharmony_ci        this.cVar.aValue();
753af6ab5fSopenharmony_ci    }
763af6ab5fSopenharmony_ci}
773af6ab5fSopenharmony_ci
783af6ab5fSopenharmony_ciinterface iface2<T>{
793af6ab5fSopenharmony_ci    ifaceMet(): int;
803af6ab5fSopenharmony_ci}
813af6ab5fSopenharmony_ci
823af6ab5fSopenharmony_ciclass C implements iface2<Object>{
833af6ab5fSopenharmony_ci    public override ifaceMet(): int{
843af6ab5fSopenharmony_ci        return 10;
853af6ab5fSopenharmony_ci    }
863af6ab5fSopenharmony_ci    public cMet(): int {
873af6ab5fSopenharmony_ci        return 17;
883af6ab5fSopenharmony_ci    }
893af6ab5fSopenharmony_ci}
903af6ab5fSopenharmony_ci
913af6ab5fSopenharmony_ciclass D extends C{
923af6ab5fSopenharmony_ci    public dMet(): int {
933af6ab5fSopenharmony_ci        return 8;
943af6ab5fSopenharmony_ci    }
953af6ab5fSopenharmony_ci}
963af6ab5fSopenharmony_ci
973af6ab5fSopenharmony_ciclass B {
983af6ab5fSopenharmony_ci    public bMet<LU extends C>(a: LU): LU {
993af6ab5fSopenharmony_ci        let b: int = 2;
1003af6ab5fSopenharmony_ci        a.ifaceMet();
1013af6ab5fSopenharmony_ci        return a;
1023af6ab5fSopenharmony_ci    }
1033af6ab5fSopenharmony_ci}
1043af6ab5fSopenharmony_ci
1053af6ab5fSopenharmony_ciinterface ifaceExt2 {
1063af6ab5fSopenharmony_ci  imet1(other: Object): int;
1073af6ab5fSopenharmony_ci  imet2(): int;
1083af6ab5fSopenharmony_ci}
1093af6ab5fSopenharmony_ci
1103af6ab5fSopenharmony_cifunction bar<T extends impExt>(x: T, y: T): int {
1113af6ab5fSopenharmony_ci  let a = x.imet2();
1123af6ab5fSopenharmony_ci  let b = y.imet2();
1133af6ab5fSopenharmony_ci  return a - b;
1143af6ab5fSopenharmony_ci}
1153af6ab5fSopenharmony_ci
1163af6ab5fSopenharmony_ciclass impExt implements ifaceExt2{
1173af6ab5fSopenharmony_ci    override imet1(other: Object): int{
1183af6ab5fSopenharmony_ci        return 20;
1193af6ab5fSopenharmony_ci    }
1203af6ab5fSopenharmony_ci    override imet2(): int{
1213af6ab5fSopenharmony_ci        return 21;
1223af6ab5fSopenharmony_ci    }
1233af6ab5fSopenharmony_ci}
1243af6ab5fSopenharmony_ci
1253af6ab5fSopenharmony_ciclass Ext1 extends impExt{
1263af6ab5fSopenharmony_ci    override imet1(other: Object): int{
1273af6ab5fSopenharmony_ci        return 11;
1283af6ab5fSopenharmony_ci    }
1293af6ab5fSopenharmony_ci    override imet2(): int {
1303af6ab5fSopenharmony_ci        return 14;
1313af6ab5fSopenharmony_ci    }
1323af6ab5fSopenharmony_ci}
1333af6ab5fSopenharmony_ci
1343af6ab5fSopenharmony_ciclass Ext2 extends impExt{
1353af6ab5fSopenharmony_ci    override imet1(other: Object): int{
1363af6ab5fSopenharmony_ci        return 22;
1373af6ab5fSopenharmony_ci    }
1383af6ab5fSopenharmony_ci    override imet2(): int {
1393af6ab5fSopenharmony_ci        return 7;
1403af6ab5fSopenharmony_ci    }
1413af6ab5fSopenharmony_ci}
1423af6ab5fSopenharmony_ci
1433af6ab5fSopenharmony_ciinterface inter3<T>{
1443af6ab5fSopenharmony_ci    met1(a0: T): int;
1453af6ab5fSopenharmony_ci    met2(a1: T): T;
1463af6ab5fSopenharmony_ci    met3(a3: T): inter3<T>;
1473af6ab5fSopenharmony_ci}
1483af6ab5fSopenharmony_ci
1493af6ab5fSopenharmony_ciclass ImplInter3<T> implements inter3<Int>{
1503af6ab5fSopenharmony_ci    public override met1(a0: Int): int {
1513af6ab5fSopenharmony_ci        return 1;
1523af6ab5fSopenharmony_ci    }
1533af6ab5fSopenharmony_ci
1543af6ab5fSopenharmony_ci    public override met2(a0: Int): Int {
1553af6ab5fSopenharmony_ci        return 2;
1563af6ab5fSopenharmony_ci    }
1573af6ab5fSopenharmony_ci
1583af6ab5fSopenharmony_ci    public override met3(a0: Int): inter3<Int> {
1593af6ab5fSopenharmony_ci        let a: inter3<Int> = new ImplInter3<Int>();
1603af6ab5fSopenharmony_ci        return a;
1613af6ab5fSopenharmony_ci    }
1623af6ab5fSopenharmony_ci}
163