* 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.
*/
import * as arkts from '@koalaui/libarkts';
import { CustomDialogNames } from '../../../common/predefines';
import { expectNameInTypeReference } from '../../../common/arkts-utils';
import { isDeclFromArkUI } from '../../../collectors/ui-collectors/utils';
export interface CustomDialogControllerPropertyInfo {
propertyName: string;
controllerTypeName: string;
}
function findCustomDialogControllerTypeName(
node: arkts.TypeNode | undefined,
ignoreDecl: boolean = false
): string | undefined {
if (!node) {
return undefined;
}
if (arkts.isETSUnionType(node)) {
for (const typeNode of node.types) {
const controllerName = findCustomDialogControllerTypeName(typeNode, ignoreDecl);
if (!!controllerName) {
return controllerName;
}
}
return undefined;
}
if (arkts.isETSTypeReference(node)) {
const nameNode = expectNameInTypeReference(node);
if (!nameNode) {
return undefined;
}
const decl = arkts.getPeerIdentifierDecl(nameNode.peer);
if (!decl || !arkts.isClassDefinition(decl)) {
return undefined;
}
if (!ignoreDecl && !isDeclFromArkUI(decl)) {
return undefined;
}
if (nameNode.name === CustomDialogNames.CUSTOM_DIALOG_CONTROLLER) {
return nameNode.name;
}
return undefined;
}
return undefined;
}
function collectInfoFromProperty(
node: arkts.ClassProperty,
typeNode: arkts.TypeNode | undefined,
ignoreDecl: boolean = false
): CustomDialogControllerPropertyInfo | undefined {
const key = node.key;
if (!key || !arkts.isIdentifier(key) || !typeNode) {
return undefined;
}
const controllerTypeName = findCustomDialogControllerTypeName(typeNode, ignoreDecl);
if (!controllerTypeName) {
return undefined;
}
return { propertyName: key.name, controllerTypeName };
}
export class CustomDialogControllerPropertyCache {
private _cache: Map<string, CustomDialogControllerPropertyInfo>;
private static instance: CustomDialogControllerPropertyCache;
private constructor() {
this._cache = new Map<string, CustomDialogControllerPropertyInfo>();
}
static getInstance(): CustomDialogControllerPropertyCache {
if (!this.instance) {
this.instance = new CustomDialogControllerPropertyCache();
}
return this.instance;
}
reset(): void {
this._cache.clear();
}
getInfo(className: string): CustomDialogControllerPropertyInfo | undefined {
return this._cache.get(className);
}
collect(
property: arkts.ClassProperty,
propertyType: arkts.TypeNode | undefined,
className: string,
ignoreDecl: boolean = false
): void {
const info = collectInfoFromProperty(property, propertyType, ignoreDecl);
if (!!info) {
this._cache.set(className, info);
}
}
}