* 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 { getAnnotationUsage, getIdentifierName, hasAnnotation, PresetDecorators } from '../utils';
import { AbstractUISyntaxRule } from './ui-syntax-rule';
class ComponentComponentV2InitCheckRule extends AbstractUISyntaxRule {
private componentV1WithLinkList: string[] = [];
public setup(): Record<string, string> {
return {
componentInitLinkCheck: `A V2 component cannot be used with any member property decorated by '@Link' in a V1 component.`,
};
}
public beforeTransform(): void {
this.componentV1WithLinkList = [];
}
public parsed(node: arkts.AstNode): void {
this.initComponentV1WithLinkList(node);
this.checkComponentInitLink(node);
}
private initComponentV1WithLinkList(node: arkts.AstNode): void {
if (arkts.nodeType(node) !== arkts.Es2pandaAstNodeType.AST_NODE_TYPE_ETS_MODULE) {
return;
}
node.getChildren().forEach((member) => {
if (!arkts.isETSStructDeclaration(member) || !member.definition.ident ||
!hasAnnotation(member?.definition.annotations, PresetDecorators.COMPONENT_V1)) {
return;
}
let structName: string = member.definition.ident?.name ?? '';
member.definition?.body?.forEach((item) => {
if (!arkts.isClassProperty(item) || !item.key) {
return;
}
if (item.annotations.some(annotation => annotation.expr &&
getIdentifierName(annotation.expr) === PresetDecorators.LINK)) {
this.componentV1WithLinkList.push(structName);
}
});
});
}
private checkComponentInitLink(node: arkts.AstNode): void {
if (!arkts.isIdentifier(node) || !this.componentV1WithLinkList.includes(getIdentifierName(node))) {
return;
}
if (!node.parent) {
return;
}
let structNode = node.parent;
while (!arkts.isETSStructDeclaration(structNode)) {
if (!structNode.parent) {
return;
}
structNode = structNode.parent;
}
if (getAnnotationUsage(structNode, PresetDecorators.COMPONENT_V2) === undefined) {
return;
}
const reportNode = node.parent.parent && arkts.isExpressionStatement(node.parent.parent)
? node.parent.parent
: node.parent;
this.report({
node: reportNode,
message: this.messages.componentInitLinkCheck,
fix: () => {
return {
title: 'Remove the component',
range: [reportNode.startPosition, reportNode.endPosition],
code: '',
};
}
});
}
}
export default ComponentComponentV2InitCheckRule;