diff --git a/static_core/plugins/ets/runtime/ets_libbase_runtime.yaml b/static_core/plugins/ets/runtime/ets_libbase_runtime.yaml index 9649558f769dcd992b3b88cb32f7c251cc815d95..cd8b2767ece186feb706054e7489f3d28b3c8e48 100644 --- a/static_core/plugins/ets/runtime/ets_libbase_runtime.yaml +++ b/static_core/plugins/ets/runtime/ets_libbase_runtime.yaml @@ -6016,6 +6016,46 @@ intrinsics: args: [ ] impl: ark::ets::intrinsics::StdCoreClassGetDescriptor + - name: StdCoreClassGetInterfaces + space: ets + class_name: std.core.Class + method_name: getInterfaces + static: false + signature: + ret: std.core.Class[] + args: [ ] + impl: ark::ets::intrinsics::StdCoreClassGetInterfaces + + - name: StdCoreClassIsEnum + space: ets + class_name: std.core.Class + method_name: isEnum + static: false + signature: + ret: u1 + args: [ ] + impl: ark::ets::intrinsics::StdCoreClassIsEnum + + - name: StdCoreClassIsInterface + space: ets + class_name: std.core.Class + method_name: isInterface + static: false + signature: + ret: u1 + args: [ ] + impl: ark::ets::intrinsics::StdCoreClassIsInterface + + - name: StdCoreClassIsFixedArray + space: ets + class_name: std.core.Class + method_name: isFixedArray + static: false + signature: + ret: u1 + args: [ ] + impl: ark::ets::intrinsics::StdCoreClassIsFixedArray + ########################## # std.core.RuntimeLinker # ########################## diff --git a/static_core/plugins/ets/runtime/intrinsics/std_core_Class.cpp b/static_core/plugins/ets/runtime/intrinsics/std_core_Class.cpp index 56f52b034188ce9ebde3a6f0c611bbe83a975af9..6ab934f6658cc6e1378b3bc06bc22b92ee0b48a5 100644 --- a/static_core/plugins/ets/runtime/intrinsics/std_core_Class.cpp +++ b/static_core/plugins/ets/runtime/intrinsics/std_core_Class.cpp @@ -78,6 +78,17 @@ EtsString *StdCoreClassGetDescriptor(EtsClass *cls) return EtsString::CreateFromMUtf8(cls->GetDescriptor()); } +ObjectHeader *StdCoreClassGetInterfaces(EtsClass *cls) +{ + auto *coro = EtsCoroutine::GetCurrent(); + const auto interfaces = cls->GetRuntimeClass()->GetInterfaces(); + auto result = EtsObjectArray::Create(PlatformTypes(coro)->coreClass, interfaces.size()); + for (size_t i = 0; i < interfaces.size(); i++) { + result->Set(i, reinterpret_cast(EtsClass::FromRuntimeClass(interfaces[i]))); + } + return reinterpret_cast(result); +} + EtsObject *StdCoreClassCreateInstance(EtsClass *cls) { ASSERT(cls != nullptr); @@ -154,4 +165,22 @@ EtsRuntimeLinker *EtsGetNearestNonBootRuntimeLinker() return nullptr; } +EtsBoolean StdCoreClassIsEnum(EtsClass *cls) +{ + ASSERT(cls != nullptr); + return cls->IsEtsEnum(); +} + +EtsBoolean StdCoreClassIsInterface(EtsClass *cls) +{ + ASSERT(cls != nullptr); + return cls->IsInterface(); +} + +EtsBoolean StdCoreClassIsFixedArray(EtsClass *cls) +{ + ASSERT(cls != nullptr); + return cls->IsArrayClass(); +} + } // namespace ark::ets::intrinsics diff --git a/static_core/plugins/ets/stdlib/std/core/Class.ets b/static_core/plugins/ets/stdlib/std/core/Class.ets index e290401d2a4942338bfefc942855a8d46e1362a5..eafb797034624045541c69cdb89587b485055c4a 100644 --- a/static_core/plugins/ets/stdlib/std/core/Class.ets +++ b/static_core/plugins/ets/stdlib/std/core/Class.ets @@ -38,6 +38,8 @@ export final class Class { public native getLinker(): RuntimeLinker + public native getInterfaces(): FixedArray + /** * Invoke class initializer once if class is not initialized */ @@ -62,4 +64,11 @@ export final class Class { */ // NOTE(ekaterinazaytseva): unable to replace internal - used in RuntimeLinker.ets as public internal native getDescriptor(): string + + public native isEnum(): boolean + + public native isInterface(): boolean + + public native isFixedArray(): boolean + } diff --git a/static_core/plugins/ets/tests/ets_func_tests/std/core/ClassTest.ets b/static_core/plugins/ets/tests/ets_func_tests/std/core/ClassTest.ets new file mode 100644 index 0000000000000000000000000000000000000000..a3b6bbb970e26c63fc6e17501481dfa5c70c09e7 --- /dev/null +++ b/static_core/plugins/ets/tests/ets_func_tests/std/core/ClassTest.ets @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace X { + export class A { + x: int + + } + + export interface B { + + } + + export class C implements B { + y: String + } + + export enum D { + aa, + bb + } + + export function voidFunc(): void {} + + export function primFunc(): int { + return 42 + } + + export function faFunc(): FixedArray { + let x: FixedArray = [1, 2, 3] + return x + } + + export function objectFunc(): A { + return new A() + } + + export class funcContainer { + public voidFunc(): void {} + + public primFunc(): int { + return 42 + } + + public faFunc(): FixedArray { + let x: FixedArray = [1, 2, 3] + return x + } + + public objectFunc(): A { + return new A() + } + } + + interface E { + + } + + class F implements E { + + } + + export function returnHiddenClassObject(): F { + return new F() + } + + enum G { + aa, + bb + } + + export function returnHiddenEnumValue(): G { + return G.aa + } +} + +export class A { + +} + +export interface B { + +} + +export class C implements B { + +} + +export enum D { + aa, + bb +} + + +export function voidFunc(): void {} + +export function primFunc(): int { + return 42 +} + +export function faFunc(): FixedArray { + let x: FixedArray = [1, 2, 3] + return x +} + +export function objectFunc(): A { + return new A() +} + +export class funcContainer { + public voidFunc(): void {} + + public primFunc(): int { + return 42 + } + + public faFunc(): FixedArray { + let x: FixedArray = [1, 2, 3] + return x + } + + public objectFunc(): A { + return new A() + } +} + +function checkClassIsNotEnumAndNotInterface() { + for (let obj of [new X.C(), new X.A(), new C(), new A(), X.returnHiddenClassObject()]) { + arktest.assertFalse(Class.of(obj).isEnum()) + arktest.assertFalse(Class.of(obj).isInterface()) + } +} + +function checkEnumIsEnumAndNotInterface() { + for (let obj of [X.D.aa, D.aa]) { + arktest.assertTrue(Class.of(obj).isEnum()) + arktest.assertFalse(Class.of(obj).isInterface()) + } + arktest.assertTrue(Class.of(X.returnHiddenEnumValue()).isEnum()) + arktest.assertFalse(Class.of(X.returnHiddenEnumValue()).isInterface()) +} + +function checkInterfaceIsInterfaceAndNotEnum() { + let cls1 = Class.of(new X.C()) + let inf1 = cls1.getInterfaces()[0] + let cls2 = Class.of(new C()) + let inf2 = cls2.getInterfaces()[0] + let cls3 = Class.of(X.returnHiddenClassObject()) + let inf3 = cls3.getInterfaces()[0] + for (let inf of [inf1, inf2, inf3]) { + arktest.assertFalse(inf.isEnum()) + arktest.assertTrue(inf.isInterface()) + } +} + +function checkFixedArray() { + let varInt = 5 + let varDouble = 5.5 + let varPrimitiveArray: Array = [1, 2, 3] + let varObjectArray: Array = [new A()] + let varPrimitiveFixedArray: FixedArray = [1, 2, 3] + let varObjectFixedArray: FixedArray = [new A()] + let varObject = new A() + let varString = "abc" + arktest.assertFalse(Class.of(varInt).isFixedArray()) + arktest.assertFalse(Class.of(varDouble).isFixedArray()) + arktest.assertFalse(Class.of(varPrimitiveArray).isFixedArray()) + arktest.assertFalse(Class.of(varObjectArray).isFixedArray()) + arktest.assertTrue(Class.of(varPrimitiveFixedArray).isFixedArray()) + arktest.assertTrue(Class.of(varObjectFixedArray).isFixedArray()) + arktest.assertFalse(Class.of(varString).isFixedArray()) + arktest.assertFalse(Class.of(varObject).isFixedArray()) + arktest.assertFalse(Class.of(D.aa).isFixedArray()) + arktest.assertFalse(Class.of(new C()).getInterfaces()[0].isFixedArray()) + arktest.assertFalse(Class.of(faFunc).isFixedArray()) + arktest.assertFalse(Class.of(new funcContainer().faFunc).isFixedArray()) +} + +function checkFunctions() { + let gc = new funcContainer() + let nc = new X.funcContainer() + let gList = [voidFunc, primFunc, faFunc, objectFunc] + let gcList = [gc.voidFunc, gc.primFunc, gc.faFunc, gc.objectFunc] + let nList = [X.voidFunc, X.primFunc, X.faFunc, X.objectFunc] + let ncList = [nc.voidFunc, nc.primFunc, nc.faFunc, nc.objectFunc] + for (let funcList of [gList, gcList, nList, ncList]) { + for (let func of funcList) { + let cls = Class.of(func) + arktest.assertFalse(cls.isEnum()) + arktest.assertFalse(cls.isInterface()) + arktest.assertFalse(cls.isFixedArray()) + } + } +} + +function main(): void { + let ts = new arktest.ArkTestsuite("Class API test") + ts.addTest("checkClassIsNotEnumAndNotInterface", checkClassIsNotEnumAndNotInterface) + ts.addTest("checkEnumIsEnumAndNotInterface", checkEnumIsEnumAndNotInterface) + ts.addTest("checkInterfaceIsInterfaceAndNotEnum", checkInterfaceIsInterfaceAndNotEnum) + ts.addTest("checkFixedArray", checkFixedArray) + ts.addTest("checkFunctions", checkFunctions) + ts.run(); +}