• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
16//@ts-ignore -- to avoid @types/node missing
17import { EventEmitter } from 'stream';
18//@ts-ignore -- to avoid @types/node missing
19const etsVm = require('lib/module/ets_interop_js_napi');
20
21type ClassType = new (...args: {}[]) => {};
22
23const ETS_MODULE_NAME: string = 'interop_class_extension';
24const makePrefix = (packageName: string): string => 'L' + packageName.replace('.', '/') + '/';
25
26const getClass = (name: string, packageName?: string): ClassType => etsVm.getClass(makePrefix(packageName ?? ETS_MODULE_NAME) + name + ';');
27
28export const DEFAULT_STRING_VALUE = 'Panda';
29//@ts-ignore -- to avoid @types/node missing
30export const DEFAULT_NUMERIC_VALUE = Math.round(Math.random() * Number!.MAX_SAFE_INTEGER);
31
32type AnyType = {};
33
34export const helperIsJSInstanceOf = (obj: AnyType, classObj: Function): boolean => {
35	return obj instanceof classObj;
36};
37
38export class TestUserClass {
39	private _privateValue: string = DEFAULT_STRING_VALUE;
40	protected protectedValue: string = DEFAULT_STRING_VALUE;
41	public publicValue: string = DEFAULT_STRING_VALUE;
42	public readonly readonlyValue: string = DEFAULT_STRING_VALUE;
43	public readonly constructorSetValue: string;
44
45	static isMyInstance(obj: {}): boolean {
46		return obj instanceof TestUserClass;
47	}
48
49	constructor(constructorArg: string) {
50		this.constructorSetValue = constructorArg;
51	}
52}
53
54export const TestNativeClass = EventEmitter;
55
56export const extendUserClass = (): boolean => {
57	const TSTestUserClass = getClass('TSTestUserClass');
58	class ExtendedEtsUserClass extends TSTestUserClass {}
59	const classInstance = new ExtendedEtsUserClass();
60	return classInstance instanceof ExtendedEtsUserClass;
61};
62
63export const extendNativeClass = (): boolean => {
64	const TSTestNativeClass = getClass('ArrayBuffer', 'escompat');
65	class ExtendedEtsNativeClass extends TSTestNativeClass {
66		constructor(length: 2) {
67			super(length);
68		}
69	}
70	const classInstance = new ExtendedEtsNativeClass(2);
71	return classInstance instanceof TSTestNativeClass;
72};
73
74export const jsRespectsProtectedModifier = (): boolean => {
75	const TSTestUserClass = getClass('TSTestUserClass');
76	try {
77		class ExtendedEtsUserClass extends TSTestUserClass {
78			constructor() {
79				super();
80				//@ts-ignore -- to ignore compile-time check, as TSTestUserClass is only acquired in runtime
81				this.protectedProperty = 'redefinedProtected';
82			}
83
84			validProtectedGetter(): string {
85				//@ts-ignore -- to ignore compile-time check, as TSTestUserClass is only acquired in runtime
86				return this.protectedProperty;
87			}
88		}
89		const classInstance = new ExtendedEtsUserClass();
90		return classInstance.validProtectedGetter() === 'redefinedProtected';
91	} catch (e) {
92		return false;
93	}
94};
95
96export const jsRespectsStaticModifier = (): boolean => {
97	const TSTestUserClass = getClass('TSTestUserClass');
98	class ExtendedEtsUserClass extends TSTestUserClass {}
99	//@ts-ignore -- to ignore compile-time check, as TSTestUserClass is only acquired in runtime
100	return ExtendedEtsUserClass?.staticProperty === 'static';
101};
102