diff --git a/arkui-plugins/collectors/collector.ts b/arkui-plugins/collectors/collector.ts new file mode 100644 index 0000000000000000000000000000000000000000..803c766d81197d1474bea83675fcbaa340785138 --- /dev/null +++ b/arkui-plugins/collectors/collector.ts @@ -0,0 +1,118 @@ +/* + * 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 { AbstractVisitor, VisitorOptions } from '../common/abstract-visitor'; +import { matchPrefix } from '../common/arkts-utils'; +import { LINTER_EXCLUDE_EXTERNAL_SOURCE_PREFIXES } from '../common/predefines'; +import { LogCollector } from '../common/log-collector'; +import { ImportCollector } from '../common/import-collector'; +import { ValidatorBuilder } from './ui-collectors/validators'; +import { CallRecordCollector } from './ui-collectors/call-record-collector'; +import { UICollectMetadata } from './ui-collectors/shared-types'; +import { collectUINodeByTypeInPostOrder, collectUINodeByTypeInPreOrder } from './ui-collectors/factory'; +import { collectMemoableNodeByTypeInPostOrder} from './memo-collectors/factory'; + +export interface CollectorOptions extends VisitorOptions { + disableMemoCollect?: boolean; + disableUICollect?: boolean; + disableUILinterCheck?: boolean; + shouldIgnoreDecl?: boolean; +} + +export class Collector extends AbstractVisitor { + private _shouldIgnoreDecl?: boolean; + private _disableMemoCollect?: boolean; + private _disableUICollect?: boolean; + private _disableUILinterCheck?: boolean; + + constructor(options?: CollectorOptions) { + super(options); + this._shouldIgnoreDecl = options?.shouldIgnoreDecl; + this._disableMemoCollect = options?.disableMemoCollect; + this._disableUICollect = options?.disableUICollect; + this._disableUILinterCheck = options?.disableUILinterCheck; + } + + get shouldIgnoreDecl(): boolean { + return this._shouldIgnoreDecl ?? false; + } + + get disableMemoCollect(): boolean { + return this._disableMemoCollect ?? false; + } + + get disableUICollect(): boolean { + return this._disableUICollect ?? false; + } + + get disableUILinterCheck(): boolean { + if (!this._disableUILinterCheck) { + return false; + } + return this.disableUICollect; + } + + init(): void { + if (this.disableUILinterCheck) { + ValidatorBuilder.shouldSkip = true; + } else if (!!this.externalSourceName) { + ValidatorBuilder.shouldSkip = matchPrefix(LINTER_EXCLUDE_EXTERNAL_SOURCE_PREFIXES, this.externalSourceName); + } + } + + reset(): void { + if (!this.disableUICollect) { + CallRecordCollector.getInstance(this.getMetadata()).reset(); + } + if (!this.disableUILinterCheck) { + LogCollector.getInstance().emitLogInfo(); + LogCollector.getInstance().reset(); + ValidatorBuilder.reset(); + } + if (!this.disableMemoCollect) { + ImportCollector.getInstance().insertCurrentImports(this.program); + } + } + + private getMetadata(): UICollectMetadata { + return { + isExternal: this.isExternal, + externalSourceName: this.externalSourceName, + program: this.program, + shouldIgnoreDecl: this.shouldIgnoreDecl, + } + } + + private preOrderVisitor(node: arkts.AstNode): arkts.AstNode { + const nodeType = arkts.nodeType(node); + collectUINodeByTypeInPreOrder(nodeType, node, this.getMetadata()); + return node; + } + + private postOrderVisitor(node: arkts.AstNode): arkts.AstNode { + const nodeType = arkts.nodeType(node); + collectUINodeByTypeInPostOrder(nodeType, node, this.getMetadata()); + collectMemoableNodeByTypeInPostOrder(nodeType, node); + return node; + } + + visitor(node: arkts.AstNode): arkts.AstNode { + this.preOrderVisitor(node); + const newNode = this.visitEachChild(node); + this.postOrderVisitor(newNode); + return newNode; + } +} diff --git a/arkui-plugins/collectors/memo-collectors/factory.ts b/arkui-plugins/collectors/memo-collectors/factory.ts index e1d6e17454c127feec7599709a30a131149aec9a..fa51dcd6ac3298f06e3ed41f3f98caafefa4df8a 100644 --- a/arkui-plugins/collectors/memo-collectors/factory.ts +++ b/arkui-plugins/collectors/memo-collectors/factory.ts @@ -25,12 +25,15 @@ import { findCanAddMemoFromTypeAlias, } from './utils'; -export function findAndCollectMemoableNode(node: arkts.AstNode): arkts.AstNode { +export function findAndCollectMemoableNode(node: arkts.AstNode): void { const type = arkts.nodeType(node); + collectMemoableNodeByTypeInPostOrder(type, node); +} + +export function collectMemoableNodeByTypeInPostOrder(type: arkts.Es2pandaAstNodeType, node: arkts.AstNode): void { if (collectByType.has(type)) { - return collectByType.get(type)!(node); + collectByType.get(type)!(node); } - return node; } export class factory { diff --git a/arkui-plugins/collectors/memo-collectors/function-collector.ts b/arkui-plugins/collectors/memo-collectors/function-collector.ts index 2f9d07b8ce41349e4bfa04de26dee4904c038fad..e8cc8dfbc21274dc3ed4e27a24e05ac3026056ae 100644 --- a/arkui-plugins/collectors/memo-collectors/function-collector.ts +++ b/arkui-plugins/collectors/memo-collectors/function-collector.ts @@ -15,6 +15,7 @@ import * as arkts from '@koalaui/libarkts'; import { AbstractVisitor } from '../../common/abstract-visitor'; +import { NodeCacheNames } from '../../common/predefines'; import { checkIsMemoFromMemoableInfo, collectMemoableInfoInFunctionReturnType, @@ -57,14 +58,14 @@ export class MemoFunctionCollector extends AbstractVisitor { private collectMemoAstNode(node: arkts.AstNode, info: MemoableInfo): void { if (checkIsMemoFromMemoableInfo(info, false)) { - arkts.NodeCache.getInstance().collect(node); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(node); } } private collectCallWithDeclaredPeerInParamMap(node: arkts.CallExpression, peer: arkts.AstNode['peer']): void { const memoableInfo = this.paramMemoableInfoMap!.get(peer)!; if (checkIsMemoFromMemoableInfo(memoableInfo, true)) { - arkts.NodeCache.getInstance().collect(node); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(node); } } @@ -73,10 +74,11 @@ export class MemoFunctionCollector extends AbstractVisitor { declarator: arkts.VariableDeclarator ): void { const shouldCollect = - arkts.NodeCache.getInstance().has(declarator) || - (!!declarator.initializer && arkts.NodeCache.getInstance().has(declarator.initializer)); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(declarator) || + (!!declarator.initializer && + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(declarator.initializer)); if (shouldCollect) { - arkts.NodeCache.getInstance().collect(node); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(node); } } @@ -122,7 +124,7 @@ export class MemoFunctionCollector extends AbstractVisitor { } private visitCallExpression(node: arkts.CallExpression): arkts.AstNode { - if (arkts.NodeCache.getInstance().has(node)) { + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node)) { this.disableCollectReturnBeforeCallback(() => { this.visitEachChild(node); }); @@ -136,8 +138,8 @@ export class MemoFunctionCollector extends AbstractVisitor { }); return node; } - if (arkts.NodeCache.getInstance().has(decl)) { - arkts.NodeCache.getInstance().collect(node); + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(decl)) { + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(node); } if (this.paramMemoableInfoMap?.has(decl.peer)) { this.collectCallWithDeclaredPeerInParamMap(node, decl.peer); @@ -158,9 +160,9 @@ export class MemoFunctionCollector extends AbstractVisitor { return node; } if (this.paramMemoableInfoMap?.has(decl.peer)) { - arkts.NodeCache.getInstance().collect(node); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(node); } else if (arkts.isEtsParameterExpression(decl) && this.paramMemoableInfoMap?.has(decl.identifier.peer)) { - arkts.NodeCache.getInstance().collect(node); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(node); } return node; } @@ -169,7 +171,7 @@ export class MemoFunctionCollector extends AbstractVisitor { if (!!this.returnMemoableInfo && !!node.argument && arkts.isArrowFunctionExpression(node.argument)) { this.collectMemoAstNode(node.argument, this.returnMemoableInfo); } - arkts.NodeCache.getInstance().collect(node); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(node); this.visitEachChild(node); return node; } @@ -216,8 +218,8 @@ export class MemoFunctionCollector extends AbstractVisitor { } if ( arkts.isArrowFunctionExpression(node) && - !arkts.NodeCache.getInstance().has(node) && - !arkts.NodeCache.getInstance().has(node.scriptFunction) + !arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node) && + !arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node.scriptFunction) ) { this.shouldCollectReturn = false; } diff --git a/arkui-plugins/collectors/memo-collectors/utils.ts b/arkui-plugins/collectors/memo-collectors/utils.ts index 306df073108794fb2c11bb13b94222b1b2004072..3cbb6cff3f26131f9cf8688b081559d70a6e8aba 100644 --- a/arkui-plugins/collectors/memo-collectors/utils.ts +++ b/arkui-plugins/collectors/memo-collectors/utils.ts @@ -16,7 +16,7 @@ import * as arkts from '@koalaui/libarkts'; import { annotation, forEachArgWithParam, isDecoratorAnnotation } from '../../common/arkts-utils'; import { ImportCollector } from '../../common/import-collector'; -import { DecoratorNames, GenSymPrefix, MEMO_IMPORT_SOURCE_NAME } from '../../common/predefines'; +import { DecoratorNames, BuiltInNames, MEMO_IMPORT_SOURCE_NAME, NodeCacheNames } from '../../common/predefines'; import { MemoFunctionCollector } from './function-collector'; export enum MemoNames { @@ -78,11 +78,11 @@ export function addMemoAnnotation(node: T, memoName: Memo collectMemoAnnotationImport(memoName); if (arkts.isEtsParameterExpression(node)) { node.annotations = newAnnotations; - arkts.NodeCache.getInstance().collect(node); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(node); return node; } const newNode = node.setAnnotations(newAnnotations) as T; - arkts.NodeCache.getInstance().collect(newNode); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(newNode); return newNode; } @@ -121,7 +121,7 @@ export function collectMemoAnnotationSource(memoName: MemoNames = MemoNames.MEMO export function collectMemoableInfoInUnionType(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo { let currInfo = info ?? {}; - if (arkts.NodeCache.getInstance().has(node)) { + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node)) { return { ...currInfo, hasMemo: true, hasProperType: true }; } if (!arkts.isETSUnionType(node)) { @@ -165,8 +165,8 @@ function collectMemoableInfoInTypeReferencePart(node: arkts.ETSTypeReferencePart export function collectMemoableInfoInTypeReference(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo { let currInfo = info ?? {}; - if (arkts.NodeCache.getInstance().has(node)) { - const metadata = arkts.NodeCache.getInstance().get(node)?.metadata; + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node)) { + const metadata = arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).get(node)?.metadata; return { ...currInfo, ...metadata }; } if (!arkts.isETSTypeReference(node) || !node.part || !arkts.isETSTypeReferencePart(node.part)) { @@ -178,7 +178,7 @@ export function collectMemoableInfoInTypeReference(node: arkts.AstNode, info?: M }; const expr = node.part.name; let decl: arkts.AstNode | undefined; - if (!expr || !(decl = arkts.getDecl(expr))) { + if (!expr || !(decl = arkts.getPeerIdentifierDecl(expr.peer))) { return currInfo; } return { @@ -189,7 +189,7 @@ export function collectMemoableInfoInTypeReference(node: arkts.AstNode, info?: M export function collectMemoableInfoInFunctionType(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo { let currInfo = info ?? {}; - if (arkts.NodeCache.getInstance().has(node)) { + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node)) { return { ...currInfo, hasMemo: true, hasProperType: true }; } if (!arkts.isETSFunctionType(node)) { @@ -202,7 +202,7 @@ export function collectMemoableInfoInFunctionType(node: arkts.AstNode, info?: Me export function collectMemoableInfoInTypeAlias(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo { let currInfo = info ?? {}; - if (arkts.NodeCache.getInstance().has(node)) { + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node)) { return { ...currInfo, hasMemo: true, hasProperType: true }; } if (!arkts.isTSTypeAliasDeclaration(node)) { @@ -223,8 +223,8 @@ export function collectMemoableInfoInTypeAlias(node: arkts.AstNode, info?: Memoa export function collectMemoableInfoInParameter(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo { let currInfo = info ?? {}; - if (arkts.NodeCache.getInstance().has(node)) { - const metadata = arkts.NodeCache.getInstance().get(node)?.metadata; + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node)) { + const metadata = arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).get(node)?.metadata; return { ...currInfo, ...metadata }; } if (!arkts.isEtsParameterExpression(node)) { @@ -248,14 +248,16 @@ export function collectMemoableInfoInParameter(node: arkts.AstNode, info?: Memoa } if (!!currInfo.isWithinTypeParams) { const forbidTypeRewrite = !checkIsMemoFromMemoableInfo(currInfo); - arkts.NodeCache.getInstance().collect(node, { forbidTypeRewrite, isWithinTypeParams: true }); + arkts.NodeCacheFactory.getInstance() + .getCache(NodeCacheNames.MEMO) + .collect(node, { forbidTypeRewrite, isWithinTypeParams: true }); } return currInfo; } export function collectMemoableInfoInVariableDeclarator(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo { let currInfo = info ?? {}; - if (arkts.NodeCache.getInstance().has(node)) { + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node)) { return { ...currInfo, hasMemo: true, hasProperType: true }; } if (!arkts.isVariableDeclarator(node)) { @@ -279,7 +281,7 @@ export function collectMemoableInfoInVariableDeclarator(node: arkts.AstNode, inf ...hasMemoableAnnotation(node.parent), }; } - const decl = arkts.getDecl(node.name); + const decl = arkts.getPeerIdentifierDecl(node.name.peer); if (!decl) { return currInfo; } @@ -299,7 +301,7 @@ export function collectMemoableInfoInVariableDeclarator(node: arkts.AstNode, inf export function collectMemoableInfoInProperty(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo { let currInfo = info ?? {}; - if (arkts.NodeCache.getInstance().has(node)) { + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node)) { const property = node as arkts.Property; const hasProperType = !!property.value && arkts.isArrowFunctionExpression(property.value); return { ...currInfo, hasMemo: true, hasProperType }; @@ -307,7 +309,7 @@ export function collectMemoableInfoInProperty(node: arkts.AstNode, info?: Memoab if (!arkts.isProperty(node) || !node.key || !arkts.isIdentifier(node.key)) { return currInfo; } - const decl = arkts.getDecl(node.key); + const decl = arkts.getPeerPropertyDecl(node.peer); if (!decl || !arkts.isMethodDefinition(decl)) { return currInfo; } @@ -337,7 +339,7 @@ export function collectMemoableInfoInProperty(node: arkts.AstNode, info?: Memoab export function collectMemoableInfoInClassProperty(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo { let currInfo = info ?? {}; - if (arkts.NodeCache.getInstance().has(node)) { + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node)) { return { ...currInfo, hasMemo: true, hasProperType: true }; } if (!arkts.isClassProperty(node)) { @@ -361,7 +363,7 @@ export function collectMemoableInfoInClassProperty(node: arkts.AstNode, info?: M export function collectMemoableInfoInArrowFunction(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo { let currInfo = info ?? {}; - if (arkts.NodeCache.getInstance().has(node)) { + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node)) { return { ...currInfo, hasMemo: true, hasProperType: true }; } if (!arkts.isArrowFunctionExpression(node)) { @@ -377,7 +379,7 @@ export function collectMemoableInfoInArrowFunction(node: arkts.AstNode, info?: M } if (!!node.parent && arkts.isAssignmentExpression(node.parent) && !!node.parent.left) { const expr = arkts.isMemberExpression(node.parent.left) ? node.parent.left.property : node.parent.left; - const decl = arkts.getDecl(expr); + const decl = arkts.getPeerIdentifierDecl(expr.peer); if (!decl) { return currInfo; } @@ -393,7 +395,7 @@ export function collectMemoableInfoInArrowFunction(node: arkts.AstNode, info?: M export function collectMemoableInfoInScriptFunction(node: arkts.AstNode, info?: MemoableInfo): MemoableInfo { let currInfo = info ?? {}; - if (arkts.NodeCache.getInstance().has(node)) { + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node)) { return { ...currInfo, hasMemo: true, hasProperType: true }; } if (!arkts.isScriptFunction(node)) { @@ -434,13 +436,13 @@ export function collectMemoableInfoInType(node: arkts.AstNode, info?: MemoableIn export function collectMemoableInfoInFunctionReturnType(node: arkts.ScriptFunction): MemoableInfo { if (!!node.returnTypeAnnotation) { let memoableInfo: MemoableInfo; - if (arkts.NodeCache.getInstance().has(node.returnTypeAnnotation)) { + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node.returnTypeAnnotation)) { memoableInfo = { hasMemo: true, hasProperType: true }; } else { memoableInfo = collectMemoableInfoInType(node.returnTypeAnnotation); } if ((memoableInfo.hasMemo || memoableInfo.hasBuilder) && memoableInfo.hasProperType) { - arkts.NodeCache.getInstance().collect(node.returnTypeAnnotation); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(node.returnTypeAnnotation); } return memoableInfo; } @@ -449,14 +451,16 @@ export function collectMemoableInfoInFunctionReturnType(node: arkts.ScriptFuncti export function collectScriptFunctionReturnTypeFromInfo(node: arkts.ScriptFunction, info: MemoableInfo): void { const returnType = node.returnTypeAnnotation; - if (!returnType || arkts.NodeCache.getInstance().has(returnType)) { + if (!returnType || arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(returnType)) { return; } const isMemoReturnType = checkIsMemoFromMemoableInfo(info); const isWithinTypeParams = info.isWithinTypeParams; if (isMemoReturnType || isWithinTypeParams) { const forbidTypeRewrite = !isMemoReturnType; - arkts.NodeCache.getInstance().collect(returnType, { forbidTypeRewrite, isWithinTypeParams }); + arkts.NodeCacheFactory.getInstance() + .getCache(NodeCacheNames.MEMO) + .collect(returnType, { forbidTypeRewrite, isWithinTypeParams }); } } @@ -464,7 +468,7 @@ export function collectGensymDeclarator(declarator: arkts.VariableDeclarator, in if (!info.hasMemo && !info.hasBuilder) { return; } - arkts.NodeCache.getInstance().collect(declarator); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(declarator); const initializer = declarator.initializer; if (!initializer || !arkts.isConditionalExpression(initializer)) { return; @@ -521,14 +525,18 @@ function collectMemoableInfoInFunctionParam( const peers: arkts.AstNode['peer'][] = []; let memoableInfo: MemoableInfo; const _param = param as arkts.ETSParameterExpression; - if (arkts.NodeCache.getInstance().has(_param)) { - const metadata = arkts.NodeCache.getInstance().get(_param)!.metadata ?? {}; + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(_param)) { + const metadata = arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).get(_param)!.metadata ?? {}; const { hasMemoSkip } = metadata; memoableInfo = { hasMemo: true, hasMemoSkip, hasProperType: true }; } else { memoableInfo = collectMemoableInfoInParameter(_param); } - if (_param.identifier.name.startsWith(GenSymPrefix.INTRINSIC) && !!node.body && arkts.isBlockStatement(node.body)) { + if ( + _param.identifier.name.startsWith(BuiltInNames.GENSYM_INTRINSIC_PREFIX) && + !!node.body && + arkts.isBlockStatement(node.body) + ) { const declaration = node.body.statements.at(gensymCount); if (!!declaration && arkts.isVariableDeclaration(declaration) && declaration.declarators.length > 0) { const declarator = declaration.declarators[0]; @@ -540,7 +548,9 @@ function collectMemoableInfoInFunctionParam( } } if (checkIsMemoFromMemoableInfo(memoableInfo)) { - arkts.NodeCache.getInstance().collect(_param, { hasMemoSkip: memoableInfo.hasMemoSkip }); + arkts.NodeCacheFactory.getInstance() + .getCache(NodeCacheNames.MEMO) + .collect(_param, { hasMemoSkip: memoableInfo.hasMemoSkip }); } if (!memoableInfo.hasMemoSkip && shouldCollectParameter) { peers.push(_param.identifier.peer); @@ -562,7 +572,7 @@ export function findCanAddMemoFromTypeAnnotation( } const memoableInfo = collectMemoableInfoInType(typeAnnotation); if (!!memoableInfo.hasMemo && !!memoableInfo.hasProperType) { - arkts.NodeCache.getInstance().collect(typeAnnotation); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(typeAnnotation); } return !!memoableInfo.hasBuilder && !memoableInfo.hasMemo && !!memoableInfo.hasProperType; } @@ -576,7 +586,7 @@ export function findCanAddMemoFromTypeAnnotation( export function findCanAddMemoFromProperty(property: arkts.AstNode): property is arkts.Property { const memoableInfo = collectMemoableInfoInProperty(property); if (!!memoableInfo.hasMemo && !!memoableInfo.hasProperType) { - arkts.NodeCache.getInstance().collect(property); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(property); } return !!memoableInfo.hasBuilder && !memoableInfo.hasMemo && !!memoableInfo.hasProperType; } @@ -590,11 +600,13 @@ export function findCanAddMemoFromProperty(property: arkts.AstNode): property is export function findCanAddMemoFromClassProperty(property: arkts.AstNode): property is arkts.ClassProperty { const memoableInfo = collectMemoableInfoInClassProperty(property); if (!!memoableInfo.hasMemo && !!memoableInfo.hasProperType) { - arkts.NodeCache.getInstance().collect(property); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(property); } const hasBuilderType = !!memoableInfo.hasBuilder || !!memoableInfo.hasBuilderParam; if (!!memoableInfo.isWithinTypeParams) { - arkts.NodeCache.getInstance().collect(property, { isWithinTypeParams: true }); + arkts.NodeCacheFactory.getInstance() + .getCache(NodeCacheNames.MEMO) + .collect(property, { isWithinTypeParams: true }); } return hasBuilderType && !memoableInfo.hasMemo && !!memoableInfo.hasProperType && !memoableInfo.isWithinTypeParams; } @@ -611,7 +623,9 @@ export function findCanAddMemoFromParameter(param: arkts.AstNode | undefined): p } const memoableInfo = collectMemoableInfoInParameter(param); if (!!memoableInfo.hasMemo && !!memoableInfo.hasProperType) { - arkts.NodeCache.getInstance().collect(param, { hasMemoSkip: memoableInfo.hasMemoSkip }); + arkts.NodeCacheFactory.getInstance() + .getCache(NodeCacheNames.MEMO) + .collect(param, { hasMemoSkip: memoableInfo.hasMemoSkip }); } return !!memoableInfo.hasBuilder && !memoableInfo.hasMemo && !!memoableInfo.hasProperType; } @@ -636,8 +650,10 @@ export function findCanAddMemoFromArrowFunction(node: arkts.AstNode): node is ar !hasMemoEntry && !hasMemoIntrinsic ); const isMemo = checkIsMemoFromMemoableInfo(memoableInfo); - if (isMemo && !arkts.NodeCache.getInstance().has(node)) { - arkts.NodeCache.getInstance().collect(node, { hasMemoEntry, hasMemoIntrinsic }); + if (isMemo && !arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node)) { + arkts.NodeCacheFactory.getInstance() + .getCache(NodeCacheNames.MEMO) + .collect(node, { hasMemoEntry, hasMemoIntrinsic }); const body = func.body; if (!!body && arkts.isBlockStatement(body)) { const disableCollectReturn = hasMemoEntry || hasMemoIntrinsic; @@ -662,7 +678,7 @@ export function findCanAddMemoFromArrowFunction(node: arkts.AstNode): node is ar export function findCanAddMemoFromTypeAlias(node: arkts.AstNode): node is arkts.TSTypeAliasDeclaration { const memoableInfo = collectMemoableInfoInTypeAlias(node); if (!!memoableInfo.hasMemo && !!memoableInfo.hasProperType) { - arkts.NodeCache.getInstance().collect(node); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(node); } return !!memoableInfo.hasBuilder && !memoableInfo.hasMemo && !!memoableInfo.hasProperType; } @@ -687,13 +703,15 @@ export function findCanAddMemoFromMethod(node: arkts.AstNode): node is arkts.Met !hasMemoEntry && !hasMemoIntrinsic ); const isMemo = checkIsMemoFromMemoableInfo(memoableInfo); - if (isMemo && !arkts.NodeCache.getInstance().has(node)) { + if (isMemo && !arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node)) { const metadata = collectMetadataInMethod(node); - arkts.NodeCache.getInstance().collect(node, { - ...metadata, - hasMemoEntry, - hasMemoIntrinsic, - }); + arkts.NodeCacheFactory.getInstance() + .getCache(NodeCacheNames.MEMO) + .collect(node, { + ...metadata, + hasMemoEntry, + hasMemoIntrinsic, + }); const body = func.body; if (!!body && arkts.isBlockStatement(body)) { const disableCollectReturn = hasMemoEntry || hasMemoIntrinsic; @@ -716,7 +734,7 @@ export function findCanAddMemoFromMethod(node: arkts.AstNode): node is arkts.Met * @param node `arkts.CallExpression` node. */ export function collectMemoFromCallExpression(node: arkts.CallExpression): void { - if (arkts.NodeCache.getInstance().has(node)) { + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node)) { return; } const expr = findIdentifierFromCallee(node.expression); @@ -725,8 +743,8 @@ export function collectMemoFromCallExpression(node: arkts.CallExpression): void return; } let isCollected: boolean = false; - if (arkts.NodeCache.getInstance().has(decl)) { - arkts.NodeCache.getInstance().collect(node); + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(decl)) { + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(node); isCollected = true; } if (arkts.isMethodDefinition(decl)) { @@ -735,18 +753,18 @@ export function collectMemoFromCallExpression(node: arkts.CallExpression): void isCollected = collectCallWithDeclaredClassProperty(node, decl); } if (isCollected && arkts.isTSAsExpression(node.expression) && node.expression.typeAnnotation) { - arkts.NodeCache.getInstance().collect(node.expression.typeAnnotation); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(node.expression.typeAnnotation); } } export function collectCallWithDeclaredClassProperty(node: arkts.CallExpression, decl: arkts.ClassProperty): boolean { - if (arkts.NodeCache.getInstance().has(decl)) { - arkts.NodeCache.getInstance().collect(node); + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(decl)) { + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(node); return true; } const memoableInfo = collectMemoableInfoInClassProperty(decl); if (checkIsMemoFromMemoableInfo(memoableInfo, false) || memoableInfo.hasBuilder || memoableInfo.hasBuilderParam) { - arkts.NodeCache.getInstance().collect(node); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(node); return true; } return false; @@ -760,15 +778,20 @@ export function collectCallWithDeclaredMethod(node: arkts.CallExpression, decl: const isTrailingCall = node.isTrailingCall; const options = { hasRestParameter, isTrailingCall }; forEachArgWithParam(args, params, collectCallArgsWithMethodParams, options); - if (arkts.NodeCache.getInstance().has(decl)) { - const { hasMemoEntry, hasMemoIntrinsic } = arkts.NodeCache.getInstance().get(decl)!.metadata ?? {}; - arkts.NodeCache.getInstance().collect(node, { hasReceiver, hasMemoEntry, hasMemoIntrinsic }); + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(decl)) { + const { hasMemoEntry, hasMemoIntrinsic } = + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).get(decl)!.metadata ?? {}; + arkts.NodeCacheFactory.getInstance() + .getCache(NodeCacheNames.MEMO) + .collect(node, { hasReceiver, hasMemoEntry, hasMemoIntrinsic }); return true; } else { const memoableInfo = collectMemoableInfoInScriptFunction(decl.scriptFunction); if (checkIsMemoFromMemoableInfo(memoableInfo, true)) { const { hasMemoEntry, hasMemoIntrinsic } = memoableInfo; - arkts.NodeCache.getInstance().collect(node, { hasReceiver, hasMemoEntry, hasMemoIntrinsic }); + arkts.NodeCacheFactory.getInstance() + .getCache(NodeCacheNames.MEMO) + .collect(node, { hasReceiver, hasMemoEntry, hasMemoIntrinsic }); return true; } } @@ -780,13 +803,13 @@ export function collectCallArgsWithMethodParams(arg: arkts.Expression | undefine return; } let info: MemoableInfo; - if (arkts.NodeCache.getInstance().has(param)) { + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(param)) { info = { hasMemo: true, hasProperType: true }; } else { info = collectMemoableInfoInParameter(param); } if (checkIsMemoFromMemoableInfo(info) && arkts.isArrowFunctionExpression(arg)) { - arkts.NodeCache.getInstance().collect(arg); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(arg); const func = arg.scriptFunction; const returnMemoableInfo = collectMemoableInfoInFunctionReturnType(func); collectScriptFunctionReturnTypeFromInfo(func, returnMemoableInfo); @@ -853,7 +876,12 @@ export function checkIsMemoFromMemoableInfo(info: MemoableInfo, ignoreType: bool } export function getDeclResolveAlias(node: arkts.AstNode): arkts.AstNode | undefined { - const decl = arkts.getDecl(node); + let decl: arkts.AstNode | undefined; + if (!!node.parent && arkts.isProperty(node.parent)) { + decl = arkts.getPeerPropertyDecl(node.parent.peer); + } else { + decl = arkts.getPeerIdentifierDecl(node.peer); + } if (!!decl && !!decl.parent && arkts.isIdentifier(decl) && arkts.isVariableDeclarator(decl.parent)) { if (!!decl.parent.initializer && arkts.isIdentifier(decl.parent.initializer)) { return getDeclResolveAlias(decl.parent.initializer); diff --git a/arkui-plugins/collectors/ui-collectors/call-record-collector.ts b/arkui-plugins/collectors/ui-collectors/call-record-collector.ts new file mode 100644 index 0000000000000000000000000000000000000000..a66d0a97836ab3daecf24d7cbfb2ba93f7bc5a90 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/call-record-collector.ts @@ -0,0 +1,179 @@ +/* + * 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 { CallInfo, CallRecord } from './records'; +import { UICollectMetadata } from './shared-types'; +import { checkIsCustomComponentFromInfo, findRootCallee, findRootCallObject } from './utils'; +import { StructCallValidator, ValidatorBuilder } from './validators'; +import { ARKUI_FOREACH_SOURCE_NAME, InnerComponentNames, NodeCacheNames } from '../../common/predefines'; + +export interface CallRecordInfo { + call: arkts.CallExpression; + callRecord: CallRecord; +} + +export class CallRecordCollector { + private static instance: CallRecordCollector; + private _metadata: UICollectMetadata; + private _prevCallInfo?: CallRecordInfo; + private _chainingCallData: ChainingCallDataSource; + + private externalSourceName: string | undefined; + + private constructor(metadata: UICollectMetadata) { + this._metadata = metadata; + this._chainingCallData = new ChainingCallDataSource(); + } + + static getInstance(metadata: UICollectMetadata): CallRecordCollector { + if (!this.instance) { + this.instance = new CallRecordCollector(metadata); + } + return this.instance; + } + + get lastCallInfo(): CallRecordInfo | undefined { + return this._prevCallInfo; + } + + get chainingCallData(): ChainingCallDataSource { + return this._chainingCallData; + } + + private canCollectCallFromInfo(info: CallInfo): boolean { + const rootCallInfo = info; + if (!!rootCallInfo.annotationInfo?.hasComponentBuilder) { + return true; + } + if (!!rootCallInfo.isResourceCall || !!rootCallInfo.isBindableCall) { + return true; + } + if (!!rootCallInfo.structDeclInfo && checkIsCustomComponentFromInfo(rootCallInfo.structDeclInfo)) { + return true; + } + if ( + this.externalSourceName === ARKUI_FOREACH_SOURCE_NAME && + rootCallInfo.declName === InnerComponentNames.FOR_EACH + ) { + return true; + } + // console.log("[CANNOT COLLECT] info: ", info); + return false; + } + + withExternalSourceName(externalSourceName: string | undefined): this { + this.externalSourceName = externalSourceName; + return this; + } + + reset() { + this._prevCallInfo = undefined; + this._chainingCallData.reset(); + } + + collect(call: arkts.CallExpression, isFromChainCall?: boolean): void { + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).shouldUpdate(call)) { + return; + } + const isWithInChain = this._chainingCallData.isWithInChain(); + // if (isWithInChain) { + // console.log('[INCHAIN VISIT] call: ', call.dumpSrc()); + // } else { + // console.log('[VISIT] call: ', call.dumpSrc()); + // } + const callRecord = new CallRecord(this._metadata); + const rootCallObject = findRootCallObject(call.expression); + const rootCallee = findRootCallee(call.expression); + callRecord.withRootCallObject(rootCallObject).withRootCallee(rootCallee); + if (isWithInChain) { + callRecord.withRootCallInfo(this._chainingCallData.rootCallInfo!.callRecord.toRecord()!); + callRecord.withChainingCallInfos(this._chainingCallData.chainingCallInfos); + } + callRecord.collect(call); + const callInfo = callRecord.toRecord(); + if (!callInfo) { + return; + } + this._prevCallInfo = { call, callRecord }; + this._chainingCallData.setRootCallInfo({ call, callRecord }).addChainingCallInfo(callRecord.toChainJSON()); + if (this.canCollectCallFromInfo(callInfo)) { + // console.log('[CAN COLLECT] call: ', call.dumpSrc()); + collectCallAndAllParentCalls.bind(this)(call, callRecord); + } + if (!isFromChainCall) { + this._chainingCallData.reset(); + } + } +} + +class ChainingCallDataSource { + rootCallInfo: CallRecordInfo | undefined; + chainingCallInfos: CallInfo[]; + + constructor(rootCallInfo?: CallRecordInfo, chainingCallInfos?: CallInfo[]) { + this.rootCallInfo = rootCallInfo; + this.chainingCallInfos = chainingCallInfos ?? []; + } + + isWithInChain(): boolean { + return !!this.rootCallInfo && !!this.chainingCallInfos && this.chainingCallInfos.length > 0; + } + + setRootCallInfo(rootCallInfo: CallRecordInfo): this { + if (!this.rootCallInfo) { + this.rootCallInfo = rootCallInfo; + } + return this; + } + + addChainingCallInfo(chainingCallInfo: CallInfo): this { + this.chainingCallInfos.push(chainingCallInfo); + return this; + } + + reset(): void { + this.rootCallInfo = undefined; + this.chainingCallInfos = []; + } +} + +function collectCallAndAllParentCalls( + this: CallRecordCollector, + call: arkts.CallExpression, + callRecord: CallRecord, +): void { + const uiNodeCache = arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI); + uiNodeCache.addNodeToUpdate(call); + let prevCall: arkts.CallExpression = call; + let currParent: arkts.AstNode | undefined = call.parent; + while (!!currParent && !uiNodeCache.shouldUpdate(currParent)) { + if (arkts.isCallExpression(currParent)) { + if (!currParent.expression.findNodeInInnerChild(prevCall)) { + break; + } + this.collect(currParent, true); + prevCall = currParent; + } + uiNodeCache.addNodeToUpdate(currParent); + currParent = currParent.parent; + } + const { call: lastCall, callRecord: lastCallRecord } = this.lastCallInfo ?? { call, callRecord }; + ValidatorBuilder.build(StructCallValidator).checkIsViolated(lastCall, lastCallRecord.toRecord()); + // console.log("[CACHE COLLECT] call: ", lastCall.dumpSrc()); + // console.log("[CACHE COLLECT] lastCallRecord: ", lastCallRecord.toJSON()); + uiNodeCache.collect(lastCall, lastCallRecord.toJSON()); + this.chainingCallData.reset(); +} diff --git a/arkui-plugins/collectors/ui-collectors/factory.ts b/arkui-plugins/collectors/ui-collectors/factory.ts new file mode 100644 index 0000000000000000000000000000000000000000..dd974db03e31ef54e1f4f4b6f40bd7e80dace8f8 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/factory.ts @@ -0,0 +1,184 @@ +/* + * 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 { + checkIsCustomComponentDeclaredClassFromInfo, + checkIsCustomComponentFromInfo, + checkIsObservedClassFromInfo, + checkIsETSGlobalClassFromInfo, + checkIsCommonMethodInterfaceFromInfo, + checkCanCollectNormalClassFromInfo, +} from './utils'; +import { + CustomComponentInterfaceRecord, + CustomComponentRecord, + NormalClassRecord, + NormalInterfaceRecord, +} from './records'; +import { StructCollector } from './struct-collector'; +import { GlobalClassCollector } from './global-class-collector'; +import { NormalClassCollector } from './normal-class-collector'; +import { StructInterfaceCollector } from './struct-interface-collector'; +import { NormalInterfaceCollector } from './normal-interface-collector'; +import { CallRecordCollector } from './call-record-collector'; +import { UICollectMetadata } from './shared-types'; +import { + ARKUI_COMPONENT_COMMON_SOURCE_NAME, + ARKUI_IMPORT_PREFIX_NAMES, + LINTER_EXCLUDE_EXTERNAL_SOURCE_PREFIXES, + NodeCacheNames, +} from '../../common/predefines'; +import { LogCollector } from '../../common/log-collector'; +import { matchPrefix } from '../../common/arkts-utils'; +import { ValidatorBuilder } from './validators'; + +export function findAndCollectUINodeInPreOrder(node: arkts.AstNode, metadata?: UICollectMetadata): void { + const type = arkts.nodeType(node); + collectUINodeByTypeInPreOrder(type, node, metadata); +} + +export function collectUINodeByTypeInPreOrder( + type: arkts.Es2pandaAstNodeType, + node: arkts.AstNode, + metadata?: UICollectMetadata +): void { + if (preOrderCollectByType.has(type)) { + preOrderCollectByType.get(type)!(node, metadata); + } +} + +export function findAndCollectUINodeInPostOrder(node: arkts.AstNode, metadata?: UICollectMetadata): void { + const type = arkts.nodeType(node); + collectUINodeByTypeInPostOrder(type, node, metadata); +} + +export function collectUINodeByTypeInPostOrder( + type: arkts.Es2pandaAstNodeType, + node: arkts.AstNode, + metadata?: UICollectMetadata +): void { + if (postOrderCollectByType.has(type)) { + postOrderCollectByType.get(type)!(node, metadata); + } +} + +export class CollectFactory { + static findAndCollectClass(node: arkts.ClassDeclaration, metadata: UICollectMetadata): arkts.AstNode { + const isFromArkUI: boolean = + !!metadata.externalSourceName && matchPrefix(ARKUI_IMPORT_PREFIX_NAMES, metadata.externalSourceName); + const structRecord = new CustomComponentRecord(metadata); + structRecord.withIsFromArkUI(isFromArkUI).collect(node); + + let classInfo = structRecord.toRecord(); + if (!!classInfo && checkIsCustomComponentFromInfo(classInfo)) { + // TODO: collect CustomComponent Class + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).collect(node, structRecord.toJSON()); + const structCollector = new StructCollector({ ...metadata, structRecord }); + structCollector.visitor(node); + structCollector.reset(); + // console.log("[STRUCT] node: ", node.dumpSrc()); + return node; + } + if (!!classInfo && checkIsCustomComponentDeclaredClassFromInfo(classInfo)) { + // TODO: collect CustomComponent Declaration Class + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).collect(node, structRecord.toJSON()); + const structCollector = new StructCollector({ ...metadata, structRecord }); + structCollector.disableCollectProperty().visitor(node); + structCollector.reset(); + // console.log("[CUSTOM COMPONENT DECL] node: ", node.dumpSrc()); + return node; + } + + const classRecord = new NormalClassRecord(metadata); + classRecord.collect(node); + + classInfo = classRecord.toRecord(); + // console.log("[CLASS] node: ", node.dumpSrc()); + // console.log("[CLASS] classInfo: ", classInfo?.annotationInfo); + if (!!classInfo) { + if (checkCanCollectNormalClassFromInfo(classInfo)) { + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).collect(node, classRecord.toJSON()); + } + if (checkIsETSGlobalClassFromInfo(classInfo)) { + const globalClassCollector = new GlobalClassCollector(metadata); + globalClassCollector.visitor(node); + globalClassCollector.reset(); + // console.log("[ETSGLOBAL CLASS] node: ", node.dumpSrc()); + return node; + } + const normalClassCollector = new NormalClassCollector({ ...metadata, classRecord }); + normalClassCollector.visitor(node); + normalClassCollector.reset(); + // console.log("[NORMAL CLASS] node: ", node.dumpSrc()); + return node; + } + return node; + } + + static findAndCollectInterface(node: arkts.TSInterfaceDeclaration, metadata: UICollectMetadata): arkts.AstNode { + const interfaceRecord = new CustomComponentInterfaceRecord(metadata); + interfaceRecord.collect(node); + + let interfaceInfo = interfaceRecord.toRecord(); + if (!!interfaceInfo && checkIsCustomComponentFromInfo(interfaceInfo)) { + // TODO: collect __Options_ CustomComponent Interface + const interfaceCollector = new StructInterfaceCollector({ ...metadata, interfaceRecord }); + interfaceCollector.visitor(node); + interfaceCollector.reset(); + // console.log("[STRUCT INTERFACE] node: ", node.dumpSrc()); + return node; + } + + const normalInterfaceRecord = new NormalInterfaceRecord(metadata); + normalInterfaceRecord.collect(node); + + interfaceInfo = normalInterfaceRecord.toRecord(); + if ( + metadata.externalSourceName === ARKUI_COMPONENT_COMMON_SOURCE_NAME && + checkIsCommonMethodInterfaceFromInfo(interfaceInfo) + ) { + // TODO: collect CommonMethod Declared Interface + arkts.NodeCacheFactory.getInstance() + .getCache(NodeCacheNames.UI) + .collect(node, normalInterfaceRecord.toJSON()); + } + + const interfaceCollector = new NormalInterfaceCollector({ + ...metadata, + interfaceRecord: normalInterfaceRecord, + }); + interfaceCollector.visitor(node); + interfaceCollector.reset(); + // console.log("[INTERFACE METHOD] node: ", node.dumpSrc()); + + return node; + } + + static findAndCollectCall(node: arkts.CallExpression, metadata: UICollectMetadata): arkts.AstNode { + // console.log('[VISIT] node: ', node.dumpSrc()); + CallRecordCollector.getInstance(metadata).collect(node); + return node; + } +} + +const preOrderCollectByType = new Map arkts.AstNode>([ + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CLASS_DECLARATION, CollectFactory.findAndCollectClass], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_TS_INTERFACE_DECLARATION, CollectFactory.findAndCollectInterface], +]); + +const postOrderCollectByType = new Map arkts.AstNode>([ + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CALL_EXPRESSION, CollectFactory.findAndCollectCall], +]); diff --git a/arkui-plugins/collectors/ui-collectors/global-class-collector.ts b/arkui-plugins/collectors/ui-collectors/global-class-collector.ts new file mode 100644 index 0000000000000000000000000000000000000000..4b04d3c9431e5a73af368d7b0cf671d1bbb697ae --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/global-class-collector.ts @@ -0,0 +1,58 @@ +/* + * 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 { AbstractVisitor, VisitorOptions } from '../../common/abstract-visitor'; +import { NodeCacheNames } from '../../common/predefines'; +import { FunctionRecord } from './records/function'; + +export interface GlobalClassCollectorOptions extends VisitorOptions { + shouldIgnoreDecl?: boolean; +} + +export class GlobalClassCollector extends AbstractVisitor { + public shouldIgnoreDecl: boolean; + + constructor(options: GlobalClassCollectorOptions) { + super(options); + this.shouldIgnoreDecl = options.shouldIgnoreDecl ?? false; + } + + private collectMethod(node: arkts.MethodDefinition): void { + const methodRecord = new FunctionRecord({ + shouldIgnoreDecl: this.shouldIgnoreDecl, + }); + methodRecord.collect(node); + + const methodInfo = methodRecord.toRecord(); + if (!methodInfo || methodInfo.isGlobalInit || methodInfo.isGlobalMain) { + return; + } + if (!!methodInfo.annotationInfo && Object.keys(methodInfo.annotationInfo).length > 0) { + // TODO: collect method info to cache + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).collect(node, methodRecord.toJSON()); + // console.log("[ETSGLOBAL CLASS METHOD] node: ", node.dumpSrc()); + } + } + + visitor(node: arkts.ClassDeclaration): arkts.ClassDeclaration { + node.definition?.body.forEach((st) => { + if (arkts.isMethodDefinition(st)) { + this.collectMethod(st); + } + }); + return node; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/normal-class-collector.ts b/arkui-plugins/collectors/ui-collectors/normal-class-collector.ts new file mode 100644 index 0000000000000000000000000000000000000000..f64770951e0fd6c652f5136fa82a417d607844d1 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/normal-class-collector.ts @@ -0,0 +1,155 @@ +/* + * 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 { AbstractVisitor, VisitorOptions } from '../../common/abstract-visitor'; +import { + NormalClassMethodInfo, + NormalClassMethodRecord, + NormalClassPropertyInfo, + NormalClassPropertyRecord, + NormalClassRecord, +} from './records'; +import { BuiltInNames, EntryWrapperNames, NodeCacheNames } from '../../common/predefines'; +import { formatBuiltInImplementedPropertyName } from './utils'; +import { NormalClassMethodValidator, NormalClassPropertyValidator, ValidatorBuilder } from './validators'; + +export interface NormalClassCollectorOptions extends VisitorOptions { + classRecord: NormalClassRecord; + shouldIgnoreDecl?: boolean; +} + +interface MethodRecordCollection { + node: arkts.MethodDefinition; + record: NormalClassMethodRecord; +} + +export class NormalClassCollector extends AbstractVisitor { + private _classRecord: NormalClassRecord; + public shouldIgnoreDecl: boolean; + + private _getters: MethodRecordCollection[]; + private _setters: MethodRecordCollection[]; + private _implementedPropertyNames: string[]; + + constructor(options: NormalClassCollectorOptions) { + super(options); + this._classRecord = options.classRecord; + this.shouldIgnoreDecl = options.shouldIgnoreDecl ?? false; + this._getters = []; + this._setters = []; + this._implementedPropertyNames = []; + } + + private canCollectPropertyFromInfo(info: NormalClassPropertyInfo): boolean { + if (info.classInfo?.annotationInfo?.hasObserved) { + return true; + } + if (!!info.annotationInfo && Object.keys(info.annotationInfo).length > 0) { + return true; + } + return false; + } + + private canCollectMethodFromInfo(info: NormalClassMethodInfo): boolean { + if (info.classInfo?.name === EntryWrapperNames.WRAPPER_CLASS_NAME) { + return true; + } + return false; + } + + private collectProperty(node: arkts.ClassProperty): void { + const propertyRecord = new NormalClassPropertyRecord({ + classRecord: this._classRecord, + shouldIgnoreDecl: this.shouldIgnoreDecl, + }); + propertyRecord.collect(node); + + const propertyInfo = propertyRecord.toRecord(); + if (!propertyInfo) { + return; + } + if (this.canCollectPropertyFromInfo(propertyInfo)) { + if (propertyInfo.name?.startsWith(BuiltInNames.IMPLEMENT_PROPETY_PREFIX)) { + this._implementedPropertyNames.push(formatBuiltInImplementedPropertyName(propertyInfo.name)); + } + // TODO: collect property info to cache + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).collect(node, propertyRecord.toJSON()); + } + // console.log('[NORMAL CLASS PROPERTY] node: ', node.dumpSrc()); + ValidatorBuilder.build(NormalClassPropertyValidator).checkIsViolated(node, propertyInfo); + } + + private rememberMethod(node: arkts.MethodDefinition, record: NormalClassMethodRecord): void { + if (node.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_GET) { + this._getters.push({ node, record }); + } + if (node.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_SET) { + this._setters.push({ node, record }); + } + } + + private collectMethod(node: arkts.MethodDefinition): void { + const methodRecord = new NormalClassMethodRecord({ + classRecord: this._classRecord, + shouldIgnoreDecl: this.shouldIgnoreDecl, + }); + methodRecord.collect(node); + + const methodInfo = methodRecord.toRecord(); + if (!methodInfo) { + return; + } + + if (this.canCollectMethodFromInfo(methodInfo)) { + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).collect(node, methodRecord.toJSON()); + } else if (this._implementedPropertyNames.includes(node.name.name)) { + this.rememberMethod(node, methodRecord); + } + // TODO: @Computed methods should be collected for UI-Plugin + + // console.log('[NORMAL CLASS METHOD] node: ', node.dumpSrc()); + // console.log('[NORMAL CLASS METHOD] methodInfo: ', methodInfo); + ValidatorBuilder.build(NormalClassMethodValidator).checkIsViolated(node, methodInfo); + } + + private cacheMethod(collection: MethodRecordCollection) { + arkts.NodeCacheFactory.getInstance() + .getCache(NodeCacheNames.UI) + .collect(collection.node, collection.record.toJSON()); + } + + reset(): void { + super.reset(); + this._getters = []; + this._setters = []; + this._implementedPropertyNames = []; + } + + visitor(node: arkts.ClassDeclaration): arkts.ClassDeclaration { + node.definition?.body.forEach((st) => { + if (arkts.isClassProperty(st)) { + this.collectProperty(st); + } else if (arkts.isMethodDefinition(st)) { + this.collectMethod(st); + } + }); + if (this._implementedPropertyNames.length > 0) { + this._getters.forEach((collection) => this.cacheMethod(collection)); + this._setters.forEach((collection) => this.cacheMethod(collection)); + } + return node; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/normal-interface-collector.ts b/arkui-plugins/collectors/ui-collectors/normal-interface-collector.ts new file mode 100644 index 0000000000000000000000000000000000000000..ee0f00e3c6f9cc00fdc568cc74d7c9369a8f0222 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/normal-interface-collector.ts @@ -0,0 +1,73 @@ +/* + * 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 { AbstractVisitor, VisitorOptions } from '../../common/abstract-visitor'; +import { + NormalInterfacePropertyInfo, + NormalInterfacePropertyRecord, + NormalInterfaceRecord, +} from './records'; +import { NodeCacheNames } from '../../common/predefines'; + +export interface NormalInterfaceCollectorOptions extends VisitorOptions { + interfaceRecord: NormalInterfaceRecord; + shouldIgnoreDecl?: boolean; +} + +export class NormalInterfaceCollector extends AbstractVisitor { + private _interfaceRecord: NormalInterfaceRecord; + public shouldIgnoreDecl: boolean; + + constructor(options: NormalInterfaceCollectorOptions) { + super(options); + this._interfaceRecord = options.interfaceRecord; + this.shouldIgnoreDecl = options.shouldIgnoreDecl ?? false; + } + + private canCollectMethodFromInfo(info: NormalInterfacePropertyInfo): boolean { + if (!!info.annotationInfo && Object.keys(info.annotationInfo).length > 0) { + return true; + } + return false; + } + + private collectMethod(node: arkts.MethodDefinition): void { + const methodRecord = new NormalInterfacePropertyRecord({ + interfaceRecord: this._interfaceRecord, + shouldIgnoreDecl: this.shouldIgnoreDecl, + }); + methodRecord.collect(node); + + const methodInfo = methodRecord.toRecord(); + if (!methodInfo) { + return; + } + if (this.canCollectMethodFromInfo(methodInfo)) { + // TODO: collect method info to cache + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).collect(node, methodRecord.toJSON()); + // console.log("[INTERFACE METHOD] node: ", node.dumpSrc()); + } + } + + visitor(node: arkts.TSInterfaceDeclaration): arkts.TSInterfaceDeclaration { + node.body?.body.forEach((st) => { + if (arkts.isMethodDefinition(st)) { + this.collectMethod(st); + } + }); + return node; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/annotations/base.ts b/arkui-plugins/collectors/ui-collectors/records/annotations/base.ts new file mode 100644 index 0000000000000000000000000000000000000000..8f8303a2ced31e4ae610361c1aa20f4d153d5569 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/annotations/base.ts @@ -0,0 +1,132 @@ +/* + * 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 { getAnnotationName } from '../../utils'; +import { BaseRecord, RecordOptions } from '../base'; + +export type Annotations = { + [K in string]?: arkts.AnnotationUsage; +}; + +export type AnnotationInfo = { + [K in string as `has${K}`]?: boolean; +}; + +export type AnnotationRecord = { + annotations?: U; + annotationInfo?: V; + ignoredAnnotations?: Annotations; + ignoredAnnotationInfo?: AnnotationInfo; +}; + +function firstToLower(str: string): string { + return str.charAt(0).toLowerCase() + str.slice(1); +} + +export abstract class BaseAnnotationRecord< + U extends Annotations = Annotations, + V extends AnnotationInfo = AnnotationInfo +> extends BaseRecord> { + protected abstract annotationNames: string[]; + protected _annotations: U = {} as U; + protected _annotationInfo: V = {} as V; + + protected _ignoredAnnotations: Annotations = {}; + protected _ignoredAnnotationInfo: AnnotationInfo = {}; + + constructor(options: RecordOptions) { + super(options); + } + + public get annotations(): U | undefined { + if (Object.keys(this._annotations).length === 0) { + return undefined; + } + return this._annotations; + } + + public get annotationInfo(): V | undefined { + if (Object.keys(this._annotationInfo).length === 0) { + return undefined; + } + return this._annotationInfo; + } + + public get ignoredAnnotations(): Annotations | undefined { + if (Object.keys(this._ignoredAnnotations).length === 0) { + return undefined; + } + return this._ignoredAnnotations; + } + + public get ignoredAnnotationInfo(): AnnotationInfo | undefined { + if (Object.keys(this._ignoredAnnotationInfo).length === 0) { + return undefined; + } + return this._ignoredAnnotationInfo; + } + + private updateAnnotationInfo(name: string | undefined): void { + const newInfo = this.updateAnnotationInfoByName(this._annotationInfo, name); + this._annotationInfo = newInfo; + } + + private updateAnnotations(anno: arkts.AnnotationUsage, name: string | undefined): void { + if (!!name && !!this._annotationInfo[`has${name}`] && !this._annotations[name]) { + this._annotations = { ...this._annotations, [name]: anno }; + } + } + + private updateIgnoreAnnotationInfo(name: string | undefined): void { + if (!!name && !this.annotationNames.includes(name)) { + this._ignoredAnnotationInfo[`has${name}`] = true; + } + } + + private updateIgnoreAnnotations(anno: arkts.AnnotationUsage, name: string | undefined): void { + if (!!name && !!this._ignoredAnnotationInfo[`has${name}`] && !this._ignoredAnnotations[name]) { + this._ignoredAnnotations = { ...this._ignoredAnnotations, [name]: anno }; + } + } + + collectFromNode(node: arkts.AnnotationUsage): void { + const name = getAnnotationName(node, this.shouldIgnoreDecl); + this.updateAnnotationInfo(name); + this.updateAnnotations(node, name); + this.updateIgnoreAnnotationInfo(name); + this.updateIgnoreAnnotations(node, name); + } + + refreshOnce(): void { + const currInfo: AnnotationRecord = { + ...this.info, + ...(this.annotations && { annotations: this.annotations }), + ...(this.annotationInfo && { annotationInfo: this.annotationInfo }), + ...(this.ignoredAnnotations && { ignoredAnnotations: this.ignoredAnnotations }), + ...(this.ignoredAnnotationInfo && { ignoredAnnotationInfo: this.ignoredAnnotationInfo }), + }; + this.info = currInfo; + } + + toJSON(): AnnotationRecord { + this.refresh(); + return { + ...(this.info?.annotationInfo && { annotationInfo: this.info.annotationInfo }), + }; + } + + abstract updateAnnotationInfoByName(info: V, name: string | undefined): V; +} diff --git a/arkui-plugins/collectors/ui-collectors/records/annotations/call-declaration.ts b/arkui-plugins/collectors/ui-collectors/records/annotations/call-declaration.ts new file mode 100644 index 0000000000000000000000000000000000000000..7c7dd162fe13423f391de02add8cb94ab91802ec --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/annotations/call-declaration.ts @@ -0,0 +1,77 @@ +/* + * 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 { FunctionAnnotationInfo, FunctionAnnotations } from './function'; +import { StructPropertyAnnotationInfo, StructPropertyAnnotations } from './struct-property'; +import { StructMethodAnnotationInfo, StructMethodAnnotations } from './struct-method'; +import { NormalClassPropertyAnnotationInfo, NormalClassPropertyAnnotations } from './normal-class-property'; +import { NormalClassMethodAnnotationInfo, NormalClassMethodAnnotations } from './normal-class-method'; +import { BaseAnnotationRecord } from './base'; +import { RecordOptions } from '../base'; +import { BuilderLambdaNames, DecoratorNames } from '../../../../common/predefines'; + +export type CallDeclAnnotationInfo = FunctionAnnotationInfo & + StructPropertyAnnotationInfo & + StructMethodAnnotationInfo & + NormalClassPropertyAnnotationInfo & + NormalClassMethodAnnotationInfo; + +export type CallDeclAnnotations = FunctionAnnotations & + StructPropertyAnnotations & + StructMethodAnnotations & + NormalClassPropertyAnnotations & + NormalClassMethodAnnotations; + +export class CallDeclAnnotationRecord extends BaseAnnotationRecord { + protected annotationNames: string[]; + + constructor(options: RecordOptions) { + super(options); + this.annotationNames = [ + DecoratorNames.BUILDER, + DecoratorNames.ANIMATABLE_EXTEND, + BuilderLambdaNames.ANNOTATION_NAME, + DecoratorNames.STATE, + DecoratorNames.STORAGE_LINK, + DecoratorNames.STORAGE_PROP, + DecoratorNames.LINK, + DecoratorNames.PROP, + DecoratorNames.PROVIDE, + DecoratorNames.CONSUME, + DecoratorNames.OBJECT_LINK, + DecoratorNames.WATCH, + DecoratorNames.BUILDER_PARAM, + DecoratorNames.LOCAL_STORAGE_PROP, + DecoratorNames.LOCAL_STORAGE_LINK, + DecoratorNames.PROP_REF, + DecoratorNames.STORAGE_PROP_REF, + DecoratorNames.LOCAL, + DecoratorNames.PARAM, + DecoratorNames.EVENT, + DecoratorNames.REQUIRE, + DecoratorNames.COMPUTED, + DecoratorNames.JSONSTRINGIFYIGNORE, + DecoratorNames.JSONRENAME, + DecoratorNames.TRACK, + ]; + } + + updateAnnotationInfoByName(info: CallDeclAnnotationInfo, name: string | undefined): CallDeclAnnotationInfo { + if (!!name && this.annotationNames.includes(name)) { + info[`has${name}`] = true; + } + return info; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/annotations/custom-component.ts b/arkui-plugins/collectors/ui-collectors/records/annotations/custom-component.ts new file mode 100644 index 0000000000000000000000000000000000000000..640402ebbe4cc6c516c2d743dabb482c8d6cac5d --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/annotations/custom-component.ts @@ -0,0 +1,81 @@ +/* + * 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 { AnnotationInfo, Annotations, BaseAnnotationRecord } from './base'; +import { StructDecoratorNames } from '../../../../common/predefines'; +import { RecordOptions } from '../base'; + +export interface StructAnnotationInfo extends AnnotationInfo { + hasComponent?: boolean; + hasComponentV2?: boolean; + hasEntry?: boolean; + hasReusable?: boolean; + hasReusableV2?: boolean; + hasCustomLayout?: boolean; + hasCustomDialog?: boolean; +} + +export interface CustomComponentAnnotations extends Annotations { + [StructDecoratorNames.COMPONENT]?: arkts.AnnotationUsage; + [StructDecoratorNames.COMPONENT_V2]?: arkts.AnnotationUsage; + [StructDecoratorNames.ENTRY]?: arkts.AnnotationUsage; + [StructDecoratorNames.RESUABLE]?: arkts.AnnotationUsage; + [StructDecoratorNames.RESUABLE_V2]?: arkts.AnnotationUsage; + [StructDecoratorNames.CUSTOM_LAYOUT]?: arkts.AnnotationUsage; + [StructDecoratorNames.CUSTOMDIALOG]?: arkts.AnnotationUsage; +} + +export class CustomComponentAnnotationRecord extends BaseAnnotationRecord< + CustomComponentAnnotations, + StructAnnotationInfo +> { + protected annotationNames: string[]; + + constructor(options: RecordOptions) { + super(options); + this.shouldIgnoreDecl = false; // TODO: remove this line + this.annotationNames = Object.values(StructDecoratorNames); + } + + updateAnnotationInfoByName(info: StructAnnotationInfo, name: string | undefined): StructAnnotationInfo { + switch (name) { + case StructDecoratorNames.COMPONENT: + info.hasComponent = true; + break; + case StructDecoratorNames.COMPONENT_V2: + info.hasComponentV2 = true; + break; + case StructDecoratorNames.ENTRY: + info.hasEntry = true; + break; + case StructDecoratorNames.RESUABLE: + info.hasReusable = true; + break; + case StructDecoratorNames.RESUABLE_V2: + info.hasReusableV2 = true; + break; + case StructDecoratorNames.CUSTOM_LAYOUT: + info.hasCustomLayout = true; + break; + case StructDecoratorNames.CUSTOMDIALOG: + info.hasCustomDialog = true; + break; + default: + return info; + } + return info; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/annotations/function.ts b/arkui-plugins/collectors/ui-collectors/records/annotations/function.ts new file mode 100644 index 0000000000000000000000000000000000000000..48ddc371968fb1554bf1bfcbc7f046af4bf8a8f7 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/annotations/function.ts @@ -0,0 +1,62 @@ +/* + * 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 { AnnotationInfo, Annotations, BaseAnnotationRecord } from './base'; +import { BuilderLambdaNames, DecoratorNames } from '../../../../common/predefines'; +import { RecordOptions } from '../base'; + +export interface FunctionAnnotationInfo extends AnnotationInfo { + hasBuilder?: boolean; + hasAnimatableExtend?: boolean; + hasComponentBuilder?: boolean; +} + +export interface FunctionAnnotations extends Annotations { + [DecoratorNames.BUILDER]?: arkts.AnnotationUsage; + [DecoratorNames.ANIMATABLE_EXTEND]?: arkts.AnnotationUsage; + [BuilderLambdaNames.ANNOTATION_NAME]?: arkts.AnnotationUsage; +} + +export class FunctionAnnotationRecord extends BaseAnnotationRecord { + protected annotationNames: string[]; + + constructor(options: RecordOptions) { + super(options); + this.shouldIgnoreDecl = false; // TODO: remove this line + this.annotationNames = [ + DecoratorNames.BUILDER, + DecoratorNames.ANIMATABLE_EXTEND, + BuilderLambdaNames.ANNOTATION_NAME, + ]; + } + + updateAnnotationInfoByName(info: FunctionAnnotationInfo, name: string | undefined): FunctionAnnotationInfo { + switch (name) { + case DecoratorNames.BUILDER: + info.hasBuilder = true; + break; + case DecoratorNames.ANIMATABLE_EXTEND: + info.hasAnimatableExtend = true; + break; + case BuilderLambdaNames.ANNOTATION_NAME: + info.hasComponentBuilder = true; + break; + default: + return info; + } + return info; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/annotations/index.ts b/arkui-plugins/collectors/ui-collectors/records/annotations/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..5600cd48e269c2a2b40b763daf7504ef1b45ac0a --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/annotations/index.ts @@ -0,0 +1,24 @@ +/* + * 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. + */ + +export * from './custom-component'; +export * from './normal-class'; +export * from './normal-class-property'; +export * from './normal-class-method'; +export * from './function'; +export * from './struct-property'; +export * from './struct-method'; +export * from './normal-interface-property'; +export * from './call-declaration'; \ No newline at end of file diff --git a/arkui-plugins/collectors/ui-collectors/records/annotations/normal-class-method.ts b/arkui-plugins/collectors/ui-collectors/records/annotations/normal-class-method.ts new file mode 100644 index 0000000000000000000000000000000000000000..9f07002f480a642940b5abfb31dbd114430be4a0 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/annotations/normal-class-method.ts @@ -0,0 +1,51 @@ +/* + * 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 { AnnotationInfo, Annotations, BaseAnnotationRecord } from './base'; +import { DecoratorNames } from '../../../../common/predefines'; +import { RecordOptions } from '../base'; + +export interface NormalClassMethodAnnotationInfo extends AnnotationInfo { + hasComputed?: boolean; +} + +export interface NormalClassMethodAnnotations extends Annotations { + [DecoratorNames.COMPUTED]?: arkts.AnnotationUsage; +} + +export class NormalClassMethodAnnotationRecord extends BaseAnnotationRecord< + NormalClassMethodAnnotations, + NormalClassMethodAnnotationInfo +> { + protected annotationNames: string[]; + + constructor(options: RecordOptions) { + super(options); + this.shouldIgnoreDecl = false; // TODO: remove this line + this.annotationNames = [DecoratorNames.COMPUTED]; + } + + updateAnnotationInfoByName(info: NormalClassMethodAnnotationInfo, name: string | undefined): NormalClassMethodAnnotationInfo { + switch (name) { + case DecoratorNames.COMPUTED: + info.hasComputed = true; + break; + default: + return info; + } + return info; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/annotations/normal-class-property.ts b/arkui-plugins/collectors/ui-collectors/records/annotations/normal-class-property.ts new file mode 100644 index 0000000000000000000000000000000000000000..fbf628221d0b8c62634e47e39db3449f95ccdd99 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/annotations/normal-class-property.ts @@ -0,0 +1,64 @@ +/* + * 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 { AnnotationInfo, Annotations, BaseAnnotationRecord } from './base'; +import { DecoratorNames } from '../../../../common/predefines'; +import { RecordOptions } from '../base'; + +export interface NormalClassPropertyAnnotationInfo extends AnnotationInfo { + hasJsonStringifyIgnore?: boolean; + hasJsonRename?: boolean; + hasTrack?: boolean; +} + +export interface NormalClassPropertyAnnotations extends Annotations { + [DecoratorNames.JSONSTRINGIFYIGNORE]?: arkts.AnnotationUsage; + [DecoratorNames.JSONRENAME]?: arkts.AnnotationUsage; + [DecoratorNames.TRACK]?: arkts.AnnotationUsage; +} + +export class NormalClassPropertyAnnotationRecord extends BaseAnnotationRecord< + NormalClassPropertyAnnotations, + NormalClassPropertyAnnotationInfo +> { + protected annotationNames: string[]; + + constructor(options: RecordOptions) { + super(options); + this.shouldIgnoreDecl = false; // TODO: remove this line + this.annotationNames = [DecoratorNames.JSONSTRINGIFYIGNORE, DecoratorNames.JSONRENAME, DecoratorNames.TRACK]; + } + + updateAnnotationInfoByName( + info: NormalClassPropertyAnnotationInfo, + name: string | undefined + ): NormalClassPropertyAnnotationInfo { + switch (name) { + case DecoratorNames.JSONSTRINGIFYIGNORE: + info.hasJsonStringifyIgnore = true; + break; + case DecoratorNames.JSONRENAME: + info.hasJsonRename = true; + break; + case DecoratorNames.TRACK: + info.hasTrack = true; + break; + default: + return info; + } + return info; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/annotations/normal-class.ts b/arkui-plugins/collectors/ui-collectors/records/annotations/normal-class.ts new file mode 100644 index 0000000000000000000000000000000000000000..ed636e9549a4213fd9a0542b3e1bcca8c7c78720 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/annotations/normal-class.ts @@ -0,0 +1,56 @@ +/* + * 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 { AnnotationInfo, Annotations, BaseAnnotationRecord } from './base'; +import { DecoratorNames } from '../../../../common/predefines'; +import { RecordOptions } from '../base'; + +export interface NormalClassAnnotationInfo extends AnnotationInfo { + hasObserved?: boolean; + hasObservedV2?: boolean; +} + +export interface NormalClassAnnotations extends Annotations { + [DecoratorNames.OBSERVED]?: arkts.AnnotationUsage; + [DecoratorNames.OBSERVED_V2]?: arkts.AnnotationUsage; +} + +export class NormalClassAnnotationRecord extends BaseAnnotationRecord< + NormalClassAnnotations, + NormalClassAnnotationInfo +> { + protected annotationNames: string[]; + + constructor(options: RecordOptions) { + super(options); + this.shouldIgnoreDecl = false; // TODO: remove this line + this.annotationNames = [DecoratorNames.OBSERVED, DecoratorNames.OBSERVED_V2]; + } + + updateAnnotationInfoByName(info: NormalClassAnnotationInfo, name: string | undefined): NormalClassAnnotationInfo { + switch (name) { + case DecoratorNames.OBSERVED: + info.hasObserved = true; + break; + case DecoratorNames.OBSERVED_V2: + info.hasObservedV2 = true; + break; + default: + return info; + } + return info; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/annotations/normal-interface-property.ts b/arkui-plugins/collectors/ui-collectors/records/annotations/normal-interface-property.ts new file mode 100644 index 0000000000000000000000000000000000000000..5bbe8faf073f111159de02750213f62017f0e20b --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/annotations/normal-interface-property.ts @@ -0,0 +1,54 @@ +/* + * 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 { AnnotationInfo, Annotations, BaseAnnotationRecord } from './base'; +import { DecoratorNames } from '../../../../common/predefines'; +import { RecordOptions } from '../base'; + +export interface NormalInterfacePropertyAnnotationInfo extends AnnotationInfo { + hasBuilder?: boolean; +} + +export interface NormalInterfacePropertyAnnotations extends Annotations { + [DecoratorNames.BUILDER]?: arkts.AnnotationUsage; +} + +export class NormalInterfacePropertyAnnotationRecord extends BaseAnnotationRecord< + NormalInterfacePropertyAnnotations, + NormalInterfacePropertyAnnotationInfo +> { + protected annotationNames: string[]; + + constructor(options: RecordOptions) { + super(options); + this.shouldIgnoreDecl = false; // TODO: remove this line + this.annotationNames = [DecoratorNames.BUILDER]; + } + + updateAnnotationInfoByName( + info: NormalInterfacePropertyAnnotationInfo, + name: string | undefined + ): NormalInterfacePropertyAnnotationInfo { + switch (name) { + case DecoratorNames.BUILDER: + info.hasBuilder = true; + break; + default: + return info; + } + return info; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/annotations/struct-method.ts b/arkui-plugins/collectors/ui-collectors/records/annotations/struct-method.ts new file mode 100644 index 0000000000000000000000000000000000000000..43febba1f755b05493570b79356a28bb142f7865 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/annotations/struct-method.ts @@ -0,0 +1,60 @@ +/* + * 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 { AnnotationInfo, Annotations, BaseAnnotationRecord } from './base'; +import { BuilderLambdaNames, DecoratorNames } from '../../../../common/predefines'; +import { RecordOptions } from '../base'; + +export interface StructMethodAnnotationInfo extends AnnotationInfo { + hasComponentBuilder?: boolean; + hasBuilder?: boolean; + hasComputed?: boolean; +} + +export interface StructMethodAnnotations extends Annotations { + [BuilderLambdaNames.ANNOTATION_NAME]?: arkts.AnnotationUsage; + [DecoratorNames.BUILDER]?: arkts.AnnotationUsage; + [DecoratorNames.COMPUTED]?: arkts.AnnotationUsage; +} + +export class StructMethodAnnotationRecord extends BaseAnnotationRecord< + StructMethodAnnotations, + StructMethodAnnotationInfo +> { + protected annotationNames: string[]; + + constructor(options: RecordOptions) { + super(options); + this.annotationNames = [BuilderLambdaNames.ANNOTATION_NAME, DecoratorNames.BUILDER, DecoratorNames.COMPUTED]; + } + + updateAnnotationInfoByName(info: StructMethodAnnotationInfo, name: string | undefined): StructMethodAnnotationInfo { + switch (name) { + case BuilderLambdaNames.ANNOTATION_NAME: + info.hasComponentBuilder = true; + break; + case DecoratorNames.BUILDER: + info.hasBuilder = true; + break; + case DecoratorNames.COMPUTED: + info.hasComputed = true; + break; + default: + return info; + } + return info; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/annotations/struct-property.ts b/arkui-plugins/collectors/ui-collectors/records/annotations/struct-property.ts new file mode 100644 index 0000000000000000000000000000000000000000..239e0d68ff15592b15348c8112e175c4570cd674 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/annotations/struct-property.ts @@ -0,0 +1,112 @@ +/* + * 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 { AnnotationInfo, Annotations, BaseAnnotationRecord } from './base'; +import { DecoratorNames } from '../../../../common/predefines'; +import { RecordOptions } from '../base'; + +export interface StructPropertyAnnotationInfo extends AnnotationInfo { + hasState?: boolean; + hasStorageLink?: boolean; + hasStorageProp?: boolean; + hasLink?: boolean; + hasProp?: boolean; + hasProvide?: boolean; + hasConsume?: boolean; + hasObjectLink?: boolean; + hasWatch?: boolean; + hasBuilderParam?: boolean; + hasLocalStorageProp?: boolean; + hasLocalStorageLink?: boolean; + hasPropRef?: boolean; + hasStoragePropRef?: boolean; + hasLocal?: boolean; + hasOnce?: boolean; + hasParam?: boolean; + hasEvent?: boolean; + hasRequire?: boolean; + hasConsumer?: boolean; + hasProvider?: boolean; +} + +export interface StructPropertyAnnotations extends Annotations { + [DecoratorNames.STATE]?: arkts.AnnotationUsage; + [DecoratorNames.STORAGE_LINK]?: arkts.AnnotationUsage; + [DecoratorNames.STORAGE_PROP]?: arkts.AnnotationUsage; + [DecoratorNames.LINK]?: arkts.AnnotationUsage; + [DecoratorNames.PROP]?: arkts.AnnotationUsage; + [DecoratorNames.PROVIDE]?: arkts.AnnotationUsage; + [DecoratorNames.CONSUME]?: arkts.AnnotationUsage; + [DecoratorNames.OBJECT_LINK]?: arkts.AnnotationUsage; + [DecoratorNames.WATCH]?: arkts.AnnotationUsage; + [DecoratorNames.BUILDER_PARAM]?: arkts.AnnotationUsage; + [DecoratorNames.LOCAL_STORAGE_PROP]?: arkts.AnnotationUsage; + [DecoratorNames.LOCAL_STORAGE_LINK]?: arkts.AnnotationUsage; + [DecoratorNames.PROP_REF]?: arkts.AnnotationUsage; + [DecoratorNames.STORAGE_PROP_REF]?: arkts.AnnotationUsage; + [DecoratorNames.LOCAL]?: arkts.AnnotationUsage; + [DecoratorNames.ONCE]?: arkts.AnnotationUsage; + [DecoratorNames.PARAM]?: arkts.AnnotationUsage; + [DecoratorNames.EVENT]?: arkts.AnnotationUsage; + [DecoratorNames.REQUIRE]?: arkts.AnnotationUsage; + [DecoratorNames.CONSUMER]?: arkts.AnnotationUsage; + [DecoratorNames.PROVIDER]?: arkts.AnnotationUsage; +} + +export class StructPropertyAnnotationRecord extends BaseAnnotationRecord< + StructPropertyAnnotations, + StructPropertyAnnotationInfo +> { + protected annotationNames: string[]; + + constructor(options: RecordOptions) { + super(options); + this.shouldIgnoreDecl = false; // TODO: remove this line + this.annotationNames = [ + DecoratorNames.STATE, + DecoratorNames.STORAGE_LINK, + DecoratorNames.STORAGE_PROP, + DecoratorNames.LINK, + DecoratorNames.PROP, + DecoratorNames.PROVIDE, + DecoratorNames.CONSUME, + DecoratorNames.OBJECT_LINK, + DecoratorNames.WATCH, + DecoratorNames.BUILDER_PARAM, + DecoratorNames.LOCAL_STORAGE_PROP, + DecoratorNames.LOCAL_STORAGE_LINK, + DecoratorNames.PROP_REF, + DecoratorNames.STORAGE_PROP_REF, + DecoratorNames.LOCAL, + DecoratorNames.ONCE, + DecoratorNames.PARAM, + DecoratorNames.EVENT, + DecoratorNames.REQUIRE, + DecoratorNames.CONSUMER, + DecoratorNames.PROVIDER, + ]; + } + + updateAnnotationInfoByName( + info: StructPropertyAnnotationInfo, + name: string | undefined + ): StructPropertyAnnotationInfo { + if (!!name && this.annotationNames.includes(name)) { + info[`has${name}`] = true; + } + return info; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/base.ts b/arkui-plugins/collectors/ui-collectors/records/base.ts new file mode 100644 index 0000000000000000000000000000000000000000..fff4152d4b1831ac9b6d83a9798d05a74a72c691 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/base.ts @@ -0,0 +1,75 @@ +/* + * 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'; + +export interface RecordOptions { + shouldIgnoreDecl: boolean; +} + +export abstract class BaseRecord> { + protected info: T | undefined; + protected shouldIgnoreDecl: boolean; + + private _isChanged: boolean = false; + private _isCollected: boolean = false; + + constructor(options: RecordOptions) { + this.shouldIgnoreDecl = options.shouldIgnoreDecl; + } + + protected get isChanged(): boolean { + return this._isChanged; + } + + protected set isChanged(isChanged: boolean) { + this._isChanged = isChanged; + } + + get isCollected(): boolean { + return this._isCollected; + } + + getOptions(): RecordOptions { + return { + shouldIgnoreDecl: this.shouldIgnoreDecl + } + } + + toRecord(): T | undefined { + this.refresh(); + return this.info; + } + + collect(node: Node): void { + this.collectFromNode(node); + this.isChanged = true; + this._isCollected = true; + } + + refresh(): void { + if (!this.isChanged) { + return; + } + this.refreshOnce(); + this.isChanged = false; + } + + protected abstract collectFromNode(node: Node): void; + + protected abstract refreshOnce(): void; + + abstract toJSON(): T; +} \ No newline at end of file diff --git a/arkui-plugins/collectors/ui-collectors/records/cache.ts b/arkui-plugins/collectors/ui-collectors/records/cache.ts new file mode 100644 index 0000000000000000000000000000000000000000..2ea11e0b3a8e57557264977174f244724430c814 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/cache.ts @@ -0,0 +1,167 @@ +/* + * 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 { BaseRecord } from './base'; +import { AstNodePointer } from 'common/safe-types'; + +/** + * Singleton LRU Cache implementation using Map's insertion order + * for efficient least-recently-used eviction. + */ +export class RecordCache>> { + private static instance: RecordCache>>; + private cache: Map; + private maxSize: number; + + private constructor(maxSize: number = 100) { + if (maxSize <= 0) { + throw new Error('Cache size must be positive'); + } + this.cache = new Map(); + this.maxSize = maxSize; + } + + /** + * Get the singleton instance of the cache + * @param maxSize Maximum number of items to store (default: 100) + * @returns The cache instance + */ + public static getInstance>>( + maxSize: number = 100 + ): RecordCache { + if (!this.instance) { + this.instance = new RecordCache(maxSize); + } else if (maxSize !== RecordCache.instance.maxSize) { + this.instance.resize(maxSize); + } + return this.instance as RecordCache; + } + + /** + * Get a value from the cache + * @param key Cache key + * @returns The cached value or undefined if not found + */ + public get(key: AstNodePointer): T | undefined { + const value = this.cache.get(key); + if (value !== undefined) { + // Refresh key by deleting and re-adding it + this.cache.delete(key); + this.cache.set(key, value); + } + return value; + } + + /** + * Set a value in the cache + * @param key Cache key + * @param value Value to cache + */ + public set(key: AstNodePointer, value: T): void { + if (this.cache.has(key)) { + // Refresh key by deleting it first + this.cache.delete(key); + } else if (this.cache.size >= this.maxSize) { + // Evict the first item (least recently used) + const firstKey = this.cache.keys().next().value; + if (firstKey !== undefined) { + this.cache.delete(firstKey); + } + } + this.cache.set(key, value); + } + + /** + * Check if a key exists in the cache + * @param key Cache key to check + * @returns True if the key exists + */ + public has(key: AstNodePointer): boolean { + return this.cache.has(key); + } + + /** + * Delete a key from the cache + * @param key Cache key to delete + * @returns True if the key was deleted + */ + public delete(key: AstNodePointer): boolean { + return this.cache.delete(key); + } + + /** + * Clear all items from the cache + */ + public clear(): void { + this.cache.clear(); + } + + /** + * Get the current number of items in the cache + * @returns Number of cached items + */ + public size(): number { + return this.cache.size; + } + + /** + * Get all cache keys (in order of most recently used) + * @returns Array of keys + */ + public keys(): string[] { + return Array.from(this.cache.keys()).reverse(); + } + + /** + * Get all cache values (in order of most recently used) + * @returns Array of values + */ + public values(): T[] { + return Array.from(this.cache.values()).reverse(); + } + + /** + * Get all cache entries (in order of most recently used) + * @returns Array of [key, value] pairs + */ + public entries(): [string, T][] { + return Array.from(this.cache.entries()).reverse(); + } + + /** + * Resize the cache (evicts LRU items if new size is smaller) + * @param newSize New maximum cache size + */ + public resize(newSize: number): void { + if (newSize <= 0) { + throw new Error('Cache size must be positive'); + } + + this.maxSize = newSize; + while (this.cache.size > this.maxSize) { + const firstKey = this.cache.keys().next().value!; + this.cache.delete(firstKey); + } + } + + /** + * Execute a function for each cache entry (from most to least recently used) + * @param callback Function to execute + */ + public forEach(callback: (value: T, key: AstNodePointer) => void): void { + this.entries().forEach(([key, value]) => callback(value, key)); + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/call-declaration.ts b/arkui-plugins/collectors/ui-collectors/records/call-declaration.ts new file mode 100644 index 0000000000000000000000000000000000000000..bcaa17a1c7808f8bd123eca722720e6d81a83af1 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/call-declaration.ts @@ -0,0 +1,146 @@ +/* + * 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 { CallDeclAnnotationInfo, CallDeclAnnotationRecord, CallDeclAnnotations } from './annotations'; +import { AnnotationRecord } from './annotations/base'; +import { BaseRecord, RecordOptions } from './base'; +import { BuiltInNames } from '../../../common/predefines'; + +export type CallDeclInfo = AnnotationRecord & { + /** + * declaration node's name. + */ + declName?: string; + + /** + * declaration node's modifier flags. + */ + modifiers?: arkts.Es2pandaModifierFlags; + + /** + * the module name where the declaration node is from. + */ + moduleName?: string; + + /** + * whether the call has function with receiver. + */ + hasReceiver?: boolean; + + /** + * whether the declaration node is a class property. + */ + isDeclFromClassProperty?: boolean; + + /** + * whether the declaration node is a class method. + */ + isDeclFromMethod?: boolean; + + /** + * whether declaration node is a global function. + */ + isDeclFromFunction?: boolean; +}; + +export class CallDeclRecord extends BaseRecord { + private _annotationRecord: CallDeclAnnotationRecord; + + protected declName?: string; + protected modifiers?: arkts.Es2pandaModifierFlags; + protected moduleName?: string; + protected hasReceiver?: boolean; + protected isDeclFromClassProperty?: boolean; + protected isDeclFromMethod?: boolean; + protected isDeclFromFunction?: boolean; + + constructor(options: RecordOptions) { + super(options); + this._annotationRecord = new CallDeclAnnotationRecord(options); + } + + private collectAnnotations(annotations: readonly arkts.AnnotationUsage[]): void { + for (const anno of annotations) { + this._annotationRecord.collect(anno); + } + } + + private collectFromClassProperty(node: arkts.ClassProperty): void { + if (!node.key || !arkts.isIdentifier(node.key)) { + return; + } + this.collectAnnotations(node.annotations); + this.declName = node.key.name; + this.modifiers = node.modifiers; + this.isDeclFromClassProperty = true; + } + + private collectFromMethod(node: arkts.MethodDefinition): void { + this.collectAnnotations(node.scriptFunction.annotations); + this.declName = node.name.name; + this.modifiers = node.modifiers; + this.hasReceiver = node.scriptFunction.hasReceiver; + if ( + !!node.parent && + arkts.isMethodDefinition(node.parent) && + node.parent.name.name === BuiltInNames.ETS_GLOBAL_CLASS + ) { + this.isDeclFromFunction = true; + } else { + this.isDeclFromMethod = true; + } + } + + protected collectFromNode(node: arkts.AstNode): void { + this.moduleName = arkts.getProgramFromAstNode(node)?.moduleName; + if (arkts.isClassProperty(node)) { + this.collectFromClassProperty(node); + } else if (arkts.isMethodDefinition(node)) { + this.collectFromMethod(node); + } + } + + protected refreshOnce(): void { + let currInfo = this.info ?? {}; + const annotationRecord = this._annotationRecord.toRecord(); + currInfo = { + ...currInfo, + ...(this.declName && { declName: this.declName }), + ...(this.modifiers && { modifiers: this.modifiers }), + ...(this.hasReceiver && { hasReceiver: this.hasReceiver }), + ...(this.moduleName && { moduleName: this.moduleName }), + ...(this.isDeclFromClassProperty && { isDeclFromClassProperty: this.isDeclFromClassProperty }), + ...(this.isDeclFromMethod && { isDeclFromMethod: this.isDeclFromMethod }), + ...(this.isDeclFromFunction && { isDeclFromFunction: this.isDeclFromFunction }), + ...(annotationRecord && { ...annotationRecord }), + }; + this.info = currInfo; + } + + toJSON(): CallDeclInfo { + this.refresh(); + return { + ...(this.info?.declName && { declName: this.info.declName }), + ...(this.info?.modifiers && { modifiers: this.info.modifiers }), + ...(this.info?.hasReceiver && { hasReceiver: this.info.hasReceiver }), + ...(this.info?.moduleName && { moduleName: this.info.moduleName }), + ...(this.info?.isDeclFromClassProperty && { isDeclFromClassProperty: this.info.isDeclFromClassProperty }), + ...(this.info?.isDeclFromMethod && { isDeclFromMethod: this.info.isDeclFromMethod }), + ...(this.info?.isDeclFromFunction && { isDeclFromFunction: this.info.isDeclFromFunction }), + ...(this.info?.annotationInfo && { annotationInfo: this.info.annotationInfo }), + }; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/function-call.ts b/arkui-plugins/collectors/ui-collectors/records/function-call.ts new file mode 100644 index 0000000000000000000000000000000000000000..92963f21249df27c66b6f05403a572862cdb3442 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/function-call.ts @@ -0,0 +1,428 @@ +/* + * 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 { BaseRecord, RecordOptions } from './base'; +import { CallDeclInfo, CallDeclRecord } from './call-declaration'; +import { CustomComponentInfo, CustomComponentRecord } from './struct'; +import { RecordBuilder } from './record-builder'; +import { + checkIsCallNameFromBindable, + checkIsCallNameFromResource, + checkIsStructFromNode, + findRootCallee, + findRootCallObject, + getDeclFromArkUI, + getStructFromCall, +} from '../utils'; +import { AstNodePointer } from '../../../common/safe-types'; +import { ARKUI_IMPORT_PREFIX_NAMES, Dollars } from '../../../common/predefines'; +import { filterDefined, matchPrefix } from '../../../common/arkts-utils'; +import { DeclarationCollector } from '../../../common/declaration-collector'; +import { + CustomComponentInterfacePropertyInfo, + CustomComponentInterfacePropertyRecord, +} from './struct-interface-property'; + +export type CallInfo = CallDeclInfo & { + /** + * this call node pointer + */ + ptr?: AstNodePointer; + + /** + * this call name (i.e. callee must be an Identifier), e.g calls like `a[0]()` has no call name + */ + callName?: string; + + /** + * a list of call infos start from the root call to this call in a chain (root call exclusive) + */ + chainingCallInfos?: CallInfo[]; + + /** + * whether this call is from current class's method or property + */ + isThis?: boolean; + + /** + * whether this call has trailing lambda argument + */ + isTrailingCall?: boolean; + + /** + * whether this call is `$$()` bindable call + */ + isBindableCall?: Dollars.DOLLAR_DOLLAR; + + /** + * whether bthis call is `$r()` or `$rawfile()` resource call + */ + isResourceCall?: Dollars.DOLLAR_RESOURCE | Dollars.DOLLAR_RAWFILE; + + /** + * call information from this call's root (e.g. `A.b().c()` has root call `b()`), call is root call if not exist + */ + rootCallInfo?: CallInfo; + + /** + * struct information from this call's object, call is not a struct call if not exist + */ + structDeclInfo?: CustomComponentInfo; + + /** + * struct call's options argument information, call is not a struct call or no options argument if not exist + */ + structPropertyInfos?: [AstNodePointer, CustomComponentInterfacePropertyInfo | undefined][]; + + /** + * struct information which contains this call, call is not in a struct if not exist + */ + fromStructInfo?: CustomComponentInfo; +}; + +export class CallRecord extends BaseRecord { + private _declRecord: CallDeclRecord; + private _structDeclRecord?: CustomComponentRecord; + private _fromStructRecord?: CustomComponentRecord; + private _structPropertyRecords?: [AstNodePointer, CustomComponentInterfacePropertyRecord][]; + + protected callName?: string; + protected ptr?: AstNodePointer; + protected isThis?: boolean; + protected isTrailingCall?: boolean; + protected isBindableCall?: Dollars.DOLLAR_DOLLAR; + protected isResourceCall?: Dollars.DOLLAR_RESOURCE | Dollars.DOLLAR_RAWFILE; + protected declInfo?: CallDeclInfo; + protected structDeclInfo?: CustomComponentInfo; + protected fromStructInfo?: CustomComponentInfo; + + private _rootCallObject?: arkts.Identifier | undefined; + private _rootCallee?: arkts.Identifier | undefined; + private _rootCallInfo?: CallInfo; + private _chainingCallInfos?: CallInfo[]; + + constructor(options: RecordOptions) { + super(options); + this._declRecord = new CallDeclRecord(options); + } + + get callPtr(): AstNodePointer | undefined { + return this.ptr; + } + + protected get rootCallInfo(): CallInfo | undefined { + return this._rootCallInfo; + } + + protected set rootCallInfo(rootCallInfo: CallInfo | undefined) { + if (this._rootCallInfo?.ptr !== rootCallInfo?.ptr) { + this._rootCallInfo = rootCallInfo; + this.isChanged = true; + } + } + + protected get chainingCallInfos(): CallInfo[] | undefined { + return this._chainingCallInfos; + } + + protected set chainingCallInfos(chainingCallInfos: CallInfo[] | undefined) { + this._chainingCallInfos = chainingCallInfos; + this.isChanged = true; + } + + protected get isStructCall(): boolean { + return !!this._structDeclRecord?.isCollected || !!this.rootCallInfo?.structDeclInfo || !!this.structDeclInfo; + } + + private checkIsThisFromCallee(callee: arkts.Identifier | undefined): boolean { + if (!callee) { + return false; + } + if (!callee.parent || !arkts.isMemberExpression(callee.parent)) { + return false; + } + return callee.parent.object && arkts.isThisExpression(callee.parent.object); + } + + private collectFromDecl(decl: arkts.AstNode | undefined): void { + if (!decl) { + return; + } + this._declRecord.collect(decl); + } + + private collectStructDeclInfo(structNode: arkts.ClassDefinition | undefined): void { + if ( + !structNode || + !structNode.parent || + !arkts.isClassDeclaration(structNode.parent) || + !checkIsStructFromNode(structNode.parent) + ) { + return; + } + const _record = RecordBuilder.build(CustomComponentRecord, structNode.parent, this.getOptions()); + this._structDeclRecord = _record; + if (!this._structDeclRecord.isCollected) { + this._structDeclRecord.collect(structNode.parent); + } + } + + private collectStructPropertyInfoFromStructCall(call: arkts.CallExpression): void { + if (!this.isStructCall || !!this._structPropertyRecords) { + return; + } + const optionsArg = call.arguments.at(1); // Options is the second argument of a custom component call. + if (!optionsArg || !arkts.isObjectExpression(optionsArg)) { + return; + } + const records: [AstNodePointer, CustomComponentInterfacePropertyRecord][] = []; + (optionsArg.properties as arkts.Property[]).forEach((prop) => { + let decl: arkts.AstNode | undefined; + if ( + !prop.key || + !prop.value || + !(decl = arkts.getPeerPropertyDecl(prop.peer)) || + !arkts.isMethodDefinition(decl) + ) { + return; + } + const structInterfacePropRecord = RecordBuilder.build( + CustomComponentInterfacePropertyRecord, + decl, + this.getOptions() + ); + if (!structInterfacePropRecord.isCollected) { + structInterfacePropRecord.collect(decl); + } + records.push([prop.peer, structInterfacePropRecord]); + }); + if (Object.keys(records).length > 0) { + this._structPropertyRecords = records; + } + } + + private collectFromStructInfo(structNode: arkts.ClassDefinition | undefined): void { + if ( + !structNode || + !structNode.parent || + !arkts.isClassDeclaration(structNode.parent) || + !checkIsStructFromNode(structNode.parent) + ) { + return; + } + const _record = RecordBuilder.build(CustomComponentRecord, structNode.parent, this.getOptions()); + this._fromStructRecord = _record; + if (!this._fromStructRecord.isCollected) { + this._fromStructRecord.collect(structNode.parent); + } + } + + private findStructDeclInfo(): void { + if (!!this.rootCallInfo?.structDeclInfo) { + this.structDeclInfo = this.rootCallInfo.structDeclInfo; + } else if (!this.structDeclInfo) { + const structNode = getStructFromCall(this._rootCallObject, this._rootCallee); + this.collectStructDeclInfo(structNode); + } + } + + private findFromStructInfo(): void { + if (!!this.rootCallInfo?.fromStructInfo) { + this.fromStructInfo = this.rootCallInfo.fromStructInfo; + } else if (!this.fromStructInfo) { + const structNode = this._rootCallee?.findOuterParent( + arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CLASS_DEFINITION + ); + this.collectFromStructInfo(structNode); + } + } + + private findResourceCall(decl: arkts.AstNode, declInfo: CallDeclInfo): void { + const name = declInfo.declName; + const moduleName = declInfo.moduleName; + if (!this.shouldIgnoreDecl && (!moduleName || !matchPrefix(ARKUI_IMPORT_PREFIX_NAMES, moduleName))) { + return; + } + if (!name || !checkIsCallNameFromResource(name)) { + return; + } + this.isResourceCall = name; + DeclarationCollector.getInstance().collect(decl); + } + + private findBinableCall(decl: arkts.AstNode, declInfo: CallDeclInfo): void { + const name = declInfo.declName; + const moduleName = declInfo.moduleName; + if (!this.shouldIgnoreDecl && (!moduleName || !matchPrefix(ARKUI_IMPORT_PREFIX_NAMES, moduleName))) { + return; + } + if (!name || !checkIsCallNameFromBindable(name)) { + return; + } + this.isBindableCall = name; + DeclarationCollector.getInstance().collect(decl); + } + + private findIsSpecialCall(decl?: arkts.AstNode): void { + const declInfo = this._declRecord.toRecord(); + if (!decl || !declInfo || !declInfo.declName) { + return; + } + this.findBinableCall(decl, declInfo); + this.findResourceCall(decl, declInfo); + } + + withRootCallee(rootCallee: arkts.Identifier | undefined): this { + this._rootCallee = rootCallee; + this.findStructDeclInfo(); + this.findFromStructInfo(); + return this; + } + + withRootCallObject(rootCallObject: arkts.Identifier | undefined): this { + this._rootCallObject = rootCallObject; + this.findStructDeclInfo(); + return this; + } + + withRootCallInfo(rootCallInfo: CallInfo): this { + this.rootCallInfo = rootCallInfo; + this.findStructDeclInfo(); + this.findFromStructInfo(); + return this; + } + + withChainingCallInfos(chainingCallInfos: CallInfo[]): this { + this.chainingCallInfos = chainingCallInfos; + return this; + } + + collectFromNode(node: arkts.CallExpression): void { + this.ptr = node.peer; + + const callee = node.expression; + this._rootCallObject = this._rootCallObject ?? findRootCallObject(callee); + this._rootCallee = this._rootCallee ?? findRootCallee(callee); + this.callName = this._rootCallee?.name; + this.isThis = this.checkIsThisFromCallee(this._rootCallee); + this.isTrailingCall = node.isTrailingCall; + this.findStructDeclInfo(); + this.findFromStructInfo(); + this.collectStructPropertyInfoFromStructCall(node); + + if (!!this._rootCallee) { + // console.log("[DECL INFO] callee: ", callee.dumpSrc()); + // console.log("[DECL INFO] _rootCallee: ", this._rootCallee?.dumpSrc()); + const decl = arkts.getPeerIdentifierDecl(this._rootCallee.peer); + this.collectFromDecl(decl); + this.findIsSpecialCall(decl); + // console.log("[DECL INFO] info: ", this._declRecord.toJSON()); + } + } + + toPropertyRecords(): [AstNodePointer, CustomComponentInterfacePropertyInfo | undefined][] | undefined { + if (!this._structPropertyRecords) { + return undefined; + } + const records: [AstNodePointer, CustomComponentInterfacePropertyInfo | undefined][] = []; + this._structPropertyRecords.forEach((record) => { + records.push([record[0], record[1].toJSON()]); + }); + return records; + } + + refreshOnce(): void { + let currInfo = this.info ?? {}; + const declRecord = this._declRecord.toRecord(); + const structDeclInfo = this.structDeclInfo ?? this._structDeclRecord?.toRecord(); + const fromStructInfo = this.fromStructInfo ?? this._fromStructRecord?.toRecord(); + const structPropertyInfos = this.toPropertyRecords(); + currInfo = { + ...currInfo, + ...(this.ptr && { ptr: this.ptr }), + ...(this.callName && { callName: this.callName }), + ...(this.chainingCallInfos && { chainingCallInfos: this.chainingCallInfos }), + ...(this.isThis && { isThis: this.isThis }), + ...(this.isTrailingCall && { isTrailingCall: this.isTrailingCall }), + ...(declRecord && { ...declRecord }), + ...(this.rootCallInfo && { rootCallInfo: this.rootCallInfo }), + ...(structDeclInfo && { structDeclInfo }), + ...(fromStructInfo && { fromStructInfo }), + ...(structPropertyInfos && { structPropertyInfos }), + }; + this.info = currInfo; + } + + toPropertyJSONs(): [AstNodePointer, CustomComponentInterfacePropertyInfo | undefined][] | undefined { + if (!this._structPropertyRecords) { + return undefined; + } + const records: [AstNodePointer, CustomComponentInterfacePropertyInfo | undefined][] = []; + this._structPropertyRecords.forEach((record) => { + records.push([-1, record[1].toJSON()]); + }); + return records; + } + + toRootCallJSON(): CallInfo | undefined { + if (!this.info || !this.info.rootCallInfo) { + return undefined; + } + const rootInfo = this.info.rootCallInfo; + return { + ...(rootInfo.callName && { callName: rootInfo.callName }), + ...(rootInfo.isThis && { isThis: rootInfo.isThis }), + ...(rootInfo.isTrailingCall && { isTrailingCall: rootInfo.isTrailingCall }), + ...(rootInfo.declName && { declName: rootInfo.declName }), + ...(rootInfo.modifiers && { modifiers: rootInfo.modifiers }), + ...(rootInfo.moduleName && { moduleName: rootInfo.moduleName }), + ...(rootInfo.isDeclFromClassProperty && { isDeclFromClassProperty: rootInfo.isDeclFromClassProperty }), + ...(rootInfo.isDeclFromMethod && { isDeclFromMethod: rootInfo.isDeclFromMethod }), + ...(rootInfo.isDeclFromFunction && { isDeclFromFunction: rootInfo.isDeclFromFunction }), + ...(rootInfo.annotationInfo && { annotationInfo: rootInfo.annotationInfo }), + }; + } + + toChainJSON(): CallInfo { + this.refresh(); + const declInfo = this._declRecord.toJSON(); + return { + ...(this.info?.callName && { callName: this.info.callName }), + ...(this.info?.isTrailingCall && { isTrailingCall: this.info.isTrailingCall }), + ...(declInfo && { ...declInfo }), + }; + } + + toJSON(): CallInfo { + this.refresh(); + const declInfo = this._declRecord.toJSON(); + const rootCallInfo = this.toRootCallJSON(); + const structDeclInfo = this._structDeclRecord?.toJSON(); + const fromStructInfo = this._fromStructRecord?.toJSON(); + const structPropertyInfos = this.toPropertyJSONs(); + return { + ...(this.info?.callName && { callName: this.info.callName }), + ...(this.info?.chainingCallInfos && { chainingCallInfos: this.info.chainingCallInfos }), + ...(this.info?.isThis && { isThis: this.info.isThis }), + ...(this.info?.isTrailingCall && { isTrailingCall: this.info.isTrailingCall }), + ...(declInfo && { ...declInfo }), + ...(rootCallInfo && { rootCallInfo }), + ...(structDeclInfo && { structDeclInfo }), + ...(fromStructInfo && { fromStructInfo }), + ...(structPropertyInfos && { structPropertyInfos }), + }; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/function.ts b/arkui-plugins/collectors/ui-collectors/records/function.ts new file mode 100644 index 0000000000000000000000000000000000000000..2e00b30f36eeba4eb26ab8e8ab93aaf7582d11eb --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/function.ts @@ -0,0 +1,87 @@ +/* + * 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 { FunctionAnnotationInfo, FunctionAnnotationRecord, FunctionAnnotations } from './annotations'; +import { AnnotationRecord } from './annotations/base'; +import { BaseRecord, RecordOptions } from './base'; +import { BuiltInNames } from '../../../common/predefines'; + +export type FunctionInfo = AnnotationRecord< + FunctionAnnotations, + FunctionAnnotationInfo +> & { + name?: string; + modifiers?: arkts.Es2pandaModifierFlags; + kind?: arkts.Es2pandaMethodDefinitionKind; + isDecl?: boolean; + isGlobalInit?: boolean; + isGlobalMain?: boolean; +}; + +export class FunctionRecord extends BaseRecord { + private _annotationRecord: FunctionAnnotationRecord; + + protected name?: string; + protected modifiers?: arkts.Es2pandaModifierFlags; + protected kind?: arkts.Es2pandaMethodDefinitionKind; + protected isDecl?: boolean; + protected isGlobalInit?: boolean; + protected isGlobalMain?: boolean; + + constructor(options: RecordOptions) { + super(options); + this._annotationRecord = new FunctionAnnotationRecord(options); + } + + collectFromNode(node: arkts.MethodDefinition): void { + this.name = node.name.name; + this.modifiers = node.modifiers; + this.kind = node.kind; + this.isDecl = arkts.hasModifierFlag(node, arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_DECLARE); + this.isGlobalInit = this.name === BuiltInNames.GLOBAL_INIT_METHOD; + this.isGlobalMain = this.name === BuiltInNames.GLOBAL_MAIN_METHOD; + for (const anno of node.scriptFunction.annotations) { + this._annotationRecord.collect(anno); + } + } + + refreshOnce(): void { + let currInfo = this.info ?? {}; + const annotationRecord = this._annotationRecord.toRecord(); + currInfo = { + ...currInfo, + ...(this.name && { name: this.name }), + ...(this.modifiers && { modifiers: this.modifiers }), + ...(this.kind && { kind: this.kind }), + ...(this.isDecl && { isDecl: this.isDecl }), + ...(this.isGlobalInit && { isGlobalInit: this.isGlobalInit }), + ...(this.isGlobalMain && { isGlobalMain: this.isGlobalMain }), + ...(annotationRecord && { ...annotationRecord }), + }; + this.info = currInfo; + } + + toJSON(): FunctionInfo { + this.refresh(); + return { + ...(this.info?.name && { name: this.info.name }), + ...(this.info?.modifiers && { modifiers: this.info.modifiers }), + ...(this.info?.kind && { kind: this.info.kind }), + ...(this.info?.isDecl && { isDecl: this.info.isDecl }), + ...(this.info?.annotationInfo && { annotationInfo: this.info.annotationInfo }), + }; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/index.ts b/arkui-plugins/collectors/ui-collectors/records/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..c48cb8bd32914c6a0249a9eef93d6b9432b61af0 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/index.ts @@ -0,0 +1,31 @@ +/* + * 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. + */ + +export * from './annotations'; +export * from './normal-class'; +export * from './normal-class-property'; +export * from './normal-class-method'; +export * from './normal-interface'; +export * from './normal-interface-property'; +export * from './struct'; +export * from './struct-property'; +export * from './struct-method'; +export * from './struct-interface'; +export * from './struct-interface-property'; +export * from './call-declaration'; +export * from './function'; +export * from './function-call'; +export * from './record-builder'; +export * from './cache'; \ No newline at end of file diff --git a/arkui-plugins/collectors/ui-collectors/records/normal-class-method.ts b/arkui-plugins/collectors/ui-collectors/records/normal-class-method.ts new file mode 100644 index 0000000000000000000000000000000000000000..f1f6de1247a08d568f6e4406f6a68fc313bcb86c --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/normal-class-method.ts @@ -0,0 +1,91 @@ +/* + * 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 { BaseRecord, RecordOptions } from './base'; +import { NormalClassInfo, NormalClassRecord } from './normal-class'; +import { AnnotationRecord } from './annotations/base'; +import { + NormalClassMethodAnnotationInfo, + NormalClassMethodAnnotationRecord, + NormalClassMethodAnnotations, +} from './annotations'; + +export type NormalClassMethodInfo = AnnotationRecord & { + classInfo?: NormalClassInfo; + name?: string; + modifiers?: arkts.Es2pandaModifierFlags; + kind?: arkts.Es2pandaMethodDefinitionKind; + isDecl?: boolean; +}; + +export interface NormalClassMethodRecordOptions extends RecordOptions { + classRecord?: NormalClassRecord; +} + +export class NormalClassMethodRecord extends BaseRecord { + private _annotationRecord: NormalClassMethodAnnotationRecord; + private _classRecord?: NormalClassRecord; + + protected name?: string; + protected modifiers?: arkts.Es2pandaModifierFlags; + protected kind?: arkts.Es2pandaMethodDefinitionKind; + protected isDecl?: boolean; + + constructor(options: NormalClassMethodRecordOptions) { + super(options); + this._classRecord = options.classRecord; + this._annotationRecord = new NormalClassMethodAnnotationRecord(options); + } + + collectFromNode(node: arkts.MethodDefinition): void { + this.name = node.name.name; + this.modifiers = node.modifiers; + this.kind = node.kind; + this.isDecl = arkts.hasModifierFlag(node, arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_DECLARE); + for (const anno of node.scriptFunction.annotations) { + this._annotationRecord.collect(anno); + } + } + + refreshOnce(): void { + let currInfo = this.info ?? {}; + const annotationRecord = this._annotationRecord.toRecord(); + const classRecord = this._classRecord?.toRecord(); + currInfo = { + ...currInfo, + ...(this.name && { name: this.name }), + ...(this.modifiers && { modifiers: this.modifiers }), + ...(this.kind && { kind: this.kind }), + ...(this.isDecl && { isDecl: this.isDecl }), + ...(annotationRecord && { ...annotationRecord }), + ...(classRecord && { classInfo: classRecord }), + }; + this.info = currInfo; + } + + toJSON(): NormalClassMethodInfo { + this.refresh(); + const classInfo = this._classRecord?.toJSON(); + return { + ...(this.info?.name && { name: this.info.name }), + ...(this.info?.modifiers && { modifiers: this.info.modifiers }), + ...(this.info?.kind && { kind: this.info.kind }), + ...(this.info?.isDecl && { isDecl: this.info.isDecl }), + ...(this.info?.annotationInfo && { annotationInfo: this.info.annotationInfo }), + ...(classInfo && { classInfo }), + }; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/normal-class-property.ts b/arkui-plugins/collectors/ui-collectors/records/normal-class-property.ts new file mode 100644 index 0000000000000000000000000000000000000000..923c7cbd82a8addee0773921c4ba3aa883d99e60 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/normal-class-property.ts @@ -0,0 +1,88 @@ +/* + * 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 { + NormalClassPropertyAnnotationInfo, + NormalClassPropertyAnnotationRecord, + NormalClassPropertyAnnotations, +} from './annotations'; +import { AnnotationRecord } from './annotations/base'; +import { BaseRecord, RecordOptions } from './base'; +import { NormalClassInfo, NormalClassRecord } from './normal-class'; + +export type NormalClassPropertyInfo = AnnotationRecord< + NormalClassPropertyAnnotations, + NormalClassPropertyAnnotationInfo +> & { + classInfo?: NormalClassInfo; + name?: string; + modifiers?: arkts.Es2pandaModifierFlags; +}; + +export interface NormalClassPropertyRecordOptions extends RecordOptions { + classRecord: NormalClassRecord; +} + +export class NormalClassPropertyRecord extends BaseRecord { + private _annotationRecord: NormalClassPropertyAnnotationRecord; + private _classRecord: NormalClassRecord; + + protected name?: string; + protected modifiers?: arkts.Es2pandaModifierFlags; + + constructor(options: NormalClassPropertyRecordOptions) { + super(options); + this._classRecord = options.classRecord; + this._annotationRecord = new NormalClassPropertyAnnotationRecord(options); + } + + collectFromNode(node: arkts.ClassProperty): void { + const key: arkts.Expression | undefined = node.key; + if (!key || !arkts.isIdentifier(key)) { + return; + } + this.name = key.name; + this.modifiers = node.modifiers; + for (const anno of node.annotations) { + this._annotationRecord.collect(anno); + } + } + + refreshOnce(): void { + let currInfo = this.info ?? {}; + const annotationRecord = this._annotationRecord.toRecord(); + const classRecord = this._classRecord.toRecord(); + currInfo = { + ...currInfo, + ...(this.name && { name: this.name }), + ...(this.modifiers && { modifiers: this.modifiers }), + ...(annotationRecord && { ...annotationRecord }), + ...(classRecord && { classInfo: classRecord }), + }; + this.info = currInfo; + } + + toJSON(): NormalClassPropertyInfo { + this.refresh(); + const classInfo = this._classRecord.toJSON(); + return { + ...(this.info?.name && { name: this.info.name }), + ...(this.info?.modifiers && { modifiers: this.info.modifiers }), + ...(this.info?.annotationInfo && { annotationInfo: this.info.annotationInfo }), + ...(classInfo && { classInfo }), + }; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/normal-class.ts b/arkui-plugins/collectors/ui-collectors/records/normal-class.ts new file mode 100644 index 0000000000000000000000000000000000000000..cbb94876b73d3e466df76d7d2f4afde98e628459 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/normal-class.ts @@ -0,0 +1,97 @@ +/* + * 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 { NormalClassAnnotationInfo, NormalClassAnnotationRecord, NormalClassAnnotations } from './annotations'; +import { AnnotationRecord } from './annotations/base'; +import { BaseRecord, RecordOptions } from './base'; +import { RecordCache } from './cache'; +import { BuiltInNames } from '../../../common/predefines'; +import { AstNodePointer } from '../../../common/safe-types'; + +export type NormalClassInfo = AnnotationRecord & { + /** + * class defintion node's pointer. + */ + definitionPtr?: AstNodePointer; + + /** + * class name. + */ + name?: string; + + /** + * whether this class is declared. + */ + isDecl?: boolean; + + /** + * whether this class is ETSGLOBAL class. + */ + isETSGlobal?: boolean; +}; + +export class NormalClassRecord extends BaseRecord { + private _annotationRecord: NormalClassAnnotationRecord; + + protected definitionPtr?: AstNodePointer; + protected name?: string; + protected isDecl?: boolean; + protected isETSGlobal?: boolean; + + constructor(options: RecordOptions) { + super(options); + this._annotationRecord = new NormalClassAnnotationRecord(options); + } + + collectFromNode(node: arkts.ClassDeclaration): void { + const definition: arkts.ClassDefinition | undefined = node.definition; + if (!definition || !definition?.ident?.name) { + return; + } + this.name = definition.ident.name; + this.definitionPtr = definition.peer; + this.isETSGlobal = this.name === BuiltInNames.ETS_GLOBAL_CLASS; + this.isDecl = arkts.hasModifierFlag(node, arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_DECLARE); + for (const anno of definition.annotations) { + this._annotationRecord.collect(anno); + } + RecordCache.getInstance().set(node.peer, this); // TODO: don't need this + } + + refreshOnce(): void { + let currInfo = this.info ?? {}; + const annotationRecord = this._annotationRecord.toRecord(); + currInfo = { + ...currInfo, + ...(this.name && { name: this.name }), + ...(this.isDecl && { isDecl: this.isDecl }), + ...(this.isETSGlobal && { isETSGlobal: this.isETSGlobal }), + ...(this.definitionPtr && { definitionPtr: this.definitionPtr }), + ...(annotationRecord && { ...annotationRecord }), + }; + this.info = currInfo; + } + + toJSON(): NormalClassInfo { + this.refresh(); + return { + ...(this.info?.name && { name: this.info.name }), + ...(this.info?.isDecl && { isDecl: this.info.isDecl }), + ...(this.isETSGlobal && { isETSGlobal: this.isETSGlobal }), + ...(this.info?.annotationInfo && { annotationInfo: this.info.annotationInfo }), + }; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/normal-interface-property.ts b/arkui-plugins/collectors/ui-collectors/records/normal-interface-property.ts new file mode 100644 index 0000000000000000000000000000000000000000..43bd7c03a84e5b2e6ce6fa12a50c60250ed03e35 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/normal-interface-property.ts @@ -0,0 +1,89 @@ +/* + * 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 { + NormalInterfacePropertyAnnotationInfo, + NormalInterfacePropertyAnnotationRecord, + NormalInterfacePropertyAnnotations, +} from './annotations'; +import { AnnotationRecord } from './annotations/base'; +import { BaseRecord, RecordOptions } from './base'; +import { NormalInterfaceInfo, NormalInterfaceRecord } from './normal-interface'; + +export type NormalInterfacePropertyInfo = AnnotationRecord< + NormalInterfacePropertyAnnotations, + NormalInterfacePropertyAnnotationInfo +> & { + interfaceInfo?: NormalInterfaceInfo; + name?: string; + modifiers?: arkts.Es2pandaModifierFlags; + kind?: arkts.Es2pandaMethodDefinitionKind; +}; + +export interface NormalInterfacePropertyRecordOptions extends RecordOptions { + interfaceRecord: NormalInterfaceRecord; +} + +export class NormalInterfacePropertyRecord extends BaseRecord { + private _annotationRecord: NormalInterfacePropertyAnnotationRecord; + private _interfaceRecord: NormalInterfaceRecord; + + protected name?: string; + protected modifiers?: arkts.Es2pandaModifierFlags; + protected kind?: arkts.Es2pandaMethodDefinitionKind; + + constructor(options: NormalInterfacePropertyRecordOptions) { + super(options); + this._interfaceRecord = options.interfaceRecord; + this._annotationRecord = new NormalInterfacePropertyAnnotationRecord(options); + } + + collectFromNode(node: arkts.MethodDefinition): void { + this.name = node.name.name; + this.modifiers = node.modifiers; + this.kind = node.kind; + for (const anno of node.scriptFunction.annotations) { + this._annotationRecord.collect(anno); + } + } + + refreshOnce(): void { + let currInfo = this.info ?? {}; + const annotationRecord = this._annotationRecord.toRecord(); + const interfaceRecord = this._interfaceRecord.toRecord(); + currInfo = { + ...currInfo, + ...(this.name && { name: this.name }), + ...(this.modifiers && { modifiers: this.modifiers }), + ...(this.kind && { kind: this.kind }), + ...(annotationRecord && { ...annotationRecord }), + ...(interfaceRecord && { interfaceInfo: interfaceRecord }), + }; + this.info = currInfo; + } + + toJSON(): NormalInterfacePropertyInfo { + this.refresh(); + const interfaceInfo = this._interfaceRecord.toJSON(); + return { + ...(this.info?.name && { name: this.info.name }), + ...(this.info?.modifiers && { modifiers: this.info.modifiers }), + ...(this.info?.kind && { kind: this.info.kind }), + ...(this.info?.annotationInfo && { annotationInfo: this.info.annotationInfo }), + ...(interfaceInfo && { interfaceInfo }), + }; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/normal-interface.ts b/arkui-plugins/collectors/ui-collectors/records/normal-interface.ts new file mode 100644 index 0000000000000000000000000000000000000000..729be1798dc26ad5a014a9cb76a57bbd06f174d9 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/normal-interface.ts @@ -0,0 +1,53 @@ +/* + * 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 { BaseRecord, RecordOptions } from './base'; + +export type NormalInterfaceInfo = { + name?: string; +}; + +export class NormalInterfaceRecord extends BaseRecord { + protected name?: string; + + constructor(options: RecordOptions) { + super(options); + } + + collectFromNode(node: arkts.TSInterfaceDeclaration): void { + const interfaceBody: arkts.TSInterfaceBody | undefined = node.body; + if (!interfaceBody || !node.id?.name) { + return; + } + this.name = node.id.name; + } + + refreshOnce(): void { + let currInfo = this.info ?? {}; + currInfo = { + ...currInfo, + ...(this.name && { name: this.name }), + } + this.info = currInfo; + } + + toJSON(): NormalInterfaceInfo { + this.refresh(); + return { + ...(this.info?.name && { name: this.info.name }), + } + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/record-builder.ts b/arkui-plugins/collectors/ui-collectors/records/record-builder.ts new file mode 100644 index 0000000000000000000000000000000000000000..8af86e11fe5ad70add05c72124f007df6ec91c8b --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/record-builder.ts @@ -0,0 +1,45 @@ +/* + * 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 { BaseRecord, RecordOptions } from './base'; +import { RecordCache } from './cache'; +import { AstNodePointer } from 'common/safe-types'; + +function getOrPut< + T extends BaseRecord>, + U extends RecordOptions = RecordOptions +>(key: AstNodePointer, options: U, create: (options: U) => T): T { + if (RecordCache.getInstance().has(key)) { + return RecordCache.getInstance().get(key)!; + } + const newRecord = create(options); + RecordCache.getInstance().set(key, newRecord); + return newRecord; +} + +export class RecordBuilder { + static build>, T extends RecordOptions = RecordOptions>( + Record: { new (options: T): V }, + node: U, + options: T + ): V { + return getOrPut(node.peer, options, (options: T) => new Record(options)); + } + + static reset(): void { + RecordCache.getInstance().clear(); + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/struct-interface-property.ts b/arkui-plugins/collectors/ui-collectors/records/struct-interface-property.ts new file mode 100644 index 0000000000000000000000000000000000000000..ca30129715274a305f25dc1a6f908d75ce106a14 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/struct-interface-property.ts @@ -0,0 +1,90 @@ +/* + * 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 { StructPropertyAnnotationInfo, StructPropertyAnnotationRecord, StructPropertyAnnotations } from './annotations'; +import { AnnotationRecord } from './annotations/base'; +import { BaseRecord, RecordOptions } from './base'; +import { CustomComponentInterfaceInfo, CustomComponentInterfaceRecord } from './struct-interface'; +import { RecordCache } from './cache'; + +export type CustomComponentInterfacePropertyInfo = AnnotationRecord< + StructPropertyAnnotations, + StructPropertyAnnotationInfo +> & { + interfaceInfo?: CustomComponentInterfaceInfo; + name?: string; + modifiers?: arkts.Es2pandaModifierFlags; + kind?: arkts.Es2pandaMethodDefinitionKind; +}; + +export interface CustomComponentInterfacePropertyRecordOptions extends RecordOptions { + interfaceRecord?: CustomComponentInterfaceRecord; +} + +export class CustomComponentInterfacePropertyRecord extends BaseRecord< + arkts.MethodDefinition, + CustomComponentInterfacePropertyInfo +> { + private _annotationRecord: StructPropertyAnnotationRecord; + private _interfaceRecord?: CustomComponentInterfaceRecord; + + protected name?: string; + protected modifiers?: arkts.Es2pandaModifierFlags; + protected kind?: arkts.Es2pandaMethodDefinitionKind; + + constructor(options: CustomComponentInterfacePropertyRecordOptions) { + super(options); + this._interfaceRecord = options.interfaceRecord; + this._annotationRecord = new StructPropertyAnnotationRecord(options); + } + + collectFromNode(node: arkts.MethodDefinition): void { + this.name = node.name.name; + this.modifiers = node.modifiers; + this.kind = node.kind; + for (const anno of node.scriptFunction.annotations) { + this._annotationRecord.collect(anno); + } + RecordCache.getInstance().set(node.peer, this); + } + + refreshOnce(): void { + let currInfo = this.info ?? {}; + const annotationRecord = this._annotationRecord.toRecord(); + const interfaceRecord = this._interfaceRecord?.toRecord(); + currInfo = { + ...currInfo, + ...(this.name && { name: this.name }), + ...(this.modifiers && { modifiers: this.modifiers }), + ...(this.kind && { kind: this.kind }), + ...(annotationRecord && { ...annotationRecord }), + ...(interfaceRecord && { interfaceInfo: interfaceRecord }), + }; + this.info = currInfo; + } + + toJSON(): CustomComponentInterfacePropertyInfo { + this.refresh(); + const interfaceInfo = this._interfaceRecord?.toJSON(); + return { + ...(this.info?.name && { name: this.info.name }), + ...(this.info?.modifiers && { modifiers: this.info.modifiers }), + ...(this.info?.kind && { kind: this.info.kind }), + ...(this.info?.annotationInfo && { annotationInfo: this.info.annotationInfo }), + ...(interfaceInfo && { interfaceInfo }), + }; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/struct-interface.ts b/arkui-plugins/collectors/ui-collectors/records/struct-interface.ts new file mode 100644 index 0000000000000000000000000000000000000000..83bdd9ac52410187284f8f58bbfa792674ed15b2 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/struct-interface.ts @@ -0,0 +1,66 @@ +/* + * 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 { CustomComponentAnnotationRecord, CustomComponentAnnotations, StructAnnotationInfo } from './annotations'; +import { AnnotationRecord } from './annotations/base'; +import { BaseRecord, RecordOptions } from './base'; +import { RecordCache } from './cache'; + +export type CustomComponentInterfaceInfo = AnnotationRecord & { + name?: string; +}; + +export class CustomComponentInterfaceRecord extends BaseRecord { + private _annotationRecord: CustomComponentAnnotationRecord; + + protected name?: string; + + constructor(options: RecordOptions) { + super(options); + this._annotationRecord = new CustomComponentAnnotationRecord(options); + } + + collectFromNode(node: arkts.TSInterfaceDeclaration): void { + const interfaceBody: arkts.TSInterfaceBody | undefined = node.body; + if (!interfaceBody || !node.id?.name) { + return; + } + this.name = node.id.name; + for (const anno of node.annotations) { + this._annotationRecord.collect(anno); + } + RecordCache.getInstance().set(node.peer, this); + } + + refreshOnce(): void { + let currInfo = this.info ?? {}; + const annotationRecord = this._annotationRecord.toRecord(); + currInfo = { + ...currInfo, + ...(this.name && { name: this.name }), + ...(annotationRecord && { ...annotationRecord }) + } + this.info = currInfo; + } + + toJSON(): CustomComponentInterfaceInfo { + this.refresh(); + return { + ...(this.info?.name && { name: this.info.name }), + ...(this.info?.annotationInfo && { annotationInfo: this.info.annotationInfo }), + } + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/struct-method.ts b/arkui-plugins/collectors/ui-collectors/records/struct-method.ts new file mode 100644 index 0000000000000000000000000000000000000000..28804dc5be9bd3c49585ea92e19ab6ad0bfed47b --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/struct-method.ts @@ -0,0 +1,95 @@ +/* + * 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 { StructMethodAnnotationInfo, StructMethodAnnotationRecord, StructMethodAnnotations } from './annotations'; +import { AnnotationRecord } from './annotations/base'; +import { BaseRecord, RecordOptions } from './base'; +import { CustomComponentRecord, CustomComponentInfo } from './struct'; +import { CustomComponentNames } from '../../../common/predefines'; +import { RecordCache } from './cache'; + +export type StructMethodInfo = AnnotationRecord & { + structInfo?: CustomComponentInfo; + name?: string; + modifiers?: arkts.Es2pandaModifierFlags; + kind?: arkts.Es2pandaMethodDefinitionKind; + isDecl?: boolean; + isCtor?: boolean; +}; + +export interface StructMethodRecordOptions extends RecordOptions { + structRecord?: CustomComponentRecord; +} + +export class StructMethodRecord extends BaseRecord { + private _annotationRecord: StructMethodAnnotationRecord; + private _structRecord?: CustomComponentRecord; + + protected name?: string; + protected modifiers?: arkts.Es2pandaModifierFlags; + protected kind?: arkts.Es2pandaMethodDefinitionKind; + protected isDecl?: boolean; + protected isCtor?: boolean; + + constructor(options: StructMethodRecordOptions) { + super(options); + this._structRecord = options.structRecord; + this._annotationRecord = new StructMethodAnnotationRecord(options); + } + + collectFromNode(node: arkts.MethodDefinition): void { + this.name = node.name.name; + this.modifiers = node.modifiers; + this.kind = node.kind; + this.isDecl = arkts.hasModifierFlag(node, arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_DECLARE); + this.isCtor = this.name === CustomComponentNames.COMPONENT_CONSTRUCTOR_ORI; + for (const anno of node.scriptFunction.annotations) { + this._annotationRecord.collect(anno); + } + RecordCache.getInstance().set(node.peer, this); + } + + refreshOnce(): void { + let currInfo = this.info ?? {}; + const annotationRecord = this._annotationRecord.toRecord(); + const structRecord = this._structRecord?.toRecord(); + currInfo = { + ...currInfo, + ...(this.name && { name: this.name }), + ...(this.modifiers && { modifiers: this.modifiers }), + ...(this.kind && { kind: this.kind }), + ...(this.isDecl && { isDecl: this.isDecl }), + ...(this.isCtor && { isCtor: this.isCtor }), + ...(annotationRecord && { ...annotationRecord }), + ...(structRecord && { structInfo: structRecord }), + }; + this.info = currInfo; + } + + toJSON(): StructMethodInfo { + this.refresh(); + const structInfo = this._structRecord?.toJSON(); + return { + ...(this.info?.name && { name: this.info.name }), + ...(this.info?.modifiers && { modifiers: this.info.modifiers }), + ...(this.info?.kind && { kind: this.info.kind }), + ...(this.info?.isDecl && { isDecl: this.info.isDecl }), + ...(this.info?.isCtor && { isCtor: this.info.isCtor }), + ...(this.info?.annotationInfo && { annotationInfo: this.info.annotationInfo }), + ...(structInfo && { structInfo }), + }; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/struct-property.ts b/arkui-plugins/collectors/ui-collectors/records/struct-property.ts new file mode 100644 index 0000000000000000000000000000000000000000..ff1d698adf82fb4aaf7bb422bf40b537ddc697eb --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/struct-property.ts @@ -0,0 +1,83 @@ +/* + * 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 { StructPropertyAnnotationInfo, StructPropertyAnnotationRecord, StructPropertyAnnotations } from './annotations'; +import { AnnotationRecord } from './annotations/base'; +import { BaseRecord, RecordOptions } from './base'; +import { CustomComponentRecord, CustomComponentInfo } from './struct'; +import { RecordCache } from './cache'; + +export type StructPropertyInfo = AnnotationRecord & { + structInfo?: CustomComponentInfo; + name?: string; + modifiers?: arkts.Es2pandaModifierFlags; +}; + +export interface StructPropertyRecordOptions extends RecordOptions { + structRecord: CustomComponentRecord; +} + +export class StructPropertyRecord extends BaseRecord { + private _annotationRecord: StructPropertyAnnotationRecord; + private _structRecord: CustomComponentRecord; + + protected name?: string; + protected modifiers?: arkts.Es2pandaModifierFlags; + + constructor(options: StructPropertyRecordOptions) { + super(options); + this._structRecord = options.structRecord; + this._annotationRecord = new StructPropertyAnnotationRecord(options); + } + + collectFromNode(node: arkts.ClassProperty): void { + const key: arkts.Expression | undefined = node.key; + if (!key || !arkts.isIdentifier(key)) { + return; + } + this.name = key.name; + this.modifiers = node.modifiers; + for (const anno of node.annotations) { + this._annotationRecord.collect(anno); + } + RecordCache.getInstance().set(node.peer, this); + } + + refreshOnce(): void { + let currInfo = this.info ?? {}; + const annotationRecord = this._annotationRecord.toRecord(); + const structRecord = this._structRecord.toRecord(); + currInfo = { + ...currInfo, + ...(this.name && { name: this.name }), + ...(this.modifiers && { modifiers: this.modifiers }), + ...(annotationRecord && { ...annotationRecord }), + ...(structRecord && { structInfo: structRecord }), + }; + this.info = currInfo; + } + + toJSON(): StructPropertyInfo { + this.refresh(); + const structInfo = this._structRecord.toJSON(); + return { + ...(this.info?.name && { name: this.info.name }), + ...(this.info?.modifiers && { modifiers: this.info.modifiers }), + ...(this.info?.annotationInfo && { annotationInfo: this.info.annotationInfo }), + ...(structInfo && { structInfo }), + }; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/records/struct.ts b/arkui-plugins/collectors/ui-collectors/records/struct.ts new file mode 100644 index 0000000000000000000000000000000000000000..42f346416b8a859b262a8f235da84d76a65032c3 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/records/struct.ts @@ -0,0 +1,120 @@ +/* + * 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 { CustomComponentAnnotationRecord, CustomComponentAnnotations, StructAnnotationInfo } from './annotations'; +import { AnnotationRecord } from './annotations/base'; +import { BaseRecord, RecordOptions } from './base'; +import { + checkIsCustomComponentDeclaredClassFromInfo, + checkIsStructFromNode, +} from '../utils'; +import { AstNodePointer } from '../../../common/safe-types'; +import { RecordCache } from './cache'; + +export type CustomComponentInfo = AnnotationRecord & { + /** + * class defintion node's pointer. + */ + definitionPtr?: AstNodePointer; + + /** + * struct name, or declared `CustomComponent` etcs. name in header files. + */ + name?: string; + + /** + * whether struct or declared `CustomComponent` is from ArkUI SDK. + */ + isFromArkUI?: boolean; + + /** + * whether this struct or `CustomComponent` class is declared. + */ + isDecl?: boolean; +}; + +export class CustomComponentRecord extends BaseRecord { + private _annotationRecord: CustomComponentAnnotationRecord; + + protected definitionPtr?: AstNodePointer; + protected name?: string; + protected isDecl?: boolean; + protected isFromArkUI?: boolean; + + constructor(options: RecordOptions) { + super(options); + this._annotationRecord = new CustomComponentAnnotationRecord(options); + } + + withIsFromArkUI(isFromArkUI: boolean): this { + this.isFromArkUI = isFromArkUI; + return this; + } + + collectFromNode(node: arkts.ClassDeclaration): void { + const definition: arkts.ClassDefinition | undefined = node.definition; + if (!definition) { + return; + } + const name = definition.ident?.name; + if (!name) { + return; + } + const isDecl = arkts.hasModifierFlag(node, arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_DECLARE); + const isStruct = checkIsStructFromNode(node); + const isCustomComponentClass = checkIsCustomComponentDeclaredClassFromInfo({ + name, + isDecl, + isFromArkUI: this.isFromArkUI, + }); + if (!isStruct && !isCustomComponentClass) { + return; + } + this.name = name; + this.isDecl = isDecl; + if (isStruct) { + for (const anno of definition.annotations) { + this._annotationRecord.collect(anno); + } + this.definitionPtr = definition.peer; + RecordCache.getInstance().set(node.peer, this); + } + } + + refreshOnce(): void { + let currInfo = this.info ?? {}; + const annotationRecord = this._annotationRecord.toRecord(); + currInfo = { + ...currInfo, + ...(this.name && { name: this.name }), + ...(this.isDecl && { isDecl: this.isDecl }), + ...(this.isFromArkUI && { isFromArkUI: this.isFromArkUI }), + ...(this.definitionPtr && { definitionPtr: this.definitionPtr }), + ...(annotationRecord && { ...annotationRecord }), + }; + this.info = currInfo; + } + + toJSON(): CustomComponentInfo { + this.refresh(); + return { + ...(this.info?.name && { name: this.info.name }), + ...(this.info?.isDecl && { isDecl: this.info.isDecl }), + ...(this.info?.isFromArkUI && { isFromArkUI: this.info.isFromArkUI }), + ...(this.info?.annotationInfo && { annotationInfo: this.info.annotationInfo }), + }; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/shared-types.ts b/arkui-plugins/collectors/ui-collectors/shared-types.ts new file mode 100644 index 0000000000000000000000000000000000000000..c0625bb4bae1fe3ac48e1f30cadb51ea955c1f34 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/shared-types.ts @@ -0,0 +1,27 @@ +/* + * 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 { VisitorOptions } from "../../common/abstract-visitor"; +import { AstNodePointer } from "../../common/safe-types"; +import { CustomComponentInfo, StructMethodInfo, StructPropertyInfo } from "./records"; + +export interface UICollectMetadata extends VisitorOptions { + shouldIgnoreDecl: boolean; +} + +export interface StructCollectorInfo extends CustomComponentInfo { + propertyInfoMap: Record; + methodInfoMap: Record; +} \ No newline at end of file diff --git a/arkui-plugins/collectors/ui-collectors/struct-collector.ts b/arkui-plugins/collectors/ui-collectors/struct-collector.ts new file mode 100644 index 0000000000000000000000000000000000000000..67f14461d4b43f64aa0b2b8b4ba44b83d5876d65 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/struct-collector.ts @@ -0,0 +1,160 @@ +/* + * 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 { + CustomComponentRecord, + StructMethodInfo, + StructMethodRecord, + StructPropertyInfo, + StructPropertyRecord, +} from './records'; +import { AbstractVisitor, VisitorOptions } from '../../common/abstract-visitor'; +import { BuilderLambdaNames, CustomComponentNames, NodeCacheNames } from '../../common/predefines'; +import { AstNodePointer } from '../../common/safe-types'; +import { StructMethodValidator, StructPropertyValidator, ValidatorBuilder } from './validators'; +import { checkIsCustomComponentFromInfo } from './utils'; + +export interface StructCollectorOptions extends VisitorOptions { + structRecord: CustomComponentRecord; + shouldIgnoreDecl?: boolean; +} + +export class StructCollector extends AbstractVisitor { + private _structRecord: CustomComponentRecord; + private _disableCollectProperty: boolean = false; + private _shouldCollectProperty: boolean = true; + // private _properties: Record = {}; + // private _methods: Record = {}; + + public shouldIgnoreDecl: boolean; + + constructor(options: StructCollectorOptions) { + super(options); + this._structRecord = options.structRecord; + this.shouldIgnoreDecl = options.shouldIgnoreDecl ?? false; + } + + // get propertyInfoMap(): Record { + // return this._properties; + // } + + // get methodInfoMap(): Record { + // return this._methods; + // } + + private get shouldCollectProperty(): boolean { + if (this._disableCollectProperty) { + return false; + } + return this._shouldCollectProperty; + } + + private set shouldCollectProperty(newValue: boolean) { + if (this._disableCollectProperty) { + return; + } + this._shouldCollectProperty = newValue; + } + + private canCollectMethodFromInfo(info: StructMethodInfo): boolean { + if (!!info.structInfo && checkIsCustomComponentFromInfo(info.structInfo) && info.isCtor) { + return true; + } + if (info.isDecl && info.name === BuilderLambdaNames.ORIGIN_METHOD_NAME) { + return true; + } + if (info.name === CustomComponentNames.COMPONENT_BUILD_ORI) { + return true; + } + if (!!info.annotationInfo && Object.keys(info.annotationInfo).length > 0) { + return true; + } + return false; + } + + private collectProperty(node: arkts.ClassProperty): void { + const propertyRecord = new StructPropertyRecord({ + structRecord: this._structRecord, + shouldIgnoreDecl: this.shouldIgnoreDecl, + }); + propertyRecord.collect(node); + + const propertyInfo = propertyRecord.toRecord(); + if (!propertyInfo) { + return; + } + // console.log("[collectProperty] node: ", node.dumpSrc()); + // console.log("[collectProperty] propertyInfo: ", propertyInfo); + // TODO: call ui-checker + // TODO: collect property info to cache + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).collect(node, propertyRecord.toJSON()); + // this._properties[node.peer] = propertyInfo; + + // console.log('[STRUCT PROPERTY] node: ', node.dumpSrc()); + // console.log('[STRUCT PROPERTY] propertyInfo: ', propertyInfo); + ValidatorBuilder.build(StructPropertyValidator).checkIsViolated(node, propertyInfo); + } + + private collectMethod(node: arkts.MethodDefinition): void { + const methodRecord = new StructMethodRecord({ + structRecord: this._structRecord, + shouldIgnoreDecl: this.shouldIgnoreDecl, + }); + methodRecord.collect(node); + + const methodInfo = methodRecord.toRecord(); + if (!methodInfo) { + return; + } + // TODO: call ui-checker + if (this.canCollectMethodFromInfo(methodInfo)) { + // TODO: collect method info to cache + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).collect(node, methodRecord.toJSON()); + // this._methods[node.peer] = methodInfo; + } + // console.log('[STRUCT METHOD] node: ', node.dumpSrc()); + // console.log('[STRUCT METHOD] methodInfo: ', methodInfo); + ValidatorBuilder.build(StructMethodValidator).checkIsViolated(node, methodInfo); + } + + disableCollectProperty(): this { + this._disableCollectProperty = true; + return this; + } + + enableCollectProperty(): this { + this._disableCollectProperty = false; + return this; + } + + reset(): void { + this._shouldCollectProperty = true; + this._disableCollectProperty = false; + // this._properties = {}; + // this._methods = {}; + } + + visitor(node: arkts.ClassDeclaration): arkts.ClassDeclaration { + node.definition?.body.forEach((st) => { + if (arkts.isClassProperty(st) && this.shouldCollectProperty) { + this.collectProperty(st); + } else if (arkts.isMethodDefinition(st)) { + this.collectMethod(st); + } + }); + return node; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/struct-interface-collector.ts b/arkui-plugins/collectors/ui-collectors/struct-interface-collector.ts new file mode 100644 index 0000000000000000000000000000000000000000..f62b214d3f6b3a5e2d82b3f223131fa83e8a7391 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/struct-interface-collector.ts @@ -0,0 +1,73 @@ +/* + * 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 { AbstractVisitor, VisitorOptions } from '../../common/abstract-visitor'; +import { + CustomComponentInterfacePropertyInfo, + CustomComponentInterfacePropertyRecord, + CustomComponentInterfaceRecord, +} from './records'; +import { NodeCacheNames } from '../../common/predefines'; + +export interface StructInterfaceCollectorOptions extends VisitorOptions { + interfaceRecord: CustomComponentInterfaceRecord; + shouldIgnoreDecl?: boolean; +} + +export class StructInterfaceCollector extends AbstractVisitor { + private _interfaceRecord: CustomComponentInterfaceRecord; + public shouldIgnoreDecl: boolean; + + constructor(options: StructInterfaceCollectorOptions) { + super(options); + this._interfaceRecord = options.interfaceRecord; + this.shouldIgnoreDecl = options.shouldIgnoreDecl ?? false; + } + + private canCollectMethodFromInfo(info: CustomComponentInterfacePropertyInfo): boolean { + if (!!info.annotationInfo && Object.keys(info.annotationInfo).length > 0) { + return true; + } + return false; + } + + private collectMethod(node: arkts.MethodDefinition): void { + const methodRecord = new CustomComponentInterfacePropertyRecord({ + interfaceRecord: this._interfaceRecord, + shouldIgnoreDecl: this.shouldIgnoreDecl, + }); + methodRecord.collect(node); + + const methodInfo = methodRecord.toRecord(); + if (!methodInfo) { + return; + } + if (this.canCollectMethodFromInfo(methodInfo)) { + // TODO: collect method info to cache + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).collect(node, methodRecord.toJSON()); + // console.log("[STRUCT INTERFACE METHOD] node: ", node.dumpSrc()); + } + } + + visitor(node: arkts.TSInterfaceDeclaration): arkts.TSInterfaceDeclaration { + node.body?.body.forEach((st) => { + if (arkts.isMethodDefinition(st)) { + this.collectMethod(st); + } + }); + return node; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/ui-visitor.ts b/arkui-plugins/collectors/ui-collectors/ui-visitor.ts new file mode 100644 index 0000000000000000000000000000000000000000..21773cd2acde37b3ef703e8ee97920c3b97e39cc --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/ui-visitor.ts @@ -0,0 +1,66 @@ +/* + * 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 { findAndCollectUINodeInPostOrder, findAndCollectUINodeInPreOrder } from './factory'; +import { UICollectMetadata } from './shared-types'; +import { CallRecordCollector } from './call-record-collector'; +import { ValidatorBuilder } from './validators'; +import { AbstractVisitor, VisitorOptions } from '../../common/abstract-visitor'; +import { LogCollector } from '../../common/log-collector'; +import { matchPrefix } from '../../common/arkts-utils'; +import { LINTER_EXCLUDE_EXTERNAL_SOURCE_PREFIXES } from '../../common/predefines'; + +export interface UIVisitorOptions extends VisitorOptions { + shouldIgnoreDecl?: boolean; +} + +export class UIVisitor extends AbstractVisitor { + private shouldIgnoreDecl?: boolean; + + constructor(options?: UIVisitorOptions) { + super(options); + this.shouldIgnoreDecl = false; // options?.shouldIgnoreDecl; + } + + init(): void { + if (!!this.externalSourceName) { + ValidatorBuilder.shouldSkip = matchPrefix(LINTER_EXCLUDE_EXTERNAL_SOURCE_PREFIXES, this.externalSourceName); + } + } + + reset(): void { + LogCollector.getInstance().emitLogInfo(); + LogCollector.getInstance().reset(); + CallRecordCollector.getInstance(this.getMetadata()).reset(); + ValidatorBuilder.reset(); + } + + getMetadata(): UICollectMetadata { + return { + isExternal: this.isExternal, + externalSourceName: this.externalSourceName, + program: this.program, + shouldIgnoreDecl: this.shouldIgnoreDecl ?? false, + } + } + + visitor(node: arkts.AstNode): arkts.AstNode { + findAndCollectUINodeInPreOrder(node, this.getMetadata()); + const newNode = this.visitEachChild(node); + findAndCollectUINodeInPostOrder(newNode, this.getMetadata()); + return newNode; + } +} diff --git a/arkui-plugins/collectors/ui-collectors/utils.ts b/arkui-plugins/collectors/ui-collectors/utils.ts new file mode 100644 index 0000000000000000000000000000000000000000..a74133ab5bf8208c0121c587aa4c142a1f72dd3a --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/utils.ts @@ -0,0 +1,186 @@ +/* + * 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 { matchPrefix } from '../../common/arkts-utils'; +import { DeclarationCollector } from '../../common/declaration-collector'; +import { + CustomComponentNames, + ARKUI_IMPORT_PREFIX_NAMES, + ArkUIDeclInterfaceNames, + BuiltInNames, + BuilderLambdaNames, + Dollars, + StateManagementTypes, + ARKUI_BUILDER_SOURCE_NAME, +} from '../../common/predefines'; +import { CustomComponentInfo, CustomComponentInterfaceInfo, NormalClassInfo, NormalInterfaceInfo } from './records'; + +export function checkCanCollectNormalClassFromInfo(info: NormalClassInfo, externalSourceName?: string): boolean { + if (checkIsObservedClassFromInfo(info)) { + // TODO: Non-observed class can have @Track + // TODO: collect @Observed Normal Class + return true; + } + if (externalSourceName === ARKUI_BUILDER_SOURCE_NAME && checkIsETSGlobalClassFromInfo(info)) { + return true; + } + return false; +} + +export function findRootCallee(callee: arkts.AstNode | undefined): arkts.Identifier | undefined { + if (!callee) { + return undefined; + } + if (arkts.isIdentifier(callee)) { + return callee; + } + if (arkts.isMemberExpression(callee)) { + return findRootCallee(callee.property); + } + if (arkts.isTSAsExpression(callee)) { + return findRootCallee(callee.expr); + } + if (arkts.isTSNonNullExpression(callee)) { + return findRootCallee(callee.expr); + } + return undefined; +} + +export function findRootCallObject(callee: arkts.AstNode | undefined): arkts.Identifier | undefined { + if (!callee) { + return undefined; + } + if (arkts.isIdentifier(callee)) { + return callee; + } + if (arkts.isMemberExpression(callee)) { + return findRootCallee(callee.object); + } + if (arkts.isTSAsExpression(callee)) { + return findRootCallee(callee.expr); + } + if (arkts.isTSNonNullExpression(callee)) { + return findRootCallee(callee.expr); + } + return undefined; +} + +export function getAnnotationName(anno: arkts.AnnotationUsage, ignoreDecl?: boolean): string | undefined { + if (!anno.expr || !arkts.isIdentifier(anno.expr)) { + return undefined; + } + if (!ignoreDecl && !getDeclFromArkUI(anno.expr)) { + return undefined; + } + return anno.expr.name; +} + +export function getDeclFromArkUI( + node: arkts.AstNode, + matchSourcePrefix: (string | RegExp)[] = ARKUI_IMPORT_PREFIX_NAMES +): arkts.AstNode | undefined { + const decl = arkts.getPeerIdentifierDecl(node.peer); + if (!decl) { + return undefined; + } + const moduleName: string | undefined = arkts.getProgramFromAstNode(decl)?.moduleName; + if (!moduleName || !matchPrefix(matchSourcePrefix, moduleName)) { + return undefined; + } + DeclarationCollector.getInstance().collect(decl); + return decl; +} + +export function formatBuiltInImplementedPropertyName(name: string): string { + return name.slice(BuiltInNames.IMPLEMENT_PROPETY_PREFIX.length); +} + +export function getStructFromCall( + callObject: arkts.Identifier | undefined, + callee: arkts.Identifier | undefined +): arkts.ClassDefinition | undefined { + if (!callObject || !callee) { + return undefined; + } + if (callee.name !== BuilderLambdaNames.ORIGIN_METHOD_NAME) { + return undefined; + } + const decl = arkts.getPeerIdentifierDecl(callObject.peer); + if (!decl || !arkts.isClassDefinition(decl) || !arkts.classDefinitionIsFromStructConst(decl) || !decl.ident) { + return undefined; + } + return decl; +} + +export function checkIsCallNameFromResource(name: string): name is Dollars.DOLLAR_RESOURCE | Dollars.DOLLAR_RAWFILE { + return name === Dollars.DOLLAR_RESOURCE || name === Dollars.DOLLAR_RAWFILE; +} + +export function checkIsCallNameFromBindable(name: string): name is Dollars.DOLLAR_DOLLAR { + return name === Dollars.DOLLAR_DOLLAR; +} + +export function checkIsNameStartWithBackingField(node: arkts.AstNode | undefined): boolean { + if (!node || !arkts.isIdentifier(node)) { + return false; + } + return node.name.startsWith(StateManagementTypes.BACKING); +} + +export function checkIsStructFromNode(node: arkts.AstNode): boolean { + if (arkts.isStructDeclaration(node)) { + return true; + } + if ( + arkts.isClassDeclaration(node) && + !!node.definition && + arkts.classDefinitionIsFromStructConst(node.definition) + ) { + return true; + } + return false; +} + +export function checkIsCustomComponentFromInfo( + info: CustomComponentInfo | CustomComponentInterfaceInfo | undefined +): boolean { + const annotationInfo = info?.annotationInfo ?? {}; + return !!annotationInfo.hasComponent || !!annotationInfo.hasComponentV2 || !!annotationInfo.hasCustomDialog; +} + +export function checkIsCustomComponentDeclaredClassFromInfo(info: CustomComponentInfo | undefined): boolean { + if (!info || !info.name || !info.isDecl || !info.isFromArkUI) { + return false; + } + return ( + info.name === CustomComponentNames.COMPONENT_CLASS_NAME || + info.name === CustomComponentNames.COMPONENT_V2_CLASS_NAME || + info.name === CustomComponentNames.BASE_CUSTOM_DIALOG_NAME + ); +} + +export function checkIsObservedClassFromInfo(info: NormalClassInfo | undefined): boolean { + const annotationInfo = info?.annotationInfo ?? {}; + return !!annotationInfo.hasObserved || !!annotationInfo.hasObservedV2; +} + +export function checkIsETSGlobalClassFromInfo(info: NormalClassInfo | undefined): boolean { + return !!info?.isETSGlobal; +} + +export function checkIsCommonMethodInterfaceFromInfo(info: NormalInterfaceInfo | undefined): boolean { + return info?.name === ArkUIDeclInterfaceNames.COMMON_METHOD; +} diff --git a/arkui-plugins/collectors/ui-collectors/validators/base.ts b/arkui-plugins/collectors/ui-collectors/validators/base.ts new file mode 100644 index 0000000000000000000000000000000000000000..c4eb4393c201912b54bf990e8db5db3d7f06d469 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/base.ts @@ -0,0 +1,90 @@ +/* + * 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 { LogCollector, LogInfo, SuggestionOptions } from '../../../common/log-collector'; + +export interface Validator { + checkIsViolated(node: TargetNode, metadata?: ContextMetadata): void; + collectContext(context: ContextMetadata): this; + reset(): void; +} + +export interface ValidatorOptions { + shouldSkip?: boolean; +} + +export abstract class BaseValidator implements Validator { + protected context?: R; + protected shouldSkip: boolean; + + constructor(options: ValidatorOptions) { + this.shouldSkip = options.shouldSkip ?? false; + } + + reset(): void { + this.context = undefined; + } + + checkIsViolated(node: T, metadata?: R | undefined): void { + if (this.shouldSkip) { + return; + } + if (!!metadata) { + this.collectContext(metadata); + } + this.reportIfViolated(node); + } + + collectContext(context: R): this { + this.context = context; + return this; + } + + protected report(logInfo: LogInfo): void { + // console.log('[VALIDATOR] report: ', formatReport(logInfo)); + LogCollector.getInstance().collectLogInfo(logInfo); + } + + abstract reportIfViolated(node: T): void; +} + +// TODO: remove this +function formatReport(logInfo: LogInfo): string { + const node = logInfo.node.dumpSrc(); + return JSON.stringify( + { + node, + level: logInfo.level, + message: logInfo.message, + args: logInfo.args, + suggestion: formatSuggestion(logInfo.suggestion), + code: logInfo.code, + }, + null, + 2 + ); +} + +// TODO: remove this +function formatSuggestion(suggestion: SuggestionOptions | undefined): Object | undefined { + if (!suggestion) { + return undefined; + } + const startRange = `(${suggestion.range[0].index()}, ${suggestion.range[0].line()})`; + const endRange = `(${suggestion.range[1].index()}, ${suggestion.range[1].line()})`; + const range = `${startRange} - ${endRange}`; + return { code: suggestion.code, range, args: suggestion.args }; +} diff --git a/arkui-plugins/collectors/ui-collectors/validators/cache.ts b/arkui-plugins/collectors/ui-collectors/validators/cache.ts new file mode 100644 index 0000000000000000000000000000000000000000..c66b85a8444b9a35c5f523a95ffed73f28ab63bd --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/cache.ts @@ -0,0 +1,33 @@ +/* + * 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 { Validator } from "./base"; + +const cache = new Map(); + +export function getOrPut(key: string, create: () => Validator): Validator { + if (cache.has(key)) { + return cache.get(key)!; + } + + const newValidator = create(); + cache.set(key, newValidator); + return newValidator; +} + +export function clearValidatorCache(): void { + Array.from(cache.values()).forEach((validator) => validator.reset()); + cache.clear(); +} \ No newline at end of file diff --git a/arkui-plugins/collectors/ui-collectors/validators/index.ts b/arkui-plugins/collectors/ui-collectors/validators/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..56c26b9d12a6a560b0246f38702189cc0973e09f --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/index.ts @@ -0,0 +1,21 @@ +/* + * 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. + */ + +export * from './struct-call-validator'; +export * from './struct-property-validator'; +export * from './struct-method-validator'; +export * from './normal-class-method-validator'; +export * from './normal-class-property-validator'; +export * from './validator-builder'; \ No newline at end of file diff --git a/arkui-plugins/collectors/ui-collectors/validators/normal-class-method-validator.ts b/arkui-plugins/collectors/ui-collectors/validators/normal-class-method-validator.ts new file mode 100644 index 0000000000000000000000000000000000000000..a104fa0ff3fd1898ed5e813c5b1ef59e8ee37508 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/normal-class-method-validator.ts @@ -0,0 +1,33 @@ +/* + * 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 { BaseValidator } from './base'; +import { NormalClassMethodInfo } from '../records'; +import { checkComputedDecorator, checkConsumerProviderDecorator } from './rules'; + +export class NormalClassMethodValidator extends BaseValidator { + reportIfViolated(node: arkts.MethodDefinition): void { + const metadata = this.context ?? {}; + if (!metadata.classInfo?.definitionPtr) { + return; + } + + checkConsumerProviderDecorator.bind(this)(node); + + const classNode = arkts.classByPeer(metadata.classInfo.definitionPtr); + checkComputedDecorator.bind(this)(node, classNode); + } +} diff --git a/arkui-plugins/collectors/ui-collectors/validators/normal-class-property-validator.ts b/arkui-plugins/collectors/ui-collectors/validators/normal-class-property-validator.ts new file mode 100644 index 0000000000000000000000000000000000000000..87471506c8f419c76865f33a3a1bbd2be30a12e3 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/normal-class-property-validator.ts @@ -0,0 +1,33 @@ +/* + * 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 { BaseValidator } from './base'; +import { NormalClassPropertyInfo } from '../records'; +import { checkComputedDecorator, checkConsumerProviderDecorator } from './rules'; + +export class NormalClassPropertyValidator extends BaseValidator { + reportIfViolated(node: arkts.ClassProperty): void { + const metadata = this.context ?? {}; + if (!metadata.classInfo?.definitionPtr) { + return; + } + + checkConsumerProviderDecorator.bind(this)(node); + + const classNode = arkts.classByPeer(metadata.classInfo.definitionPtr); + checkComputedDecorator.bind(this)(node, classNode); + } +} diff --git a/arkui-plugins/collectors/ui-collectors/validators/rules/check-builder-param.ts b/arkui-plugins/collectors/ui-collectors/validators/rules/check-builder-param.ts new file mode 100644 index 0000000000000000000000000000000000000000..71d8a20a366b666dcdd98999a5ceb93cff2427e9 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/rules/check-builder-param.ts @@ -0,0 +1,63 @@ +/* + * 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 { BaseValidator } from '../base'; +import { isAnnotatedProperty } from '../utils'; +import { CallInfo } from '../../records'; +import { DecoratorNames, LogType } from '../../../../common/predefines'; + +/** + * 校验规则:自定义组件尾随闭包调用的场景,struct 声明中只能有1个BuilderParam + * + * 校验等级:error + */ +export function checkBuilderParam( + this: BaseValidator, + struct: arkts.ClassDefinition +): void { + const metadata = this.context ?? {}; + if (!metadata.isTrailingCall) { + return; + } + + // 从struct 中获取被@BuilderParam 修饰的属性个数 + const properties: Array<{ property: arkts.ClassProperty; argc: number }> = []; + for (const member of struct.body) { + if (isAnnotatedProperty(member, DecoratorNames.BUILDER_PARAM)) { + properties.push({ + property: member, + argc: getBuilderParamTypeArgc(member), + }); + } + } + + // 如果@BuilderParam个数超过1个或者@BuilderParam修饰的函数类型有参数,那么就报错 + if (properties.length > 1 || (properties.length === 1 && properties[0].argc > 0)) { + const structName = struct.ident!.name; + this.report({ + node: struct.parent!, // Class Declaration has correct position information + level: LogType.ERROR, + message: `In the trailing lambda case, '${structName}' must have one and only one property decorated with @BuilderParam, and its @BuilderParam expects no parameter.`, + }); + } +} + +function getBuilderParamTypeArgc(property: arkts.ClassProperty): number { + if (!property.typeAnnotation || !arkts.isETSFunctionType(property.typeAnnotation)) { + return -1; + } + return property.typeAnnotation.params.length; +} diff --git a/arkui-plugins/collectors/ui-collectors/validators/rules/check-component-link-init.ts b/arkui-plugins/collectors/ui-collectors/validators/rules/check-component-link-init.ts new file mode 100644 index 0000000000000000000000000000000000000000..b22387aa2765add0e93c4ccfecab327d8d3f3057 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/rules/check-component-link-init.ts @@ -0,0 +1,51 @@ +/* + * 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 { BaseValidator } from '../base'; +import { isAnnotatedProperty } from '../utils'; +import { CallInfo } from '../../records'; +import { DecoratorNames, LogType } from '../../../../common/predefines'; +import { createSuggestion, getPositionRangeFromNode } from '../../../../common/log-collector'; + +/** + * 校验规则:当V2组件使用V1组件时,V1组件中不允许存在被`@Link`装饰的属性 + * + * 校验等级:error + */ +export function checkComponentLinkInit( + this: BaseValidator, + struct: arkts.ClassDefinition +): void { + const metadata = this.context ?? {}; + const fromComponentV2: boolean = !!metadata.fromStructInfo?.annotationInfo?.hasComponentV2; + const isComponentCall: boolean = !!metadata.structDeclInfo?.annotationInfo?.hasComponent; + if (!(fromComponentV2 && isComponentCall)) { + return; + } + + // 只要当前struct 中有被"@Link" 修饰的属性就报错 + for (const member of struct.body) { + if (isAnnotatedProperty(member, DecoratorNames.LINK)) { + const declaration = struct.parent!; // Class Declaration has correct position information + this.report({ + node: declaration, + level: LogType.ERROR, + message: `A V2 component cannot be used with any member property annotated by '@Link' in a V1 component.`, + suggestion: createSuggestion('', ...getPositionRangeFromNode(declaration)), + }); + } + } +} diff --git a/arkui-plugins/collectors/ui-collectors/validators/rules/check-component-v2-mix-use.ts b/arkui-plugins/collectors/ui-collectors/validators/rules/check-component-v2-mix-use.ts new file mode 100644 index 0000000000000000000000000000000000000000..0f26984d8870f0b026ce4ce9f9ac4eead7666e98 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/rules/check-component-v2-mix-use.ts @@ -0,0 +1,135 @@ +/* + * 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 { BaseValidator } from '../base'; +import { NormalClassRecord, RecordBuilder, StructPropertyInfo } from '../../records'; +import { DecoratorNames, LogType } from '../../../../common/predefines'; + +/** + * 校验规则:禁止在`@Component`中使用`@ObservedV2`装饰的类 + * + * 校验等级:error + */ +export function checkComponentV2MixUse( + this: BaseValidator, + classProperty: arkts.ClassProperty +): void { + const metadata = this.context ?? {}; + if (!metadata.structInfo?.annotationInfo?.hasComponent) { + return; + } + + const v1Decorators = findStructPropertyV1DecoratorsFromInfo(metadata); + if (v1Decorators.length === 0) { + return; + } + let decl: arkts.AstNode | undefined; + let expr: arkts.Identifier | undefined; + expr = findTypeRefIdentFromType(classProperty.typeAnnotation); + if (!expr && checkIsNewClass(classProperty.value)) { + expr = findTypeRefIdentFromType(classProperty.value.getTypeRef); + } + if (!!expr) { + decl = arkts.getPeerIdentifierDecl(expr.peer); + } + if (!decl || !checkIsClassDef(decl) || !checkIsClassDecl(decl.parent)) { + return; + } + const classRecord = RecordBuilder.build(NormalClassRecord, decl.parent, { shouldIgnoreDecl: false }); // TODO: change back to false; + if (!classRecord.isCollected) { + classRecord.collect(decl.parent); + } + const classInfo = classRecord.toRecord(); + if (!classInfo?.annotationInfo?.hasObservedV2) { + return; + } + v1Decorators.forEach((info) => + this.report({ + node: info.annotation, + message: `The type of the ${info.name} property cannot be a class decorated with '@ObservedV2'.`, + level: LogType.ERROR, + }) + ); +} + +interface DecoratorInfo { + name: string; + annotation: arkts.AnnotationUsage; +} + +const v1ComponentDecorators: string[] = [ + DecoratorNames.STATE, + DecoratorNames.PROP_REF, + DecoratorNames.LINK, + DecoratorNames.PROVIDE, + DecoratorNames.CONSUME, + DecoratorNames.STORAGE_LINK, + DecoratorNames.STORAGE_PROP_REF, + DecoratorNames.LOCAL_STORAGE_LINK, +]; + +function findStructPropertyV1DecoratorsFromInfo(info: StructPropertyInfo): DecoratorInfo[] { + if (!info.annotationInfo || !info.annotations) { + return []; + } + return v1ComponentDecorators + .filter((name) => !!info.annotationInfo?.[`has${name}`]) + .map((name) => ({ + name, + annotation: info.annotations?.[name]!, + })); +} + +function checkIsClassDef(node: arkts.AstNode | undefined): node is arkts.ClassDefinition { + return !!node && arkts.isClassDefinition(node); +} + +function checkIsClassDecl(node: arkts.AstNode | undefined): node is arkts.ClassDeclaration { + return !!node && arkts.isClassDeclaration(node); +} + +function checkIsTypeRef(node: arkts.AstNode | undefined): node is arkts.ETSTypeReference { + return !!node && arkts.isETSTypeReference(node); +} + +function checkIsTypeRefPart(node: arkts.AstNode | undefined): node is arkts.ETSTypeReferencePart { + return !!node && arkts.isETSTypeReferencePart(node); +} + +function checkIsIdentifier(node: arkts.AstNode | undefined): node is arkts.Identifier { + return !!node && arkts.isIdentifier(node); +} + +function checkIsUnionType(node: arkts.AstNode | undefined): node is arkts.ETSUnionType { + return !!node && arkts.isETSUnionType(node); +} + +function checkIsNewClass(node: arkts.AstNode | undefined): node is arkts.ETSNewClassInstanceExpression { + return !!node && arkts.isETSNewClassInstanceExpression(node); +} + +function findTypeRefIdentFromType(node: arkts.AstNode | undefined): arkts.Identifier | undefined { + if (checkIsIdentifier(node)) { + return node; + } + if (checkIsTypeRef(node) && checkIsTypeRefPart(node.part) && checkIsIdentifier(node.part.name)) { + return node.part.name; + } + if (checkIsUnionType(node)) { + return node.types.map(findTypeRefIdentFromType).find((t) => !!t); + } + return undefined; +} diff --git a/arkui-plugins/collectors/ui-collectors/validators/rules/check-componentV2-state-usage.ts b/arkui-plugins/collectors/ui-collectors/validators/rules/check-componentV2-state-usage.ts new file mode 100644 index 0000000000000000000000000000000000000000..be3e301845df0edac056ed76b289bd50c861483c --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/rules/check-componentV2-state-usage.ts @@ -0,0 +1,223 @@ +/* + * 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 { BaseValidator } from '../base'; +import { coerceToAstNode } from '../utils'; +import type { IntrinsicValidatorFunction, ModifiedValidatorFunction } from '../safe-types'; +import { + CallInfo, + CustomComponentInterfacePropertyRecord, + RecordBuilder, + StructMethodInfo, + StructPropertyInfo, +} from '../../records'; +import { checkIsNameStartWithBackingField } from '../../utils'; +import { DecoratorNames, LogType } from '../../../../common/predefines'; +import { createSuggestion, getPositionRangeFromNode } from '../../../../common/log-collector'; + +/** + * 校验规则: + * 1. 确保成员属性或方法不能同时被多个内置装饰器(`@Local`, `@Param`, `@Event`)装饰; + * 2. 当用`@Param`装饰的变量没有被分配默认值时,它也必须用`@Require`装饰; + * 3. 在被`@ComponentV2`装饰的结构体中,`@Require`只能与`@Param`一起使用; + * 4. 检查自定义组件中的`@Local`属性和无装饰器属性是否尝试在外部初始化; + * 5. 确保`@Local`,`@Param`,`@Event`装饰器只能用于成员属性,而不能用于方法。 + * + * 校验等级:error + */ +export function checkComponentV2StateUsage(this: BaseValidator, node: arkts.AstNode): void { + const nodeType = arkts.nodeType(node); + if (checkByType.has(nodeType)) { + checkByType.get(nodeType)!.bind(this)(node); + } +} + +function checkComponentV2StateUsageInClassProperty( + this: BaseValidator, + node: T +): void { + const _node = coerceToAstNode(node); + const metadata = this.context ?? {}; + if (!metadata.structInfo?.annotationInfo?.hasComponentV2) { + return; + } + const decorators = findStructAttributeBuiltInDecoratorsFromInfo(metadata); + // 成员属性不能同时被多个内置装饰器(`@Local`, `@Param`, `@Event`)装饰 + if (decorators.length > 1) { + decorators.forEach((info) => + this.report({ + node: info.annotation, + message: `The member property or method cannot be decorated by multiple built-in annotations.`, + level: LogType.ERROR, + }) + ); + } + // 当用`@Param`装饰的变量没有被分配默认值时,它也必须用`@Require`装饰 + if (!_node.value && checkIsParamNotPairedWithRequireFromInfo(metadata)) { + const position = node.startPosition; + this.report({ + node, + message: `When a variable decorated with '@Param' is not assigned a default value, it must also be decorated with '@Require'.`, + level: LogType.ERROR, + suggestion: createSuggestion(`@${DecoratorNames.REQUIRE}`, position, position), + }); + } + // 在被`@ComponentV2`装饰的结构体中,`@Require`只能与`@Param`一起使用 + if (checkIsRequireNotPariedWithParamOrBuilderParam(metadata)) { + const requiredDecorator = metadata.annotations?.[DecoratorNames.REQUIRE]!; + this.report({ + node: requiredDecorator, + message: `In a struct decorated with '@ComponentV2', '@Require' can only be used with '@Param' or '@BuilderParam'.`, + level: LogType.ERROR, + suggestion: createSuggestion('', ...getPositionRangeFromNode(requiredDecorator)), + }); + } +} + +function checkComponentV2StateUsageInStructCall( + this: BaseValidator, + node: T +): void { + const metadata = this.context ?? {}; + if (!metadata.structDeclInfo?.name) { + return; + } + const structName = metadata.structDeclInfo.name; + ////////////////////////////////////////////////////// + const propertyInfos = metadata.structPropertyInfos ?? []; + // 检查自定义组件中的`@Local`属性和无装饰器属性是否尝试在外部初始化 + for (const propInfo of propertyInfos) { + const propPtr = propInfo[0]; + const propertyInfo = propInfo[1]; + let reportDecoratorName: string | undefined; + if (propertyInfo?.annotationInfo?.hasLocal) { + reportDecoratorName = `@${DecoratorNames.LOCAL}`; + } else if (!propertyInfo?.annotationInfo || Object.keys(propertyInfo.annotationInfo).length === 0) { + reportDecoratorName = 'regular'; + } + if (!!reportDecoratorName && !!propertyInfo?.name) { + const prop = arkts.classByPeer(propPtr); + this.report({ + node: prop, + message: getLocalNeedNoInitReportMessage(reportDecoratorName, propertyInfo?.name, structName), + level: LogType.ERROR, + suggestion: createSuggestion('', ...getPositionRangeFromNode(prop)), + }); + } + } + ////////////////////////////////////////////////////// + // const call = coerceToAstNode(node); + // const optionsArg = call.arguments.at(1); // Options is the second argument of a custom component call. + // if (!optionsArg || !arkts.isObjectExpression(optionsArg)) { + // return; + // } + // // 检查自定义组件中的`@Local`属性和无装饰器属性是否尝试在外部初始化 + // (optionsArg.properties as arkts.Property[]).forEach((prop) => { + // let decl: arkts.AstNode | undefined; + // if (!prop.key || !prop.value || !(decl = arkts.getPeerPropertyDecl(prop.peer)) || !arkts.isMethodDefinition(decl)) { + // return; + // } + // if (checkIsNameStartWithBackingField(decl.name)) { + // return; + // } + // const structInterfacePropRecord = RecordBuilder.build(CustomComponentInterfacePropertyRecord, decl, { + // shouldIgnoreDecl: false, + // }); // TODO: change back to false; + // if (!structInterfacePropRecord.isCollected) { + // structInterfacePropRecord.collect(decl); + // } + // const propertyInfo = structInterfacePropRecord.toRecord(); + // let reportDecoratorName: string | undefined; + // if (propertyInfo?.annotationInfo?.hasLocal) { + // reportDecoratorName = `@${DecoratorNames.LOCAL}`; + // } else if (!propertyInfo?.annotationInfo || Object.keys(propertyInfo.annotationInfo).length === 0) { + // reportDecoratorName = 'regular'; + // } + // if (!!reportDecoratorName) { + // this.report({ + // node: prop, + // message: getLocalNeedNoInitReportMessage(reportDecoratorName, decl.name.name, structName), + // level: LogType.ERROR, + // suggestion: createSuggestion('', ...getPositionRangeFromNode(prop)), + // }); + // } + // }); +} + +function checkComponentV2StateUsageInStructMethod( + this: BaseValidator, + node: T +): void { + const metadata = this.context ?? {}; + if (!metadata.structInfo?.annotationInfo?.hasComponentV2) { + return; + } + const decorators = findStructAttributeBuiltInDecoratorsFromInfo(metadata); + // 确保`@Local`,`@Param`,`@Event`装饰器只能用于成员属性,而不能用于方法 + if (decorators.length > 0) { + decorators.forEach((info) => + this.report({ + node: info.annotation, + message: `'@${info.name}' can only decorate member property.`, + level: LogType.ERROR, + suggestion: createSuggestion('', ...getPositionRangeFromNode(info.annotation)), + }) + ); + } +} + +const checkByType = new Map([ + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CLASS_PROPERTY, checkComponentV2StateUsageInClassProperty], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CALL_EXPRESSION, checkComponentV2StateUsageInStructCall], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_METHOD_DEFINITION, checkComponentV2StateUsageInStructMethod], +]); + +interface DecoratorInfo { + name: string; + annotation: arkts.AnnotationUsage; +} + +const builtInDecorators: string[] = [DecoratorNames.LOCAL, DecoratorNames.PARAM, DecoratorNames.EVENT]; + +function getLocalNeedNoInitReportMessage(decorator: string, key: string, component: string): string { + return `The '${decorator}' property '${key}' in the custom component '${component}' cannot be initialized here (forbidden to specify).`; +} + +function findStructAttributeBuiltInDecoratorsFromInfo(info: StructPropertyInfo | StructMethodInfo): DecoratorInfo[] { + if (!info.annotationInfo || !info.annotations) { + return []; + } + return builtInDecorators + .filter((name) => !!info.annotationInfo?.[`has${name}`]) + .map((name) => ({ + name, + annotation: info.annotations?.[name]!, + })); +} + +function checkIsParamNotPairedWithRequireFromInfo(info: StructPropertyInfo): boolean { + if (!info.annotationInfo) { + return false; + } + return !!info.annotationInfo.hasParam && !info.annotationInfo.hasRequire; +} + +function checkIsRequireNotPariedWithParamOrBuilderParam(info: StructPropertyInfo): boolean { + if (!info.annotationInfo || !info.annotationInfo.hasRequire) { + return false; + } + return !info.annotationInfo.hasParam && !info.annotationInfo.hasBuilderParam; +} diff --git a/arkui-plugins/collectors/ui-collectors/validators/rules/check-computed-decorator.ts b/arkui-plugins/collectors/ui-collectors/validators/rules/check-computed-decorator.ts new file mode 100644 index 0000000000000000000000000000000000000000..725041b004d41aeb70b979354a6d672f00425bbb --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/rules/check-computed-decorator.ts @@ -0,0 +1,246 @@ +/* + * 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 { BaseValidator } from '../base'; +import { coerceToAstNode } from '../utils'; +import type { ExtendedValidatorFunction, IntrinsicValidatorFunction } from '../safe-types'; +import { + CallInfo, + NormalClassMethodAnnotationRecord, + NormalClassMethodInfo, + NormalClassPropertyInfo, + RecordBuilder, + StructMethodInfo, + StructMethodRecord, + StructPropertyInfo, +} from '../../records'; +import { DecoratorNames, LogType, StructDecoratorNames } from '../../../../common/predefines'; +import { createSuggestion, getPositionRangeFromNode } from '../../../../common/log-collector'; + +/** + * 校验规则: + * 1. `@Computed`装饰器只能用来装饰获取器(即`getter`方法); + * 2. `@Computed`装饰器在已经被`@ObservedV2`装饰器装饰的类`class`中的成员方法上使用; + * 3. `@Computed`装饰器在已经被`@ComponentV2`装饰器修饰的结构体`struct`中使用 + * 4. `@Computed`装饰器修饰的属性不能与双向绑定语法一起使用; + * 5. `@Computed`装饰器修饰的属性不能定义一个设置器(即`setter`方法)。 + * + * 校验等级:error + */ +export function checkComputedDecorator( + this: BaseValidator, + node: arkts.AstNode, + other?: arkts.AstNode +): void { + const nodeType = arkts.nodeType(node); + if (checkByType.has(nodeType)) { + checkByType.get(nodeType)!.bind(this)(node, other); + } +} + +function checkComputedDecoratorInMethod< + T extends arkts.AstNode = arkts.MethodDefinition, + U extends arkts.AstNode = arkts.ClassDefinition +>(this: BaseValidator, node: T, classDecl?: U): void { + const metadata = this.context ?? {}; + const method = coerceToAstNode(node); + const classDef = classDecl ? coerceToAstNode(classDecl) : undefined; + const setter = findSetterMethod(method, metadata); + const getter = findGetterFromSetterMethod(setter, classDef); + if (!!setter && !!getter && checkIsMethodHasComputed(getter)) { + // `@Computed`装饰器修饰的属性不能定义一个设置器(即`setter`方法) + this.report({ + node: setter, + message: `A property decorated by '@Computed' cannot define a set method.`, + level: LogType.ERROR, + suggestion: createSuggestion('', ...getPositionRangeFromNode(setter)), + }); + } + if (!metadata.annotationInfo?.hasComputed) { + return; + } + const computedAnnotation = metadata.annotations?.[DecoratorNames.COMPUTED]!; + if (!checkIsGetterMethod(method, metadata)) { + // `@Computed`装饰器只能用来装饰获取器(即`getter`方法) + this.report({ + node: computedAnnotation, + message: `@${DecoratorNames.COMPUTED} can only decorate 'GetAccessor'.`, + level: LogType.ERROR, + suggestion: createSuggestion('', ...getPositionRangeFromNode(computedAnnotation)), + }); + } else if (!checkIsFromObervedV2InNormalClass(metadata) && !!classDef?.parent) { + // `@Computed`装饰器在已经被`@ObservedV2`装饰器装饰的类`class`中的成员方法上使用 + this.report({ + node: computedAnnotation, + message: `The '@Computed' can decorate only member method within a 'class' decorated with ObservedV2.`, + level: LogType.ERROR, + suggestion: createSuggestion( + `@${DecoratorNames.OBSERVED_V2}`, + ...getPositionRangeFromNode(classDef.parent) + ), + }); + } else if (!checkIsFromComponentV2InStruct(metadata) && !!classDef?.parent) { + // `@Computed`装饰器在已经被`@ComponentV2`装饰器修饰的结构体`struct`中使用 + this.report({ + node: computedAnnotation, + message: `The '@Computed' annotation can only be used in a 'struct' decorated with ComponentV2.`, + level: LogType.ERROR, + suggestion: createSuggestion( + `@${StructDecoratorNames.COMPONENT_V2}`, + ...getPositionRangeFromNode(classDef.parent) + ), + }); + } +} + +function checkComputedDecoratorInProperty( + this: BaseValidator, + node: T +): void { + const metadata = this.context ?? {}; + // Since property cannot have `@Computed`, it is an ignored annotation. + if (!metadata.ignoredAnnotationInfo?.hasComputed) { + return; + } + const computedAnnotation = metadata.ignoredAnnotations?.[DecoratorNames.COMPUTED]!; + // `@Computed`装饰器只能用来装饰获取器(即`getter`方法) + this.report({ + node: computedAnnotation, + message: `@${DecoratorNames.COMPUTED} can only decorate 'GetAccessor'.`, + level: LogType.ERROR, + suggestion: createSuggestion('', ...getPositionRangeFromNode(computedAnnotation)), + }); +} + +function checkComputedDecoratorInStructCall( + this: BaseValidator, + node: T +): void { + const metadata = this.context ?? {}; + if (!metadata.structDeclInfo?.name) { + return; + } + const call = coerceToAstNode(node); + const optionsArg = call.arguments.at(1); // Options is the second argument of a custom component call. + if (!optionsArg || !arkts.isObjectExpression(optionsArg)) { + return; + } + // `@Computed`装饰器修饰的属性不能与双向绑定语法一起使用 + (optionsArg.properties as arkts.Property[]).forEach((prop) => { + if (!prop.key || !prop.value || !arkts.isCallExpression(prop.value)) { + return; + } + const computedArgs = findComputedArgInBindablePropertyValue(prop.value.arguments); + computedArgs.forEach((node) => { + this.report({ + node, + message: `A property decorated by '@Computed' cannot be used with two-way bind syntax.`, + level: LogType.ERROR, + suggestion: createSuggestion('', ...getPositionRangeFromNode(node)), + }); + }); + }); +} + +const checkByType = new Map([ + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_METHOD_DEFINITION, checkComputedDecoratorInMethod], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CLASS_PROPERTY, checkComputedDecoratorInProperty], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CALL_EXPRESSION, checkComputedDecoratorInStructCall], +]); + +type MethodInfo = StructMethodInfo & NormalClassMethodInfo; + +type PropertyInfo = StructPropertyInfo & NormalClassPropertyInfo; + +function findComputedArgInBindablePropertyValue(args: readonly arkts.Expression[]): readonly arkts.Expression[] { + return args.filter((arg) => { + if (!arkts.isMemberExpression(arg) || !arkts.isThisExpression(arg.object)) { + return false; + } + const decl = arkts.getPeerIdentifierDecl(arg.property.peer); + if (!decl || !arkts.isMethodDefinition(decl)) { + return false; + } + const structMethodRecord = RecordBuilder.build(StructMethodRecord, decl, { shouldIgnoreDecl: false }); // TODO: change back to false; + if (!structMethodRecord.isCollected) { + structMethodRecord.collect(decl); + } + const methodInfo = structMethodRecord.toRecord(); + return !!methodInfo?.annotationInfo?.hasComputed; + }); +} + +function checkIsFromComponentV2InStruct(info: MethodInfo | PropertyInfo): boolean { + if (!info.structInfo && !!info.classInfo) { + return true; // Skip checking. This implies from normal class rather than from struct. + } + return !!info.structInfo?.annotationInfo?.hasComponentV2; +} + +function checkIsFromObervedV2InNormalClass(info: MethodInfo | PropertyInfo): boolean { + if (!info.classInfo && !!info.structInfo) { + return true; // Skip checking. This implies from struct rather than from normal class. + } + return !!info.classInfo?.annotationInfo?.hasObservedV2; +} + +function checkIsGetterMethod(node: arkts.MethodDefinition, info?: MethodInfo): boolean { + if (info?.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_GET) { + return true; + } + let isGetter: boolean = node.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_GET; + if (!isGetter) { + isGetter = node.overloads.some((method) => checkIsGetterMethod(method)); + } + return isGetter; +} + +function findSetterMethod(node: arkts.MethodDefinition, info?: MethodInfo): arkts.MethodDefinition | undefined { + if (info?.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_SET) { + return node; + } + let isSetter: boolean = node.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_SET; + if (isSetter) { + return node; + } + return node.overloads.find((method) => findSetterMethod(method)); +} + +function findGetterFromSetterMethod( + setter: arkts.MethodDefinition | undefined, + classDecl: arkts.ClassDefinition | undefined +): arkts.MethodDefinition | undefined { + if (!setter || !classDecl) { + return undefined; + } + const getterInOverload = setter.overloads.find((method) => checkIsGetterMethod(method)); + if (!!getterInOverload) { + return getterInOverload; + } + const name = setter.name.name; + return classDecl.body.find( + (st) => arkts.isMethodDefinition(st) && checkIsGetterMethod(st) && st.name.name === name + ) as arkts.MethodDefinition | undefined; +} + +function checkIsMethodHasComputed(node: arkts.MethodDefinition): boolean { + const annotationRecord = new NormalClassMethodAnnotationRecord({ shouldIgnoreDecl: false }); // TODO: change back to false; + for (const annotation of node.scriptFunction.annotations) { + annotationRecord.collect(annotation); + } + const annotationInfo = annotationRecord.toRecord(); + return !!annotationInfo?.annotationInfo?.hasComputed; +} diff --git a/arkui-plugins/collectors/ui-collectors/validators/rules/check-consumer-provider-decorator.ts b/arkui-plugins/collectors/ui-collectors/validators/rules/check-consumer-provider-decorator.ts new file mode 100644 index 0000000000000000000000000000000000000000..5ce398b9b65d75ae02360efff9d1d8e78e7aa006 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/rules/check-consumer-provider-decorator.ts @@ -0,0 +1,250 @@ +/* + * 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 { BaseValidator } from '../base'; +import { coerceToAstNode } from '../utils'; +import type { ExtendedValidatorFunction, IntrinsicValidatorFunction } from '../safe-types'; +import { + CallInfo, + CustomComponentInterfacePropertyInfo, + CustomComponentInterfacePropertyRecord, + NormalClassPropertyInfo, + RecordBuilder, + StructMethodInfo, + StructPropertyInfo, +} from '../../records'; +import { checkIsNameStartWithBackingField } from '../../utils'; +import { DecoratorNames, LogType, StateManagementTypes } from '../../../../common/predefines'; +import { createSuggestion, getPositionRangeFromNode } from '../../../../common/log-collector'; + +/** + * 校验规则: + * 1. `@Provider`/`@Consumer`只能用来修饰类成员属性(不能修饰方法、参数等); + * 2. 结构体成员变量不能被多个内置装饰器修饰; + * 3. `@Provider`/`@Consumer`装饰器只能用于`struct`类型,而不能用于类(`class`)或其他类型; + * 4. 自定义组件中的`@Provider`/`@Consumer`装饰的属性不能在父组件初始化(禁止指定初始值)。 + * + * 校验等级:error + */ +export function checkConsumerProviderDecorator( + this: BaseValidator, + node: arkts.AstNode, + other?: arkts.AstNode +): void { + const nodeType = arkts.nodeType(node); + if (checkByType.has(nodeType)) { + checkByType.get(nodeType)!.bind(this)(node, other); + } +} + +function checkConsumerProviderDecoratorInStructMethod( + this: BaseValidator, + node: T +): void { + const metadata = this.context ?? {}; + // `@Provider`/`@Consumer`只能用来修饰类成员属性(不能修饰方法、参数等); + if (metadata.ignoredAnnotationInfo?.hasConsumer) { + const annotation = metadata.ignoredAnnotations?.[DecoratorNames.CONSUMER]!; + this.report({ + node: annotation, + message: `'@${DecoratorNames.CONSUMER}' can only decorate member property.`, + level: LogType.ERROR, + suggestion: createSuggestion('', ...getPositionRangeFromNode(annotation)), + }); + } + if (metadata.ignoredAnnotationInfo?.hasProvider) { + const annotation = metadata.ignoredAnnotations?.[DecoratorNames.PROVIDER]!; + this.report({ + node: annotation, + message: `'@${DecoratorNames.PROVIDER}' can only decorate member property.`, + level: LogType.ERROR, + suggestion: createSuggestion('', ...getPositionRangeFromNode(annotation)), + }); + } +} + +function checkConsumerProviderDecoratorInProperty( + this: BaseValidator, + node: T +): void { + const metadata = this.context ?? {}; + //`@Provider`/`@Consumer`装饰器只能用于`struct`类型,而不能用于类(`class`)或其他类型; + if (!!metadata.classInfo && metadata.ignoredAnnotationInfo?.hasConsumer) { + const annotation = metadata.ignoredAnnotations?.[DecoratorNames.CONSUMER]!; + this.report({ + node: annotation, + message: `The '@${DecoratorNames.CONSUMER}' annotation can only be used with 'struct'.`, + level: LogType.ERROR, + suggestion: createSuggestion('', ...getPositionRangeFromNode(annotation)), + }); + } + if (!!metadata.classInfo && metadata.ignoredAnnotationInfo?.hasProvider) { + const annotation = metadata.ignoredAnnotations?.[DecoratorNames.PROVIDER]!; + this.report({ + node: annotation, + message: `The '@${DecoratorNames.PROVIDER}' annotation can only be used with 'struct'.`, + level: LogType.ERROR, + suggestion: createSuggestion('', ...getPositionRangeFromNode(annotation)), + }); + } + // 结构体成员变量不能被多个内置装饰器修饰; + let foundOther: arkts.AnnotationUsage | undefined; + if ( + metadata.annotationInfo?.hasConsumer && + !!(foundOther = findOtherDecoratorFromInfo(metadata, DecoratorNames.CONSUMER)) + ) { + this.report({ + node: foundOther, + message: `The struct member variable can not be decorated by multiple built-in annotations.`, + level: LogType.ERROR, + suggestion: createSuggestion('', ...getPositionRangeFromNode(foundOther)), + }); + } + if ( + metadata.annotationInfo?.hasProvider && + !!(foundOther = findOtherDecoratorFromInfo(metadata, DecoratorNames.PROVIDER)) + ) { + this.report({ + node: foundOther, + message: `The struct member variable can not be decorated by multiple built-in annotations.`, + level: LogType.ERROR, + suggestion: createSuggestion('', ...getPositionRangeFromNode(foundOther)), + }); + } +} + +function checkConsumerProviderDecoratorInStructCall( + this: BaseValidator, + node: T +): void { + const metadata = this.context ?? {}; + if (!metadata.structDeclInfo?.name) { + return; + } + const structName = metadata.structDeclInfo.name; + ////////////////////////////////////////////////////// + const propertyInfos = metadata.structPropertyInfos ?? []; + // 自定义组件中的`@Provider`/`@Consumer`装饰的属性不能在父组件初始化(禁止指定初始值) + for (const propInfo of propertyInfos) { + const propPtr = propInfo[0]; + const propertyInfo = propInfo[1]; + if (!propertyInfo?.name || propertyInfo.name.startsWith(StateManagementTypes.BACKING)) { + return; + } + const decoratorInfo = findConsumerOrProviderFromInterfacePropertyInfo(propertyInfo); + if (!!decoratorInfo) { + const prop = arkts.classByPeer(propPtr); + this.report({ + node: prop, + message: getForbiddenInitializationMessage(decoratorInfo.name, propertyInfo.name, structName), + level: LogType.ERROR, + suggestion: createSuggestion('', ...getPositionRangeFromNode(node)), + }); + } + } + ////////////////////////////////////////////////////// + + // const call = coerceToAstNode(node); + // const optionsArg = call.arguments.at(1); // Options is the second argument of a custom component call. + // if (!optionsArg || !arkts.isObjectExpression(optionsArg)) { + // return; + // } + // // 自定义组件中的`@Provider`/`@Consumer`装饰的属性不能在父组件初始化(禁止指定初始值) + // (optionsArg.properties as arkts.Property[]).forEach((prop) => { + // let decl: arkts.AstNode | undefined; + // if ( + // !prop.key || + // !prop.value || + // !(decl = arkts.getPeerPropertyDecl(prop.peer)) || + // !arkts.isMethodDefinition(decl) + // ) { + // return; + // } + // console.log("[Property] decl: ", decl.dumpSrc()); + // if (checkIsNameStartWithBackingField(decl.name)) { + // return; + // } + // const decoratorInfo = findConsumerOrProviderFromInterfaceProperty(decl); + // if (!!decoratorInfo) { + // this.report({ + // node: prop, + // message: getForbiddenInitializationMessage(decoratorInfo.name, decl.name.name, structName), + // level: LogType.ERROR, + // suggestion: createSuggestion('', ...getPositionRangeFromNode(call)), + // }); + // } + // }); +} + +const checkByType = new Map([ + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_METHOD_DEFINITION, checkConsumerProviderDecoratorInStructMethod], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CLASS_PROPERTY, checkConsumerProviderDecoratorInProperty], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CALL_EXPRESSION, checkConsumerProviderDecoratorInStructCall], +]); + +type PropertyInfo = StructPropertyInfo & NormalClassPropertyInfo; + +interface DecoratorInfo { + name: string; + annotation: arkts.AnnotationUsage; +} + +function findOtherDecoratorFromInfo(info: StructPropertyInfo, except: string): arkts.AnnotationUsage | undefined { + let foundName: string | undefined; + foundName = Object.keys(info.annotations ?? {}).find((name) => name !== except); + if (!!foundName) { + return info.annotations?.[foundName]!; + } + foundName = Object.keys(info.ignoredAnnotations ?? {}).find((name) => name !== except); + return foundName ? info.ignoredAnnotations?.[foundName] : undefined; +} + +function findConsumerOrProviderFromInterfacePropertyInfo( + propertyInfo: CustomComponentInterfacePropertyInfo +): DecoratorInfo | undefined { + if (propertyInfo?.annotationInfo?.hasConsumer) { + const annotation = propertyInfo.annotations?.[DecoratorNames.CONSUMER]!; + return { name: DecoratorNames.CONSUMER, annotation }; + } + if (propertyInfo?.annotationInfo?.hasProvider) { + const annotation = propertyInfo.annotations?.[DecoratorNames.PROVIDER]!; + return { name: DecoratorNames.PROVIDER, annotation }; + } + return undefined; +} + +function findConsumerOrProviderFromInterfaceProperty(property: arkts.MethodDefinition): DecoratorInfo | undefined { + const structInterfacePropRecord = RecordBuilder.build(CustomComponentInterfacePropertyRecord, property, { + shouldIgnoreDecl: false, + }); // TODO: change back to false; + if (!structInterfacePropRecord.isCollected) { + structInterfacePropRecord.collect(property); + } + const propertyInfo = structInterfacePropRecord.toRecord(); + if (propertyInfo?.annotationInfo?.hasConsumer) { + const annotation = propertyInfo.annotations?.[DecoratorNames.CONSUMER]!; + return { name: DecoratorNames.CONSUMER, annotation }; + } + if (propertyInfo?.annotationInfo?.hasProvider) { + const annotation = propertyInfo.annotations?.[DecoratorNames.PROVIDER]!; + return { name: DecoratorNames.PROVIDER, annotation }; + } + return undefined; +} + +function getForbiddenInitializationMessage(decorator: string, key: string, component: string): string { + return `The '@${decorator}' property '${key}' in the custom component '${component}' cannot be initialized here (forbidden to specify).`; +} diff --git a/arkui-plugins/collectors/ui-collectors/validators/rules/check-entry-localstorage.ts b/arkui-plugins/collectors/ui-collectors/validators/rules/check-entry-localstorage.ts new file mode 100644 index 0000000000000000000000000000000000000000..d8fa65ded42443c36df5f67b2321c286ccfef50d --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/rules/check-entry-localstorage.ts @@ -0,0 +1,57 @@ +/* + * 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 { BaseValidator } from '../base'; +import { StructPropertyInfo } from '../../records'; +import { EntryParamNames, LogType, StructDecoratorNames } from '../../../../common/predefines'; + +/** + * 校验规则:`struct`结构体中使用了`@LocalStorageLink`来绑定属性,需要在`@Entry`装饰器中传入storage参数 + * + * 校验等级:warn + */ +export function checkEntryLocalStorage( + this: BaseValidator, + classProperty: arkts.ClassProperty +): void { + const metadata = this.context ?? {}; + if (!metadata.annotationInfo?.hasLocalStorageLink || !metadata.structInfo?.annotationInfo?.hasEntry) { + return; + } + const entryAnnotation = metadata.structInfo?.annotations?.[StructDecoratorNames.ENTRY]!; + if (!findStorageParamFromEntryAnnotation(entryAnnotation)) { + this.report({ + node: entryAnnotation, + level: LogType.WARN, + message: `'@Entry' should have a parameter, like '@Entry ({ storage: "__get_local_storage__" })'.`, + }); + } +} + +function findStorageParamFromEntryAnnotation(node: arkts.AnnotationUsage): boolean { + return !!node.properties.find((prop) => { + if (!arkts.isClassProperty(prop)) { + return false; + } + if (!prop.key || !arkts.isIdentifier(prop.key) || prop.key.name !== EntryParamNames.ENTRY_STORAGE) { + return false; + } + if (!prop.value || !arkts.isStringLiteral(prop.value) || prop.value.str.length === 0) { + return false; + } + return true; + }); +} diff --git a/arkui-plugins/collectors/ui-collectors/validators/rules/check-nested-relationship.ts b/arkui-plugins/collectors/ui-collectors/validators/rules/check-nested-relationship.ts new file mode 100644 index 0000000000000000000000000000000000000000..3a547be7d8fe8471cf48d541c0b0da806db776ff --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/rules/check-nested-relationship.ts @@ -0,0 +1,55 @@ +/* + * 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 { BaseValidator } from '../base'; +import { isAnnotatedProperty } from '../utils'; +import { CallInfo } from '../../records'; +import { DecoratorNames, LogType } from '../../../../common/predefines'; +import { createSuggestion, getPositionRangeFromNode } from '../../../../common/log-collector'; + +/** + * 校验规则: + * 1. 原子组件不可包含子组件; + * 2. 单子组件最多允许包含一个组件; + * 3. 特定组件的父组件必须是限定组件; + * 4. 特定组件的子组件必须是限定组件。 + * + * 校验等级:error + */ +export function checkNestedRelationship( + this: BaseValidator, + struct: arkts.ClassDefinition +): void { + const metadata = this.context ?? {}; + const fromComponentV2: boolean = !!metadata.fromStructInfo?.annotationInfo?.hasComponentV2; + const isComponentCall: boolean = !!metadata.structDeclInfo?.annotationInfo?.hasComponent; + if (!(fromComponentV2 && isComponentCall)) { + return; + } + + // 只要当前struct 中有被"@Link" 修饰的属性就报错 + for (const member of struct.body) { + if (isAnnotatedProperty(member, DecoratorNames.LINK)) { + const declaration = struct.parent!; // Class Declaration has correct position information + this.report({ + node: declaration, + level: LogType.ERROR, + message: `A V2 component cannot be used with any member property annotated by '@Link' in a V1 component.`, + suggestion: createSuggestion('', ...getPositionRangeFromNode(declaration)), + }); + } + } +} diff --git a/arkui-plugins/collectors/ui-collectors/validators/rules/index.ts b/arkui-plugins/collectors/ui-collectors/validators/rules/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..145dcadc504c2219420467ccc2be35e92573aa34 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/rules/index.ts @@ -0,0 +1,22 @@ +/* + * 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. + */ + +export * from './check-builder-param'; +export * from './check-component-link-init'; +export * from './check-component-v2-mix-use'; +export * from './check-componentV2-state-usage'; +export * from './check-computed-decorator'; +export * from './check-consumer-provider-decorator'; +export * from './check-entry-localstorage'; \ No newline at end of file diff --git a/arkui-plugins/collectors/ui-collectors/validators/safe-types.ts b/arkui-plugins/collectors/ui-collectors/validators/safe-types.ts new file mode 100644 index 0000000000000000000000000000000000000000..2d69f17170b0f3dcd3bdccdb8a17a24a5035b62b --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/safe-types.ts @@ -0,0 +1,30 @@ +/* + * 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 { BaseValidator } from './base'; + +export type IntrinsicValidatorFunction = (this: BaseValidator, node: T) => void; + +export type ModifiedValidatorFunction = ( + this: BaseValidator, + node: U +) => void; + +export type ExtendedValidatorFunction = ( + this: BaseValidator, + node: T, + other?: U +) => void; \ No newline at end of file diff --git a/arkui-plugins/collectors/ui-collectors/validators/struct-call-validator.ts b/arkui-plugins/collectors/ui-collectors/validators/struct-call-validator.ts new file mode 100644 index 0000000000000000000000000000000000000000..aeecdfbef63ed9bd7c15c6c384014d969c23c312 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/struct-call-validator.ts @@ -0,0 +1,38 @@ +/* + * 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 { BaseValidator } from './base'; +import { checkBuilderParam, checkComponentLinkInit, checkComponentV2StateUsage, checkComputedDecorator, checkConsumerProviderDecorator } from './rules'; +import { CallInfo } from '../records'; +import { checkIsCustomComponentFromInfo } from '../utils'; + +export class StructCallValidator extends BaseValidator { + reportIfViolated(node: arkts.CallExpression): void { + const metadata = this.context ?? {}; + // 只处理自定义组件 CallExpression的场景 + if (!checkIsCustomComponentFromInfo(metadata.structDeclInfo) || !metadata.structDeclInfo?.definitionPtr) { + return; + } + + checkComponentV2StateUsage.bind(this)(node); + checkComputedDecorator.bind(this)(node); + checkConsumerProviderDecorator.bind(this)(node); + + const struct = arkts.classByPeer(metadata.structDeclInfo.definitionPtr); + checkBuilderParam.bind(this)(struct); + checkComponentLinkInit.bind(this)(struct); + } +} diff --git a/arkui-plugins/collectors/ui-collectors/validators/struct-method-validator.ts b/arkui-plugins/collectors/ui-collectors/validators/struct-method-validator.ts new file mode 100644 index 0000000000000000000000000000000000000000..d360d7ff52b29b13b49de3cfe5a1b5e7957584a9 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/struct-method-validator.ts @@ -0,0 +1,34 @@ +/* + * 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 { BaseValidator } from './base'; +import { StructMethodInfo } from '../records'; +import { checkComponentV2StateUsage, checkComputedDecorator, checkConsumerProviderDecorator } from './rules'; + +export class StructMethodValidator extends BaseValidator { + reportIfViolated(node: arkts.MethodDefinition): void { + const metadata = this.context ?? {}; + if (!metadata.structInfo?.definitionPtr) { + return; + } + + checkComponentV2StateUsage.bind(this)(node); + checkConsumerProviderDecorator.bind(this)(node); + + const struct = arkts.classByPeer(metadata.structInfo.definitionPtr); + checkComputedDecorator.bind(this)(node, struct); + } +} diff --git a/arkui-plugins/collectors/ui-collectors/validators/struct-property-validator.ts b/arkui-plugins/collectors/ui-collectors/validators/struct-property-validator.ts new file mode 100644 index 0000000000000000000000000000000000000000..d90833850bd634faee117f9e286c0e724cde0a4e --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/struct-property-validator.ts @@ -0,0 +1,42 @@ +/* + * 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 { BaseValidator } from './base'; +import { StructPropertyInfo } from '../records'; +import { + checkComponentV2MixUse, + checkComponentV2StateUsage, + checkComputedDecorator, + checkConsumerProviderDecorator, + checkEntryLocalStorage, +} from './rules'; + +export class StructPropertyValidator extends BaseValidator { + reportIfViolated(node: arkts.ClassProperty): void { + const metadata = this.context ?? {}; + if (!metadata.structInfo?.definitionPtr) { + return; + } + + checkComponentV2MixUse.bind(this)(node); + checkComponentV2StateUsage.bind(this)(node); + checkConsumerProviderDecorator.bind(this)(node); + checkEntryLocalStorage.bind(this)(node); + + const struct = arkts.classByPeer(metadata.structInfo.definitionPtr); + checkComputedDecorator.bind(this)(node, struct); + } +} diff --git a/arkui-plugins/collectors/ui-collectors/validators/utils.ts b/arkui-plugins/collectors/ui-collectors/validators/utils.ts new file mode 100644 index 0000000000000000000000000000000000000000..2a3cf8c22061ed7825280727558e0612a8b1e006 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/utils.ts @@ -0,0 +1,38 @@ +/* + * 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 { getAnnotationName } from '../utils'; + +export function isAnnotatedProperty(node: arkts.AstNode, annotationName: string, ignoreDecl: boolean = false): node is arkts.ClassProperty { + if (!arkts.isClassProperty(node)) { + return false; + } + return !!getAnnotationByName(node.annotations, annotationName, ignoreDecl); +} + +export function getAnnotationByName( + annotations: readonly arkts.AnnotationUsage[], + name: string, + ignoreDecl: boolean = false +): arkts.AnnotationUsage | undefined { + return annotations.find((annotation: arkts.AnnotationUsage): boolean => { + return getAnnotationName(annotation, ignoreDecl) === name; + }); +} + +export function coerceToAstNode(node: arkts.AstNode): T { + return node as T; +} diff --git a/arkui-plugins/collectors/ui-collectors/validators/validator-builder.ts b/arkui-plugins/collectors/ui-collectors/validators/validator-builder.ts new file mode 100644 index 0000000000000000000000000000000000000000..c4f271cde1a566e4d60c674bfebb78706ac7c228 --- /dev/null +++ b/arkui-plugins/collectors/ui-collectors/validators/validator-builder.ts @@ -0,0 +1,30 @@ +/* + * 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 { Validator, ValidatorOptions } from './base'; +import { clearValidatorCache, getOrPut } from './cache'; + +export class ValidatorBuilder { + static shouldSkip: boolean = false; + + static build(Validator: { name: string; new (options: ValidatorOptions): Validator }): Validator { + return getOrPut(Validator.name, () => new Validator({ shouldSkip: this.shouldSkip })); + } + + static reset(): void { + this.shouldSkip = false; + clearValidatorCache(); + } +} diff --git a/arkui-plugins/common/abstract-visitor.ts b/arkui-plugins/common/abstract-visitor.ts index 2c7a307da160e41671fa8d0aca5586a38d30ef8e..fbcf0cd34b96a3a6f3aaf4f7aa2e72b7a24ac097 100644 --- a/arkui-plugins/common/abstract-visitor.ts +++ b/arkui-plugins/common/abstract-visitor.ts @@ -41,8 +41,18 @@ export abstract class AbstractVisitor implements VisitorOptions { return result; } + getOptions(): VisitorOptions { + return { + isExternal: this.isExternal, + externalSourceName: this.externalSourceName, + program: this.program, + }; + } + abstract visitor(node: arkts.AstNode): arkts.AstNode; + init(): void {} + reset(): void { this.indentation = 0; } diff --git a/arkui-plugins/common/arkts-utils.ts b/arkui-plugins/common/arkts-utils.ts index 1b01d924856e72a453897a32d3fbf7dbefd5098d..11ac3dbb0861d69f95f99392e92769db5b7e1b14 100644 --- a/arkui-plugins/common/arkts-utils.ts +++ b/arkui-plugins/common/arkts-utils.ts @@ -69,7 +69,7 @@ export function isDecoratorAnnotation( if (!decl) { return false; } - const moduleName: string = arkts.getProgramFromAstNode(decl).moduleName; + const moduleName = arkts.getProgramFromAstNode(decl)?.moduleName; if (!moduleName || !matchPrefix(ARKUI_IMPORT_PREFIX_NAMES, moduleName)) { return false; } @@ -85,24 +85,6 @@ export function removeAnnotationByName( return annotations.filter((it) => !isAnnotation(it, annoName)); } -export function expectName(node: arkts.AstNode | undefined): string { - if (!node) { - throw new Error('Expected an identifier, got empty node'); - } - if (!arkts.isIdentifier(node)) { - throw new Error('Expected an identifier, got: ' + arkts.nodeType(node).toString()); - } - return node.name; -} - -export function mangle(value: string): string { - return `__${value}`; -} - -export function backingField(originalName: string): string { - return mangle(`backing_${originalName}`); -} - export function filterDefined(value: (T | undefined)[]): T[] { return value.filter((it: T | undefined): it is T => it != undefined); } diff --git a/arkui-plugins/common/declaration-collector.ts b/arkui-plugins/common/declaration-collector.ts index d65f0d40da094bc237037b592d7b699e322c77bd..a867d3d18b25c26881fcd0ba1b61fe8081655c18 100644 --- a/arkui-plugins/common/declaration-collector.ts +++ b/arkui-plugins/common/declaration-collector.ts @@ -62,7 +62,10 @@ export class DeclarationCollector { if (!declName) { return; } - let sourceName: string = arkts.getProgramFromAstNode(decl).moduleName; + let sourceName = arkts.getProgramFromAstNode(decl)?.moduleName; + if (!sourceName) { + return; + } this.fromExternalSourceNameMap.set(declName, sourceName); this.fromExternalSourceNodePeerMap.set(decl.peer, sourceName); diff --git a/arkui-plugins/common/import-collector.ts b/arkui-plugins/common/import-collector.ts index 935b339af29f87951a69cc85508b64f1fa83e810..ccb52166bbc397689c78accc2de454cab96c5f8b 100644 --- a/arkui-plugins/common/import-collector.ts +++ b/arkui-plugins/common/import-collector.ts @@ -58,10 +58,14 @@ export class ImportCollector { } reset(): void { - this.importInfos = []; - this.imported.clear(); this.localMap.clear(); this.sourceMap.clear(); + this.clearImports(); + } + + clearImports(): void { + this.importInfos = []; + this.imported.clear(); } collectSource(imported: string, source: string): void { diff --git a/arkui-plugins/common/log-collector.ts b/arkui-plugins/common/log-collector.ts index 5fa9ed7af815dca0e10d9c5bc469f3477762227d..56de52a6c99daf1f4f52ed0056f94567562e93d2 100644 --- a/arkui-plugins/common/log-collector.ts +++ b/arkui-plugins/common/log-collector.ts @@ -16,20 +16,59 @@ import * as arkts from '@koalaui/libarkts'; import { LogType } from './predefines'; -interface LogInfo { - type: LogType; - message: string; - node: arkts.AstNode; +export interface SuggestionOptions { code: string; + range: [start: arkts.SourcePosition, end: arkts.SourcePosition]; + args?: string[]; +} + +export interface LogInfo { + node: arkts.AstNode; + level: LogType; + message: string; + args?: string[]; + position?: arkts.SourcePosition; + suggestion?: SuggestionOptions; + code?: string; +} + +export function createSuggestion( + code: string, + rangeStart: arkts.SourcePosition, + rangeEnd: arkts.SourcePosition, + ...args: string[] +): SuggestionOptions { + return { code, range: [rangeStart, rangeEnd], args }; +} + +export function getPositionRangeFromNode(node: arkts.AstNode): [arkts.SourcePosition, arkts.SourcePosition] { + return [node.startPosition, node.endPosition]; } export function generateDiagnosticKind(logItem: LogInfo): arkts.DiagnosticKind { - return arkts.DiagnosticKind.create( - `${logItem.code}: ${logItem.message}`, - logItem.type === LogType.ERROR + const message: string = !!logItem.code ? `${logItem.code}: ${logItem.message}` : logItem.message; + const level: arkts.PluginDiagnosticType = + logItem.level === LogType.ERROR ? arkts.PluginDiagnosticType.ES2PANDA_PLUGIN_ERROR - : arkts.PluginDiagnosticType.ES2PANDA_PLUGIN_WARNING - ); + : arkts.PluginDiagnosticType.ES2PANDA_PLUGIN_WARNING; + return arkts.DiagnosticKind.create(message, level); +} + +export function generateDiagnosticInfo(logItem: LogInfo, pos: arkts.SourcePosition): arkts.DiagnosticInfo { + const diagnosticArgs = logItem.args ?? []; + const diagnosticKind = generateDiagnosticKind(logItem); + return arkts.DiagnosticInfo.create(diagnosticKind, pos, ...diagnosticArgs); +} + +export function generateSuggestionInfo(suggestion: SuggestionOptions, message: string, range: arkts.SourceRange): arkts.SuggestionInfo { + const suggestionArgs = suggestion.args ?? []; + const suggestionKind = arkts.DiagnosticKind.create(message, arkts.PluginDiagnosticType.ES2PANDA_PLUGIN_SUGGESTION); + return arkts.SuggestionInfo.create(suggestionKind, suggestion.code, range, ...suggestionArgs); +} + +export function generateSuggestionRange(suggestion: SuggestionOptions): arkts.SourceRange { + const [startPosition, endPosition] = suggestion.range; + return arkts.SourceRange.create(startPosition, endPosition); } export class LogCollector { @@ -49,6 +88,21 @@ export class LogCollector { return this.instance; } + private reportDiagnostic(log: LogInfo): void { + const args = log.args ?? []; + const position = log.position ?? arkts.getStartPosition(log.node); + const suggestion = log.suggestion; + if (!suggestion) { + const kind = generateDiagnosticKind(log); + arkts.Diagnostic.logDiagnostic(kind, position, ...args); + } else { + const info = generateDiagnosticInfo(log, position); + const suggestionRange = generateSuggestionRange(suggestion); + const suggestionInfo = generateSuggestionInfo(suggestion, log.message, suggestionRange); + arkts.Diagnostic.logDiagnosticWithSuggestion(info, suggestionInfo); + } + } + reset(): void { this.logInfos = []; this.ignoreError = false; @@ -63,7 +117,7 @@ export class LogCollector { return; } this.logInfos.forEach((logItem: LogInfo) => { - arkts.Diagnostic.logDiagnostic(generateDiagnosticKind(logItem), arkts.getStartPosition(logItem.node)); + this.reportDiagnostic(logItem); }); } diff --git a/arkui-plugins/common/predefines.ts b/arkui-plugins/common/predefines.ts index de04875ea5abe398c9d4fa4e4b22972cfca43658..a7834d677c5067a5aa51fa1abef5fd36b74eb89f 100644 --- a/arkui-plugins/common/predefines.ts +++ b/arkui-plugins/common/predefines.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -export const EXTERNAL_SOURCE_PREFIX_NAMES: (string | RegExp)[] = [ +export const LINTER_EXCLUDE_EXTERNAL_SOURCE_PREFIXES: Array = [ 'std', 'escompat', 'security', @@ -21,18 +21,31 @@ export const EXTERNAL_SOURCE_PREFIX_NAMES: (string | RegExp)[] = [ 'permissions', 'bundleManager', 'commonEvent', + 'global', + 'arkui', /@arkts\..*/, - /@ohos\.(?!arkui).*/, + /@ohos\.*/, /@system\..*/, + /@koalaui\./, /ability\..*/, ]; -export const EXTERNAL_SOURCE_PREFIX_NAMES_FOR_FRAMEWORK: (string | RegExp)[] = [ +export const EXTERNAL_SOURCE_PREFIX_NAMES: (string | RegExp)[] = [ 'std', 'escompat', - /@arkts\..*/ + 'security', + 'application', + 'permissions', + 'bundleManager', + 'commonEvent', + /@arkts\..*/, + /@ohos\.(?!arkui).*/, + /@system\..*/, + /ability\..*/, ]; +export const EXTERNAL_SOURCE_PREFIX_NAMES_FOR_FRAMEWORK: (string | RegExp)[] = ['std', 'escompat', /@arkts\..*/]; + export const ARKUI_IMPORT_PREFIX_NAMES: (string | RegExp)[] = [/arkui\..*/, /@ohos\..*/, /@kit\..*/]; export const MEMO_IMPORT_SOURCE_NAME: string = 'arkui.stateManagement.runtime'; @@ -92,7 +105,7 @@ export enum EntryWrapperNames { REGISTER_NAMED_ROUTER = 'RegisterNamedRouter', ROUTER_NAME = 'routerName', INSTANCE = 'instance', - PARAM = 'param' + PARAM = 'param', } export enum ObservedNames { @@ -120,7 +133,7 @@ export enum MonitorNames { export enum EntryParamNames { ENTRY_STORAGE = 'storage', ENTRY_USE_SHARED_STORAGE = 'useSharedStorage', - ENTRY_ROUTE_NAME = 'routeName' + ENTRY_ROUTE_NAME = 'routeName', } export enum InnerComponentNames { @@ -151,17 +164,17 @@ export enum DecoratorNames { JSONRENAME = 'JSONRename', ANIMATABLE_EXTEND = 'AnimatableExtend', PROP_REF = 'PropRef', - LOCAL = 'Local', - LOCAL_STORAGE_PROP_REF = 'LocalStoragePropRef', + LOCAL_STORAGE_PROP_REF = 'LocalStoragePropRef', STORAGE_PROP_REF = 'StoragePropRef', + LOCAL = 'Local', PARAM = 'Param', ONCE = 'Once', + REQUIRE = 'Require', PROVIDER = 'Provider', CONSUMER = 'Consumer', MONITOR = 'Monitor', COMPUTED = 'Computed', - EVENT = 'Event', - REQUIRE = 'Require' + EVENT = 'Event' } export enum TypeNames { @@ -169,10 +182,6 @@ export enum TypeNames { ANY = 'Any' } -export enum DecoratorIntrinsicNames { - LINK = '__Link_intrinsic', -} - export enum StateManagementTypes { STATE_MANAGEMENT_FACTORY = 'STATE_MGMT_FACTORY', STATE_DECORATED = 'IStateDecoratedVariable', @@ -201,6 +210,8 @@ export enum StateManagementTypes { RENDER_ID_TYPE = 'RenderIdType', OBSERVE = 'OBSERVE', META = '__meta', + BACKING = '__backing', + VALUE = 'value', SUBSCRIBED_WATCHES = 'ISubscribedWatches', STORAGE_LINK_STATE = 'StorageLinkState', OBSERVABLE_PROXY = 'observableProxy', @@ -252,6 +263,44 @@ export enum ConditionNames { CONDITION_BRANCH = 'ConditionBranch', } +export enum CustomComponentNames { + COMPONENT_BUILD_ORI = 'build', + COMPONENT_CONSTRUCTOR_ORI = 'constructor', + COMPONENT_CLASS_NAME = 'CustomComponent', + COMPONENT_V2_CLASS_NAME = 'CustomComponentV2', + BASE_CUSTOM_DIALOG_NAME = 'BaseCustomDialog', + COMPONENT_INTERFACE_PREFIX = '__Options_', + COMPONENT_INITIALIZE_STRUCT = '__initializeStruct', + COMPONENT_UPDATE_STRUCT = '__updateStruct', + COMPONENT_INITIALIZERS_NAME = 'initializers', + COMPONENT_TO_RECORD = '__toRecord', + BUILD_COMPATIBLE_NODE = '_buildCompatibleNode', + OPTIONS = 'options', + PAGE_LIFE_CYCLE = 'PageLifeCycle', + LAYOUT_CALLBACK = 'LayoutCallback', +} + +export enum CustomDialogNames { + CUSTOM_DIALOG_ANNOTATION_NAME = 'CustomDialog', + CUSTOM_DIALOG_CONTROLLER = 'CustomDialogController', + CUSTOM_DIALOG_CONTROLLER_OPTIONS = 'CustomDialogControllerOptions', + SET_DIALOG_CONTROLLER_METHOD = '__setDialogController__', + CONTROLLER = 'controller', + OPTIONS_BUILDER = 'builder', + BASE_COMPONENT = 'baseComponent', + EXTENDABLE_COMPONENT = 'ExtendableComponent', + CUSTOM_BUILDER = 'CustomBuilder', +} + +export enum BuilderLambdaNames { + ANNOTATION_NAME = 'ComponentBuilder', + ORIGIN_METHOD_NAME = '$_instantiate', + TRANSFORM_METHOD_NAME = '_instantiateImpl', + STYLE_PARAM_NAME = 'style', + STYLE_ARROW_PARAM_NAME = 'instance', + CONTENT_PARAM_NAME = 'content' +} + export const RESOURCE_TYPE: Record = { color: 10001, float: 10002, @@ -282,8 +331,8 @@ export const DECORATOR_TYPE_MAP = new Map( [DecoratorNames.PROVIDE, StateManagementTypes.PROVIDE_DECORATED], [DecoratorNames.CONSUME, StateManagementTypes.CONSUME_DECORATED], [DecoratorNames.LOCAL, StateManagementTypes.LOCAL_DECORATED], - [DecoratorNames.PARAM, StateManagementTypes.PARAM_DECORATED], [DecoratorNames.ONCE, StateManagementTypes.ONCE_DECORATED], + [DecoratorNames.PARAM, StateManagementTypes.PARAM_DECORATED], [DecoratorNames.PROVIDER, StateManagementTypes.PROVIDER_DECORATED], [DecoratorNames.CONSUMER, StateManagementTypes.CONSUMER_DECORATED], ]); @@ -293,7 +342,14 @@ export const INTERMEDIATE_IMPORT_SOURCE: Map = new Map = new Map = new Map = new Map = new Map [StateManagementTypes.OBSERVABLE_PROXY, 'arkui.stateManagement.runtime'], [StateManagementTypes.PROP_STATE, 'arkui.stateManagement.runtime'], [StateManagementTypes.UI_UTILS, 'arkui.stateManagement.utils'], - [AnimationNames.ANIMATABLE_ARITHMETIC, 'arkui.component.common'] + [AnimationNames.ANIMATABLE_ARITHMETIC, 'arkui.component.common'], ]); export enum GetSetTypes { @@ -384,7 +440,20 @@ export enum GetSetTypes { SET = 'set', } -export enum GenSymPrefix { - INTRINSIC = 'gensym%%', - UI = 'gensym__' +export enum NodeCacheNames { + MEMO = 'memo', + UI = 'ui', +} + +export enum BuiltInNames { + GENSYM_INTRINSIC_PREFIX = 'gensym%%', + GENSYM_UI_PREFIX = 'gensym__', + ETS_GLOBAL_CLASS = 'ETSGLOBAL', + GLOBAL_INIT_METHOD = '_$init$_', + GLOBAL_MAIN_METHOD = 'main', + IMPLEMENT_PROPETY_PREFIX = '' +} + +export enum ArkUIDeclInterfaceNames { + COMMON_METHOD = 'CommonMethod' } \ No newline at end of file diff --git a/arkui-plugins/common/program-visitor.ts b/arkui-plugins/common/program-visitor.ts index 55ac1aad41e3b936d0d1faeeb5d037b98db90c66..348fb8b0fd5a7a5c6e5b06277164582c619659f8 100644 --- a/arkui-plugins/common/program-visitor.ts +++ b/arkui-plugins/common/program-visitor.ts @@ -257,6 +257,7 @@ export class ProgramVisitor extends AbstractVisitor { if (this.legacyStructMap.size > 0 && transformer instanceof ComponentTransformer) { transformer.registerMap(this.legacyStructMap); } + transformer.init(); this.visitTransformer(transformer, script, externalSourceName, program); transformer.reset(); arkts.setAllParents(script); diff --git a/arkui-plugins/common/safe-types.ts b/arkui-plugins/common/safe-types.ts index 899ef0c39b3dccec8dbbbe1fb68d6243a009dcc2..87345cf196a2952101a3b802924e95b6d3991503 100644 --- a/arkui-plugins/common/safe-types.ts +++ b/arkui-plugins/common/safe-types.ts @@ -40,4 +40,6 @@ export type PickNested = { [P in keyof T]: P extends K ? T[P] : T[P] extends object ? NestedKey : T[P]; }; -export type PartialNestedExcept = PartialNested> & PickNested; \ No newline at end of file +export type PartialNestedExcept = PartialNested> & PickNested; + +export type AstNodePointer = arkts.AstNode['peer']; \ No newline at end of file diff --git a/arkui-plugins/memo-plugins/function-transformer.ts b/arkui-plugins/memo-plugins/function-transformer.ts index 4f2c55f1f4c572c8cabfa2ede178bc0d0cc1018d..2cecfa8406c05cc71868e8f597a38296af1499ad 100644 --- a/arkui-plugins/memo-plugins/function-transformer.ts +++ b/arkui-plugins/memo-plugins/function-transformer.ts @@ -56,6 +56,7 @@ import { SignatureTransformer } from './signature-transformer'; import { moveToFront } from '../common/arkts-utils'; import { InternalsTransformer } from './internal-transformer'; import { CachedMetadata, rewriteByType } from './memo-cache-factory'; +import { NodeCacheNames } from '../common/predefines'; interface ScopeInfo extends MemoInfo { regardAsSameScope?: boolean; @@ -682,9 +683,12 @@ export class FunctionTransformer extends AbstractVisitor { } private visitorWithCache(beforeChildren: arkts.AstNode): arkts.AstNode { + if (!arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).shouldUpdate(beforeChildren)) { + return beforeChildren; + } const node = this.visitEachChild(beforeChildren); - if (arkts.NodeCache.getInstance().has(node)) { - const value = arkts.NodeCache.getInstance().get(node)!; + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).has(node)) { + const value = arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).get(node)!; if (rewriteByType.has(value.type)) { this.modified = true; const metadata: CachedMetadata = { ...value.metadata, internalsTransformer: this.internalsTransformer }; diff --git a/arkui-plugins/memo-plugins/index.ts b/arkui-plugins/memo-plugins/index.ts index 5c19bc8414083b125b060e9fa01acd1f62e8bbf6..6f00963cf7719d6974ab7e480f66f051b49d5c2a 100644 --- a/arkui-plugins/memo-plugins/index.ts +++ b/arkui-plugins/memo-plugins/index.ts @@ -20,7 +20,7 @@ import { PositionalIdTracker } from './utils'; import { ReturnTransformer } from './return-transformer'; import { ParameterTransformer } from './parameter-transformer'; import { ProgramVisitor } from '../common/program-visitor'; -import { EXTERNAL_SOURCE_PREFIX_NAMES, EXTERNAL_SOURCE_PREFIX_NAMES_FOR_FRAMEWORK } from '../common/predefines'; +import { EXTERNAL_SOURCE_PREFIX_NAMES, EXTERNAL_SOURCE_PREFIX_NAMES_FOR_FRAMEWORK, NodeCacheNames } from '../common/predefines'; import { debugDump, debugLog, getDumpFileName } from '../common/debug'; import { SignatureTransformer } from './signature-transformer'; import { InternalsTransformer } from './internal-transformer'; @@ -31,6 +31,7 @@ export function unmemoizeTransform(): Plugins { checked: checkedTransform, clean() { arkts.arktsGlobal.clearContext(); + arkts.NodeCacheFactory.getInstance().clear(); }, }; } @@ -49,7 +50,7 @@ function checkedTransform(this: PluginContext): arkts.EtsScript | undefined { const canSkipPhases = !isFrameworkMode && program.canSkipPhases(); debugDump( script.dumpSrc(), - getDumpFileName(0, 'SRC', 5, 'MEMO_AfterCheck_Begin'), + getDumpFileName(0, 'SRC', 7, 'MEMO_AfterCheck_Begin'), true, cachePath, program.fileNameWithExtension @@ -61,7 +62,7 @@ function checkedTransform(this: PluginContext): arkts.EtsScript | undefined { debugLog('[AFTER MEMO SCRIPT] script: ', script.dumpSrc()); debugDump( script.dumpSrc(), - getDumpFileName(0, 'SRC', 6, 'MEMO_AfterCheck_End'), + getDumpFileName(0, 'SRC', 8, 'MEMO_AfterCheck_End'), true, cachePath, program.fileNameWithExtension @@ -95,6 +96,7 @@ function checkedProgramVisit( debugLog('[SKIP PHASE] phase: memo-checked, moduleName: ', program.moduleName); } else { debugLog('[CANT SKIP PHASE] phase: memo-checked, moduleName: ', program.moduleName); + // arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).visualize(); const positionalIdTracker = new PositionalIdTracker(arkts.getFileName(), false); const parameterTransformer = new ParameterTransformer({ positionalIdTracker }); const returnTransformer = new ReturnTransformer(); @@ -109,7 +111,7 @@ function checkedProgramVisit( returnTransformer, signatureTransformer, internalsTransformer, - useCache: arkts.NodeCache.getInstance().isCollected(), + useCache: arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).isCollected(), }); const skipPrefixNames = isFrameworkMode ? EXTERNAL_SOURCE_PREFIX_NAMES_FOR_FRAMEWORK @@ -122,7 +124,7 @@ function checkedProgramVisit( pluginContext, }); program = programVisitor.programVisitor(program); - arkts.NodeCache.getInstance().clear(); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).clear(); } return program; } diff --git a/arkui-plugins/memo-plugins/memo-cache-factory.ts b/arkui-plugins/memo-plugins/memo-cache-factory.ts index 1ca4234ed596b0ebecb6b28d244b19272ebb1d75..1460aeab7d6661d7baaebea8f29f1a908580af2f 100644 --- a/arkui-plugins/memo-plugins/memo-cache-factory.ts +++ b/arkui-plugins/memo-plugins/memo-cache-factory.ts @@ -29,9 +29,21 @@ import { PositionalIdTracker, } from './utils'; import { InternalsTransformer } from './internal-transformer'; -import { GenSymPrefix } from '../common/predefines'; +import { BuiltInNames } from '../common/predefines'; -export interface CachedMetadata extends arkts.AstNodeCacheValueMetadata { +export interface CacheValueMetadata { + callName?: string; + hasReceiver?: boolean; + isSetter?: boolean; + isGetter?: boolean; + forbidTypeRewrite?: boolean; + isWithinTypeParams?: boolean; + hasMemoSkip?: boolean; + hasMemoIntrinsic?: boolean; + hasMemoEntry?: boolean; +} + +export interface CachedMetadata extends CacheValueMetadata { internalsTransformer?: InternalsTransformer; } @@ -138,7 +150,7 @@ export class RewriteFactory { static rewriteArrowFunction( node: arkts.ArrowFunctionExpression, - metadata?: arkts.AstNodeCacheValueMetadata, + metadata?: CachedMetadata, expectReturn?: arkts.TypeNode ): arkts.ArrowFunctionExpression { return arkts.factory.updateArrowFunction( @@ -294,7 +306,7 @@ export class RewriteFactory { node: arkts.Identifier, metadata?: CachedMetadata ): arkts.Identifier | arkts.MemberExpression { - if (!node.name.startsWith(GenSymPrefix.INTRINSIC) && !node.name.startsWith(GenSymPrefix.UI)) { + if (!node.name.startsWith(BuiltInNames.GENSYM_INTRINSIC_PREFIX) && !node.name.startsWith(BuiltInNames.GENSYM_UI_PREFIX)) { return factory.createMemoParameterAccess(node.name); } return node; diff --git a/arkui-plugins/memo-plugins/parameter-transformer.ts b/arkui-plugins/memo-plugins/parameter-transformer.ts index 8aef0822cd3d5292081474db178b415b6a50a612..4af68149b2c57461413cc7b8ff0d3352e22b3aef 100644 --- a/arkui-plugins/memo-plugins/parameter-transformer.ts +++ b/arkui-plugins/memo-plugins/parameter-transformer.ts @@ -210,7 +210,7 @@ export class ParameterTransformer extends AbstractVisitor { if (!shouldUpdate) { return node; } - const decl = arkts.getPeerDecl(memoInfo.rewritePeer); + const decl = arkts.getPeerIdentifierDecl(memoInfo.rewritePeer); if (!decl || !arkts.isEtsParameterExpression(decl)) { return node; } @@ -245,7 +245,7 @@ export class ParameterTransformer extends AbstractVisitor { return that.updateParamReDeclare(declarator, memoInfo); } if (!!declarator.initializer && arkts.isIdentifier(declarator.initializer)) { - const decl = arkts.getPeerDecl(declarator.initializer.originalPeer); + const decl = arkts.getPeerIdentifierDecl(declarator.initializer.originalPeer); if (decl && that.rewriteIdentifiers?.has(decl.peer)) { return arkts.factory.updateVariableDeclarator( declarator, @@ -282,7 +282,7 @@ export class ParameterTransformer extends AbstractVisitor { return this.updateVariableReDeclarationFromParam(beforeChildren); } if (arkts.isCallExpression(beforeChildren) && arkts.isIdentifier(beforeChildren.expression)) { - const decl = arkts.getPeerDecl(beforeChildren.expression.originalPeer); + const decl = arkts.getPeerIdentifierDecl(beforeChildren.expression.originalPeer); if (decl && this.rewriteCalls?.has(decl.peer)) { const updateCall = this.rewriteCalls.get(decl.peer)!( beforeChildren.arguments.map((it) => this.visitor(it) as arkts.Expression) @@ -296,7 +296,7 @@ export class ParameterTransformer extends AbstractVisitor { } const node = this.visitEachChild(beforeChildren); if (arkts.isIdentifier(node)) { - const decl = arkts.getPeerDecl(node.originalPeer); + const decl = arkts.getPeerIdentifierDecl(node.originalPeer); if (decl && this.rewriteIdentifiers?.has(decl.peer)) { return this.rewriteIdentifiers.get(decl.peer)!(); } diff --git a/arkui-plugins/test/ut/ui-plugins/component/declare-component.test.ts b/arkui-plugins/test/ut/ui-plugins/component/declare-component.test.ts index 6261ad5d528fcbf90be7e222a349ac309d78c360..210dd0c69139515a4a90119fa044aabfb743b5bc 100644 --- a/arkui-plugins/test/ut/ui-plugins/component/declare-component.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/component/declare-component.test.ts @@ -60,11 +60,11 @@ import { Prop as Prop, State as State } from "@ohos.arkui.stateManagement"; } @Component() export declare interface __Options_SwipeRefresher { - content?: (ResourceStr | undefined); + @Prop() content?: (ResourceStr | undefined); @Prop() __backing_content?: (ResourceStr | undefined); - isLoading?: boolean; + @Prop() isLoading?: boolean; @Prop() __backing_isLoading?: boolean; - code?: number; + @State() code?: number; @State() __backing_code?: number; } @@ -105,21 +105,21 @@ function main() {} } @Component() export declare interface __Options_SwipeRefresher { - set content(content: ((ResourceStr | undefined) | undefined)) + @Prop() set content(content: ((ResourceStr | undefined) | undefined)) - get content(): ((ResourceStr | undefined) | undefined) + @Prop() get content(): ((ResourceStr | undefined) | undefined) set __backing_content(__backing_content: (IPropDecoratedVariable<(ResourceStr | undefined)> | undefined)) get __backing_content(): (IPropDecoratedVariable<(ResourceStr | undefined)> | undefined) - set isLoading(isLoading: (boolean | undefined)) + @Prop() set isLoading(isLoading: (boolean | undefined)) - get isLoading(): (boolean | undefined) + @Prop() get isLoading(): (boolean | undefined) set __backing_isLoading(__backing_isLoading: (IPropDecoratedVariable | undefined)) get __backing_isLoading(): (IPropDecoratedVariable | undefined) - set code(code: (number | undefined)) + @State() set code(code: (number | undefined)) - get code(): (number | undefined) + @State() get code(): (number | undefined) set __backing_code(__backing_code: (IStateDecoratedVariable | undefined)) get __backing_code(): (IStateDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/computed/computed-in-struct.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/computed/computed-in-struct.test.ts index 7ce255df6bdbc5052ed91936586e1abf3ae94461..8353bdd5befd0664726f229a2682f4addf1caa10 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/computed/computed-in-struct.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/computed/computed-in-struct.test.ts @@ -130,15 +130,15 @@ function main() {} } @ComponentV2() export interface __Options_Index { - set firstName(firstName: (string | undefined)) + @Local() set firstName(firstName: (string | undefined)) - get firstName(): (string | undefined) + @Local() get firstName(): (string | undefined) set __backing_firstName(__backing_firstName: (ILocalDecoratedVariable | undefined)) get __backing_firstName(): (ILocalDecoratedVariable | undefined) - set lastName(lastName: (string | undefined)) + @Local() set lastName(lastName: (string | undefined)) - get lastName(): (string | undefined) + @Local() get lastName(): (string | undefined) set __backing_lastName(__backing_lastName: (ILocalDecoratedVariable | undefined)) get __backing_lastName(): (ILocalDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/base-custom-dialog.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/base-custom-dialog.test.ts index 7547b4bfe17a101048e2c8d8eac4c05f11dd47a2..6313ac2170f39e67442eaf1fb3941404228b84d3 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/base-custom-dialog.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/base-custom-dialog.test.ts @@ -242,9 +242,9 @@ function main() {} set aaController(aaController: ((CustomDialogController | undefined) | undefined)) get aaController(): ((CustomDialogController | undefined) | undefined) - set text(text: (string | undefined)) + @State() set text(text: (string | undefined)) - get text(): (string | undefined) + @State() get text(): (string | undefined) set __backing_text(__backing_text: (IStateDecoratedVariable | undefined)) get __backing_text(): (IStateDecoratedVariable | undefined) @@ -254,9 +254,9 @@ function main() {} set confirm(confirm: ((()=> void) | undefined)) get confirm(): ((()=> void) | undefined) - set hh(hh: (string | undefined)) + @State() set hh(hh: (string | undefined)) - get hh(): (string | undefined) + @State() get hh(): (string | undefined) set __backing_hh(__backing_hh: (IStateDecoratedVariable | undefined)) get __backing_hh(): (IStateDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/controller-in-build.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/controller-in-build.test.ts index 9ad581f09cae75e99d9b61ba4101a9b9f5eae658..fe98b42efa0432496fe42781189fd910a46649a4 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/controller-in-build.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/custom-dialog/controller-in-build.test.ts @@ -156,15 +156,15 @@ function main() {} set aaController(aaController: ((CustomDialogController | undefined) | undefined)) get aaController(): ((CustomDialogController | undefined) | undefined) - set text(text: (string | undefined)) + @State() set text(text: (string | undefined)) - get text(): (string | undefined) + @State() get text(): (string | undefined) set __backing_text(__backing_text: (IStateDecoratedVariable | undefined)) get __backing_text(): (IStateDecoratedVariable | undefined) - set hh(hh: (string | undefined)) + @State() set hh(hh: (string | undefined)) - get hh(): (string | undefined) + @State() get hh(): (string | undefined) set __backing_hh(__backing_hh: (IStateDecoratedVariable | undefined)) get __backing_hh(): (IStateDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/event/event-initialize.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/event/event-initialize.test.ts index 783bcc981d0c1695a1c18d5f1924782e505d2801..f7651899753216f3e7b450b97854053d3c8149f0 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/event/event-initialize.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/event/event-initialize.test.ts @@ -88,16 +88,16 @@ import { Event as Event, Param as Param, Local as Local } from "@ohos.arkui.stat } @ComponentV2() export interface __Options_Child { - index?: number; + @Param() index?: number; @Param() __backing_index?: number; - changeIndex?: ((val: number)=> void); - testEvent?: ((val: number)=> number); - testEvent2?: ((val: number)=> number); + @Event() changeIndex?: ((val: number)=> void); + @Event() testEvent?: ((val: number)=> number); + @Event() testEvent2?: ((val: number)=> number); } @ComponentV2() export interface __Options_Index { - index?: number; + @Local() index?: number; @Local() __backing_index?: number; } @@ -231,28 +231,28 @@ function main() {} } @ComponentV2() export interface __Options_Child { - set index(index: (number | undefined)) + @Param() set index(index: (number | undefined)) - get index(): (number | undefined) + @Param() get index(): (number | undefined) set __backing_index(__backing_index: (IParamDecoratedVariable | undefined)) get __backing_index(): (IParamDecoratedVariable | undefined) - set changeIndex(changeIndex: (((val: number)=> void) | undefined)) + @Event() set changeIndex(changeIndex: (((val: number)=> void) | undefined)) - get changeIndex(): (((val: number)=> void) | undefined) - set testEvent(testEvent: (((val: number)=> number) | undefined)) + @Event() get changeIndex(): (((val: number)=> void) | undefined) + @Event() set testEvent(testEvent: (((val: number)=> number) | undefined)) - get testEvent(): (((val: number)=> number) | undefined) - set testEvent2(testEvent2: (((val: number)=> number) | undefined)) + @Event() get testEvent(): (((val: number)=> number) | undefined) + @Event() set testEvent2(testEvent2: (((val: number)=> number) | undefined)) - get testEvent2(): (((val: number)=> number) | undefined) + @Event() get testEvent2(): (((val: number)=> number) | undefined) } @ComponentV2() export interface __Options_Index { - set index(index: (number | undefined)) + @Local() set index(index: (number | undefined)) - get index(): (number | undefined) + @Local() get index(): (number | undefined) set __backing_index(__backing_index: (ILocalDecoratedVariable | undefined)) get __backing_index(): (ILocalDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/link/link-basic-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/link/link-basic-type.test.ts index 62f3f08e27f76c430231a30a6d20cc892a51c2c8..d0e8eb280d53da4affefbb8e212fb70d0a574246 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/link/link-basic-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/link/link-basic-type.test.ts @@ -140,36 +140,34 @@ function main() {} } -@Retention({policy:"SOURCE"}) @interface __Link_intrinsic {} - @Component() export interface __Options_LinkParent { - @__Link_intrinsic() set linkVar1(linkVar1: (string | undefined)) + @Link() set linkVar1(linkVar1: (string | undefined)) - @__Link_intrinsic() get linkVar1(): (string | undefined) + @Link() get linkVar1(): (string | undefined) set __backing_linkVar1(__backing_linkVar1: (LinkSourceType | undefined)) get __backing_linkVar1(): (LinkSourceType | undefined) - @__Link_intrinsic() set linkVar2(linkVar2: (number | undefined)) + @Link() set linkVar2(linkVar2: (number | undefined)) - @__Link_intrinsic() get linkVar2(): (number | undefined) + @Link() get linkVar2(): (number | undefined) set __backing_linkVar2(__backing_linkVar2: (LinkSourceType | undefined)) get __backing_linkVar2(): (LinkSourceType | undefined) - @__Link_intrinsic() set linkVar3(linkVar3: (boolean | undefined)) + @Link() set linkVar3(linkVar3: (boolean | undefined)) - @__Link_intrinsic() get linkVar3(): (boolean | undefined) + @Link() get linkVar3(): (boolean | undefined) set __backing_linkVar3(__backing_linkVar3: (LinkSourceType | undefined)) get __backing_linkVar3(): (LinkSourceType | undefined) - @__Link_intrinsic() set linkVar4(linkVar4: (undefined | undefined)) + @Link() set linkVar4(linkVar4: (undefined | undefined)) - @__Link_intrinsic() get linkVar4(): (undefined | undefined) + @Link() get linkVar4(): (undefined | undefined) set __backing_linkVar4(__backing_linkVar4: (LinkSourceType | undefined)) get __backing_linkVar4(): (LinkSourceType | undefined) - @__Link_intrinsic() set linkVar5(linkVar5: (null | undefined)) + @Link() set linkVar5(linkVar5: (null | undefined)) - @__Link_intrinsic() get linkVar5(): (null | undefined) + @Link() get linkVar5(): (null | undefined) set __backing_linkVar5(__backing_linkVar5: (LinkSourceType | undefined)) get __backing_linkVar5(): (LinkSourceType | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/link/link-complex-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/link/link-complex-type.test.ts index bd0b32e4b72f4d01a753769b9853aa684b66ba16..8eaa4a762fdf49b10f52076e72a54cbdc7d8fe13 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/link/link-complex-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/link/link-complex-type.test.ts @@ -312,78 +312,76 @@ final class LinkType extends BaseEnum { } -@Retention({policy:"SOURCE"}) @interface __Link_intrinsic {} - @Component() export interface __Options_Parent { - @__Link_intrinsic() set linkVar1(linkVar1: (Per | undefined)) + @Link() set linkVar1(linkVar1: (Per | undefined)) - @__Link_intrinsic() get linkVar1(): (Per | undefined) + @Link() get linkVar1(): (Per | undefined) set __backing_linkVar1(__backing_linkVar1: (LinkSourceType | undefined)) get __backing_linkVar1(): (LinkSourceType | undefined) - @__Link_intrinsic() set linkVar2(linkVar2: (Array | undefined)) + @Link() set linkVar2(linkVar2: (Array | undefined)) - @__Link_intrinsic() get linkVar2(): (Array | undefined) + @Link() get linkVar2(): (Array | undefined) set __backing_linkVar2(__backing_linkVar2: (LinkSourceType> | undefined)) get __backing_linkVar2(): (LinkSourceType> | undefined) - @__Link_intrinsic() set linkVar3(linkVar3: (LinkType | undefined)) + @Link() set linkVar3(linkVar3: (LinkType | undefined)) - @__Link_intrinsic() get linkVar3(): (LinkType | undefined) + @Link() get linkVar3(): (LinkType | undefined) set __backing_linkVar3(__backing_linkVar3: (LinkSourceType | undefined)) get __backing_linkVar3(): (LinkSourceType | undefined) - @__Link_intrinsic() set linkVar4(linkVar4: (Set | undefined)) + @Link() set linkVar4(linkVar4: (Set | undefined)) - @__Link_intrinsic() get linkVar4(): (Set | undefined) + @Link() get linkVar4(): (Set | undefined) set __backing_linkVar4(__backing_linkVar4: (LinkSourceType> | undefined)) get __backing_linkVar4(): (LinkSourceType> | undefined) - @__Link_intrinsic() set linkVar5(linkVar5: (Array | undefined)) + @Link() set linkVar5(linkVar5: (Array | undefined)) - @__Link_intrinsic() get linkVar5(): (Array | undefined) + @Link() get linkVar5(): (Array | undefined) set __backing_linkVar5(__backing_linkVar5: (LinkSourceType> | undefined)) get __backing_linkVar5(): (LinkSourceType> | undefined) - @__Link_intrinsic() set linkVar6(linkVar6: (Array | undefined)) + @Link() set linkVar6(linkVar6: (Array | undefined)) - @__Link_intrinsic() get linkVar6(): (Array | undefined) + @Link() get linkVar6(): (Array | undefined) set __backing_linkVar6(__backing_linkVar6: (LinkSourceType> | undefined)) get __backing_linkVar6(): (LinkSourceType> | undefined) - @__Link_intrinsic() set linkVar7(linkVar7: (Array | undefined)) + @Link() set linkVar7(linkVar7: (Array | undefined)) - @__Link_intrinsic() get linkVar7(): (Array | undefined) + @Link() get linkVar7(): (Array | undefined) set __backing_linkVar7(__backing_linkVar7: (LinkSourceType> | undefined)) get __backing_linkVar7(): (LinkSourceType> | undefined) - @__Link_intrinsic() set linkVar8(linkVar8: (((sr: string)=> void) | undefined)) + @Link() set linkVar8(linkVar8: (((sr: string)=> void) | undefined)) - @__Link_intrinsic() get linkVar8(): (((sr: string)=> void) | undefined) + @Link() get linkVar8(): (((sr: string)=> void) | undefined) set __backing_linkVar8(__backing_linkVar8: (LinkSourceType<((sr: string)=> void)> | undefined)) get __backing_linkVar8(): (LinkSourceType<((sr: string)=> void)> | undefined) - @__Link_intrinsic() set linkVar9(linkVar9: (Date | undefined)) + @Link() set linkVar9(linkVar9: (Date | undefined)) - @__Link_intrinsic() get linkVar9(): (Date | undefined) + @Link() get linkVar9(): (Date | undefined) set __backing_linkVar9(__backing_linkVar9: (LinkSourceType | undefined)) get __backing_linkVar9(): (LinkSourceType | undefined) - @__Link_intrinsic() set linkVar10(linkVar10: (Map | undefined)) + @Link() set linkVar10(linkVar10: (Map | undefined)) - @__Link_intrinsic() get linkVar10(): (Map | undefined) + @Link() get linkVar10(): (Map | undefined) set __backing_linkVar10(__backing_linkVar10: (LinkSourceType> | undefined)) get __backing_linkVar10(): (LinkSourceType> | undefined) - @__Link_intrinsic() set linkVar11(linkVar11: ((string | number) | undefined)) + @Link() set linkVar11(linkVar11: ((string | number) | undefined)) - @__Link_intrinsic() get linkVar11(): ((string | number) | undefined) + @Link() get linkVar11(): ((string | number) | undefined) set __backing_linkVar11(__backing_linkVar11: (LinkSourceType<(string | number)> | undefined)) get __backing_linkVar11(): (LinkSourceType<(string | number)> | undefined) - @__Link_intrinsic() set linkVar12(linkVar12: ((Set | Per) | undefined)) + @Link() set linkVar12(linkVar12: ((Set | Per) | undefined)) - @__Link_intrinsic() get linkVar12(): ((Set | Per) | undefined) + @Link() get linkVar12(): ((Set | Per) | undefined) set __backing_linkVar12(__backing_linkVar12: (LinkSourceType<(Set | Per)> | undefined)) get __backing_linkVar12(): (LinkSourceType<(Set | Per)> | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/link/link-to-link-prop-state.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/link/link-to-link-prop-state.test.ts index 0e3f56d43115cfb37be93a9c3f17f9cd1dcaff34..3ef198fa2f04ac25c3dd9ddf9b289bf9aa992a98 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/link/link-to-link-prop-state.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/link/link-to-link-prop-state.test.ts @@ -173,12 +173,10 @@ function main() {} } -@Retention({policy:"SOURCE"}) @interface __Link_intrinsic {} - @Component() export interface __Options_Parant { - @__Link_intrinsic() set text1(text1: (string | undefined)) + @Link() set text1(text1: (string | undefined)) - @__Link_intrinsic() get text1(): (string | undefined) + @Link() get text1(): (string | undefined) set __backing_text1(__backing_text1: (LinkSourceType | undefined)) get __backing_text1(): (LinkSourceType | undefined) @@ -186,27 +184,27 @@ function main() {} } @Component() export interface __Options_Child { - @__Link_intrinsic() set childText(childText: (string | undefined)) + @Link() set childText(childText: (string | undefined)) - @__Link_intrinsic() get childText(): (string | undefined) + @Link() get childText(): (string | undefined) set __backing_childText(__backing_childText: (LinkSourceType | undefined)) get __backing_childText(): (LinkSourceType | undefined) - set childText2(childText2: (string | undefined)) + @State() set childText2(childText2: (string | undefined)) - get childText2(): (string | undefined) + @State() get childText2(): (string | undefined) set __backing_childText2(__backing_childText2: (IStateDecoratedVariable | undefined)) get __backing_childText2(): (IStateDecoratedVariable | undefined) - set childText3(childText3: (string | undefined)) + @Prop() set childText3(childText3: (string | undefined)) - get childText3(): (string | undefined) + @Prop() get childText3(): (string | undefined) set __backing_childText3(__backing_childText3: (IPropDecoratedVariable | undefined)) get __backing_childText3(): (IPropDecoratedVariable | undefined) - set childText4(childText4: (string | undefined)) + @Prop() set childText4(childText4: (string | undefined)) - get childText4(): (string | undefined) + @Prop() get childText4(): (string | undefined) set __backing_childText4(__backing_childText4: (IPropDecoratedVariable | undefined)) get __backing_childText4(): (IPropDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/link/state-to-link.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/link/state-to-link.test.ts index 8f4d4fa0ed7fd3d1a10e5891a37b6dfbca88de74..d39b4527b570a6e45b17a9290dce204232cdadd3 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/link/state-to-link.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/link/state-to-link.test.ts @@ -168,12 +168,10 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ } -@Retention({policy:"SOURCE"}) @interface __Link_intrinsic {} - @Component() export interface __Options_DateComponent { - @__Link_intrinsic() set selectedDate(selectedDate: (Date | undefined)) + @Link() set selectedDate(selectedDate: (Date | undefined)) - @__Link_intrinsic() get selectedDate(): (Date | undefined) + @Link() get selectedDate(): (Date | undefined) set __backing_selectedDate(__backing_selectedDate: (LinkSourceType | undefined)) get __backing_selectedDate(): (LinkSourceType | undefined) @@ -181,9 +179,9 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ } @Entry({useSharedStorage:false,storage:"",routeName:""}) @Component() export interface __Options_ParentComponent { - set parentSelectedDate(parentSelectedDate: (Date | undefined)) + @State() set parentSelectedDate(parentSelectedDate: (Date | undefined)) - get parentSelectedDate(): (Date | undefined) + @State() get parentSelectedDate(): (Date | undefined) set __backing_parentSelectedDate(__backing_parentSelectedDate: (IStateDecoratedVariable | undefined)) get __backing_parentSelectedDate(): (IStateDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/local/local-basic-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/local/local-basic-type.test.ts index eeda2f5dca0c88481da1a85f83b3aacac5e6a1aa..2f069b5838842791674daa6009c152bd1e855f0a 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/local/local-basic-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/local/local-basic-type.test.ts @@ -120,33 +120,33 @@ function main() {} } @ComponentV2() export interface __Options_Parent { - set localVar1(localVar1: (string | undefined)) + @Local() set localVar1(localVar1: (string | undefined)) - get localVar1(): (string | undefined) + @Local() get localVar1(): (string | undefined) set __backing_localVar1(__backing_localVar1: (ILocalDecoratedVariable | undefined)) get __backing_localVar1(): (ILocalDecoratedVariable | undefined) - set localVar2(localVar2: (number | undefined)) + @Local() set localVar2(localVar2: (number | undefined)) - get localVar2(): (number | undefined) + @Local() get localVar2(): (number | undefined) set __backing_localVar2(__backing_localVar2: (ILocalDecoratedVariable | undefined)) get __backing_localVar2(): (ILocalDecoratedVariable | undefined) - set localVar3(localVar3: (boolean | undefined)) + @Local() set localVar3(localVar3: (boolean | undefined)) - get localVar3(): (boolean | undefined) + @Local() get localVar3(): (boolean | undefined) set __backing_localVar3(__backing_localVar3: (ILocalDecoratedVariable | undefined)) get __backing_localVar3(): (ILocalDecoratedVariable | undefined) - set localVar4(localVar4: (undefined | undefined)) + @Local() set localVar4(localVar4: (undefined | undefined)) - get localVar4(): (undefined | undefined) + @Local() get localVar4(): (undefined | undefined) set __backing_localVar4(__backing_localVar4: (ILocalDecoratedVariable | undefined)) get __backing_localVar4(): (ILocalDecoratedVariable | undefined) - set localVar5(localVar5: (null | undefined)) + @Local() set localVar5(localVar5: (null | undefined)) - get localVar5(): (null | undefined) + @Local() get localVar5(): (null | undefined) set __backing_localVar5(__backing_localVar5: (ILocalDecoratedVariable | undefined)) get __backing_localVar5(): (ILocalDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/local/local-complex-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/local/local-complex-type.test.ts index 7ccf7f48e757eddc2d8e65fdcf9614d9e9e4bd83..9ce63c340d30c2619517a96ac5ea4bb3e16d71d0 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/local/local-complex-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/local/local-complex-type.test.ts @@ -263,69 +263,69 @@ final class StateType extends BaseEnum { } @ComponentV2() export interface __Options_Parent { - set localVar1(localVar1: (Per | undefined)) + @Local() set localVar1(localVar1: (Per | undefined)) - get localVar1(): (Per | undefined) + @Local() get localVar1(): (Per | undefined) set __backing_localVar1(__backing_localVar1: (ILocalDecoratedVariable | undefined)) get __backing_localVar1(): (ILocalDecoratedVariable | undefined) - set localVar2(localVar2: (Array | undefined)) + @Local() set localVar2(localVar2: (Array | undefined)) - get localVar2(): (Array | undefined) + @Local() get localVar2(): (Array | undefined) set __backing_localVar2(__backing_localVar2: (ILocalDecoratedVariable> | undefined)) get __backing_localVar2(): (ILocalDecoratedVariable> | undefined) - set localVar3(localVar3: (StateType | undefined)) + @Local() set localVar3(localVar3: (StateType | undefined)) - get localVar3(): (StateType | undefined) + @Local() get localVar3(): (StateType | undefined) set __backing_localVar3(__backing_localVar3: (ILocalDecoratedVariable | undefined)) get __backing_localVar3(): (ILocalDecoratedVariable | undefined) - set localVar4(localVar4: (Set | undefined)) + @Local() set localVar4(localVar4: (Set | undefined)) - get localVar4(): (Set | undefined) + @Local() get localVar4(): (Set | undefined) set __backing_localVar4(__backing_localVar4: (ILocalDecoratedVariable> | undefined)) get __backing_localVar4(): (ILocalDecoratedVariable> | undefined) - set localVar5(localVar5: (Array | undefined)) + @Local() set localVar5(localVar5: (Array | undefined)) - get localVar5(): (Array | undefined) + @Local() get localVar5(): (Array | undefined) set __backing_localVar5(__backing_localVar5: (ILocalDecoratedVariable> | undefined)) get __backing_localVar5(): (ILocalDecoratedVariable> | undefined) - set localVar6(localVar6: (Array | undefined)) + @Local() set localVar6(localVar6: (Array | undefined)) - get localVar6(): (Array | undefined) + @Local() get localVar6(): (Array | undefined) set __backing_localVar6(__backing_localVar6: (ILocalDecoratedVariable> | undefined)) get __backing_localVar6(): (ILocalDecoratedVariable> | undefined) - set localVar7(localVar7: (Array | undefined)) + @Local() set localVar7(localVar7: (Array | undefined)) - get localVar7(): (Array | undefined) + @Local() get localVar7(): (Array | undefined) set __backing_localVar7(__backing_localVar7: (ILocalDecoratedVariable> | undefined)) get __backing_localVar7(): (ILocalDecoratedVariable> | undefined) - set localVar9(localVar9: (Date | undefined)) + @Local() set localVar9(localVar9: (Date | undefined)) - get localVar9(): (Date | undefined) + @Local() get localVar9(): (Date | undefined) set __backing_localVar9(__backing_localVar9: (ILocalDecoratedVariable | undefined)) get __backing_localVar9(): (ILocalDecoratedVariable | undefined) - set localVar10(localVar10: (Map | undefined)) + @Local() set localVar10(localVar10: (Map | undefined)) - get localVar10(): (Map | undefined) + @Local() get localVar10(): (Map | undefined) set __backing_localVar10(__backing_localVar10: (ILocalDecoratedVariable> | undefined)) get __backing_localVar10(): (ILocalDecoratedVariable> | undefined) - set localVar11(localVar11: ((string | number) | undefined)) + @Local() set localVar11(localVar11: ((string | number) | undefined)) - get localVar11(): ((string | number) | undefined) + @Local() get localVar11(): ((string | number) | undefined) set __backing_localVar11(__backing_localVar11: (ILocalDecoratedVariable<(string | number)> | undefined)) get __backing_localVar11(): (ILocalDecoratedVariable<(string | number)> | undefined) - set localVar12(localVar12: ((Set | Per) | undefined)) + @Local() set localVar12(localVar12: ((Set | Per) | undefined)) - get localVar12(): ((Set | Per) | undefined) + @Local() get localVar12(): ((Set | Per) | undefined) set __backing_localVar12(__backing_localVar12: (ILocalDecoratedVariable<(Set | Per)> | undefined)) get __backing_localVar12(): (ILocalDecoratedVariable<(Set | Per)> | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/localstoragelink/localstoragelink-complex-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/localstoragelink/localstoragelink-complex-type.test.ts index f3261d45b4f8c097370762ecc847656be7447d94..feb8068365c98b01fcdd1877a08b76083fbd4e12 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/localstoragelink/localstoragelink-complex-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/localstoragelink/localstoragelink-complex-type.test.ts @@ -233,45 +233,45 @@ final class Status extends BaseEnum { } @Entry({useSharedStorage:false,storage:"",routeName:""}) @Component() export interface __Options_MyStateSample { - set arrayA(arrayA: (Array | undefined)) + @LocalStorageLink({value:"Prop1"}) set arrayA(arrayA: (Array | undefined)) - get arrayA(): (Array | undefined) + @LocalStorageLink({value:"Prop1"}) get arrayA(): (Array | undefined) set __backing_arrayA(__backing_arrayA: (ILocalStorageLinkDecoratedVariable> | undefined)) get __backing_arrayA(): (ILocalStorageLinkDecoratedVariable> | undefined) - set objectA(objectA: (Object | undefined)) + @LocalStorageLink({value:"Prop2"}) set objectA(objectA: (Object | undefined)) - get objectA(): (Object | undefined) + @LocalStorageLink({value:"Prop2"}) get objectA(): (Object | undefined) set __backing_objectA(__backing_objectA: (ILocalStorageLinkDecoratedVariable | undefined)) get __backing_objectA(): (ILocalStorageLinkDecoratedVariable | undefined) - set dateA(dateA: (Date | undefined)) + @LocalStorageLink({value:"Prop3"}) set dateA(dateA: (Date | undefined)) - get dateA(): (Date | undefined) + @LocalStorageLink({value:"Prop3"}) get dateA(): (Date | undefined) set __backing_dateA(__backing_dateA: (ILocalStorageLinkDecoratedVariable | undefined)) get __backing_dateA(): (ILocalStorageLinkDecoratedVariable | undefined) - set setA(setA: (Set | undefined)) + @LocalStorageLink({value:"Prop4"}) set setA(setA: (Set | undefined)) - get setA(): (Set | undefined) + @LocalStorageLink({value:"Prop4"}) get setA(): (Set | undefined) set __backing_setA(__backing_setA: (ILocalStorageLinkDecoratedVariable> | undefined)) get __backing_setA(): (ILocalStorageLinkDecoratedVariable> | undefined) - set mapA(mapA: (Map | undefined)) + @LocalStorageLink({value:"Prop5"}) set mapA(mapA: (Map | undefined)) - get mapA(): (Map | undefined) + @LocalStorageLink({value:"Prop5"}) get mapA(): (Map | undefined) set __backing_mapA(__backing_mapA: (ILocalStorageLinkDecoratedVariable> | undefined)) get __backing_mapA(): (ILocalStorageLinkDecoratedVariable> | undefined) - set classA(classA: (Person | undefined)) + @LocalStorageLink({value:"Prop7"}) set classA(classA: (Person | undefined)) - get classA(): (Person | undefined) + @LocalStorageLink({value:"Prop7"}) get classA(): (Person | undefined) set __backing_classA(__backing_classA: (ILocalStorageLinkDecoratedVariable | undefined)) get __backing_classA(): (ILocalStorageLinkDecoratedVariable | undefined) - set enumA(enumA: (Status | undefined)) + @LocalStorageLink({value:"Prop8"}) set enumA(enumA: (Status | undefined)) - get enumA(): (Status | undefined) + @LocalStorageLink({value:"Prop8"}) get enumA(): (Status | undefined) set __backing_enumA(__backing_enumA: (ILocalStorageLinkDecoratedVariable | undefined)) get __backing_enumA(): (ILocalStorageLinkDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/localstoragelink/localstoragelink-primitive-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/localstoragelink/localstoragelink-primitive-type.test.ts index 507a09fe3d75d67e8d764c668abc4245a9f9c5a0..9473dc5bbeb62341e3925d1b16dd906170fffb33 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/localstoragelink/localstoragelink-primitive-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/localstoragelink/localstoragelink-primitive-type.test.ts @@ -113,21 +113,21 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ } @Entry({useSharedStorage:false,storage:"",routeName:""}) @Component() export interface __Options_MyStateSample { - set numA(numA: (number | undefined)) + @LocalStorageLink({value:"Prop1"}) set numA(numA: (number | undefined)) - get numA(): (number | undefined) + @LocalStorageLink({value:"Prop1"}) get numA(): (number | undefined) set __backing_numA(__backing_numA: (ILocalStorageLinkDecoratedVariable | undefined)) get __backing_numA(): (ILocalStorageLinkDecoratedVariable | undefined) - set stringA(stringA: (string | undefined)) + @LocalStorageLink({value:"Prop2"}) set stringA(stringA: (string | undefined)) - get stringA(): (string | undefined) + @LocalStorageLink({value:"Prop2"}) get stringA(): (string | undefined) set __backing_stringA(__backing_stringA: (ILocalStorageLinkDecoratedVariable | undefined)) get __backing_stringA(): (ILocalStorageLinkDecoratedVariable | undefined) - set booleanA(booleanA: (boolean | undefined)) + @LocalStorageLink({value:"Prop3"}) set booleanA(booleanA: (boolean | undefined)) - get booleanA(): (boolean | undefined) + @LocalStorageLink({value:"Prop3"}) get booleanA(): (boolean | undefined) set __backing_booleanA(__backing_booleanA: (ILocalStorageLinkDecoratedVariable | undefined)) get __backing_booleanA(): (ILocalStorageLinkDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/localstorageprop-ref/localstorageprop-ref-complex-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/localstorageprop-ref/localstorageprop-ref-complex-type.test.ts index c52fc362066ff833f4e76fa897b5a051bfc46d4a..0e1071316282c353e1710c26e4a8980f2da09715 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/localstorageprop-ref/localstorageprop-ref-complex-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/localstorageprop-ref/localstorageprop-ref-complex-type.test.ts @@ -217,45 +217,45 @@ final class Status extends BaseEnum { } @Component() export interface __Options_MyStateSample { - set arrayB(arrayB: (Array | undefined)) + @LocalStoragePropRef({value:"Prop1"}) set arrayB(arrayB: (Array | undefined)) - get arrayB(): (Array | undefined) + @LocalStoragePropRef({value:"Prop1"}) get arrayB(): (Array | undefined) set __backing_arrayB(__backing_arrayB: (ILocalStoragePropRefDecoratedVariable> | undefined)) get __backing_arrayB(): (ILocalStoragePropRefDecoratedVariable> | undefined) - set objectB(objectB: (Object | undefined)) + @LocalStoragePropRef({value:"Prop2"}) set objectB(objectB: (Object | undefined)) - get objectB(): (Object | undefined) + @LocalStoragePropRef({value:"Prop2"}) get objectB(): (Object | undefined) set __backing_objectB(__backing_objectB: (ILocalStoragePropRefDecoratedVariable | undefined)) get __backing_objectB(): (ILocalStoragePropRefDecoratedVariable | undefined) - set dateB(dateB: (Date | undefined)) + @LocalStoragePropRef({value:"Prop3"}) set dateB(dateB: (Date | undefined)) - get dateB(): (Date | undefined) + @LocalStoragePropRef({value:"Prop3"}) get dateB(): (Date | undefined) set __backing_dateB(__backing_dateB: (ILocalStoragePropRefDecoratedVariable | undefined)) get __backing_dateB(): (ILocalStoragePropRefDecoratedVariable | undefined) - set setB(setB: (Set | undefined)) + @LocalStoragePropRef({value:"Prop4"}) set setB(setB: (Set | undefined)) - get setB(): (Set | undefined) + @LocalStoragePropRef({value:"Prop4"}) get setB(): (Set | undefined) set __backing_setB(__backing_setB: (ILocalStoragePropRefDecoratedVariable> | undefined)) get __backing_setB(): (ILocalStoragePropRefDecoratedVariable> | undefined) - set mapB(mapB: (Map | undefined)) + @LocalStoragePropRef({value:"Prop5"}) set mapB(mapB: (Map | undefined)) - get mapB(): (Map | undefined) + @LocalStoragePropRef({value:"Prop5"}) get mapB(): (Map | undefined) set __backing_mapB(__backing_mapB: (ILocalStoragePropRefDecoratedVariable> | undefined)) get __backing_mapB(): (ILocalStoragePropRefDecoratedVariable> | undefined) - set classB(classB: (Person | undefined)) + @LocalStoragePropRef({value:"Prop7"}) set classB(classB: (Person | undefined)) - get classB(): (Person | undefined) + @LocalStoragePropRef({value:"Prop7"}) get classB(): (Person | undefined) set __backing_classB(__backing_classB: (ILocalStoragePropRefDecoratedVariable | undefined)) get __backing_classB(): (ILocalStoragePropRefDecoratedVariable | undefined) - set enumB(enumB: (Status | undefined)) + @LocalStoragePropRef({value:"Prop8"}) set enumB(enumB: (Status | undefined)) - get enumB(): (Status | undefined) + @LocalStoragePropRef({value:"Prop8"}) get enumB(): (Status | undefined) set __backing_enumB(__backing_enumB: (ILocalStoragePropRefDecoratedVariable | undefined)) get __backing_enumB(): (ILocalStoragePropRefDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/localstorageprop-ref/localstorageprop-ref-primitive-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/localstorageprop-ref/localstorageprop-ref-primitive-type.test.ts index 14e3191b48bb15d4a35aa56117e1bbb5ce99d84b..08c63f23743aaa3f73b621b51b6553f52ce42511 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/localstorageprop-ref/localstorageprop-ref-primitive-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/localstorageprop-ref/localstorageprop-ref-primitive-type.test.ts @@ -120,33 +120,33 @@ function main() {} } @Component() export interface __Options_MyStateSample { - set numB(numB: (number | undefined)) + @LocalStoragePropRef({value:"Prop1"}) set numB(numB: (number | undefined)) - get numB(): (number | undefined) + @LocalStoragePropRef({value:"Prop1"}) get numB(): (number | undefined) set __backing_numB(__backing_numB: (ILocalStoragePropRefDecoratedVariable | undefined)) get __backing_numB(): (ILocalStoragePropRefDecoratedVariable | undefined) - set stringB(stringB: (string | undefined)) + @LocalStoragePropRef({value:"Prop2"}) set stringB(stringB: (string | undefined)) - get stringB(): (string | undefined) + @LocalStoragePropRef({value:"Prop2"}) get stringB(): (string | undefined) set __backing_stringB(__backing_stringB: (ILocalStoragePropRefDecoratedVariable | undefined)) get __backing_stringB(): (ILocalStoragePropRefDecoratedVariable | undefined) - set booleanB(booleanB: (boolean | undefined)) + @LocalStoragePropRef({value:"Prop3"}) set booleanB(booleanB: (boolean | undefined)) - get booleanB(): (boolean | undefined) + @LocalStoragePropRef({value:"Prop3"}) get booleanB(): (boolean | undefined) set __backing_booleanB(__backing_booleanB: (ILocalStoragePropRefDecoratedVariable | undefined)) get __backing_booleanB(): (ILocalStoragePropRefDecoratedVariable | undefined) - set undefinedB(undefinedB: (undefined | undefined)) + @LocalStoragePropRef({value:"Prop4"}) set undefinedB(undefinedB: (undefined | undefined)) - get undefinedB(): (undefined | undefined) + @LocalStoragePropRef({value:"Prop4"}) get undefinedB(): (undefined | undefined) set __backing_undefinedB(__backing_undefinedB: (ILocalStoragePropRefDecoratedVariable | undefined)) get __backing_undefinedB(): (ILocalStoragePropRefDecoratedVariable | undefined) - set nullB(nullB: (null | undefined)) + @LocalStoragePropRef({value:"Prop5"}) set nullB(nullB: (null | undefined)) - get nullB(): (null | undefined) + @LocalStoragePropRef({value:"Prop5"}) get nullB(): (null | undefined) set __backing_nullB(__backing_nullB: (ILocalStoragePropRefDecoratedVariable | undefined)) get __backing_nullB(): (ILocalStoragePropRefDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/monitor/monitor-in-struct.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/monitor/monitor-in-struct.test.ts index df17928a94392870b457c5ba6e1855a1480b9305..d9a7f54623b7016e4b37b2e982c80d2c0cada10e 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/monitor/monitor-in-struct.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/monitor/monitor-in-struct.test.ts @@ -137,21 +137,21 @@ function main() {} } @ComponentV2() export interface __Options_Index { - set message(message: (string | undefined)) + @Local() set message(message: (string | undefined)) - get message(): (string | undefined) + @Local() get message(): (string | undefined) set __backing_message(__backing_message: (ILocalDecoratedVariable | undefined)) get __backing_message(): (ILocalDecoratedVariable | undefined) - set name(name: (string | undefined)) + @Local() set name(name: (string | undefined)) - get name(): (string | undefined) + @Local() get name(): (string | undefined) set __backing_name(__backing_name: (ILocalDecoratedVariable | undefined)) get __backing_name(): (ILocalDecoratedVariable | undefined) - set age(age: (number | undefined)) + @Local() set age(age: (number | undefined)) - get age(): (number | undefined) + @Local() get age(): (number | undefined) set __backing_age(__backing_age: (ILocalDecoratedVariable | undefined)) get __backing_age(): (ILocalDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/monitor/monitor-params.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/monitor/monitor-params.test.ts index 5a078ffe8d8558225a2707f1e3659681afdba815..98b7e20e87f38404b1be8dddc2304865fc3498c4 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/monitor/monitor-params.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/monitor/monitor-params.test.ts @@ -318,21 +318,21 @@ class GGG { } @ComponentV2() export interface __Options_Index { - set per(per: (EEE | undefined)) + @Local() set per(per: (EEE | undefined)) - get per(): (EEE | undefined) + @Local() get per(): (EEE | undefined) set __backing_per(__backing_per: (ILocalDecoratedVariable | undefined)) get __backing_per(): (ILocalDecoratedVariable | undefined) - set v1(v1: (boolean | undefined)) + @Local() set v1(v1: (boolean | undefined)) - get v1(): (boolean | undefined) + @Local() get v1(): (boolean | undefined) set __backing_v1(__backing_v1: (ILocalDecoratedVariable | undefined)) get __backing_v1(): (ILocalDecoratedVariable | undefined) - set numArr(numArr: (Array | undefined)) + @Local() set numArr(numArr: (Array | undefined)) - get numArr(): (Array | undefined) + @Local() get numArr(): (Array | undefined) set __backing_numArr(__backing_numArr: (ILocalDecoratedVariable> | undefined)) get __backing_numArr(): (ILocalDecoratedVariable> | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/objectlink/objectlink-basic.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/objectlink/objectlink-basic.test.ts index 93377b14bca0bc8882b8cb74ecb4d0508a21ea96..1278aed65ff9ffb2a1ca96f89cea70f9f661c6f3 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/objectlink/objectlink-basic.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/objectlink/objectlink-basic.test.ts @@ -205,9 +205,9 @@ function main() {} } @Component() export interface __Options_MyStateSample { - set objectlinkvar(objectlinkvar: (A | undefined)) + @ObjectLink() set objectlinkvar(objectlinkvar: (A | undefined)) - get objectlinkvar(): (A | undefined) + @ObjectLink() get objectlinkvar(): (A | undefined) set __backing_objectlinkvar(__backing_objectlinkvar: (IObjectLinkDecoratedVariable | undefined)) get __backing_objectlinkvar(): (IObjectLinkDecoratedVariable | undefined) @@ -215,21 +215,21 @@ function main() {} } @Component() export interface __Options_MyStateSample2 { - set objectlinkvar1(objectlinkvar1: ((A | undefined) | undefined)) + @ObjectLink() set objectlinkvar1(objectlinkvar1: ((A | undefined) | undefined)) - get objectlinkvar1(): ((A | undefined) | undefined) + @ObjectLink() get objectlinkvar1(): ((A | undefined) | undefined) set __backing_objectlinkvar1(__backing_objectlinkvar1: (IObjectLinkDecoratedVariable<(A | undefined)> | undefined)) get __backing_objectlinkvar1(): (IObjectLinkDecoratedVariable<(A | undefined)> | undefined) - set objectlinkvar2(objectlinkvar2: ((A | B) | undefined)) + @ObjectLink() set objectlinkvar2(objectlinkvar2: ((A | B) | undefined)) - get objectlinkvar2(): ((A | B) | undefined) + @ObjectLink() get objectlinkvar2(): ((A | B) | undefined) set __backing_objectlinkvar2(__backing_objectlinkvar2: (IObjectLinkDecoratedVariable<(A | B)> | undefined)) get __backing_objectlinkvar2(): (IObjectLinkDecoratedVariable<(A | B)> | undefined) - set objectlinkvar3(objectlinkvar3: ((A | B | null) | undefined)) + @ObjectLink() set objectlinkvar3(objectlinkvar3: ((A | B | null) | undefined)) - get objectlinkvar3(): ((A | B | null) | undefined) + @ObjectLink() get objectlinkvar3(): ((A | B | null) | undefined) set __backing_objectlinkvar3(__backing_objectlinkvar3: (IObjectLinkDecoratedVariable<(A | B | null)> | undefined)) get __backing_objectlinkvar3(): (IObjectLinkDecoratedVariable<(A | B | null)> | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/objectlink/objectlink-observed.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/objectlink/objectlink-observed.test.ts index 79774185eaecbc99a8a06a1c4313490357dd1296..c8b983f38dc2d004ff52a079959b60901543fbc1 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/objectlink/objectlink-observed.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/objectlink/objectlink-observed.test.ts @@ -263,9 +263,9 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ set label(label: (string | undefined)) get label(): (string | undefined) - set data(data: (DateClass | undefined)) + @ObjectLink() set data(data: (DateClass | undefined)) - get data(): (DateClass | undefined) + @ObjectLink() get data(): (DateClass | undefined) set __backing_data(__backing_data: (IObjectLinkDecoratedVariable | undefined)) get __backing_data(): (IObjectLinkDecoratedVariable | undefined) @@ -273,9 +273,9 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ } @Entry({useSharedStorage:false,storage:"",routeName:""}) @Component() export interface __Options_Parent { - set newData(newData: (NewDate | undefined)) + @State() set newData(newData: (NewDate | undefined)) - get newData(): (NewDate | undefined) + @State() get newData(): (NewDate | undefined) set __backing_newData(__backing_newData: (IStateDecoratedVariable | undefined)) get __backing_newData(): (IStateDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/once/once-basic-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/once/once-basic-type.test.ts index 1b5cc3d482ffeb64469978e0bafb4d98a38de3e3..4c6badfcb943826364e1a6e278502c1c0abb38a5 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/once/once-basic-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/once/once-basic-type.test.ts @@ -127,36 +127,36 @@ function main() {} } @ComponentV2() export interface __Options_Parent { - set onceVar1(onceVar1: (string | undefined)) + @Param() @Once() set onceVar1(onceVar1: (string | undefined)) - get onceVar1(): (string | undefined) - @Param() set __backing_onceVar1(__backing_onceVar1: (IParamOnceDecoratedVariable | undefined)) + @Param() @Once() get onceVar1(): (string | undefined) + set __backing_onceVar1(__backing_onceVar1: (IParamOnceDecoratedVariable | undefined)) - @Param() get __backing_onceVar1(): (IParamOnceDecoratedVariable | undefined) - set onceVar2(onceVar2: (number | undefined)) + get __backing_onceVar1(): (IParamOnceDecoratedVariable | undefined) + @Param() @Once() set onceVar2(onceVar2: (number | undefined)) - get onceVar2(): (number | undefined) - @Param() set __backing_onceVar2(__backing_onceVar2: (IParamOnceDecoratedVariable | undefined)) + @Param() @Once() get onceVar2(): (number | undefined) + set __backing_onceVar2(__backing_onceVar2: (IParamOnceDecoratedVariable | undefined)) - @Param() get __backing_onceVar2(): (IParamOnceDecoratedVariable | undefined) - set onceVar3(onceVar3: (boolean | undefined)) + get __backing_onceVar2(): (IParamOnceDecoratedVariable | undefined) + @Param() @Once() set onceVar3(onceVar3: (boolean | undefined)) - get onceVar3(): (boolean | undefined) - @Param() set __backing_onceVar3(__backing_onceVar3: (IParamOnceDecoratedVariable | undefined)) + @Param() @Once() get onceVar3(): (boolean | undefined) + set __backing_onceVar3(__backing_onceVar3: (IParamOnceDecoratedVariable | undefined)) - @Param() get __backing_onceVar3(): (IParamOnceDecoratedVariable | undefined) - set onceVar4(onceVar4: (undefined | undefined)) + get __backing_onceVar3(): (IParamOnceDecoratedVariable | undefined) + @Param() @Once() set onceVar4(onceVar4: (undefined | undefined)) - get onceVar4(): (undefined | undefined) - @Param() set __backing_onceVar4(__backing_onceVar4: (IParamOnceDecoratedVariable | undefined)) + @Param() @Once() get onceVar4(): (undefined | undefined) + set __backing_onceVar4(__backing_onceVar4: (IParamOnceDecoratedVariable | undefined)) - @Param() get __backing_onceVar4(): (IParamOnceDecoratedVariable | undefined) - set onceVar5(onceVar5: (null | undefined)) + get __backing_onceVar4(): (IParamOnceDecoratedVariable | undefined) + @Param() @Once() set onceVar5(onceVar5: (null | undefined)) - get onceVar5(): (null | undefined) - @Param() set __backing_onceVar5(__backing_onceVar5: (IParamOnceDecoratedVariable | undefined)) + @Param() @Once() get onceVar5(): (null | undefined) + set __backing_onceVar5(__backing_onceVar5: (IParamOnceDecoratedVariable | undefined)) - @Param() get __backing_onceVar5(): (IParamOnceDecoratedVariable | undefined) + get __backing_onceVar5(): (IParamOnceDecoratedVariable | undefined) } `; diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/once/once-complex-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/once/once-complex-type.test.ts index 0b9a8561a908c5c8821d3185f5d0b210fd9f67a2..4a7fd7bc002fffc5d3081f2083b5aab6cf4aea44 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/once/once-complex-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/once/once-complex-type.test.ts @@ -286,78 +286,78 @@ final class StateType extends BaseEnum { } @ComponentV2() export interface __Options_Parent { - set onceVar1(onceVar1: (Per | undefined)) + @Param() @Once() set onceVar1(onceVar1: (Per | undefined)) - get onceVar1(): (Per | undefined) - @Param() set __backing_onceVar1(__backing_onceVar1: (IParamOnceDecoratedVariable | undefined)) + @Param() @Once() get onceVar1(): (Per | undefined) + set __backing_onceVar1(__backing_onceVar1: (IParamOnceDecoratedVariable | undefined)) - @Param() get __backing_onceVar1(): (IParamOnceDecoratedVariable | undefined) - set onceVar2(onceVar2: (Array | undefined)) + get __backing_onceVar1(): (IParamOnceDecoratedVariable | undefined) + @Param() @Once() set onceVar2(onceVar2: (Array | undefined)) - get onceVar2(): (Array | undefined) - @Param() set __backing_onceVar2(__backing_onceVar2: (IParamOnceDecoratedVariable> | undefined)) + @Param() @Once() get onceVar2(): (Array | undefined) + set __backing_onceVar2(__backing_onceVar2: (IParamOnceDecoratedVariable> | undefined)) - @Param() get __backing_onceVar2(): (IParamOnceDecoratedVariable> | undefined) - set onceVar3(onceVar3: (StateType | undefined)) + get __backing_onceVar2(): (IParamOnceDecoratedVariable> | undefined) + @Param() @Once() set onceVar3(onceVar3: (StateType | undefined)) - get onceVar3(): (StateType | undefined) - @Param() set __backing_onceVar3(__backing_onceVar3: (IParamOnceDecoratedVariable | undefined)) + @Param() @Once() get onceVar3(): (StateType | undefined) + set __backing_onceVar3(__backing_onceVar3: (IParamOnceDecoratedVariable | undefined)) - @Param() get __backing_onceVar3(): (IParamOnceDecoratedVariable | undefined) - set onceVar4(onceVar4: (Set | undefined)) + get __backing_onceVar3(): (IParamOnceDecoratedVariable | undefined) + @Param() @Once() set onceVar4(onceVar4: (Set | undefined)) - get onceVar4(): (Set | undefined) - @Param() set __backing_onceVar4(__backing_onceVar4: (IParamOnceDecoratedVariable> | undefined)) + @Param() @Once() get onceVar4(): (Set | undefined) + set __backing_onceVar4(__backing_onceVar4: (IParamOnceDecoratedVariable> | undefined)) - @Param() get __backing_onceVar4(): (IParamOnceDecoratedVariable> | undefined) - set onceVar5(onceVar5: (Array | undefined)) + get __backing_onceVar4(): (IParamOnceDecoratedVariable> | undefined) + @Param() @Once() set onceVar5(onceVar5: (Array | undefined)) - get onceVar5(): (Array | undefined) - @Param() set __backing_onceVar5(__backing_onceVar5: (IParamOnceDecoratedVariable> | undefined)) + @Param() @Once() get onceVar5(): (Array | undefined) + set __backing_onceVar5(__backing_onceVar5: (IParamOnceDecoratedVariable> | undefined)) - @Param() get __backing_onceVar5(): (IParamOnceDecoratedVariable> | undefined) - set onceVar6(onceVar6: (Array | undefined)) + get __backing_onceVar5(): (IParamOnceDecoratedVariable> | undefined) + @Param() @Once() set onceVar6(onceVar6: (Array | undefined)) - get onceVar6(): (Array | undefined) - @Param() set __backing_onceVar6(__backing_onceVar6: (IParamOnceDecoratedVariable> | undefined)) + @Param() @Once() get onceVar6(): (Array | undefined) + set __backing_onceVar6(__backing_onceVar6: (IParamOnceDecoratedVariable> | undefined)) - @Param() get __backing_onceVar6(): (IParamOnceDecoratedVariable> | undefined) - set onceVar7(onceVar7: (Array | undefined)) + get __backing_onceVar6(): (IParamOnceDecoratedVariable> | undefined) + @Param() @Once() set onceVar7(onceVar7: (Array | undefined)) - get onceVar7(): (Array | undefined) - @Param() set __backing_onceVar7(__backing_onceVar7: (IParamOnceDecoratedVariable> | undefined)) + @Param() @Once() get onceVar7(): (Array | undefined) + set __backing_onceVar7(__backing_onceVar7: (IParamOnceDecoratedVariable> | undefined)) - @Param() get __backing_onceVar7(): (IParamOnceDecoratedVariable> | undefined) - set onceVar8(onceVar8: (((sr: string)=> void) | undefined)) + get __backing_onceVar7(): (IParamOnceDecoratedVariable> | undefined) + @Param() @Once() set onceVar8(onceVar8: (((sr: string)=> void) | undefined)) - get onceVar8(): (((sr: string)=> void) | undefined) - @Param() set __backing_onceVar8(__backing_onceVar8: (IParamOnceDecoratedVariable<((sr: string)=> void)> | undefined)) + @Param() @Once() get onceVar8(): (((sr: string)=> void) | undefined) + set __backing_onceVar8(__backing_onceVar8: (IParamOnceDecoratedVariable<((sr: string)=> void)> | undefined)) - @Param() get __backing_onceVar8(): (IParamOnceDecoratedVariable<((sr: string)=> void)> | undefined) - set onceVar9(onceVar9: (Date | undefined)) + get __backing_onceVar8(): (IParamOnceDecoratedVariable<((sr: string)=> void)> | undefined) + @Param() @Once() set onceVar9(onceVar9: (Date | undefined)) - get onceVar9(): (Date | undefined) - @Param() set __backing_onceVar9(__backing_onceVar9: (IParamOnceDecoratedVariable | undefined)) + @Param() @Once() get onceVar9(): (Date | undefined) + set __backing_onceVar9(__backing_onceVar9: (IParamOnceDecoratedVariable | undefined)) - @Param() get __backing_onceVar9(): (IParamOnceDecoratedVariable | undefined) - set onceVar10(onceVar10: (Map | undefined)) + get __backing_onceVar9(): (IParamOnceDecoratedVariable | undefined) + @Param() @Once() set onceVar10(onceVar10: (Map | undefined)) - get onceVar10(): (Map | undefined) - @Param() set __backing_onceVar10(__backing_onceVar10: (IParamOnceDecoratedVariable> | undefined)) + @Param() @Once() get onceVar10(): (Map | undefined) + set __backing_onceVar10(__backing_onceVar10: (IParamOnceDecoratedVariable> | undefined)) - @Param() get __backing_onceVar10(): (IParamOnceDecoratedVariable> | undefined) - set onceVar11(onceVar11: ((string | number) | undefined)) + get __backing_onceVar10(): (IParamOnceDecoratedVariable> | undefined) + @Param() @Once() set onceVar11(onceVar11: ((string | number) | undefined)) - get onceVar11(): ((string | number) | undefined) - @Param() set __backing_onceVar11(__backing_onceVar11: (IParamOnceDecoratedVariable<(string | number)> | undefined)) + @Param() @Once() get onceVar11(): ((string | number) | undefined) + set __backing_onceVar11(__backing_onceVar11: (IParamOnceDecoratedVariable<(string | number)> | undefined)) - @Param() get __backing_onceVar11(): (IParamOnceDecoratedVariable<(string | number)> | undefined) - set onceVar12(onceVar12: ((Set | Per) | undefined)) + get __backing_onceVar11(): (IParamOnceDecoratedVariable<(string | number)> | undefined) + @Param() @Once() set onceVar12(onceVar12: ((Set | Per) | undefined)) - get onceVar12(): ((Set | Per) | undefined) - @Param() set __backing_onceVar12(__backing_onceVar12: (IParamOnceDecoratedVariable<(Set | Per)> | undefined)) + @Param() @Once() get onceVar12(): ((Set | Per) | undefined) + set __backing_onceVar12(__backing_onceVar12: (IParamOnceDecoratedVariable<(Set | Per)> | undefined)) - @Param() get __backing_onceVar12(): (IParamOnceDecoratedVariable<(Set | Per)> | undefined) + get __backing_onceVar12(): (IParamOnceDecoratedVariable<(Set | Per)> | undefined) } `; diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/once/once-with-require.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/once/once-with-require.test.ts index 98dd8f1286ec7e1b17eb676f87c0e8760139ebd5..d80a9719eeb5ba3de588a346a16e1a416dd3fadf 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/once/once-with-require.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/once/once-with-require.test.ts @@ -91,17 +91,17 @@ import { Param as Param, Once as Once, ObservedV2 as ObservedV2, Trace as Trace, } @ComponentV2() export interface __Options_Child { - onceParamNum?: number; - @Once() @Param() __backing_onceParamNum?: number; - onceParamInfo?: Info; - @Once() @Param() __backing_onceParamInfo?: Info; + @Param() @Once() onceParamNum?: number; + @Param() @Once() __backing_onceParamNum?: number; + @Param() @Once() @Require() onceParamInfo?: Info; + @Param() @Once() __backing_onceParamInfo?: Info; } @ComponentV2() export interface __Options_Index { - localNum?: number; + @Local() localNum?: number; @Local() __backing_localNum?: number; - localInfo?: Info; + @Local() localInfo?: Info; @Local() __backing_localInfo?: Info; } @@ -274,31 +274,31 @@ function main() {} } @ComponentV2() export interface __Options_Child { - set onceParamNum(onceParamNum: (number | undefined)) + @Param() @Once() set onceParamNum(onceParamNum: (number | undefined)) - get onceParamNum(): (number | undefined) - @Param() set __backing_onceParamNum(__backing_onceParamNum: (IParamOnceDecoratedVariable | undefined)) + @Param() @Once() get onceParamNum(): (number | undefined) + set __backing_onceParamNum(__backing_onceParamNum: (IParamOnceDecoratedVariable | undefined)) - @Param() get __backing_onceParamNum(): (IParamOnceDecoratedVariable | undefined) - set onceParamInfo(onceParamInfo: (Info | undefined)) + get __backing_onceParamNum(): (IParamOnceDecoratedVariable | undefined) + @Param() @Once() @Require() set onceParamInfo(onceParamInfo: (Info | undefined)) - get onceParamInfo(): (Info | undefined) - @Param() set __backing_onceParamInfo(__backing_onceParamInfo: (IParamOnceDecoratedVariable | undefined)) + @Param() @Once() @Require() get onceParamInfo(): (Info | undefined) + set __backing_onceParamInfo(__backing_onceParamInfo: (IParamOnceDecoratedVariable | undefined)) - @Param() get __backing_onceParamInfo(): (IParamOnceDecoratedVariable | undefined) + get __backing_onceParamInfo(): (IParamOnceDecoratedVariable | undefined) } @ComponentV2() export interface __Options_Index { - set localNum(localNum: (number | undefined)) + @Local() set localNum(localNum: (number | undefined)) - get localNum(): (number | undefined) + @Local() get localNum(): (number | undefined) set __backing_localNum(__backing_localNum: (ILocalDecoratedVariable | undefined)) get __backing_localNum(): (ILocalDecoratedVariable | undefined) - set localInfo(localInfo: (Info | undefined)) + @Local() set localInfo(localInfo: (Info | undefined)) - get localInfo(): (Info | undefined) + @Local() get localInfo(): (Info | undefined) set __backing_localInfo(__backing_localInfo: (ILocalDecoratedVariable | undefined)) get __backing_localInfo(): (ILocalDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/param/param-basic-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/param/param-basic-type.test.ts index c53a65425498e372da06564039bb275670587b70..c3ca8c25c42e37c5e6d406b19ccccfc31d640928 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/param/param-basic-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/param/param-basic-type.test.ts @@ -126,33 +126,33 @@ function main() {} } @ComponentV2() export interface __Options_Parent { - set paramVar1(paramVar1: (string | undefined)) + @Param() set paramVar1(paramVar1: (string | undefined)) - get paramVar1(): (string | undefined) + @Param() get paramVar1(): (string | undefined) set __backing_paramVar1(__backing_paramVar1: (IParamDecoratedVariable | undefined)) get __backing_paramVar1(): (IParamDecoratedVariable | undefined) - set paramVar2(paramVar2: (number | undefined)) + @Param() set paramVar2(paramVar2: (number | undefined)) - get paramVar2(): (number | undefined) + @Param() get paramVar2(): (number | undefined) set __backing_paramVar2(__backing_paramVar2: (IParamDecoratedVariable | undefined)) get __backing_paramVar2(): (IParamDecoratedVariable | undefined) - set paramVar3(paramVar3: (boolean | undefined)) + @Param() set paramVar3(paramVar3: (boolean | undefined)) - get paramVar3(): (boolean | undefined) + @Param() get paramVar3(): (boolean | undefined) set __backing_paramVar3(__backing_paramVar3: (IParamDecoratedVariable | undefined)) get __backing_paramVar3(): (IParamDecoratedVariable | undefined) - set paramVar4(paramVar4: (undefined | undefined)) + @Param() set paramVar4(paramVar4: (undefined | undefined)) - get paramVar4(): (undefined | undefined) + @Param() get paramVar4(): (undefined | undefined) set __backing_paramVar4(__backing_paramVar4: (IParamDecoratedVariable | undefined)) get __backing_paramVar4(): (IParamDecoratedVariable | undefined) - set paramVar5(paramVar5: (null | undefined)) + @Param() set paramVar5(paramVar5: (null | undefined)) - get paramVar5(): (null | undefined) + @Param() get paramVar5(): (null | undefined) set __backing_paramVar5(__backing_paramVar5: (IParamDecoratedVariable | undefined)) get __backing_paramVar5(): (IParamDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/param/param-complex-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/param/param-complex-type.test.ts index b0209f191de22d940407cff017f9a43c3cc5d5dc..783594b88b53b1004ed730c649ceb635be8d53e6 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/param/param-complex-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/param/param-complex-type.test.ts @@ -289,75 +289,75 @@ final class StateType extends BaseEnum { } @ComponentV2() export interface __Options_Parent { - set paramVar1(paramVar1: (Per | undefined)) + @Param() set paramVar1(paramVar1: (Per | undefined)) - get paramVar1(): (Per | undefined) + @Param() get paramVar1(): (Per | undefined) set __backing_paramVar1(__backing_paramVar1: (IParamDecoratedVariable | undefined)) get __backing_paramVar1(): (IParamDecoratedVariable | undefined) - set paramVar2(paramVar2: (Array | undefined)) + @Param() set paramVar2(paramVar2: (Array | undefined)) - get paramVar2(): (Array | undefined) + @Param() get paramVar2(): (Array | undefined) set __backing_paramVar2(__backing_paramVar2: (IParamDecoratedVariable> | undefined)) get __backing_paramVar2(): (IParamDecoratedVariable> | undefined) - set paramVar3(paramVar3: (StateType | undefined)) + @Param() set paramVar3(paramVar3: (StateType | undefined)) - get paramVar3(): (StateType | undefined) + @Param() get paramVar3(): (StateType | undefined) set __backing_paramVar3(__backing_paramVar3: (IParamDecoratedVariable | undefined)) get __backing_paramVar3(): (IParamDecoratedVariable | undefined) - set paramVar4(paramVar4: (Set | undefined)) + @Param() set paramVar4(paramVar4: (Set | undefined)) - get paramVar4(): (Set | undefined) + @Param() get paramVar4(): (Set | undefined) set __backing_paramVar4(__backing_paramVar4: (IParamDecoratedVariable> | undefined)) get __backing_paramVar4(): (IParamDecoratedVariable> | undefined) - set paramVar5(paramVar5: (Array | undefined)) + @Param() set paramVar5(paramVar5: (Array | undefined)) - get paramVar5(): (Array | undefined) + @Param() get paramVar5(): (Array | undefined) set __backing_paramVar5(__backing_paramVar5: (IParamDecoratedVariable> | undefined)) get __backing_paramVar5(): (IParamDecoratedVariable> | undefined) - set paramVar6(paramVar6: (Array | undefined)) + @Param() set paramVar6(paramVar6: (Array | undefined)) - get paramVar6(): (Array | undefined) + @Param() get paramVar6(): (Array | undefined) set __backing_paramVar6(__backing_paramVar6: (IParamDecoratedVariable> | undefined)) get __backing_paramVar6(): (IParamDecoratedVariable> | undefined) - set paramVar7(paramVar7: (Array | undefined)) + @Param() set paramVar7(paramVar7: (Array | undefined)) - get paramVar7(): (Array | undefined) + @Param() get paramVar7(): (Array | undefined) set __backing_paramVar7(__backing_paramVar7: (IParamDecoratedVariable> | undefined)) get __backing_paramVar7(): (IParamDecoratedVariable> | undefined) - set paramVar8(paramVar8: (((sr: string)=> void) | undefined)) + @Param() set paramVar8(paramVar8: (((sr: string)=> void) | undefined)) - get paramVar8(): (((sr: string)=> void) | undefined) + @Param() get paramVar8(): (((sr: string)=> void) | undefined) set __backing_paramVar8(__backing_paramVar8: (IParamDecoratedVariable<((sr: string)=> void)> | undefined)) get __backing_paramVar8(): (IParamDecoratedVariable<((sr: string)=> void)> | undefined) - set paramVar9(paramVar9: (Date | undefined)) + @Param() set paramVar9(paramVar9: (Date | undefined)) - get paramVar9(): (Date | undefined) + @Param() get paramVar9(): (Date | undefined) set __backing_paramVar9(__backing_paramVar9: (IParamDecoratedVariable | undefined)) get __backing_paramVar9(): (IParamDecoratedVariable | undefined) - set paramVar10(paramVar10: (Map | undefined)) + @Param() set paramVar10(paramVar10: (Map | undefined)) - get paramVar10(): (Map | undefined) + @Param() get paramVar10(): (Map | undefined) set __backing_paramVar10(__backing_paramVar10: (IParamDecoratedVariable> | undefined)) get __backing_paramVar10(): (IParamDecoratedVariable> | undefined) - set paramVar11(paramVar11: ((string | number) | undefined)) + @Param() set paramVar11(paramVar11: ((string | number) | undefined)) - get paramVar11(): ((string | number) | undefined) + @Param() get paramVar11(): ((string | number) | undefined) set __backing_paramVar11(__backing_paramVar11: (IParamDecoratedVariable<(string | number)> | undefined)) get __backing_paramVar11(): (IParamDecoratedVariable<(string | number)> | undefined) - set paramVar12(paramVar12: ((Set | Per) | undefined)) + @Param() set paramVar12(paramVar12: ((Set | Per) | undefined)) - get paramVar12(): ((Set | Per) | undefined) + @Param() get paramVar12(): ((Set | Per) | undefined) set __backing_paramVar12(__backing_paramVar12: (IParamDecoratedVariable<(Set | Per)> | undefined)) get __backing_paramVar12(): (IParamDecoratedVariable<(Set | Per)> | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/param/param-with-require.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/param/param-with-require.test.ts index 5833664982d56b03e2717f0e0a971e72f962c9bc..6fcab352245994b8da61bf4538ff55fa0be02c94 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/param/param-with-require.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/param/param-with-require.test.ts @@ -124,19 +124,19 @@ class Info { } @ComponentV2() export interface __Options_Index { - infoList?: Info[]; + @Local() infoList?: Info[]; @Local() __backing_infoList?: Info[]; } @ComponentV2() export interface __Options_MiddleComponent { - info?: Info; + @Param() @Require() info?: Info; @Param() __backing_info?: Info; } @ComponentV2() export interface __Options_SubComponent { - region?: Region; + @Param() @Require() region?: Region; @Param() __backing_region?: Region; } @@ -296,9 +296,9 @@ class Info { } @ComponentV2() export interface __Options_Index { - set infoList(infoList: (Array | undefined)) + @Local() set infoList(infoList: (Array | undefined)) - get infoList(): (Array | undefined) + @Local() get infoList(): (Array | undefined) set __backing_infoList(__backing_infoList: (ILocalDecoratedVariable> | undefined)) get __backing_infoList(): (ILocalDecoratedVariable> | undefined) @@ -306,9 +306,9 @@ class Info { } @ComponentV2() export interface __Options_MiddleComponent { - set info(info: (Info | undefined)) + @Param() @Require() set info(info: (Info | undefined)) - get info(): (Info | undefined) + @Param() @Require() get info(): (Info | undefined) set __backing_info(__backing_info: (IParamDecoratedVariable | undefined)) get __backing_info(): (IParamDecoratedVariable | undefined) @@ -316,9 +316,9 @@ class Info { } @ComponentV2() export interface __Options_SubComponent { - set region(region: (Region | undefined)) + @Param() @Require() set region(region: (Region | undefined)) - get region(): (Region | undefined) + @Param() @Require() get region(): (Region | undefined) set __backing_region(__backing_region: (IParamDecoratedVariable | undefined)) get __backing_region(): (IParamDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/prop-ref/prop-ref-basic-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/prop-ref/prop-ref-basic-type.test.ts index b788197b52375dfc7b888c04c3bf777c92ffb7b7..0ec50ded02f0ad090170f87b12b386fdb6d3a7de 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/prop-ref/prop-ref-basic-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/prop-ref/prop-ref-basic-type.test.ts @@ -148,33 +148,33 @@ function main() {} } @Component() export interface __Options_PropParent { - set propVar1(propVar1: (string | undefined)) + @PropRef() set propVar1(propVar1: (string | undefined)) - get propVar1(): (string | undefined) + @PropRef() get propVar1(): (string | undefined) set __backing_propVar1(__backing_propVar1: (IPropRefDecoratedVariable | undefined)) get __backing_propVar1(): (IPropRefDecoratedVariable | undefined) - set propVar2(propVar2: (number | undefined)) + @PropRef() set propVar2(propVar2: (number | undefined)) - get propVar2(): (number | undefined) + @PropRef() get propVar2(): (number | undefined) set __backing_propVar2(__backing_propVar2: (IPropRefDecoratedVariable | undefined)) get __backing_propVar2(): (IPropRefDecoratedVariable | undefined) - set propVar3(propVar3: (boolean | undefined)) + @PropRef() set propVar3(propVar3: (boolean | undefined)) - get propVar3(): (boolean | undefined) + @PropRef() get propVar3(): (boolean | undefined) set __backing_propVar3(__backing_propVar3: (IPropRefDecoratedVariable | undefined)) get __backing_propVar3(): (IPropRefDecoratedVariable | undefined) - set propVar4(propVar4: (undefined | undefined)) + @PropRef() set propVar4(propVar4: (undefined | undefined)) - get propVar4(): (undefined | undefined) + @PropRef() get propVar4(): (undefined | undefined) set __backing_propVar4(__backing_propVar4: (IPropRefDecoratedVariable | undefined)) get __backing_propVar4(): (IPropRefDecoratedVariable | undefined) - set propVar5(propVar5: (null | undefined)) + @PropRef() set propVar5(propVar5: (null | undefined)) - get propVar5(): (null | undefined) + @PropRef() get propVar5(): (null | undefined) set __backing_propVar5(__backing_propVar5: (IPropRefDecoratedVariable | undefined)) get __backing_propVar5(): (IPropRefDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/prop-ref/prop-ref-complex-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/prop-ref/prop-ref-complex-type.test.ts index a0a73384ba5a422c16944bf920ff9a0709ed3e61..9b47cd481e72a54566da7b6209538b1fc89786ea 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/prop-ref/prop-ref-complex-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/prop-ref/prop-ref-complex-type.test.ts @@ -335,75 +335,75 @@ final class PropType extends BaseEnum { } @Component() export interface __Options_Parent { - set propVar1(propVar1: (Per | undefined)) + @PropRef() set propVar1(propVar1: (Per | undefined)) - get propVar1(): (Per | undefined) + @PropRef() get propVar1(): (Per | undefined) set __backing_propVar1(__backing_propVar1: (IPropRefDecoratedVariable | undefined)) get __backing_propVar1(): (IPropRefDecoratedVariable | undefined) - set propVar2(propVar2: (Array | undefined)) + @PropRef() set propVar2(propVar2: (Array | undefined)) - get propVar2(): (Array | undefined) + @PropRef() get propVar2(): (Array | undefined) set __backing_propVar2(__backing_propVar2: (IPropRefDecoratedVariable> | undefined)) get __backing_propVar2(): (IPropRefDecoratedVariable> | undefined) - set propVar3(propVar3: (PropType | undefined)) + @PropRef() set propVar3(propVar3: (PropType | undefined)) - get propVar3(): (PropType | undefined) + @PropRef() get propVar3(): (PropType | undefined) set __backing_propVar3(__backing_propVar3: (IPropRefDecoratedVariable | undefined)) get __backing_propVar3(): (IPropRefDecoratedVariable | undefined) - set propVar4(propVar4: (Set | undefined)) + @PropRef() set propVar4(propVar4: (Set | undefined)) - get propVar4(): (Set | undefined) + @PropRef() get propVar4(): (Set | undefined) set __backing_propVar4(__backing_propVar4: (IPropRefDecoratedVariable> | undefined)) get __backing_propVar4(): (IPropRefDecoratedVariable> | undefined) - set propVar5(propVar5: (Array | undefined)) + @PropRef() set propVar5(propVar5: (Array | undefined)) - get propVar5(): (Array | undefined) + @PropRef() get propVar5(): (Array | undefined) set __backing_propVar5(__backing_propVar5: (IPropRefDecoratedVariable> | undefined)) get __backing_propVar5(): (IPropRefDecoratedVariable> | undefined) - set propVar6(propVar6: (Array | undefined)) + @PropRef() set propVar6(propVar6: (Array | undefined)) - get propVar6(): (Array | undefined) + @PropRef() get propVar6(): (Array | undefined) set __backing_propVar6(__backing_propVar6: (IPropRefDecoratedVariable> | undefined)) get __backing_propVar6(): (IPropRefDecoratedVariable> | undefined) - set propVar7(propVar7: (Array | undefined)) + @PropRef() set propVar7(propVar7: (Array | undefined)) - get propVar7(): (Array | undefined) + @PropRef() get propVar7(): (Array | undefined) set __backing_propVar7(__backing_propVar7: (IPropRefDecoratedVariable> | undefined)) get __backing_propVar7(): (IPropRefDecoratedVariable> | undefined) - set propVar8(propVar8: (((sr: string)=> void) | undefined)) + @PropRef() set propVar8(propVar8: (((sr: string)=> void) | undefined)) - get propVar8(): (((sr: string)=> void) | undefined) + @PropRef() get propVar8(): (((sr: string)=> void) | undefined) set __backing_propVar8(__backing_propVar8: (IPropRefDecoratedVariable<((sr: string)=> void)> | undefined)) get __backing_propVar8(): (IPropRefDecoratedVariable<((sr: string)=> void)> | undefined) - set propVar9(propVar9: (Date | undefined)) + @PropRef() set propVar9(propVar9: (Date | undefined)) - get propVar9(): (Date | undefined) + @PropRef() get propVar9(): (Date | undefined) set __backing_propVar9(__backing_propVar9: (IPropRefDecoratedVariable | undefined)) get __backing_propVar9(): (IPropRefDecoratedVariable | undefined) - set propVar10(propVar10: (Map | undefined)) + @PropRef() set propVar10(propVar10: (Map | undefined)) - get propVar10(): (Map | undefined) + @PropRef() get propVar10(): (Map | undefined) set __backing_propVar10(__backing_propVar10: (IPropRefDecoratedVariable> | undefined)) get __backing_propVar10(): (IPropRefDecoratedVariable> | undefined) - set propVar11(propVar11: ((string | number) | undefined)) + @PropRef() set propVar11(propVar11: ((string | number) | undefined)) - get propVar11(): ((string | number) | undefined) + @PropRef() get propVar11(): ((string | number) | undefined) set __backing_propVar11(__backing_propVar11: (IPropRefDecoratedVariable<(string | number)> | undefined)) get __backing_propVar11(): (IPropRefDecoratedVariable<(string | number)> | undefined) - set propVar12(propVar12: ((Set | Per) | undefined)) + @PropRef() set propVar12(propVar12: ((Set | Per) | undefined)) - get propVar12(): ((Set | Per) | undefined) + @PropRef() get propVar12(): ((Set | Per) | undefined) set __backing_propVar12(__backing_propVar12: (IPropRefDecoratedVariable<(Set | Per)> | undefined)) get __backing_propVar12(): (IPropRefDecoratedVariable<(Set | Per)> | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/prop-ref/prop-ref-without-initialization.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/prop-ref/prop-ref-without-initialization.test.ts index c078ab4373e37272f532c1e466d895c6401f97ac..f2b2c10ebe4d1ed60dbd0a0f4c442778a474ce59 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/prop-ref/prop-ref-without-initialization.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/prop-ref/prop-ref-without-initialization.test.ts @@ -66,19 +66,19 @@ import { PropRef as PropRef } from "@ohos.arkui.stateManagement"; } @Component() export interface __Options_PropParent { - propVar1?: string; + @PropRef() propVar1?: string; @PropRef() __backing_propVar1?: string; - propVar2?: (number | undefined); + @PropRef() propVar2?: (number | undefined); @PropRef() __backing_propVar2?: (number | undefined); - propVar3?: boolean; + @PropRef() propVar3?: boolean; @PropRef() __backing_propVar3?: boolean; - propVar4?: undefined; + @PropRef() propVar4?: undefined; @PropRef() __backing_propVar4?: undefined; - propVar5?: null; + @PropRef() propVar5?: null; @PropRef() __backing_propVar5?: null; - propVar6?: (Array | null); + @PropRef() propVar6?: (Array | null); @PropRef() __backing_propVar6?: (Array | null); - propVar7?: (Map | undefined); + @PropRef() propVar7?: (Map | undefined); @PropRef() __backing_propVar7?: (Map | undefined); } @@ -218,45 +218,45 @@ function main() {} } @Component() export interface __Options_PropParent { - set propVar1(propVar1: (string | undefined)) + @PropRef() set propVar1(propVar1: (string | undefined)) - get propVar1(): (string | undefined) + @PropRef() get propVar1(): (string | undefined) set __backing_propVar1(__backing_propVar1: (IPropRefDecoratedVariable | undefined)) get __backing_propVar1(): (IPropRefDecoratedVariable | undefined) - set propVar2(propVar2: ((number | undefined) | undefined)) + @PropRef() set propVar2(propVar2: ((number | undefined) | undefined)) - get propVar2(): ((number | undefined) | undefined) + @PropRef() get propVar2(): ((number | undefined) | undefined) set __backing_propVar2(__backing_propVar2: (IPropRefDecoratedVariable<(number | undefined)> | undefined)) get __backing_propVar2(): (IPropRefDecoratedVariable<(number | undefined)> | undefined) - set propVar3(propVar3: (boolean | undefined)) + @PropRef() set propVar3(propVar3: (boolean | undefined)) - get propVar3(): (boolean | undefined) + @PropRef() get propVar3(): (boolean | undefined) set __backing_propVar3(__backing_propVar3: (IPropRefDecoratedVariable | undefined)) get __backing_propVar3(): (IPropRefDecoratedVariable | undefined) - set propVar4(propVar4: (undefined | undefined)) + @PropRef() set propVar4(propVar4: (undefined | undefined)) - get propVar4(): (undefined | undefined) + @PropRef() get propVar4(): (undefined | undefined) set __backing_propVar4(__backing_propVar4: (IPropRefDecoratedVariable | undefined)) get __backing_propVar4(): (IPropRefDecoratedVariable | undefined) - set propVar5(propVar5: (null | undefined)) + @PropRef() set propVar5(propVar5: (null | undefined)) - get propVar5(): (null | undefined) + @PropRef() get propVar5(): (null | undefined) set __backing_propVar5(__backing_propVar5: (IPropRefDecoratedVariable | undefined)) get __backing_propVar5(): (IPropRefDecoratedVariable | undefined) - set propVar6(propVar6: ((Array | null) | undefined)) + @PropRef() set propVar6(propVar6: ((Array | null) | undefined)) - get propVar6(): ((Array | null) | undefined) + @PropRef() get propVar6(): ((Array | null) | undefined) set __backing_propVar6(__backing_propVar6: (IPropRefDecoratedVariable<(Array | null)> | undefined)) get __backing_propVar6(): (IPropRefDecoratedVariable<(Array | null)> | undefined) - set propVar7(propVar7: ((Map | undefined) | undefined)) + @PropRef() set propVar7(propVar7: ((Map | undefined) | undefined)) - get propVar7(): ((Map | undefined) | undefined) + @PropRef() get propVar7(): ((Map | undefined) | undefined) set __backing_propVar7(__backing_propVar7: (IPropRefDecoratedVariable<(Map | undefined)> | undefined)) get __backing_propVar7(): (IPropRefDecoratedVariable<(Map | undefined)> | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/prop-ref/state-to-propref.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/prop-ref/state-to-propref.test.ts index 1cc5db07dcca3db2e1bb31c94c26132c2f6a81e7..89c427e1553448439b438f525f4d12809ccbb135 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/prop-ref/state-to-propref.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/prop-ref/state-to-propref.test.ts @@ -168,9 +168,9 @@ function main() {} } @Component() export interface __Options_CountDownComponent { - set count(count: (number | undefined)) + @PropRef() set count(count: (number | undefined)) - get count(): (number | undefined) + @PropRef() get count(): (number | undefined) set __backing_count(__backing_count: (IPropRefDecoratedVariable | undefined)) get __backing_count(): (IPropRefDecoratedVariable | undefined) @@ -181,9 +181,9 @@ function main() {} } @Component() export interface __Options_ParentComponent { - set countDownStartValue(countDownStartValue: (number | undefined)) + @State() set countDownStartValue(countDownStartValue: (number | undefined)) - get countDownStartValue(): (number | undefined) + @State() get countDownStartValue(): (number | undefined) set __backing_countDownStartValue(__backing_countDownStartValue: (IStateDecoratedVariable | undefined)) get __backing_countDownStartValue(): (IStateDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/prop/prop-basic-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/prop/prop-basic-type.test.ts index d8584fd5fed82a2855f1fbaea2bc803db8f927e9..a51175b8be683798a4ece3a1ddf6a58b6e42c021 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/prop/prop-basic-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/prop/prop-basic-type.test.ts @@ -149,33 +149,33 @@ function main() {} } @Component() export interface __Options_PropParent { - set propVar1(propVar1: (string | undefined)) + @Prop() set propVar1(propVar1: (string | undefined)) - get propVar1(): (string | undefined) + @Prop() get propVar1(): (string | undefined) set __backing_propVar1(__backing_propVar1: (IPropDecoratedVariable | undefined)) get __backing_propVar1(): (IPropDecoratedVariable | undefined) - set propVar2(propVar2: (number | undefined)) + @Prop() set propVar2(propVar2: (number | undefined)) - get propVar2(): (number | undefined) + @Prop() get propVar2(): (number | undefined) set __backing_propVar2(__backing_propVar2: (IPropDecoratedVariable | undefined)) get __backing_propVar2(): (IPropDecoratedVariable | undefined) - set propVar3(propVar3: (boolean | undefined)) + @Prop() set propVar3(propVar3: (boolean | undefined)) - get propVar3(): (boolean | undefined) + @Prop() get propVar3(): (boolean | undefined) set __backing_propVar3(__backing_propVar3: (IPropDecoratedVariable | undefined)) get __backing_propVar3(): (IPropDecoratedVariable | undefined) - set propVar4(propVar4: (undefined | undefined)) + @Prop() set propVar4(propVar4: (undefined | undefined)) - get propVar4(): (undefined | undefined) + @Prop() get propVar4(): (undefined | undefined) set __backing_propVar4(__backing_propVar4: (IPropDecoratedVariable | undefined)) get __backing_propVar4(): (IPropDecoratedVariable | undefined) - set propVar5(propVar5: (null | undefined)) + @Prop() set propVar5(propVar5: (null | undefined)) - get propVar5(): (null | undefined) + @Prop() get propVar5(): (null | undefined) set __backing_propVar5(__backing_propVar5: (IPropDecoratedVariable | undefined)) get __backing_propVar5(): (IPropDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/prop/prop-complex-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/prop/prop-complex-type.test.ts index e108af26c0af2c409d0fb48666b3b6dbf4f23e15..ef4a50a29a41bd6c21ec7c937fe0106ab121a5c8 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/prop/prop-complex-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/prop/prop-complex-type.test.ts @@ -336,75 +336,75 @@ final class PropType extends BaseEnum { } @Component() export interface __Options_Parent { - set propVar1(propVar1: (Per | undefined)) + @Prop() set propVar1(propVar1: (Per | undefined)) - get propVar1(): (Per | undefined) + @Prop() get propVar1(): (Per | undefined) set __backing_propVar1(__backing_propVar1: (IPropDecoratedVariable | undefined)) get __backing_propVar1(): (IPropDecoratedVariable | undefined) - set propVar2(propVar2: (Array | undefined)) + @Prop() set propVar2(propVar2: (Array | undefined)) - get propVar2(): (Array | undefined) + @Prop() get propVar2(): (Array | undefined) set __backing_propVar2(__backing_propVar2: (IPropDecoratedVariable> | undefined)) get __backing_propVar2(): (IPropDecoratedVariable> | undefined) - set propVar3(propVar3: (PropType | undefined)) + @Prop() set propVar3(propVar3: (PropType | undefined)) - get propVar3(): (PropType | undefined) + @Prop() get propVar3(): (PropType | undefined) set __backing_propVar3(__backing_propVar3: (IPropDecoratedVariable | undefined)) get __backing_propVar3(): (IPropDecoratedVariable | undefined) - set propVar4(propVar4: (Set | undefined)) + @Prop() set propVar4(propVar4: (Set | undefined)) - get propVar4(): (Set | undefined) + @Prop() get propVar4(): (Set | undefined) set __backing_propVar4(__backing_propVar4: (IPropDecoratedVariable> | undefined)) get __backing_propVar4(): (IPropDecoratedVariable> | undefined) - set propVar5(propVar5: (Array | undefined)) + @Prop() set propVar5(propVar5: (Array | undefined)) - get propVar5(): (Array | undefined) + @Prop() get propVar5(): (Array | undefined) set __backing_propVar5(__backing_propVar5: (IPropDecoratedVariable> | undefined)) get __backing_propVar5(): (IPropDecoratedVariable> | undefined) - set propVar6(propVar6: (Array | undefined)) + @Prop() set propVar6(propVar6: (Array | undefined)) - get propVar6(): (Array | undefined) + @Prop() get propVar6(): (Array | undefined) set __backing_propVar6(__backing_propVar6: (IPropDecoratedVariable> | undefined)) get __backing_propVar6(): (IPropDecoratedVariable> | undefined) - set propVar7(propVar7: (Array | undefined)) + @Prop() set propVar7(propVar7: (Array | undefined)) - get propVar7(): (Array | undefined) + @Prop() get propVar7(): (Array | undefined) set __backing_propVar7(__backing_propVar7: (IPropDecoratedVariable> | undefined)) get __backing_propVar7(): (IPropDecoratedVariable> | undefined) - set propVar8(propVar8: (((sr: string)=> void) | undefined)) + @Prop() set propVar8(propVar8: (((sr: string)=> void) | undefined)) - get propVar8(): (((sr: string)=> void) | undefined) + @Prop() get propVar8(): (((sr: string)=> void) | undefined) set __backing_propVar8(__backing_propVar8: (IPropDecoratedVariable<((sr: string)=> void)> | undefined)) get __backing_propVar8(): (IPropDecoratedVariable<((sr: string)=> void)> | undefined) - set propVar9(propVar9: (Date | undefined)) + @Prop() set propVar9(propVar9: (Date | undefined)) - get propVar9(): (Date | undefined) + @Prop() get propVar9(): (Date | undefined) set __backing_propVar9(__backing_propVar9: (IPropDecoratedVariable | undefined)) get __backing_propVar9(): (IPropDecoratedVariable | undefined) - set propVar10(propVar10: (Map | undefined)) + @Prop() set propVar10(propVar10: (Map | undefined)) - get propVar10(): (Map | undefined) + @Prop() get propVar10(): (Map | undefined) set __backing_propVar10(__backing_propVar10: (IPropDecoratedVariable> | undefined)) get __backing_propVar10(): (IPropDecoratedVariable> | undefined) - set propVar11(propVar11: ((string | number) | undefined)) + @Prop() set propVar11(propVar11: ((string | number) | undefined)) - get propVar11(): ((string | number) | undefined) + @Prop() get propVar11(): ((string | number) | undefined) set __backing_propVar11(__backing_propVar11: (IPropDecoratedVariable<(string | number)> | undefined)) get __backing_propVar11(): (IPropDecoratedVariable<(string | number)> | undefined) - set propVar12(propVar12: ((Set | Per) | undefined)) + @Prop() set propVar12(propVar12: ((Set | Per) | undefined)) - get propVar12(): ((Set | Per) | undefined) + @Prop() get propVar12(): ((Set | Per) | undefined) set __backing_propVar12(__backing_propVar12: (IPropDecoratedVariable<(Set | Per)> | undefined)) get __backing_propVar12(): (IPropDecoratedVariable<(Set | Per)> | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/prop/state-to-prop.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/prop/state-to-prop.test.ts index fb8f9e78c63d3b888b90f3bcb1b9d8db75e7d78e..8f474f700176c483f6f81b7fad025a36957c42a9 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/prop/state-to-prop.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/prop/state-to-prop.test.ts @@ -168,9 +168,9 @@ function main() {} } @Component() export interface __Options_CountDownComponent { - set count(count: (number | undefined)) + @Prop() set count(count: (number | undefined)) - get count(): (number | undefined) + @Prop() get count(): (number | undefined) set __backing_count(__backing_count: (IPropDecoratedVariable | undefined)) get __backing_count(): (IPropDecoratedVariable | undefined) @@ -181,9 +181,9 @@ function main() {} } @Component() export interface __Options_ParentComponent { - set countDownStartValue(countDownStartValue: (number | undefined)) + @State() set countDownStartValue(countDownStartValue: (number | undefined)) - get countDownStartValue(): (number | undefined) + @State() get countDownStartValue(): (number | undefined) set __backing_countDownStartValue(__backing_countDownStartValue: (IStateDecoratedVariable | undefined)) get __backing_countDownStartValue(): (IStateDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/consume-basic-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/consume-basic-type.test.ts index d8245372fbca0097ae8215e1c4ba22717524966e..d6970c2f6dd82444220e8ec4a1f52956d00e9fcb 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/consume-basic-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/consume-basic-type.test.ts @@ -62,15 +62,15 @@ import { Consume as Consume } from "@ohos.arkui.stateManagement"; } @Component() export interface __Options_PropParent { - conVar1?: string; + @Consume() conVar1?: string; @Consume() __backing_conVar1?: string; - conVar2?: number; + @Consume() conVar2?: number; @Consume() __backing_conVar2?: number; - conVar3?: boolean; + @Consume() conVar3?: boolean; @Consume() __backing_conVar3?: boolean; - conVar4?: undefined; + @Consume() conVar4?: undefined; @Consume() __backing_conVar4?: undefined; - conVar5?: null; + @Consume() conVar5?: null; @Consume() __backing_conVar5?: null; } @@ -161,33 +161,33 @@ function main() {} } @Component() export interface __Options_PropParent { - set conVar1(conVar1: (string | undefined)) + @Consume({alias:""}) set conVar1(conVar1: (string | undefined)) - get conVar1(): (string | undefined) + @Consume({alias:""}) get conVar1(): (string | undefined) set __backing_conVar1(__backing_conVar1: (IConsumeDecoratedVariable | undefined)) get __backing_conVar1(): (IConsumeDecoratedVariable | undefined) - set conVar2(conVar2: (number | undefined)) + @Consume({alias:""}) set conVar2(conVar2: (number | undefined)) - get conVar2(): (number | undefined) + @Consume({alias:""}) get conVar2(): (number | undefined) set __backing_conVar2(__backing_conVar2: (IConsumeDecoratedVariable | undefined)) get __backing_conVar2(): (IConsumeDecoratedVariable | undefined) - set conVar3(conVar3: (boolean | undefined)) + @Consume({alias:""}) set conVar3(conVar3: (boolean | undefined)) - get conVar3(): (boolean | undefined) + @Consume({alias:""}) get conVar3(): (boolean | undefined) set __backing_conVar3(__backing_conVar3: (IConsumeDecoratedVariable | undefined)) get __backing_conVar3(): (IConsumeDecoratedVariable | undefined) - set conVar4(conVar4: (undefined | undefined)) + @Consume({alias:""}) set conVar4(conVar4: (undefined | undefined)) - get conVar4(): (undefined | undefined) + @Consume({alias:""}) get conVar4(): (undefined | undefined) set __backing_conVar4(__backing_conVar4: (IConsumeDecoratedVariable | undefined)) get __backing_conVar4(): (IConsumeDecoratedVariable | undefined) - set conVar5(conVar5: (null | undefined)) + @Consume({alias:""}) set conVar5(conVar5: (null | undefined)) - get conVar5(): (null | undefined) + @Consume({alias:""}) get conVar5(): (null | undefined) set __backing_conVar5(__backing_conVar5: (IConsumeDecoratedVariable | undefined)) get __backing_conVar5(): (IConsumeDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/consume-complex-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/consume-complex-type.test.ts index b226ecbbdcb2482b046a9763fb64ebbe5399a02b..a6eb89a4e52b5a14b25354161c6e17ea5f17f8b0 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/consume-complex-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/consume-complex-type.test.ts @@ -93,31 +93,31 @@ enum PropType { } @Component() export interface __Options_Parent { - conVar1?: Per; + @Consume() conVar1?: Per; @Consume() __backing_conVar1?: Per; - conVar2?: Array; + @Consume() conVar2?: Array; @Consume() __backing_conVar2?: Array; - conVar3?: PropType; + @Consume() conVar3?: PropType; @Consume() __backing_conVar3?: PropType; - conVar4?: Set; + @Consume() conVar4?: Set; @Consume() __backing_conVar4?: Set; - conVar5?: boolean[]; + @Consume() conVar5?: boolean[]; @Consume() __backing_conVar5?: boolean[]; - conVar6?: Array; + @Consume() conVar6?: Array; @Consume() __backing_conVar6?: Array; - conVar7?: Per[]; + @Consume() conVar7?: Per[]; @Consume() __backing_conVar7?: Per[]; - conVar8?: ((sr: string)=> void); + @Consume() conVar8?: ((sr: string)=> void); @Consume() __backing_conVar8?: ((sr: string)=> void); - conVar9?: Date; + @Consume() conVar9?: Date; @Consume() __backing_conVar9?: Date; - conVar10?: Map; + @Consume() conVar10?: Map; @Consume() __backing_conVar10?: Map; - conVar11?: (string | number); + @Consume() conVar11?: (string | number); @Consume() __backing_conVar11?: (string | number); - conVar12?: (Set | Per); + @Consume() conVar12?: (Set | Per); @Consume() __backing_conVar12?: (Set | Per); - conVar13?: (Set | null); + @Consume() conVar13?: (Set | null); @Consume() __backing_conVar13?: (Set | null); } @@ -373,81 +373,81 @@ final class PropType extends BaseEnum { } @Component() export interface __Options_Parent { - set conVar1(conVar1: (Per | undefined)) + @Consume({alias:""}) set conVar1(conVar1: (Per | undefined)) - get conVar1(): (Per | undefined) + @Consume({alias:""}) get conVar1(): (Per | undefined) set __backing_conVar1(__backing_conVar1: (IConsumeDecoratedVariable | undefined)) get __backing_conVar1(): (IConsumeDecoratedVariable | undefined) - set conVar2(conVar2: (Array | undefined)) + @Consume({alias:""}) set conVar2(conVar2: (Array | undefined)) - get conVar2(): (Array | undefined) + @Consume({alias:""}) get conVar2(): (Array | undefined) set __backing_conVar2(__backing_conVar2: (IConsumeDecoratedVariable> | undefined)) get __backing_conVar2(): (IConsumeDecoratedVariable> | undefined) - set conVar3(conVar3: (PropType | undefined)) + @Consume({alias:""}) set conVar3(conVar3: (PropType | undefined)) - get conVar3(): (PropType | undefined) + @Consume({alias:""}) get conVar3(): (PropType | undefined) set __backing_conVar3(__backing_conVar3: (IConsumeDecoratedVariable | undefined)) get __backing_conVar3(): (IConsumeDecoratedVariable | undefined) - set conVar4(conVar4: (Set | undefined)) + @Consume({alias:""}) set conVar4(conVar4: (Set | undefined)) - get conVar4(): (Set | undefined) + @Consume({alias:""}) get conVar4(): (Set | undefined) set __backing_conVar4(__backing_conVar4: (IConsumeDecoratedVariable> | undefined)) get __backing_conVar4(): (IConsumeDecoratedVariable> | undefined) - set conVar5(conVar5: (Array | undefined)) + @Consume({alias:""}) set conVar5(conVar5: (Array | undefined)) - get conVar5(): (Array | undefined) + @Consume({alias:""}) get conVar5(): (Array | undefined) set __backing_conVar5(__backing_conVar5: (IConsumeDecoratedVariable> | undefined)) get __backing_conVar5(): (IConsumeDecoratedVariable> | undefined) - set conVar6(conVar6: (Array | undefined)) + @Consume({alias:""}) set conVar6(conVar6: (Array | undefined)) - get conVar6(): (Array | undefined) + @Consume({alias:""}) get conVar6(): (Array | undefined) set __backing_conVar6(__backing_conVar6: (IConsumeDecoratedVariable> | undefined)) get __backing_conVar6(): (IConsumeDecoratedVariable> | undefined) - set conVar7(conVar7: (Array | undefined)) + @Consume({alias:""}) set conVar7(conVar7: (Array | undefined)) - get conVar7(): (Array | undefined) + @Consume({alias:""}) get conVar7(): (Array | undefined) set __backing_conVar7(__backing_conVar7: (IConsumeDecoratedVariable> | undefined)) get __backing_conVar7(): (IConsumeDecoratedVariable> | undefined) - set conVar8(conVar8: (((sr: string)=> void) | undefined)) + @Consume({alias:""}) set conVar8(conVar8: (((sr: string)=> void) | undefined)) - get conVar8(): (((sr: string)=> void) | undefined) + @Consume({alias:""}) get conVar8(): (((sr: string)=> void) | undefined) set __backing_conVar8(__backing_conVar8: (IConsumeDecoratedVariable<((sr: string)=> void)> | undefined)) get __backing_conVar8(): (IConsumeDecoratedVariable<((sr: string)=> void)> | undefined) - set conVar9(conVar9: (Date | undefined)) + @Consume({alias:""}) set conVar9(conVar9: (Date | undefined)) - get conVar9(): (Date | undefined) + @Consume({alias:""}) get conVar9(): (Date | undefined) set __backing_conVar9(__backing_conVar9: (IConsumeDecoratedVariable | undefined)) get __backing_conVar9(): (IConsumeDecoratedVariable | undefined) - set conVar10(conVar10: (Map | undefined)) + @Consume({alias:""}) set conVar10(conVar10: (Map | undefined)) - get conVar10(): (Map | undefined) + @Consume({alias:""}) get conVar10(): (Map | undefined) set __backing_conVar10(__backing_conVar10: (IConsumeDecoratedVariable> | undefined)) get __backing_conVar10(): (IConsumeDecoratedVariable> | undefined) - set conVar11(conVar11: ((string | number) | undefined)) + @Consume({alias:""}) set conVar11(conVar11: ((string | number) | undefined)) - get conVar11(): ((string | number) | undefined) + @Consume({alias:""}) get conVar11(): ((string | number) | undefined) set __backing_conVar11(__backing_conVar11: (IConsumeDecoratedVariable<(string | number)> | undefined)) get __backing_conVar11(): (IConsumeDecoratedVariable<(string | number)> | undefined) - set conVar12(conVar12: ((Set | Per) | undefined)) + @Consume({alias:""}) set conVar12(conVar12: ((Set | Per) | undefined)) - get conVar12(): ((Set | Per) | undefined) + @Consume({alias:""}) get conVar12(): ((Set | Per) | undefined) set __backing_conVar12(__backing_conVar12: (IConsumeDecoratedVariable<(Set | Per)> | undefined)) get __backing_conVar12(): (IConsumeDecoratedVariable<(Set | Per)> | undefined) - set conVar13(conVar13: ((Set | null) | undefined)) + @Consume({alias:""}) set conVar13(conVar13: ((Set | null) | undefined)) - get conVar13(): ((Set | null) | undefined) + @Consume({alias:""}) get conVar13(): ((Set | null) | undefined) set __backing_conVar13(__backing_conVar13: (IConsumeDecoratedVariable<(Set | null)> | undefined)) get __backing_conVar13(): (IConsumeDecoratedVariable<(Set | null)> | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/provide-annotation-usage.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/provide-annotation-usage.test.ts index 453a2c24af11172158a83f10ca0347f518455853..aacb5ed6125ac9b01e42726b05c2eee65e4d4e6c 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/provide-annotation-usage.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/provide-annotation-usage.test.ts @@ -162,51 +162,51 @@ function main() {} } @Component() export interface __Options_Ancestors { - set count(count: ((string | undefined) | undefined)) + @Provide({alias:"count",allowOverride:false}) set count(count: ((string | undefined) | undefined)) - get count(): ((string | undefined) | undefined) + @Provide({alias:"count",allowOverride:false}) get count(): ((string | undefined) | undefined) set __backing_count(__backing_count: (IProvideDecoratedVariable<(string | undefined)> | undefined)) get __backing_count(): (IProvideDecoratedVariable<(string | undefined)> | undefined) - set count1(count1: ((string | undefined) | undefined)) + @Provide({alias:"prov1",allowOverride:false}) set count1(count1: ((string | undefined) | undefined)) - get count1(): ((string | undefined) | undefined) + @Provide({alias:"prov1",allowOverride:false}) get count1(): ((string | undefined) | undefined) set __backing_count1(__backing_count1: (IProvideDecoratedVariable<(string | undefined)> | undefined)) get __backing_count1(): (IProvideDecoratedVariable<(string | undefined)> | undefined) - set count2(count2: ((string | undefined) | undefined)) + @Provide({alias:"prov2",allowOverride:false}) set count2(count2: ((string | undefined) | undefined)) - get count2(): ((string | undefined) | undefined) + @Provide({alias:"prov2",allowOverride:false}) get count2(): ((string | undefined) | undefined) set __backing_count2(__backing_count2: (IProvideDecoratedVariable<(string | undefined)> | undefined)) get __backing_count2(): (IProvideDecoratedVariable<(string | undefined)> | undefined) - set count3(count3: ((string | undefined) | undefined)) + @Provide({alias:"prov3",allowOverride:true}) set count3(count3: ((string | undefined) | undefined)) - get count3(): ((string | undefined) | undefined) + @Provide({alias:"prov3",allowOverride:true}) get count3(): ((string | undefined) | undefined) set __backing_count3(__backing_count3: (IProvideDecoratedVariable<(string | undefined)> | undefined)) get __backing_count3(): (IProvideDecoratedVariable<(string | undefined)> | undefined) - set count4(count4: ((string | undefined) | undefined)) + @Provide({allowOverride:false,alias:"count4"}) set count4(count4: ((string | undefined) | undefined)) - get count4(): ((string | undefined) | undefined) + @Provide({allowOverride:false,alias:"count4"}) get count4(): ((string | undefined) | undefined) set __backing_count4(__backing_count4: (IProvideDecoratedVariable<(string | undefined)> | undefined)) get __backing_count4(): (IProvideDecoratedVariable<(string | undefined)> | undefined) - set count5(count5: ((string | undefined) | undefined)) + @Provide({allowOverride:true,alias:"count5"}) set count5(count5: ((string | undefined) | undefined)) - get count5(): ((string | undefined) | undefined) + @Provide({allowOverride:true,alias:"count5"}) get count5(): ((string | undefined) | undefined) set __backing_count5(__backing_count5: (IProvideDecoratedVariable<(string | undefined)> | undefined)) get __backing_count5(): (IProvideDecoratedVariable<(string | undefined)> | undefined) - set count6(count6: ((string | undefined) | undefined)) + @Provide({alias:"",allowOverride:true}) set count6(count6: ((string | undefined) | undefined)) - get count6(): ((string | undefined) | undefined) + @Provide({alias:"",allowOverride:true}) get count6(): ((string | undefined) | undefined) set __backing_count6(__backing_count6: (IProvideDecoratedVariable<(string | undefined)> | undefined)) get __backing_count6(): (IProvideDecoratedVariable<(string | undefined)> | undefined) - set count7(count7: ((string | undefined) | undefined)) + @Provide({alias:"",allowOverride:false}) set count7(count7: ((string | undefined) | undefined)) - get count7(): ((string | undefined) | undefined) + @Provide({alias:"",allowOverride:false}) get count7(): ((string | undefined) | undefined) set __backing_count7(__backing_count7: (IProvideDecoratedVariable<(string | undefined)> | undefined)) get __backing_count7(): (IProvideDecoratedVariable<(string | undefined)> | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/provide-basic-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/provide-basic-type.test.ts index 30f9174a540fdee8b50f93f0e6622cfe413fc893..73a4f2705024720c11623f736399d4e0c8a5a075 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/provide-basic-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/provide-basic-type.test.ts @@ -126,33 +126,33 @@ function main() {} } @Component() export interface __Options_PropParent { - set provideVar1(provideVar1: (string | undefined)) + @Provide({alias:"provideVar1",allowOverride:false}) set provideVar1(provideVar1: (string | undefined)) - get provideVar1(): (string | undefined) + @Provide({alias:"provideVar1",allowOverride:false}) get provideVar1(): (string | undefined) set __backing_provideVar1(__backing_provideVar1: (IProvideDecoratedVariable | undefined)) get __backing_provideVar1(): (IProvideDecoratedVariable | undefined) - set provideVar2(provideVar2: (number | undefined)) + @Provide({alias:"provideVar2",allowOverride:false}) set provideVar2(provideVar2: (number | undefined)) - get provideVar2(): (number | undefined) + @Provide({alias:"provideVar2",allowOverride:false}) get provideVar2(): (number | undefined) set __backing_provideVar2(__backing_provideVar2: (IProvideDecoratedVariable | undefined)) get __backing_provideVar2(): (IProvideDecoratedVariable | undefined) - set provideVar3(provideVar3: (boolean | undefined)) + @Provide({alias:"provideVar3",allowOverride:false}) set provideVar3(provideVar3: (boolean | undefined)) - get provideVar3(): (boolean | undefined) + @Provide({alias:"provideVar3",allowOverride:false}) get provideVar3(): (boolean | undefined) set __backing_provideVar3(__backing_provideVar3: (IProvideDecoratedVariable | undefined)) get __backing_provideVar3(): (IProvideDecoratedVariable | undefined) - set provideVar4(provideVar4: (undefined | undefined)) + @Provide({alias:"provideVar4",allowOverride:false}) set provideVar4(provideVar4: (undefined | undefined)) - get provideVar4(): (undefined | undefined) + @Provide({alias:"provideVar4",allowOverride:false}) get provideVar4(): (undefined | undefined) set __backing_provideVar4(__backing_provideVar4: (IProvideDecoratedVariable | undefined)) get __backing_provideVar4(): (IProvideDecoratedVariable | undefined) - set provideVar5(provideVar5: (null | undefined)) + @Provide({alias:"provideVar5",allowOverride:false}) set provideVar5(provideVar5: (null | undefined)) - get provideVar5(): (null | undefined) + @Provide({alias:"provideVar5",allowOverride:false}) get provideVar5(): (null | undefined) set __backing_provideVar5(__backing_provideVar5: (IProvideDecoratedVariable | undefined)) get __backing_provideVar5(): (IProvideDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/provide-complex-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/provide-complex-type.test.ts index a58210c096e6e497e3070ed491c15694f22d4d6a..689aaad409950e038a06b04e28b2aaa0561de96e 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/provide-complex-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/provide-complex-type.test.ts @@ -287,75 +287,75 @@ final class PropType extends BaseEnum { } @Component() export interface __Options_Parent { - set provideVar1(provideVar1: (Per | undefined)) + @Provide({alias:"provideVar1",allowOverride:false}) set provideVar1(provideVar1: (Per | undefined)) - get provideVar1(): (Per | undefined) + @Provide({alias:"provideVar1",allowOverride:false}) get provideVar1(): (Per | undefined) set __backing_provideVar1(__backing_provideVar1: (IProvideDecoratedVariable | undefined)) get __backing_provideVar1(): (IProvideDecoratedVariable | undefined) - set provideVar2(provideVar2: (Array | undefined)) + @Provide({alias:"provideVar2",allowOverride:false}) set provideVar2(provideVar2: (Array | undefined)) - get provideVar2(): (Array | undefined) + @Provide({alias:"provideVar2",allowOverride:false}) get provideVar2(): (Array | undefined) set __backing_provideVar2(__backing_provideVar2: (IProvideDecoratedVariable> | undefined)) get __backing_provideVar2(): (IProvideDecoratedVariable> | undefined) - set provideVar3(provideVar3: (PropType | undefined)) + @Provide({alias:"provideVar3",allowOverride:false}) set provideVar3(provideVar3: (PropType | undefined)) - get provideVar3(): (PropType | undefined) + @Provide({alias:"provideVar3",allowOverride:false}) get provideVar3(): (PropType | undefined) set __backing_provideVar3(__backing_provideVar3: (IProvideDecoratedVariable | undefined)) get __backing_provideVar3(): (IProvideDecoratedVariable | undefined) - set provideVar4(provideVar4: (Set | undefined)) + @Provide({alias:"provideVar4",allowOverride:false}) set provideVar4(provideVar4: (Set | undefined)) - get provideVar4(): (Set | undefined) + @Provide({alias:"provideVar4",allowOverride:false}) get provideVar4(): (Set | undefined) set __backing_provideVar4(__backing_provideVar4: (IProvideDecoratedVariable> | undefined)) get __backing_provideVar4(): (IProvideDecoratedVariable> | undefined) - set provideVar5(provideVar5: (Array | undefined)) + @Provide({alias:"provideVar5",allowOverride:false}) set provideVar5(provideVar5: (Array | undefined)) - get provideVar5(): (Array | undefined) + @Provide({alias:"provideVar5",allowOverride:false}) get provideVar5(): (Array | undefined) set __backing_provideVar5(__backing_provideVar5: (IProvideDecoratedVariable> | undefined)) get __backing_provideVar5(): (IProvideDecoratedVariable> | undefined) - set provideVar6(provideVar6: (Array | undefined)) + @Provide({alias:"provideVar6",allowOverride:false}) set provideVar6(provideVar6: (Array | undefined)) - get provideVar6(): (Array | undefined) + @Provide({alias:"provideVar6",allowOverride:false}) get provideVar6(): (Array | undefined) set __backing_provideVar6(__backing_provideVar6: (IProvideDecoratedVariable> | undefined)) get __backing_provideVar6(): (IProvideDecoratedVariable> | undefined) - set provideVar7(provideVar7: (Array | undefined)) + @Provide({alias:"provideVar7",allowOverride:false}) set provideVar7(provideVar7: (Array | undefined)) - get provideVar7(): (Array | undefined) + @Provide({alias:"provideVar7",allowOverride:false}) get provideVar7(): (Array | undefined) set __backing_provideVar7(__backing_provideVar7: (IProvideDecoratedVariable> | undefined)) get __backing_provideVar7(): (IProvideDecoratedVariable> | undefined) - set provideVar8(provideVar8: (((sr: string)=> void) | undefined)) + @Provide({alias:"provideVar8",allowOverride:false}) set provideVar8(provideVar8: (((sr: string)=> void) | undefined)) - get provideVar8(): (((sr: string)=> void) | undefined) + @Provide({alias:"provideVar8",allowOverride:false}) get provideVar8(): (((sr: string)=> void) | undefined) set __backing_provideVar8(__backing_provideVar8: (IProvideDecoratedVariable<((sr: string)=> void)> | undefined)) get __backing_provideVar8(): (IProvideDecoratedVariable<((sr: string)=> void)> | undefined) - set provideVar9(provideVar9: (Date | undefined)) + @Provide({alias:"provideVar9",allowOverride:false}) set provideVar9(provideVar9: (Date | undefined)) - get provideVar9(): (Date | undefined) + @Provide({alias:"provideVar9",allowOverride:false}) get provideVar9(): (Date | undefined) set __backing_provideVar9(__backing_provideVar9: (IProvideDecoratedVariable | undefined)) get __backing_provideVar9(): (IProvideDecoratedVariable | undefined) - set provideVar10(provideVar10: (Map | undefined)) + @Provide({alias:"provideVar10",allowOverride:false}) set provideVar10(provideVar10: (Map | undefined)) - get provideVar10(): (Map | undefined) + @Provide({alias:"provideVar10",allowOverride:false}) get provideVar10(): (Map | undefined) set __backing_provideVar10(__backing_provideVar10: (IProvideDecoratedVariable> | undefined)) get __backing_provideVar10(): (IProvideDecoratedVariable> | undefined) - set provideVar11(provideVar11: ((string | number) | undefined)) + @Provide({alias:"provideVar11",allowOverride:false}) set provideVar11(provideVar11: ((string | number) | undefined)) - get provideVar11(): ((string | number) | undefined) + @Provide({alias:"provideVar11",allowOverride:false}) get provideVar11(): ((string | number) | undefined) set __backing_provideVar11(__backing_provideVar11: (IProvideDecoratedVariable<(string | number)> | undefined)) get __backing_provideVar11(): (IProvideDecoratedVariable<(string | number)> | undefined) - set provideVar12(provideVar12: ((Set | Per) | undefined)) + @Provide({alias:"provideVar12",allowOverride:false}) set provideVar12(provideVar12: ((Set | Per) | undefined)) - get provideVar12(): ((Set | Per) | undefined) + @Provide({alias:"provideVar12",allowOverride:false}) get provideVar12(): ((Set | Per) | undefined) set __backing_provideVar12(__backing_provideVar12: (IProvideDecoratedVariable<(Set | Per)> | undefined)) get __backing_provideVar12(): (IProvideDecoratedVariable<(Set | Per)> | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/provide-to-consume.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/provide-to-consume.test.ts index e8293b0850962e81768187c46e8618535430bf13..c85863b6a288bf47a9e13276d4be44db2d2bde36 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/provide-to-consume.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/provide-and-consume/provide-to-consume.test.ts @@ -78,17 +78,17 @@ import { Consume as Consume, Provide as Provide } from "@ohos.arkui.stateManagem } @Component() export interface __Options_Child { - num?: number; + @Consume() num?: number; @Consume() __backing_num?: number; - str?: string; + @Consume({value:"ss"}) str?: string; @Consume({value:"ss"}) __backing_str?: string; } @Component() export interface __Options_Parent { - num?: number; + @Provide({alias:"num"}) num?: number; @Provide({alias:"num"}) __backing_num?: number; - str?: string; + @Provide({alias:"ss"}) str?: string; @Provide({alias:"ss"}) __backing_str?: string; } @@ -197,15 +197,15 @@ function main() {} } @Component() export interface __Options_Child { - set num(num: (number | undefined)) + @Consume({alias:""}) set num(num: (number | undefined)) - get num(): (number | undefined) + @Consume({alias:""}) get num(): (number | undefined) set __backing_num(__backing_num: (IConsumeDecoratedVariable | undefined)) get __backing_num(): (IConsumeDecoratedVariable | undefined) - set str(str: (string | undefined)) + @Consume({value:"ss"}) set str(str: (string | undefined)) - get str(): (string | undefined) + @Consume({value:"ss"}) get str(): (string | undefined) set __backing_str(__backing_str: (IConsumeDecoratedVariable | undefined)) get __backing_str(): (IConsumeDecoratedVariable | undefined) @@ -213,15 +213,15 @@ function main() {} } @Component() export interface __Options_Parent { - set num(num: (number | undefined)) + @Provide({alias:"num",allowOverride:false}) set num(num: (number | undefined)) - get num(): (number | undefined) + @Provide({alias:"num",allowOverride:false}) get num(): (number | undefined) set __backing_num(__backing_num: (IProvideDecoratedVariable | undefined)) get __backing_num(): (IProvideDecoratedVariable | undefined) - set str(str: (string | undefined)) + @Provide({alias:"ss",allowOverride:false}) set str(str: (string | undefined)) - get str(): (string | undefined) + @Provide({alias:"ss",allowOverride:false}) get str(): (string | undefined) set __backing_str(__backing_str: (IProvideDecoratedVariable | undefined)) get __backing_str(): (IProvideDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/consumer-basic-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/consumer-basic-type.test.ts index 477d67cb112c0504d4cf73ecbe86755ce66bf3d0..db83124cde9cfed32dc5ec30a21136a550f9e11b 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/consumer-basic-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/consumer-basic-type.test.ts @@ -122,33 +122,33 @@ function main() {} } @ComponentV2() export interface __Options_Parent { - set consumerVar1(consumerVar1: (string | undefined)) + @Consumer({alias:""}) set consumerVar1(consumerVar1: (string | undefined)) - get consumerVar1(): (string | undefined) + @Consumer({alias:""}) get consumerVar1(): (string | undefined) set __backing_consumerVar1(__backing_consumerVar1: (IConsumerDecoratedVariable | undefined)) get __backing_consumerVar1(): (IConsumerDecoratedVariable | undefined) - set consumerVar2(consumerVar2: (number | undefined)) + @Consumer({alias:""}) set consumerVar2(consumerVar2: (number | undefined)) - get consumerVar2(): (number | undefined) + @Consumer({alias:""}) get consumerVar2(): (number | undefined) set __backing_consumerVar2(__backing_consumerVar2: (IConsumerDecoratedVariable | undefined)) get __backing_consumerVar2(): (IConsumerDecoratedVariable | undefined) - set consumerVar3(consumerVar3: (boolean | undefined)) + @Consumer({alias:""}) set consumerVar3(consumerVar3: (boolean | undefined)) - get consumerVar3(): (boolean | undefined) + @Consumer({alias:""}) get consumerVar3(): (boolean | undefined) set __backing_consumerVar3(__backing_consumerVar3: (IConsumerDecoratedVariable | undefined)) get __backing_consumerVar3(): (IConsumerDecoratedVariable | undefined) - set consumerVar4(consumerVar4: (undefined | undefined)) + @Consumer({alias:""}) set consumerVar4(consumerVar4: (undefined | undefined)) - get consumerVar4(): (undefined | undefined) + @Consumer({alias:""}) get consumerVar4(): (undefined | undefined) set __backing_consumerVar4(__backing_consumerVar4: (IConsumerDecoratedVariable | undefined)) get __backing_consumerVar4(): (IConsumerDecoratedVariable | undefined) - set consumerVar5(consumerVar5: (null | undefined)) + @Consumer({alias:""}) set consumerVar5(consumerVar5: (null | undefined)) - get consumerVar5(): (null | undefined) + @Consumer({alias:""}) get consumerVar5(): (null | undefined) set __backing_consumerVar5(__backing_consumerVar5: (IConsumerDecoratedVariable | undefined)) get __backing_consumerVar5(): (IConsumerDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/consumer-complex-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/consumer-complex-type.test.ts index 559a912d3e382bc61456fbe21571365a0f7c7e42..c816348ebafd2cbc22d8a734a7d8184a9d8e0bcd 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/consumer-complex-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/consumer-complex-type.test.ts @@ -265,69 +265,69 @@ final class StateType extends BaseEnum { } @ComponentV2() export interface __Options_Parent { - set paramVar1(paramVar1: (Per | undefined)) + @Consumer({alias:""}) set paramVar1(paramVar1: (Per | undefined)) - get paramVar1(): (Per | undefined) + @Consumer({alias:""}) get paramVar1(): (Per | undefined) set __backing_paramVar1(__backing_paramVar1: (IConsumerDecoratedVariable | undefined)) get __backing_paramVar1(): (IConsumerDecoratedVariable | undefined) - set paramVar2(paramVar2: (Array | undefined)) + @Consumer({alias:""}) set paramVar2(paramVar2: (Array | undefined)) - get paramVar2(): (Array | undefined) + @Consumer({alias:""}) get paramVar2(): (Array | undefined) set __backing_paramVar2(__backing_paramVar2: (IConsumerDecoratedVariable> | undefined)) get __backing_paramVar2(): (IConsumerDecoratedVariable> | undefined) - set paramVar3(paramVar3: (StateType | undefined)) + @Consumer({alias:""}) set paramVar3(paramVar3: (StateType | undefined)) - get paramVar3(): (StateType | undefined) + @Consumer({alias:""}) get paramVar3(): (StateType | undefined) set __backing_paramVar3(__backing_paramVar3: (IConsumerDecoratedVariable | undefined)) get __backing_paramVar3(): (IConsumerDecoratedVariable | undefined) - set paramVar4(paramVar4: (Set | undefined)) + @Consumer({alias:""}) set paramVar4(paramVar4: (Set | undefined)) - get paramVar4(): (Set | undefined) + @Consumer({alias:""}) get paramVar4(): (Set | undefined) set __backing_paramVar4(__backing_paramVar4: (IConsumerDecoratedVariable> | undefined)) get __backing_paramVar4(): (IConsumerDecoratedVariable> | undefined) - set paramVar5(paramVar5: (Array | undefined)) + @Consumer({alias:""}) set paramVar5(paramVar5: (Array | undefined)) - get paramVar5(): (Array | undefined) + @Consumer({alias:""}) get paramVar5(): (Array | undefined) set __backing_paramVar5(__backing_paramVar5: (IConsumerDecoratedVariable> | undefined)) get __backing_paramVar5(): (IConsumerDecoratedVariable> | undefined) - set paramVar6(paramVar6: (Array | undefined)) + @Consumer({alias:""}) set paramVar6(paramVar6: (Array | undefined)) - get paramVar6(): (Array | undefined) + @Consumer({alias:""}) get paramVar6(): (Array | undefined) set __backing_paramVar6(__backing_paramVar6: (IConsumerDecoratedVariable> | undefined)) get __backing_paramVar6(): (IConsumerDecoratedVariable> | undefined) - set paramVar7(paramVar7: (Array | undefined)) + @Consumer({alias:""}) set paramVar7(paramVar7: (Array | undefined)) - get paramVar7(): (Array | undefined) + @Consumer({alias:""}) get paramVar7(): (Array | undefined) set __backing_paramVar7(__backing_paramVar7: (IConsumerDecoratedVariable> | undefined)) get __backing_paramVar7(): (IConsumerDecoratedVariable> | undefined) - set paramVar9(paramVar9: (Date | undefined)) + @Consumer({alias:""}) set paramVar9(paramVar9: (Date | undefined)) - get paramVar9(): (Date | undefined) + @Consumer({alias:""}) get paramVar9(): (Date | undefined) set __backing_paramVar9(__backing_paramVar9: (IConsumerDecoratedVariable | undefined)) get __backing_paramVar9(): (IConsumerDecoratedVariable | undefined) - set paramVar10(paramVar10: (Map | undefined)) + @Consumer({alias:""}) set paramVar10(paramVar10: (Map | undefined)) - get paramVar10(): (Map | undefined) + @Consumer({alias:""}) get paramVar10(): (Map | undefined) set __backing_paramVar10(__backing_paramVar10: (IConsumerDecoratedVariable> | undefined)) get __backing_paramVar10(): (IConsumerDecoratedVariable> | undefined) - set paramVar11(paramVar11: ((string | number) | undefined)) + @Consumer({alias:""}) set paramVar11(paramVar11: ((string | number) | undefined)) - get paramVar11(): ((string | number) | undefined) + @Consumer({alias:""}) get paramVar11(): ((string | number) | undefined) set __backing_paramVar11(__backing_paramVar11: (IConsumerDecoratedVariable<(string | number)> | undefined)) get __backing_paramVar11(): (IConsumerDecoratedVariable<(string | number)> | undefined) - set paramVar12(paramVar12: ((Set | Per) | undefined)) + @Consumer({alias:""}) set paramVar12(paramVar12: ((Set | Per) | undefined)) - get paramVar12(): ((Set | Per) | undefined) + @Consumer({alias:""}) get paramVar12(): ((Set | Per) | undefined) set __backing_paramVar12(__backing_paramVar12: (IConsumerDecoratedVariable<(Set | Per)> | undefined)) get __backing_paramVar12(): (IConsumerDecoratedVariable<(Set | Per)> | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/provider-basic-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/provider-basic-type.test.ts index 4727c0342ca2b0e9cb759c181b1119986235b63e..70c841919bd11bf951269ef2df528c75f5dc94e4 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/provider-basic-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/provider-basic-type.test.ts @@ -122,33 +122,33 @@ function main() {} } @ComponentV2() export interface __Options_Parent { - set providerVar1(providerVar1: (string | undefined)) + @Provider({alias:""}) set providerVar1(providerVar1: (string | undefined)) - get providerVar1(): (string | undefined) + @Provider({alias:""}) get providerVar1(): (string | undefined) set __backing_providerVar1(__backing_providerVar1: (IProviderDecoratedVariable | undefined)) get __backing_providerVar1(): (IProviderDecoratedVariable | undefined) - set providerVar2(providerVar2: (number | undefined)) + @Provider({alias:""}) set providerVar2(providerVar2: (number | undefined)) - get providerVar2(): (number | undefined) + @Provider({alias:""}) get providerVar2(): (number | undefined) set __backing_providerVar2(__backing_providerVar2: (IProviderDecoratedVariable | undefined)) get __backing_providerVar2(): (IProviderDecoratedVariable | undefined) - set providerVar3(providerVar3: (boolean | undefined)) + @Provider({alias:""}) set providerVar3(providerVar3: (boolean | undefined)) - get providerVar3(): (boolean | undefined) + @Provider({alias:""}) get providerVar3(): (boolean | undefined) set __backing_providerVar3(__backing_providerVar3: (IProviderDecoratedVariable | undefined)) get __backing_providerVar3(): (IProviderDecoratedVariable | undefined) - set providerVar4(providerVar4: (undefined | undefined)) + @Provider({alias:""}) set providerVar4(providerVar4: (undefined | undefined)) - get providerVar4(): (undefined | undefined) + @Provider({alias:""}) get providerVar4(): (undefined | undefined) set __backing_providerVar4(__backing_providerVar4: (IProviderDecoratedVariable | undefined)) get __backing_providerVar4(): (IProviderDecoratedVariable | undefined) - set providerVar5(providerVar5: (null | undefined)) + @Provider({alias:""}) set providerVar5(providerVar5: (null | undefined)) - get providerVar5(): (null | undefined) + @Provider({alias:""}) get providerVar5(): (null | undefined) set __backing_providerVar5(__backing_providerVar5: (IProviderDecoratedVariable | undefined)) get __backing_providerVar5(): (IProviderDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/provider-complex-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/provider-complex-type.test.ts index 8365360d0eb2f64cb1b1af3afcb77772658176c4..17ac972f71ef42167a69b0622ec6b42133e60135 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/provider-complex-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/provider-complex-type.test.ts @@ -265,69 +265,69 @@ final class StateType extends BaseEnum { } @ComponentV2() export interface __Options_Parent { - set paramVar1(paramVar1: (Per | undefined)) + @Provider({alias:""}) set paramVar1(paramVar1: (Per | undefined)) - get paramVar1(): (Per | undefined) + @Provider({alias:""}) get paramVar1(): (Per | undefined) set __backing_paramVar1(__backing_paramVar1: (IProviderDecoratedVariable | undefined)) get __backing_paramVar1(): (IProviderDecoratedVariable | undefined) - set paramVar2(paramVar2: (Array | undefined)) + @Provider({alias:""}) set paramVar2(paramVar2: (Array | undefined)) - get paramVar2(): (Array | undefined) + @Provider({alias:""}) get paramVar2(): (Array | undefined) set __backing_paramVar2(__backing_paramVar2: (IProviderDecoratedVariable> | undefined)) get __backing_paramVar2(): (IProviderDecoratedVariable> | undefined) - set paramVar3(paramVar3: (StateType | undefined)) + @Provider({alias:""}) set paramVar3(paramVar3: (StateType | undefined)) - get paramVar3(): (StateType | undefined) + @Provider({alias:""}) get paramVar3(): (StateType | undefined) set __backing_paramVar3(__backing_paramVar3: (IProviderDecoratedVariable | undefined)) get __backing_paramVar3(): (IProviderDecoratedVariable | undefined) - set paramVar4(paramVar4: (Set | undefined)) + @Provider({alias:""}) set paramVar4(paramVar4: (Set | undefined)) - get paramVar4(): (Set | undefined) + @Provider({alias:""}) get paramVar4(): (Set | undefined) set __backing_paramVar4(__backing_paramVar4: (IProviderDecoratedVariable> | undefined)) get __backing_paramVar4(): (IProviderDecoratedVariable> | undefined) - set paramVar5(paramVar5: (Array | undefined)) + @Provider({alias:""}) set paramVar5(paramVar5: (Array | undefined)) - get paramVar5(): (Array | undefined) + @Provider({alias:""}) get paramVar5(): (Array | undefined) set __backing_paramVar5(__backing_paramVar5: (IProviderDecoratedVariable> | undefined)) get __backing_paramVar5(): (IProviderDecoratedVariable> | undefined) - set paramVar6(paramVar6: (Array | undefined)) + @Provider({alias:""}) set paramVar6(paramVar6: (Array | undefined)) - get paramVar6(): (Array | undefined) + @Provider({alias:""}) get paramVar6(): (Array | undefined) set __backing_paramVar6(__backing_paramVar6: (IProviderDecoratedVariable> | undefined)) get __backing_paramVar6(): (IProviderDecoratedVariable> | undefined) - set paramVar7(paramVar7: (Array | undefined)) + @Provider({alias:""}) set paramVar7(paramVar7: (Array | undefined)) - get paramVar7(): (Array | undefined) + @Provider({alias:""}) get paramVar7(): (Array | undefined) set __backing_paramVar7(__backing_paramVar7: (IProviderDecoratedVariable> | undefined)) get __backing_paramVar7(): (IProviderDecoratedVariable> | undefined) - set paramVar9(paramVar9: (Date | undefined)) + @Provider({alias:""}) set paramVar9(paramVar9: (Date | undefined)) - get paramVar9(): (Date | undefined) + @Provider({alias:""}) get paramVar9(): (Date | undefined) set __backing_paramVar9(__backing_paramVar9: (IProviderDecoratedVariable | undefined)) get __backing_paramVar9(): (IProviderDecoratedVariable | undefined) - set paramVar10(paramVar10: (Map | undefined)) + @Provider({alias:""}) set paramVar10(paramVar10: (Map | undefined)) - get paramVar10(): (Map | undefined) + @Provider({alias:""}) get paramVar10(): (Map | undefined) set __backing_paramVar10(__backing_paramVar10: (IProviderDecoratedVariable> | undefined)) get __backing_paramVar10(): (IProviderDecoratedVariable> | undefined) - set paramVar11(paramVar11: ((string | number) | undefined)) + @Provider({alias:""}) set paramVar11(paramVar11: ((string | number) | undefined)) - get paramVar11(): ((string | number) | undefined) + @Provider({alias:""}) get paramVar11(): ((string | number) | undefined) set __backing_paramVar11(__backing_paramVar11: (IProviderDecoratedVariable<(string | number)> | undefined)) get __backing_paramVar11(): (IProviderDecoratedVariable<(string | number)> | undefined) - set paramVar12(paramVar12: ((Set | Per) | undefined)) + @Provider({alias:""}) set paramVar12(paramVar12: ((Set | Per) | undefined)) - get paramVar12(): ((Set | Per) | undefined) + @Provider({alias:""}) get paramVar12(): ((Set | Per) | undefined) set __backing_paramVar12(__backing_paramVar12: (IProviderDecoratedVariable<(Set | Per)> | undefined)) get __backing_paramVar12(): (IProviderDecoratedVariable<(Set | Per)> | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/provider-to-consumer.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/provider-to-consumer.test.ts index d6e40550d2e43a4eac62bed3c970e85cea5f203d..53196c0959767915984035ad8b4ce42debe979a0 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/provider-to-consumer.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/provider-and-consumer/provider-to-consumer.test.ts @@ -225,9 +225,9 @@ function main() {} } @ComponentV2() export interface __Options_Parent { - set users(users: (Array | undefined)) + @Provider({value:"data"}) set users(users: (Array | undefined)) - get users(): (Array | undefined) + @Provider({value:"data"}) get users(): (Array | undefined) set __backing_users(__backing_users: (IProviderDecoratedVariable> | undefined)) get __backing_users(): (IProviderDecoratedVariable> | undefined) @@ -235,9 +235,9 @@ function main() {} } @ComponentV2() export interface __Options_Child { - set users(users: (Array | undefined)) + @Consumer({value:"data"}) set users(users: (Array | undefined)) - get users(): (Array | undefined) + @Consumer({value:"data"}) get users(): (Array | undefined) set __backing_users(__backing_users: (IConsumerDecoratedVariable> | undefined)) get __backing_users(): (IConsumerDecoratedVariable> | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/require/basic-require.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/require/basic-require.test.ts index 659935b0028cadb56a65258f91ae607ee1f508a7..bf66aa998f7d4fae1a5b54c56543d2832621c2b8 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/require/basic-require.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/require/basic-require.test.ts @@ -72,27 +72,27 @@ import { State as State, Require as Require, Prop as Prop, Provide as Provide, P @Component() export interface __Options_MyStateSample { hello?: string; - state1?: boolean; + @State() state1?: boolean; @State() __backing_state1?: boolean; - select100?: string; - select0?: number; + @Require() select100?: string; + @State() @Require() select0?: number; @State() __backing_select0?: number; - select3?: (number | null); + @State() @Require() select3?: (number | null); @State() __backing_select3?: (number | null); - select4?: undefined; + @State() @Require() select4?: undefined; @State() __backing_select4?: undefined; - select1?: string; + @Prop() @Require() select1?: string; @Prop() __backing_select1?: string; - select2?: string[]; + @Provide({alias:"15"}) @Require() select2?: string[]; @Provide({alias:"15"}) __backing_select2?: string[]; - select6?: (string[] | undefined | string); + @Provide({alias:"t"}) @Require() select6?: (string[] | undefined | string); @Provide({alias:"t"}) __backing_select6?: (string[] | undefined | string); - @BuilderParam() builder?: (()=> void); + @BuilderParam() @Require() builder?: (()=> void); } @ComponentV2() export interface __Options_V2222 { - select1?: string; + @Param() @Require() select1?: string; @Param() __backing_select1?: string; } @@ -271,61 +271,61 @@ function main() {} set hello(hello: (string | undefined)) get hello(): (string | undefined) - set state1(state1: (boolean | undefined)) + @State() set state1(state1: (boolean | undefined)) - get state1(): (boolean | undefined) + @State() get state1(): (boolean | undefined) set __backing_state1(__backing_state1: (IStateDecoratedVariable | undefined)) get __backing_state1(): (IStateDecoratedVariable | undefined) - set select100(select100: (string | undefined)) + @Require() set select100(select100: (string | undefined)) - get select100(): (string | undefined) - set select0(select0: (number | undefined)) + @Require() get select100(): (string | undefined) + @State() @Require() set select0(select0: (number | undefined)) - get select0(): (number | undefined) + @State() @Require() get select0(): (number | undefined) set __backing_select0(__backing_select0: (IStateDecoratedVariable | undefined)) get __backing_select0(): (IStateDecoratedVariable | undefined) - set select3(select3: ((number | null) | undefined)) + @State() @Require() set select3(select3: ((number | null) | undefined)) - get select3(): ((number | null) | undefined) + @State() @Require() get select3(): ((number | null) | undefined) set __backing_select3(__backing_select3: (IStateDecoratedVariable<(number | null)> | undefined)) get __backing_select3(): (IStateDecoratedVariable<(number | null)> | undefined) - set select4(select4: (undefined | undefined)) + @State() @Require() set select4(select4: (undefined | undefined)) - get select4(): (undefined | undefined) + @State() @Require() get select4(): (undefined | undefined) set __backing_select4(__backing_select4: (IStateDecoratedVariable | undefined)) get __backing_select4(): (IStateDecoratedVariable | undefined) - set select1(select1: (string | undefined)) + @Prop() @Require() set select1(select1: (string | undefined)) - get select1(): (string | undefined) + @Prop() @Require() get select1(): (string | undefined) set __backing_select1(__backing_select1: (IPropDecoratedVariable | undefined)) get __backing_select1(): (IPropDecoratedVariable | undefined) - set select2(select2: (Array | undefined)) + @Provide({alias:"15",allowOverride:false}) @Require() set select2(select2: (Array | undefined)) - get select2(): (Array | undefined) + @Provide({alias:"15",allowOverride:false}) @Require() get select2(): (Array | undefined) set __backing_select2(__backing_select2: (IProvideDecoratedVariable> | undefined)) get __backing_select2(): (IProvideDecoratedVariable> | undefined) - set select6(select6: ((Array | undefined | string) | undefined)) + @Provide({alias:"t",allowOverride:false}) @Require() set select6(select6: ((Array | undefined | string) | undefined)) - get select6(): ((Array | undefined | string) | undefined) + @Provide({alias:"t",allowOverride:false}) @Require() get select6(): ((Array | undefined | string) | undefined) set __backing_select6(__backing_select6: (IProvideDecoratedVariable<(Array | undefined | string)> | undefined)) get __backing_select6(): (IProvideDecoratedVariable<(Array | undefined | string)> | undefined) - set builder(builder: (@memo() (()=> void) | undefined)) + @Require() set builder(builder: (@memo() (()=> void) | undefined)) - get builder(): (@memo() (()=> void) | undefined) + @Require() get builder(): (@memo() (()=> void) | undefined) } @ComponentV2() export interface __Options_V2222 { - set select1(select1: (string | undefined)) + @Param() @Require() set select1(select1: (string | undefined)) - get select1(): (string | undefined) + @Param() @Require() get select1(): (string | undefined) set __backing_select1(__backing_select1: (IParamDecoratedVariable | undefined)) get __backing_select1(): (IParamDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/reusable/reusable-basic.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/reusable/reusable-basic.test.ts index 6b65444af55b5a19ddc7fa6c158a723e361457b4..94b38b10b37f4bdc8f7d1f12d4baca11fda6bf62 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/reusable/reusable-basic.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/reusable/reusable-basic.test.ts @@ -128,15 +128,15 @@ function main() {} } @Component() @Reusable() export interface __Options_Child { - set num(num: (number | undefined)) + @Prop() set num(num: (number | undefined)) - get num(): (number | undefined) + @Prop() get num(): (number | undefined) set __backing_num(__backing_num: (IPropDecoratedVariable | undefined)) get __backing_num(): (IPropDecoratedVariable | undefined) - set num1(num1: (number | undefined)) + @State() set num1(num1: (number | undefined)) - get num1(): (number | undefined) + @State() get num1(): (number | undefined) set __backing_num1(__backing_num1: (IStateDecoratedVariable | undefined)) get __backing_num1(): (IStateDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/reusable/reusable-complex.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/reusable/reusable-complex.test.ts index f741b2deab05a38e4569d2a15348d2d6c7523ddb..a4258e596b2da4dcaed700568283f9341fbc2861 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/reusable/reusable-complex.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/reusable/reusable-complex.test.ts @@ -180,9 +180,9 @@ class Message { } @Entry({useSharedStorage:false,storage:"",routeName:""}) @Component() export interface __Options_Index { - set display(display: (boolean | undefined)) + @State() set display(display: (boolean | undefined)) - get display(): (boolean | undefined) + @State() get display(): (boolean | undefined) set __backing_display(__backing_display: (IStateDecoratedVariable | undefined)) get __backing_display(): (IStateDecoratedVariable | undefined) @@ -190,9 +190,9 @@ class Message { } @Reusable() @Component() export interface __Options_Child { - set message(message: (Message | undefined)) + @State() set message(message: (Message | undefined)) - get message(): (Message | undefined) + @State() get message(): (Message | undefined) set __backing_message(__backing_message: (IStateDecoratedVariable | undefined)) get __backing_message(): (IStateDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/state/state-basic-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/state/state-basic-type.test.ts index 61b13a9fac382565a58d0e55742ebd9bb78ce567..a9f88d4e3e11ee18f1ee7cb228f359ae1bd751cf 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/state/state-basic-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/state/state-basic-type.test.ts @@ -129,33 +129,33 @@ function main() {} } @Component() export interface __Options_Parent { - set stateVar1(stateVar1: (string | undefined)) + @State() set stateVar1(stateVar1: (string | undefined)) - get stateVar1(): (string | undefined) + @State() get stateVar1(): (string | undefined) set __backing_stateVar1(__backing_stateVar1: (IStateDecoratedVariable | undefined)) get __backing_stateVar1(): (IStateDecoratedVariable | undefined) - set stateVar2(stateVar2: (number | undefined)) + @State() set stateVar2(stateVar2: (number | undefined)) - get stateVar2(): (number | undefined) + @State() get stateVar2(): (number | undefined) set __backing_stateVar2(__backing_stateVar2: (IStateDecoratedVariable | undefined)) get __backing_stateVar2(): (IStateDecoratedVariable | undefined) - set stateVar3(stateVar3: (boolean | undefined)) + @State() set stateVar3(stateVar3: (boolean | undefined)) - get stateVar3(): (boolean | undefined) + @State() get stateVar3(): (boolean | undefined) set __backing_stateVar3(__backing_stateVar3: (IStateDecoratedVariable | undefined)) get __backing_stateVar3(): (IStateDecoratedVariable | undefined) - set stateVar4(stateVar4: (undefined | undefined)) + @State() set stateVar4(stateVar4: (undefined | undefined)) - get stateVar4(): (undefined | undefined) + @State() get stateVar4(): (undefined | undefined) set __backing_stateVar4(__backing_stateVar4: (IStateDecoratedVariable | undefined)) get __backing_stateVar4(): (IStateDecoratedVariable | undefined) - set stateVar5(stateVar5: (null | undefined)) + @State() set stateVar5(stateVar5: (null | undefined)) - get stateVar5(): (null | undefined) + @State() get stateVar5(): (null | undefined) set __backing_stateVar5(__backing_stateVar5: (IStateDecoratedVariable | undefined)) get __backing_stateVar5(): (IStateDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/state/state-complex-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/state/state-complex-type.test.ts index d53dcb99ec1b9b9138bf5503cb66896fc0433b26..9049e685921798bbf39b650e91fc50c8d5959e8e 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/state/state-complex-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/state/state-complex-type.test.ts @@ -287,75 +287,75 @@ final class StateType extends BaseEnum { } @Component() export interface __Options_Parent { - set stateVar1(stateVar1: (Per | undefined)) + @State() set stateVar1(stateVar1: (Per | undefined)) - get stateVar1(): (Per | undefined) + @State() get stateVar1(): (Per | undefined) set __backing_stateVar1(__backing_stateVar1: (IStateDecoratedVariable | undefined)) get __backing_stateVar1(): (IStateDecoratedVariable | undefined) - set stateVar2(stateVar2: (Array | undefined)) + @State() set stateVar2(stateVar2: (Array | undefined)) - get stateVar2(): (Array | undefined) + @State() get stateVar2(): (Array | undefined) set __backing_stateVar2(__backing_stateVar2: (IStateDecoratedVariable> | undefined)) get __backing_stateVar2(): (IStateDecoratedVariable> | undefined) - set stateVar3(stateVar3: (StateType | undefined)) + @State() set stateVar3(stateVar3: (StateType | undefined)) - get stateVar3(): (StateType | undefined) + @State() get stateVar3(): (StateType | undefined) set __backing_stateVar3(__backing_stateVar3: (IStateDecoratedVariable | undefined)) get __backing_stateVar3(): (IStateDecoratedVariable | undefined) - set stateVar4(stateVar4: (Set | undefined)) + @State() set stateVar4(stateVar4: (Set | undefined)) - get stateVar4(): (Set | undefined) + @State() get stateVar4(): (Set | undefined) set __backing_stateVar4(__backing_stateVar4: (IStateDecoratedVariable> | undefined)) get __backing_stateVar4(): (IStateDecoratedVariable> | undefined) - set stateVar5(stateVar5: (Array | undefined)) + @State() set stateVar5(stateVar5: (Array | undefined)) - get stateVar5(): (Array | undefined) + @State() get stateVar5(): (Array | undefined) set __backing_stateVar5(__backing_stateVar5: (IStateDecoratedVariable> | undefined)) get __backing_stateVar5(): (IStateDecoratedVariable> | undefined) - set stateVar6(stateVar6: (Array | undefined)) + @State() set stateVar6(stateVar6: (Array | undefined)) - get stateVar6(): (Array | undefined) + @State() get stateVar6(): (Array | undefined) set __backing_stateVar6(__backing_stateVar6: (IStateDecoratedVariable> | undefined)) get __backing_stateVar6(): (IStateDecoratedVariable> | undefined) - set stateVar7(stateVar7: (Array | undefined)) + @State() set stateVar7(stateVar7: (Array | undefined)) - get stateVar7(): (Array | undefined) + @State() get stateVar7(): (Array | undefined) set __backing_stateVar7(__backing_stateVar7: (IStateDecoratedVariable> | undefined)) get __backing_stateVar7(): (IStateDecoratedVariable> | undefined) - set stateVar8(stateVar8: (((sr: string)=> void) | undefined)) + @State() set stateVar8(stateVar8: (((sr: string)=> void) | undefined)) - get stateVar8(): (((sr: string)=> void) | undefined) + @State() get stateVar8(): (((sr: string)=> void) | undefined) set __backing_stateVar8(__backing_stateVar8: (IStateDecoratedVariable<((sr: string)=> void)> | undefined)) get __backing_stateVar8(): (IStateDecoratedVariable<((sr: string)=> void)> | undefined) - set stateVar9(stateVar9: (Date | undefined)) + @State() set stateVar9(stateVar9: (Date | undefined)) - get stateVar9(): (Date | undefined) + @State() get stateVar9(): (Date | undefined) set __backing_stateVar9(__backing_stateVar9: (IStateDecoratedVariable | undefined)) get __backing_stateVar9(): (IStateDecoratedVariable | undefined) - set stateVar10(stateVar10: (Map | undefined)) + @State() set stateVar10(stateVar10: (Map | undefined)) - get stateVar10(): (Map | undefined) + @State() get stateVar10(): (Map | undefined) set __backing_stateVar10(__backing_stateVar10: (IStateDecoratedVariable> | undefined)) get __backing_stateVar10(): (IStateDecoratedVariable> | undefined) - set stateVar11(stateVar11: ((string | number) | undefined)) + @State() set stateVar11(stateVar11: ((string | number) | undefined)) - get stateVar11(): ((string | number) | undefined) + @State() get stateVar11(): ((string | number) | undefined) set __backing_stateVar11(__backing_stateVar11: (IStateDecoratedVariable<(string | number)> | undefined)) get __backing_stateVar11(): (IStateDecoratedVariable<(string | number)> | undefined) - set stateVar12(stateVar12: ((Set | Per) | undefined)) + @State() set stateVar12(stateVar12: ((Set | Per) | undefined)) - get stateVar12(): ((Set | Per) | undefined) + @State() get stateVar12(): ((Set | Per) | undefined) set __backing_stateVar12(__backing_stateVar12: (IStateDecoratedVariable<(Set | Per)> | undefined)) get __backing_stateVar12(): (IStateDecoratedVariable<(Set | Per)> | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/state/state-to-state.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/state/state-to-state.test.ts index 09310a680a09e9e00d1b8cec60af3181d182e530..a1fa5fd87ba95f15489c69a4b2c0eb602fb65df4 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/state/state-to-state.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/state/state-to-state.test.ts @@ -124,9 +124,9 @@ class Per { } @Component() export interface __Options_Parent { - set parentVar1(parentVar1: (Per | undefined)) + @State() set parentVar1(parentVar1: (Per | undefined)) - get parentVar1(): (Per | undefined) + @State() get parentVar1(): (Per | undefined) set __backing_parentVar1(__backing_parentVar1: (IStateDecoratedVariable | undefined)) get __backing_parentVar1(): (IStateDecoratedVariable | undefined) @@ -134,9 +134,9 @@ class Per { } @Component() export interface __Options_Child { - set childVar1(childVar1: (Per | undefined)) + @State() set childVar1(childVar1: (Per | undefined)) - get childVar1(): (Per | undefined) + @State() get childVar1(): (Per | undefined) set __backing_childVar1(__backing_childVar1: (IStateDecoratedVariable | undefined)) get __backing_childVar1(): (IStateDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/storagelink/storagelink-appstorage.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/storagelink/storagelink-appstorage.test.ts index 8216a6a04ef4d1408c4c7f253204f19faa0691c2..e32943ac7f6fda69b4af67450186018cc4157aa5 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/storagelink/storagelink-appstorage.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/storagelink/storagelink-appstorage.test.ts @@ -119,15 +119,15 @@ class Data { } @Entry({useSharedStorage:false,storage:"",routeName:""}) @Component() export interface __Options_Index { - set storageLink(storageLink: (number | undefined)) + @StorageLink({value:"PropA"}) set storageLink(storageLink: (number | undefined)) - get storageLink(): (number | undefined) + @StorageLink({value:"PropA"}) get storageLink(): (number | undefined) set __backing_storageLink(__backing_storageLink: (IStorageLinkDecoratedVariable | undefined)) get __backing_storageLink(): (IStorageLinkDecoratedVariable | undefined) - set storageLinkObject(storageLinkObject: (Data | undefined)) + @StorageLink({value:"PropB"}) set storageLinkObject(storageLinkObject: (Data | undefined)) - get storageLinkObject(): (Data | undefined) + @StorageLink({value:"PropB"}) get storageLinkObject(): (Data | undefined) set __backing_storageLinkObject(__backing_storageLinkObject: (IStorageLinkDecoratedVariable | undefined)) get __backing_storageLinkObject(): (IStorageLinkDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/storagelink/storagelink-complex-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/storagelink/storagelink-complex-type.test.ts index dfed251b28cef5b1b176c9ba4ca20be176f11916..21540b68f2a7471c350fbc56f831aed9fd0df7a5 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/storagelink/storagelink-complex-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/storagelink/storagelink-complex-type.test.ts @@ -223,45 +223,45 @@ final class Status extends BaseEnum { } @Entry({useSharedStorage:false,storage:"",routeName:""}) @Component() export interface __Options_MyStateSample { - set arrayA(arrayA: (Array | undefined)) + @StorageLink({value:"Prop1"}) set arrayA(arrayA: (Array | undefined)) - get arrayA(): (Array | undefined) + @StorageLink({value:"Prop1"}) get arrayA(): (Array | undefined) set __backing_arrayA(__backing_arrayA: (IStorageLinkDecoratedVariable> | undefined)) get __backing_arrayA(): (IStorageLinkDecoratedVariable> | undefined) - set objectA(objectA: (Object | undefined)) + @StorageLink({value:"Prop2"}) set objectA(objectA: (Object | undefined)) - get objectA(): (Object | undefined) + @StorageLink({value:"Prop2"}) get objectA(): (Object | undefined) set __backing_objectA(__backing_objectA: (IStorageLinkDecoratedVariable | undefined)) get __backing_objectA(): (IStorageLinkDecoratedVariable | undefined) - set dateA(dateA: (Date | undefined)) + @StorageLink({value:"Prop3"}) set dateA(dateA: (Date | undefined)) - get dateA(): (Date | undefined) + @StorageLink({value:"Prop3"}) get dateA(): (Date | undefined) set __backing_dateA(__backing_dateA: (IStorageLinkDecoratedVariable | undefined)) get __backing_dateA(): (IStorageLinkDecoratedVariable | undefined) - set setA(setA: (Set | undefined)) + @StorageLink({value:"Prop4"}) set setA(setA: (Set | undefined)) - get setA(): (Set | undefined) + @StorageLink({value:"Prop4"}) get setA(): (Set | undefined) set __backing_setA(__backing_setA: (IStorageLinkDecoratedVariable> | undefined)) get __backing_setA(): (IStorageLinkDecoratedVariable> | undefined) - set mapA(mapA: (Map | undefined)) + @StorageLink({value:"Prop5"}) set mapA(mapA: (Map | undefined)) - get mapA(): (Map | undefined) + @StorageLink({value:"Prop5"}) get mapA(): (Map | undefined) set __backing_mapA(__backing_mapA: (IStorageLinkDecoratedVariable> | undefined)) get __backing_mapA(): (IStorageLinkDecoratedVariable> | undefined) - set classA(classA: (Person | undefined)) + @StorageLink({value:"Prop7"}) set classA(classA: (Person | undefined)) - get classA(): (Person | undefined) + @StorageLink({value:"Prop7"}) get classA(): (Person | undefined) set __backing_classA(__backing_classA: (IStorageLinkDecoratedVariable | undefined)) get __backing_classA(): (IStorageLinkDecoratedVariable | undefined) - set enumA(enumA: (Status | undefined)) + @StorageLink({value:"Prop8"}) set enumA(enumA: (Status | undefined)) - get enumA(): (Status | undefined) + @StorageLink({value:"Prop8"}) get enumA(): (Status | undefined) set __backing_enumA(__backing_enumA: (IStorageLinkDecoratedVariable | undefined)) get __backing_enumA(): (IStorageLinkDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/storagelink/storagelink-primitive-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/storagelink/storagelink-primitive-type.test.ts index 2b544b79425efc9ef6a6f09ede490c002b4f8bb0..ac9261e4a1486fb402ef4128d37249f3c57b1e2a 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/storagelink/storagelink-primitive-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/storagelink/storagelink-primitive-type.test.ts @@ -104,21 +104,21 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ } @Entry({useSharedStorage:false,storage:"",routeName:""}) @Component() export interface __Options_MyStateSample { - set numA(numA: (number | undefined)) + @StorageLink({value:"Prop1"}) set numA(numA: (number | undefined)) - get numA(): (number | undefined) + @StorageLink({value:"Prop1"}) get numA(): (number | undefined) set __backing_numA(__backing_numA: (IStorageLinkDecoratedVariable | undefined)) get __backing_numA(): (IStorageLinkDecoratedVariable | undefined) - set stringA(stringA: (string | undefined)) + @StorageLink({value:"Prop2"}) set stringA(stringA: (string | undefined)) - get stringA(): (string | undefined) + @StorageLink({value:"Prop2"}) get stringA(): (string | undefined) set __backing_stringA(__backing_stringA: (IStorageLinkDecoratedVariable | undefined)) get __backing_stringA(): (IStorageLinkDecoratedVariable | undefined) - set booleanA(booleanA: (boolean | undefined)) + @StorageLink({value:"Prop3"}) set booleanA(booleanA: (boolean | undefined)) - get booleanA(): (boolean | undefined) + @StorageLink({value:"Prop3"}) get booleanA(): (boolean | undefined) set __backing_booleanA(__backing_booleanA: (IStorageLinkDecoratedVariable | undefined)) get __backing_booleanA(): (IStorageLinkDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/storageprop-ref/storageprop-ref-complex-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/storageprop-ref/storageprop-ref-complex-type.test.ts index 60263a47116d7d3ecf0d42222eaaabde9fcd0f43..686d5a3129f8d00da6311b1e9d813cb5acfde8f9 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/storageprop-ref/storageprop-ref-complex-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/storageprop-ref/storageprop-ref-complex-type.test.ts @@ -219,45 +219,45 @@ final class Status extends BaseEnum { } @Component() export interface __Options_MyStateSample { - set arrayB(arrayB: (Array | undefined)) + @StoragePropRef({value:"Prop1"}) set arrayB(arrayB: (Array | undefined)) - get arrayB(): (Array | undefined) + @StoragePropRef({value:"Prop1"}) get arrayB(): (Array | undefined) set __backing_arrayB(__backing_arrayB: (IStoragePropRefDecoratedVariable> | undefined)) get __backing_arrayB(): (IStoragePropRefDecoratedVariable> | undefined) - set objectB(objectB: (Object | undefined)) + @StoragePropRef({value:"Prop2"}) set objectB(objectB: (Object | undefined)) - get objectB(): (Object | undefined) + @StoragePropRef({value:"Prop2"}) get objectB(): (Object | undefined) set __backing_objectB(__backing_objectB: (IStoragePropRefDecoratedVariable | undefined)) get __backing_objectB(): (IStoragePropRefDecoratedVariable | undefined) - set dateB(dateB: (Date | undefined)) + @StoragePropRef({value:"Prop3"}) set dateB(dateB: (Date | undefined)) - get dateB(): (Date | undefined) + @StoragePropRef({value:"Prop3"}) get dateB(): (Date | undefined) set __backing_dateB(__backing_dateB: (IStoragePropRefDecoratedVariable | undefined)) get __backing_dateB(): (IStoragePropRefDecoratedVariable | undefined) - set setB(setB: (Set | undefined)) + @StoragePropRef({value:"Prop4"}) set setB(setB: (Set | undefined)) - get setB(): (Set | undefined) + @StoragePropRef({value:"Prop4"}) get setB(): (Set | undefined) set __backing_setB(__backing_setB: (IStoragePropRefDecoratedVariable> | undefined)) get __backing_setB(): (IStoragePropRefDecoratedVariable> | undefined) - set mapB(mapB: (Map | undefined)) + @StoragePropRef({value:"Prop5"}) set mapB(mapB: (Map | undefined)) - get mapB(): (Map | undefined) + @StoragePropRef({value:"Prop5"}) get mapB(): (Map | undefined) set __backing_mapB(__backing_mapB: (IStoragePropRefDecoratedVariable> | undefined)) get __backing_mapB(): (IStoragePropRefDecoratedVariable> | undefined) - set classB(classB: (Person | undefined)) + @StoragePropRef({value:"Prop7"}) set classB(classB: (Person | undefined)) - get classB(): (Person | undefined) + @StoragePropRef({value:"Prop7"}) get classB(): (Person | undefined) set __backing_classB(__backing_classB: (IStoragePropRefDecoratedVariable | undefined)) get __backing_classB(): (IStoragePropRefDecoratedVariable | undefined) - set enumB(enumB: (Status | undefined)) + @StoragePropRef({value:"Prop8"}) set enumB(enumB: (Status | undefined)) - get enumB(): (Status | undefined) + @StoragePropRef({value:"Prop8"}) get enumB(): (Status | undefined) set __backing_enumB(__backing_enumB: (IStoragePropRefDecoratedVariable | undefined)) get __backing_enumB(): (IStoragePropRefDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/storageprop-ref/storageprop-ref-primitive-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/storageprop-ref/storageprop-ref-primitive-type.test.ts index cbf9c9f85eeea69204863e136a745460b3a823c7..d127166064e2d2916f3054a2ec19df9ed54ef06f 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/storageprop-ref/storageprop-ref-primitive-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/storageprop-ref/storageprop-ref-primitive-type.test.ts @@ -122,33 +122,33 @@ function main() {} } @Component() export interface __Options_MyStateSample { - set numB(numB: (number | undefined)) + @StoragePropRef({value:"Prop1"}) set numB(numB: (number | undefined)) - get numB(): (number | undefined) + @StoragePropRef({value:"Prop1"}) get numB(): (number | undefined) set __backing_numB(__backing_numB: (IStoragePropRefDecoratedVariable | undefined)) get __backing_numB(): (IStoragePropRefDecoratedVariable | undefined) - set stringB(stringB: (string | undefined)) + @StoragePropRef({value:"Prop2"}) set stringB(stringB: (string | undefined)) - get stringB(): (string | undefined) + @StoragePropRef({value:"Prop2"}) get stringB(): (string | undefined) set __backing_stringB(__backing_stringB: (IStoragePropRefDecoratedVariable | undefined)) get __backing_stringB(): (IStoragePropRefDecoratedVariable | undefined) - set booleanB(booleanB: (boolean | undefined)) + @StoragePropRef({value:"Prop3"}) set booleanB(booleanB: (boolean | undefined)) - get booleanB(): (boolean | undefined) + @StoragePropRef({value:"Prop3"}) get booleanB(): (boolean | undefined) set __backing_booleanB(__backing_booleanB: (IStoragePropRefDecoratedVariable | undefined)) get __backing_booleanB(): (IStoragePropRefDecoratedVariable | undefined) - set undefinedB(undefinedB: (undefined | undefined)) + @StoragePropRef({value:"Prop4"}) set undefinedB(undefinedB: (undefined | undefined)) - get undefinedB(): (undefined | undefined) + @StoragePropRef({value:"Prop4"}) get undefinedB(): (undefined | undefined) set __backing_undefinedB(__backing_undefinedB: (IStoragePropRefDecoratedVariable | undefined)) get __backing_undefinedB(): (IStoragePropRefDecoratedVariable | undefined) - set nullB(nullB: (null | undefined)) + @StoragePropRef({value:"Prop5"}) set nullB(nullB: (null | undefined)) - get nullB(): (null | undefined) + @StoragePropRef({value:"Prop5"}) get nullB(): (null | undefined) set __backing_nullB(__backing_nullB: (IStoragePropRefDecoratedVariable | undefined)) get __backing_nullB(): (IStoragePropRefDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/storageprop/storageprop-appstorage.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/storageprop/storageprop-appstorage.test.ts index 6c3476c961be22ae5c6c00aaefdcb7ac82c1061c..68c7b42c2c87dd214986fa89d0da5766c8166c6c 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/storageprop/storageprop-appstorage.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/storageprop/storageprop-appstorage.test.ts @@ -131,15 +131,15 @@ class Data { } @Entry({useSharedStorage:false,storage:"",routeName:""}) @Component() export interface __Options_Index { - set storageProp(storageProp: (number | undefined)) + @StorageProp({value:"PropA"}) set storageProp(storageProp: (number | undefined)) - get storageProp(): (number | undefined) + @StorageProp({value:"PropA"}) get storageProp(): (number | undefined) set __backing_storageProp(__backing_storageProp: (IStoragePropRefDecoratedVariable | undefined)) get __backing_storageProp(): (IStoragePropRefDecoratedVariable | undefined) - set storagePropObject(storagePropObject: (Data | undefined)) + @StorageProp({value:"PropB"}) set storagePropObject(storagePropObject: (Data | undefined)) - get storagePropObject(): (Data | undefined) + @StorageProp({value:"PropB"}) get storagePropObject(): (Data | undefined) set __backing_storagePropObject(__backing_storagePropObject: (IStoragePropRefDecoratedVariable | undefined)) get __backing_storagePropObject(): (IStoragePropRefDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/storageprop/storageprop-complex-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/storageprop/storageprop-complex-type.test.ts index e03a903c563bad0cb4dac9b0bdd5399d11ff1663..6d3d44d76c86039e7937a9c9d025c3dfaa719f55 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/storageprop/storageprop-complex-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/storageprop/storageprop-complex-type.test.ts @@ -223,45 +223,45 @@ final class Status extends BaseEnum { } @Entry({useSharedStorage:false,storage:"",routeName:""}) @Component() export interface __Options_MyStateSample { - set arrayB(arrayB: (Array | undefined)) + @StorageProp({value:"Prop1"}) set arrayB(arrayB: (Array | undefined)) - get arrayB(): (Array | undefined) + @StorageProp({value:"Prop1"}) get arrayB(): (Array | undefined) set __backing_arrayB(__backing_arrayB: (IStoragePropRefDecoratedVariable> | undefined)) get __backing_arrayB(): (IStoragePropRefDecoratedVariable> | undefined) - set objectB(objectB: (Object | undefined)) + @StorageProp({value:"Prop2"}) set objectB(objectB: (Object | undefined)) - get objectB(): (Object | undefined) + @StorageProp({value:"Prop2"}) get objectB(): (Object | undefined) set __backing_objectB(__backing_objectB: (IStoragePropRefDecoratedVariable | undefined)) get __backing_objectB(): (IStoragePropRefDecoratedVariable | undefined) - set dateB(dateB: (Date | undefined)) + @StorageProp({value:"Prop3"}) set dateB(dateB: (Date | undefined)) - get dateB(): (Date | undefined) + @StorageProp({value:"Prop3"}) get dateB(): (Date | undefined) set __backing_dateB(__backing_dateB: (IStoragePropRefDecoratedVariable | undefined)) get __backing_dateB(): (IStoragePropRefDecoratedVariable | undefined) - set setB(setB: (Set | undefined)) + @StorageProp({value:"Prop4"}) set setB(setB: (Set | undefined)) - get setB(): (Set | undefined) + @StorageProp({value:"Prop4"}) get setB(): (Set | undefined) set __backing_setB(__backing_setB: (IStoragePropRefDecoratedVariable> | undefined)) get __backing_setB(): (IStoragePropRefDecoratedVariable> | undefined) - set mapB(mapB: (Map | undefined)) + @StorageProp({value:"Prop5"}) set mapB(mapB: (Map | undefined)) - get mapB(): (Map | undefined) + @StorageProp({value:"Prop5"}) get mapB(): (Map | undefined) set __backing_mapB(__backing_mapB: (IStoragePropRefDecoratedVariable> | undefined)) get __backing_mapB(): (IStoragePropRefDecoratedVariable> | undefined) - set classB(classB: (Person | undefined)) + @StorageProp({value:"Prop7"}) set classB(classB: (Person | undefined)) - get classB(): (Person | undefined) + @StorageProp({value:"Prop7"}) get classB(): (Person | undefined) set __backing_classB(__backing_classB: (IStoragePropRefDecoratedVariable | undefined)) get __backing_classB(): (IStoragePropRefDecoratedVariable | undefined) - set enumB(enumB: (Status | undefined)) + @StorageProp({value:"Prop8"}) set enumB(enumB: (Status | undefined)) - get enumB(): (Status | undefined) + @StorageProp({value:"Prop8"}) get enumB(): (Status | undefined) set __backing_enumB(__backing_enumB: (IStoragePropRefDecoratedVariable | undefined)) get __backing_enumB(): (IStoragePropRefDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/storageprop/storageprop-primitive-type.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/storageprop/storageprop-primitive-type.test.ts index 25ed76fdea8263d1492181d2d8f3c136fb03a0a0..0592f34c1d9e1cdf6c9f49e4be5141c4bb3d7ee3 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/storageprop/storageprop-primitive-type.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/storageprop/storageprop-primitive-type.test.ts @@ -113,21 +113,21 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ } @Entry({useSharedStorage:false,storage:"",routeName:""}) @Component() export interface __Options_MyStateSample { - set numB(numB: (number | undefined)) + @StorageProp({value:"Prop1"}) set numB(numB: (number | undefined)) - get numB(): (number | undefined) + @StorageProp({value:"Prop1"}) get numB(): (number | undefined) set __backing_numB(__backing_numB: (IStoragePropRefDecoratedVariable | undefined)) get __backing_numB(): (IStoragePropRefDecoratedVariable | undefined) - set stringB(stringB: (string | undefined)) + @StorageProp({value:"Prop2"}) set stringB(stringB: (string | undefined)) - get stringB(): (string | undefined) + @StorageProp({value:"Prop2"}) get stringB(): (string | undefined) set __backing_stringB(__backing_stringB: (IStoragePropRefDecoratedVariable | undefined)) get __backing_stringB(): (IStoragePropRefDecoratedVariable | undefined) - set booleanB(booleanB: (boolean | undefined)) + @StorageProp({value:"Prop3"}) set booleanB(booleanB: (boolean | undefined)) - get booleanB(): (boolean | undefined) + @StorageProp({value:"Prop3"}) get booleanB(): (boolean | undefined) set __backing_booleanB(__backing_booleanB: (IStoragePropRefDecoratedVariable | undefined)) get __backing_booleanB(): (IStoragePropRefDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/decorators/watch/watch-basic.test.ts b/arkui-plugins/test/ut/ui-plugins/decorators/watch/watch-basic.test.ts index 5cda30f78d7ee3003f509342463f848a241e0643..0e64c9c6c1eab591916417d82c2aec9e9f0362b5 100644 --- a/arkui-plugins/test/ut/ui-plugins/decorators/watch/watch-basic.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/decorators/watch/watch-basic.test.ts @@ -307,48 +307,46 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ } -@Retention({policy:"SOURCE"}) @interface __Link_intrinsic {} - @Entry({useSharedStorage:false,storage:"",routeName:""}) @Component() export interface __Options_MyStateSample { - set statevar(statevar: (string | undefined)) + @State() @Watch({value:"stateOnChange"}) set statevar(statevar: (string | undefined)) - get statevar(): (string | undefined) + @State() @Watch({value:"stateOnChange"}) get statevar(): (string | undefined) set __backing_statevar(__backing_statevar: (IStateDecoratedVariable | undefined)) get __backing_statevar(): (IStateDecoratedVariable | undefined) - set propvar(propvar: (string | undefined)) + @Prop() @Watch({value:"propOnChange"}) set propvar(propvar: (string | undefined)) - get propvar(): (string | undefined) + @Prop() @Watch({value:"propOnChange"}) get propvar(): (string | undefined) set __backing_propvar(__backing_propvar: (IPropDecoratedVariable | undefined)) get __backing_propvar(): (IPropDecoratedVariable | undefined) - @__Link_intrinsic() set linkvar(linkvar: (string | undefined)) + @Link() @Watch({value:"linkOnChange"}) set linkvar(linkvar: (string | undefined)) - @__Link_intrinsic() get linkvar(): (string | undefined) + @Link() @Watch({value:"linkOnChange"}) get linkvar(): (string | undefined) set __backing_linkvar(__backing_linkvar: (LinkSourceType | undefined)) get __backing_linkvar(): (LinkSourceType | undefined) - set storagelinkvar(storagelinkvar: (string | undefined)) + @StorageLink({value:"prop1"}) @Watch({value:"storageLinkOnChange"}) set storagelinkvar(storagelinkvar: (string | undefined)) - get storagelinkvar(): (string | undefined) + @StorageLink({value:"prop1"}) @Watch({value:"storageLinkOnChange"}) get storagelinkvar(): (string | undefined) set __backing_storagelinkvar(__backing_storagelinkvar: (IStorageLinkDecoratedVariable | undefined)) get __backing_storagelinkvar(): (IStorageLinkDecoratedVariable | undefined) - set storagepropvar(storagepropvar: (string | undefined)) + @StorageProp({value:"prop2"}) @Watch({value:"storagePropOnChange"}) set storagepropvar(storagepropvar: (string | undefined)) - get storagepropvar(): (string | undefined) + @StorageProp({value:"prop2"}) @Watch({value:"storagePropOnChange"}) get storagepropvar(): (string | undefined) set __backing_storagepropvar(__backing_storagepropvar: (IStoragePropRefDecoratedVariable | undefined)) get __backing_storagepropvar(): (IStoragePropRefDecoratedVariable | undefined) - set objectlinkvar(objectlinkvar: (A | undefined)) + @ObjectLink() @Watch({value:"objectLinkOnChange"}) set objectlinkvar(objectlinkvar: (A | undefined)) - get objectlinkvar(): (A | undefined) + @ObjectLink() @Watch({value:"objectLinkOnChange"}) get objectlinkvar(): (A | undefined) set __backing_objectlinkvar(__backing_objectlinkvar: (IObjectLinkDecoratedVariable | undefined)) get __backing_objectlinkvar(): (IObjectLinkDecoratedVariable | undefined) - set providevar(providevar: (string | undefined)) + @Provide({alias:"providevar",allowOverride:false}) @Watch({value:"ProvideOnChange"}) set providevar(providevar: (string | undefined)) - get providevar(): (string | undefined) + @Provide({alias:"providevar",allowOverride:false}) @Watch({value:"ProvideOnChange"}) get providevar(): (string | undefined) set __backing_providevar(__backing_providevar: (IProvideDecoratedVariable | undefined)) get __backing_providevar(): (IProvideDecoratedVariable | undefined) @@ -356,9 +354,9 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ } @Component() export interface __Options_Child { - set providevar(providevar: (string | undefined)) + @Consume({alias:""}) @Watch({value:"ConsumeOnChange"}) set providevar(providevar: (string | undefined)) - get providevar(): (string | undefined) + @Consume({alias:""}) @Watch({value:"ConsumeOnChange"}) get providevar(): (string | undefined) set __backing_providevar(__backing_providevar: (IConsumeDecoratedVariable | undefined)) get __backing_providevar(): (IConsumeDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/double-dollar/double-dollar-griditem.test.ts b/arkui-plugins/test/ut/ui-plugins/double-dollar/double-dollar-griditem.test.ts index 216eb90861f4128ac63bcdff4ae070e5f258c70e..74a425ebfbcfce14cedfbb84ac6e8236b9dc4bd0 100644 --- a/arkui-plugins/test/ut/ui-plugins/double-dollar/double-dollar-griditem.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/double-dollar/double-dollar-griditem.test.ts @@ -126,9 +126,9 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ } @Entry({useSharedStorage:false,storage:"",routeName:""}) @Component() export interface __Options_MyStateSample { - set boo(boo: (boolean | undefined)) + @State() set boo(boo: (boolean | undefined)) - get boo(): (boolean | undefined) + @State() get boo(): (boolean | undefined) set __backing_boo(__backing_boo: (IStateDecoratedVariable | undefined)) get __backing_boo(): (IStateDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/double-dollar/double-dollar-toggle.test.ts b/arkui-plugins/test/ut/ui-plugins/double-dollar/double-dollar-toggle.test.ts index 8387fe7ae19c14104dc85c11b38da36e3a6bffd1..147e9b953223852e38dbe31ed988588f63b3330e 100644 --- a/arkui-plugins/test/ut/ui-plugins/double-dollar/double-dollar-toggle.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/double-dollar/double-dollar-toggle.test.ts @@ -132,15 +132,15 @@ class BooleanClass { } @Component() export interface __Options_MyStateSample { - set boo(boo: (Array | undefined)) + @State() set boo(boo: (Array | undefined)) - get boo(): (Array | undefined) + @State() get boo(): (Array | undefined) set __backing_boo(__backing_boo: (IStateDecoratedVariable> | undefined)) get __backing_boo(): (IStateDecoratedVariable> | undefined) - set booClass(booClass: (BooleanClass | undefined)) + @State() set booClass(booClass: (BooleanClass | undefined)) - get booClass(): (BooleanClass | undefined) + @State() get booClass(): (BooleanClass | undefined) set __backing_booClass(__backing_booClass: (IStateDecoratedVariable | undefined)) get __backing_booClass(): (IStateDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/imports/kit-import.test.ts b/arkui-plugins/test/ut/ui-plugins/imports/kit-import.test.ts index 0147ea48f9ced29fa9f9c1545289e25634dedd6c..1896e025610d28d822dd52aac52da7015316887d 100644 --- a/arkui-plugins/test/ut/ui-plugins/imports/kit-import.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/imports/kit-import.test.ts @@ -73,9 +73,9 @@ import hilog from "@ohos.hilog"; } @Entry() @Component() export interface __Options_A { - a?: string; + @State() a?: string; @State() __backing_a?: string; - b?: string; + @Prop() b?: string; @Prop() __backing_b?: string; } @@ -191,15 +191,15 @@ __EntryWrapper.RegisterNamedRouter("", new __EntryWrapper(), ({ } @Entry({useSharedStorage:false,storage:"",routeName:""}) @Component() export interface __Options_A { - set a(a: (string | undefined)) + @State() set a(a: (string | undefined)) - get a(): (string | undefined) + @State() get a(): (string | undefined) set __backing_a(__backing_a: (IStateDecoratedVariable | undefined)) get __backing_a(): (IStateDecoratedVariable | undefined) - set b(b: (string | undefined)) + @Prop() set b(b: (string | undefined)) - get b(): (string | undefined) + @Prop() get b(): (string | undefined) set __backing_b(__backing_b: (IPropDecoratedVariable | undefined)) get __backing_b(): (IPropDecoratedVariable | undefined) diff --git a/arkui-plugins/test/ut/ui-plugins/wrap-builder/builder-in-generic.test.ts b/arkui-plugins/test/ut/ui-plugins/wrap-builder/builder-in-generic.test.ts index 4f7fc9dc54b685a163191f5e54ea64eb2f85de53..859edba9509efbc11fbca14c55de442c77a894c2 100644 --- a/arkui-plugins/test/ut/ui-plugins/wrap-builder/builder-in-generic.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/wrap-builder/builder-in-generic.test.ts @@ -102,8 +102,8 @@ __EntryWrapper.RegisterNamedRouter(\"\", new __EntryWrapper(), ({ private constructor() {} } @Entry({useSharedStorage:false,storage:\"\",routeName:\"\"}) @Component() export interface __Options_Index { - set message(message: (string | undefined)) - get message(): (string | undefined) + @State() set message(message: (string | undefined)) + @State() get message(): (string | undefined) set __backing_message(__backing_message: (IStateDecoratedVariable | undefined)) get __backing_message(): (IStateDecoratedVariable | undefined) } @@ -262,8 +262,8 @@ __EntryWrapper.RegisterNamedRouter(\"\", new __EntryWrapper(), ({ private constructor() {} } @Entry({useSharedStorage:false,storage:\"\",routeName:\"\"}) @Component() export interface __Options_Index { - set message(message: (string | undefined)) - get message(): (string | undefined) + @State() set message(message: (string | undefined)) + @State() get message(): (string | undefined) set __backing_message(__backing_message: (IStateDecoratedVariable | undefined)) get __backing_message(): (IStateDecoratedVariable | undefined) } diff --git a/arkui-plugins/test/ut/ui-plugins/wrap-builder/wrap-builder-in-generic.test.ts b/arkui-plugins/test/ut/ui-plugins/wrap-builder/wrap-builder-in-generic.test.ts index d5e87c590cc30d38d715a493fcccfbfe00a7cda6..dd847362740bf2a4d56ffc25aa7d0dfb45e310b8 100644 --- a/arkui-plugins/test/ut/ui-plugins/wrap-builder/wrap-builder-in-generic.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/wrap-builder/wrap-builder-in-generic.test.ts @@ -102,8 +102,8 @@ __EntryWrapper.RegisterNamedRouter(\"\", new __EntryWrapper(), ({ private constructor() {} } @Entry({useSharedStorage:false,storage:\"\",routeName:\"\"}) @Component() export interface __Options_Index { - set message(message: (string | undefined)) - get message(): (string | undefined) + @State() set message(message: (string | undefined)) + @State() get message(): (string | undefined) set __backing_message(__backing_message: (IStateDecoratedVariable | undefined)) get __backing_message(): (IStateDecoratedVariable | undefined) } @@ -262,8 +262,8 @@ __EntryWrapper.RegisterNamedRouter(\"\", new __EntryWrapper(), ({ private constructor() {} } @Entry({useSharedStorage:false,storage:\"\",routeName:\"\"}) @Component() export interface __Options_Index { - set message(message: (string | undefined)) - get message(): (string | undefined) + @State() set message(message: (string | undefined)) + @State() get message(): (string | undefined) set __backing_message(__backing_message: (IStateDecoratedVariable | undefined)) get __backing_message(): (IStateDecoratedVariable | undefined) } diff --git a/arkui-plugins/test/ut/ui-plugins/wrap-builder/wrap-builder-with-lambda.test.ts b/arkui-plugins/test/ut/ui-plugins/wrap-builder/wrap-builder-with-lambda.test.ts index 38ef976e6db101c0c27258bd8a3de3cd83ea166f..28a031c9aa69de378a566729fcebb6bbcf7151a0 100644 --- a/arkui-plugins/test/ut/ui-plugins/wrap-builder/wrap-builder-with-lambda.test.ts +++ b/arkui-plugins/test/ut/ui-plugins/wrap-builder/wrap-builder-with-lambda.test.ts @@ -168,9 +168,9 @@ function main() {} } @Component() export interface __Options_Parent { - set label(label: (Tmp | undefined)) + @State() set label(label: (Tmp | undefined)) - get label(): (Tmp | undefined) + @State() get label(): (Tmp | undefined) set __backing_label(__backing_label: (IStateDecoratedVariable | undefined)) get __backing_label(): (IStateDecoratedVariable | undefined) @@ -361,9 +361,9 @@ function main() {} } @Component() export interface __Options_Parent { - set label(label: (Tmp | undefined)) + @State() set label(label: (Tmp | undefined)) - get label(): (Tmp | undefined) + @State() get label(): (Tmp | undefined) set __backing_label(__backing_label: (IStateDecoratedVariable | undefined)) get __backing_label(): (IStateDecoratedVariable | undefined) diff --git a/arkui-plugins/test/utils/plugins/memo-no-recheck.ts b/arkui-plugins/test/utils/plugins/memo-no-recheck.ts index 9396b34e5778d0fe20653018da0e6d8076ccb594..d3047d96c8da595b3d5f7f2224000cd534b97613 100644 --- a/arkui-plugins/test/utils/plugins/memo-no-recheck.ts +++ b/arkui-plugins/test/utils/plugins/memo-no-recheck.ts @@ -16,7 +16,11 @@ import * as arkts from '@koalaui/libarkts'; import { PluginContext, Plugins } from '../../../common/plugin-context'; import { ProgramVisitor } from '../../../common/program-visitor'; -import { EXTERNAL_SOURCE_PREFIX_NAMES, EXTERNAL_SOURCE_PREFIX_NAMES_FOR_FRAMEWORK } from '../../../common/predefines'; +import { + EXTERNAL_SOURCE_PREFIX_NAMES, + EXTERNAL_SOURCE_PREFIX_NAMES_FOR_FRAMEWORK, + NodeCacheNames, +} from '../../../common/predefines'; import { PositionalIdTracker } from '../../../memo-plugins/utils'; import { ParameterTransformer } from '../../../memo-plugins/parameter-transformer'; import { ReturnTransformer } from '../../../memo-plugins/return-transformer'; @@ -51,7 +55,7 @@ export const memoNoRecheck: Plugins = { returnTransformer, signatureTransformer, internalsTransformer, - useCache: arkts.NodeCache.getInstance().isCollected() + useCache: arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).isCollected(), }); const skipPrefixNames = isFrameworkMode ? EXTERNAL_SOURCE_PREFIX_NAMES_FOR_FRAMEWORK @@ -64,7 +68,7 @@ export const memoNoRecheck: Plugins = { pluginContext: this, }); program = programVisitor.programVisitor(program); - arkts.NodeCache.getInstance().clear(); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).clear(); script = program.astNode; return script; } diff --git a/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts b/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts index 9be67b1ddf165a1a545f048ca39f4c462c333a4c..c24c12f42b823a5a3b84c88cec407c1a196b0414 100644 --- a/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts +++ b/arkui-plugins/ui-plugins/builder-lambda-translators/factory.ts @@ -14,9 +14,7 @@ */ import * as arkts from '@koalaui/libarkts'; -import { BuilderLambdaNames } from '../utils'; import { - backingField, filterDefined, isDecoratorAnnotation, removeAnnotationByName, @@ -35,6 +33,7 @@ import { isBuilderLambdaFunctionCall, isSafeType, replaceBuilderLambdaDeclMethodName, + getArgumentType, isDoubleDollarCall, InstanceCallInfo, isStyleChainedCall, @@ -46,22 +45,24 @@ import { checkIsWithInIfConditionScope, BuilderLambdaConditionBranchInfo, BuilderLambdaChainingCallArgInfo, - getArgumentType, } from './utils'; -import { hasDecorator, isDecoratorIntrinsicAnnotation } from '../property-translators/utils'; +import { checkIsNameStartWithBackingField, hasDecorator } from '../property-translators/utils'; import { factory as PropertyFactory } from '../property-translators/factory'; import { factory as UIFactory } from '../ui-factory'; +import { backingField } from '../property-translators/utils'; import { AnimationNames, ARKUI_BUILDER_SOURCE_NAME, BindableDecl, ConditionNames, - DecoratorIntrinsicNames, + BuilderLambdaNames, DecoratorNames, + NodeCacheNames, } from '../../common/predefines'; import { ImportCollector } from '../../common/import-collector'; import { addMemoAnnotation, collectMemoableInfoInParameter } from '../../collectors/memo-collectors/utils'; import { factory as MemoCollectFactory } from '../../collectors/memo-collectors/factory'; +import { CallInfo, FunctionInfo, StructMethodInfo } from '../../collectors/ui-collectors/records'; export class factory { /** @@ -71,8 +72,8 @@ export class factory { node: arkts.MethodDefinition, prefixArgs: arkts.ETSParameterExpression[], newAnno: arkts.AnnotationUsage[], - newName: string | undefined, - externalSourceName?: string + oriName: string, + newName: string | undefined ): arkts.MethodDefinition { const func: arkts.ScriptFunction = node.scriptFunction; let newParams: arkts.Expression[] = []; @@ -97,8 +98,8 @@ export class factory { return arkts.factory.updateMethodDefinition( node, node.kind, - arkts.factory.updateIdentifier(node.name, newName ?? node.name.name), - node.name.name === BuilderLambdaNames.ORIGIN_METHOD_NAME ? addMemoAnnotation(updateFunc) : updateFunc, + arkts.factory.updateIdentifier(node.name, newName ?? oriName), + oriName === BuilderLambdaNames.ORIGIN_METHOD_NAME ? addMemoAnnotation(updateFunc) : updateFunc, node.modifiers, false ); @@ -108,7 +109,7 @@ export class factory { * transform arguments in style node. */ static getTransformedStyle(call: arkts.CallExpression): BuilderLambdaChainingCallArgInfo[] { - const decl = arkts.getDecl(call.expression); + const decl = arkts.getPeerIdentifierDecl(call.expression.peer); if (!decl || !arkts.isMethodDefinition(decl)) { return call.arguments.map((arg) => ({ arg })); } @@ -127,7 +128,10 @@ export class factory { } if (isDoubleDollar && !!arg) { const bindableArg: arkts.Expression = (arg as arkts.CallExpression).arguments[0]; - argInfo.push({ arg: factory.updateBindableStyleArguments(bindableArg) }); + const updateArg: arkts.Expression | undefined = factory.updateBindableStyleArguments(bindableArg); + if (!!updateArg) { + argInfo.push({ arg: updateArg }); + } } else if (!!arg) { argInfo.push({ arg, hasBuilder: hasDecorator(_param, DecoratorNames.BUILDER) }); } @@ -214,7 +218,7 @@ export class factory { ); const returnStatement = arkts.factory.createReturnStatement(); - arkts.NodeCache.getInstance().collect(returnStatement); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(returnStatement); const body: arkts.BlockStatement = arkts.factory.createBlock([ arkts.factory.createExpressionStatement(lambdaBody), returnStatement, @@ -263,7 +267,7 @@ export class factory { arkts.factory.createIdentifier(BuilderLambdaNames.STYLE_PARAM_NAME, optionalFuncType), undefined ); - arkts.NodeCache.getInstance().collect(parameter); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(parameter); return parameter; } @@ -327,23 +331,29 @@ export class factory { static updatePropertiesInOptions(prop: arkts.Property): arkts.Property { let decl: arkts.AstNode | undefined; - if (!prop.key || !prop.value || !(decl = arkts.getDecl(prop.key)) || !arkts.isMethodDefinition(decl)) { + if ( + !prop.key || + !prop.value || + !(decl = arkts.getPeerPropertyDecl(prop.peer)) || + !arkts.isMethodDefinition(decl) + ) { return prop; } + const isNotBacking: boolean = !checkIsNameStartWithBackingField(decl.name); let isBuilderParam: boolean = false; - let isLinkIntrinsic: boolean = false; + let isLink: boolean = false; decl.scriptFunction.annotations.forEach((anno) => { isBuilderParam ||= isDecoratorAnnotation(anno, DecoratorNames.BUILDER_PARAM); - isLinkIntrinsic ||= isDecoratorIntrinsicAnnotation(anno, DecoratorIntrinsicNames.LINK); + isLink ||= isDecoratorAnnotation(anno, DecoratorNames.LINK); }); - if (isDoubleDollarCall(prop.value)) { return factory.updateBindableProperty(prop); - } else if (isBuilderParam && arkts.isArrowFunctionExpression(prop.value)) { + } else if (isBuilderParam && isNotBacking && arkts.isArrowFunctionExpression(prop.value)) { addMemoAnnotation(prop.value); return prop; } else if ( - isLinkIntrinsic && + isLink && + isNotBacking && arkts.isIdentifier(prop.key) && arkts.isMemberExpression(prop.value) && arkts.isThisExpression(prop.value.object) && @@ -403,13 +413,13 @@ export class factory { lambdaBody: arkts.Identifier | arkts.CallExpression, declInfo: BuilderLambdaDeclInfo ): (arkts.AstNode | undefined)[] { - const { isFunctionCall, params, returnType, moduleName } = declInfo; + const { isFunctionCall, params, returnType, moduleName, isTrailingCall } = declInfo; const type: arkts.Identifier | undefined = builderLambdaType(leaf); const args: (arkts.AstNode | undefined)[] = [ this.createStyleArgInBuilderLambda(lambdaBody, returnType, moduleName), ]; const secondLastArgInfo = buildSecondLastArgInfo(type, isFunctionCall); - const isTrailingCall = leaf.isTrailingCall; + const _isTrailingCall = isTrailingCall ?? leaf.isTrailingCall; forEachArgWithParam( leaf.arguments, params, @@ -431,7 +441,7 @@ export class factory { } args.push(modifiedArg); }, - { isTrailingCall } + { isTrailingCall: _isTrailingCall } ); return filterDefined(args); } @@ -527,7 +537,7 @@ export class factory { const newCall = arkts.factory.createCallExpression(arkts.factory.createIdentifier(condition), undefined, [ contentArg, ]); - arkts.NodeCache.getInstance().collect(newCall); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(newCall); ImportCollector.getInstance().collectSource(condition, ARKUI_BUILDER_SOURCE_NAME); ImportCollector.getInstance().collectImport(condition); return arkts.factory.createExpressionStatement(newCall); @@ -537,16 +547,16 @@ export class factory { * update trailing lambda contents in a builder lambda call. */ static updateContentBodyInBuilderLambda(statement: arkts.Statement, hasBuilder?: boolean): arkts.Statement { - if ( - arkts.isExpressionStatement(statement) && - arkts.isCallExpression(statement.expression) && - isBuilderLambda(statement.expression) - ) { - return arkts.factory.updateExpressionStatement( - statement, - this.transformBuilderLambda(statement.expression) - ); - } + // if ( + // arkts.isExpressionStatement(statement) && + // arkts.isCallExpression(statement.expression) && + // isBuilderLambda(statement.expression) + // ) { + // return arkts.factory.updateExpressionStatement( + // statement, + // this.transformBuilderLambda(statement.expression) + // ); + // } if (arkts.isIfStatement(statement)) { return this.updateIfElseContentBodyInBuilderLambda(statement, hasBuilder); } @@ -589,26 +599,54 @@ export class factory { /** * transform `@ComponentBuilder` in declared methods. + * @deprecated */ - static transformBuilderLambdaMethodDecl( - node: arkts.MethodDefinition, - externalSourceName?: string - ): arkts.MethodDefinition { + static transformBuilderLambdaMethodDecl(node: arkts.MethodDefinition): arkts.MethodDefinition { const func: arkts.ScriptFunction = node.scriptFunction; const isFunctionCall: boolean = isBuilderLambdaFunctionCall(node); const typeNode: arkts.TypeNode | undefined = builderLambdaMethodDeclType(node); const newOverloads: arkts.MethodDefinition[] = node.overloads.map((method) => factory.transformBuilderLambdaMethodDecl(method) ); + const originName: string = node.name.name; + const newName: string | undefined = replaceBuilderLambdaDeclMethodName(originName); + const newNode = this.updateBuilderLambdaMethodDecl( + node, + [this.createStyleArgInBuilderLambdaDecl(typeNode, isFunctionCall)], + removeAnnotationByName(func.annotations, BuilderLambdaNames.ANNOTATION_NAME), + originName, + newName + ).setOverloads(newOverloads); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(newNode); + return newNode; + } + /** + * transform `@ComponentBuilder` in declared methods. + */ + static transformBuilderLambdaMethodDeclFromInfo( + node: arkts.MethodDefinition, + metadata: StructMethodInfo | FunctionInfo + ): arkts.MethodDefinition { + if (!metadata.name) { + return node; + } + const func: arkts.ScriptFunction = node.scriptFunction; + const isFunctionCall: boolean = isBuilderLambdaFunctionCall(node, metadata); + const typeNode: arkts.TypeNode | undefined = func.returnTypeAnnotation; + const newOverloads: arkts.MethodDefinition[] = node.overloads.map((method) => + factory.transformBuilderLambdaMethodDeclFromInfo(method, metadata) + ); + const originName: string = metadata.name; + const newName: string | undefined = replaceBuilderLambdaDeclMethodName(originName); const newNode = this.updateBuilderLambdaMethodDecl( node, [this.createStyleArgInBuilderLambdaDecl(typeNode, isFunctionCall)], removeAnnotationByName(func.annotations, BuilderLambdaNames.ANNOTATION_NAME), - replaceBuilderLambdaDeclMethodName(node.name.name), - externalSourceName + originName, + newName ).setOverloads(newOverloads); - arkts.NodeCache.getInstance().collect(newNode); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(newNode); return newNode; } @@ -648,6 +686,7 @@ export class factory { /** * transform `@ComponentBuilder` in non-declared calls. + * @deprecated */ static transformBuilderLambda(node: arkts.CallExpression): arkts.AstNode { let instanceCalls: InstanceCallInfo[] = []; @@ -691,7 +730,7 @@ export class factory { instanceCalls = instanceCalls.reverse(); this.updateAnimation(instanceCalls); lambdaBody = arkts.factory.createIdentifier(BuilderLambdaNames.STYLE_ARROW_PARAM_NAME); - arkts.NodeCache.getInstance().collect(lambdaBody); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(lambdaBody); instanceCalls.forEach((callInfo) => { lambdaBody = this.createStyleLambdaBody(lambdaBody!, callInfo); }); @@ -699,7 +738,61 @@ export class factory { const args: (arkts.AstNode | undefined)[] = this.generateArgsInBuilderLambda(leaf, lambdaBody!, declInfo); const newNode = arkts.factory.updateCallExpression(node, replace, leaf.typeArguments, filterDefined(args)); - arkts.NodeCache.getInstance().collect(newNode); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(newNode); + return newNode; + } + + /** + * transform `@ComponentBuilder` in non-declared calls. + */ + static transformBuilderLambdaFromInfo(node: arkts.CallExpression, metadata: CallInfo): arkts.AstNode { + const rootCallInfo = metadata.rootCallInfo ?? metadata; + if (!rootCallInfo.declName) { + return node; + } + let instanceCalls: InstanceCallInfo[] = []; + let leaf: arkts.CallExpression = node; + const chainingCallInfos = metadata.chainingCallInfos ?? []; + while (chainingCallInfos.length > 0) { + const chainedCallInfo = chainingCallInfos.pop()!; + const callee = leaf.expression; + const isReceiver = !!chainedCallInfo?.hasReceiver; + if (isStyleChainedCall(callee, chainedCallInfo)) { + instanceCalls.push({ + isReceiver, + call: arkts.factory.createCallExpression( + (callee as arkts.MemberExpression).property, + leaf.typeArguments, + leaf.arguments + ), + }); + leaf = (callee as arkts.MemberExpression).object as arkts.CallExpression; + } else if (isStyleWithReceiverCall(leaf, callee, chainedCallInfo)) { + instanceCalls.push({ + isReceiver, + call: arkts.factory.createCallExpression(callee, leaf.typeArguments, leaf.arguments), + }); + leaf = leaf.arguments[0] as arkts.CallExpression; + } + } + const replace: arkts.Identifier | arkts.MemberExpression | undefined = this.builderLambdaReplace(leaf); + const declInfo: BuilderLambdaDeclInfo | undefined = findBuilderLambdaDeclInfo(leaf, rootCallInfo); + if (!replace || !declInfo) { + return node; + } + let lambdaBody: arkts.Identifier | arkts.CallExpression | undefined; + if (instanceCalls.length > 0) { + instanceCalls = instanceCalls.reverse(); + // this.updateAnimation(instanceCalls); // TODO: uncomment this + lambdaBody = arkts.factory.createIdentifier(BuilderLambdaNames.STYLE_ARROW_PARAM_NAME); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(lambdaBody); + instanceCalls.forEach((callInfo) => { + lambdaBody = this.createStyleLambdaBody(lambdaBody!, callInfo); + }); + } + const args: (arkts.AstNode | undefined)[] = this.generateArgsInBuilderLambda(leaf, lambdaBody!, declInfo); + const newNode = arkts.factory.updateCallExpression(node, replace, leaf.typeArguments, filterDefined(args)); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(newNode); return newNode; } @@ -814,7 +907,7 @@ export class factory { undefined ); param.annotations = [annotation(DecoratorNames.BUILDER)]; - arkts.NodeCache.getInstance().collect(param); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(param); const method = UIFactory.createMethodDefinition({ key, kind: arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_NONE, @@ -828,7 +921,7 @@ export class factory { }, modifiers, }); - arkts.NodeCache.getInstance().collect(method); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(method); return method; } diff --git a/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts b/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts index 9ccc36a1ccbafae6670096c81a7a703a64e13a7e..37f6a17c1f12d2f8f0966b403baa63c51499db3d 100644 --- a/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts +++ b/arkui-plugins/ui-plugins/builder-lambda-translators/utils.ts @@ -15,16 +15,26 @@ import * as arkts from '@koalaui/libarkts'; import { isAnnotation, matchPrefix } from '../../common/arkts-utils'; -import { BuilderLambdaNames, isCustomComponentAnnotation } from '../utils'; +import { checkIsStructMethodFromInfo, isCustomComponentAnnotation } from '../utils'; import { DeclarationCollector } from '../../common/declaration-collector'; -import { ARKUI_IMPORT_PREFIX_NAMES, BindableDecl, Dollars, StructDecoratorNames } from '../../common/predefines'; +import { + ARKUI_IMPORT_PREFIX_NAMES, + BindableDecl, + BuilderLambdaNames, + Dollars, + StructDecoratorNames, +} from '../../common/predefines'; import { ImportCollector } from '../../common/import-collector'; +import { CallInfo, FunctionInfo, StructMethodInfo } from '../../collectors/ui-collectors/records'; +import { checkIsCustomComponentDeclaredClassFromInfo } from '../../collectors/ui-collectors/utils'; +import { coerceToAstNode } from '../../collectors/ui-collectors/validators/utils'; export type BuilderLambdaDeclInfo = { isFunctionCall: boolean; // isFunctionCall means it is from $_instantiate. params: readonly arkts.Expression[]; returnType: arkts.TypeNode | undefined; moduleName: string; + isTrailingCall?: boolean; }; export type BuilderLambdaAstNode = arkts.ScriptFunction | arkts.ETSParameterExpression | arkts.FunctionDeclaration; @@ -62,7 +72,7 @@ export function buildSecondLastArgInfo( let isReusable: boolean | undefined; let reuseId: string | undefined; if (!isFunctionCall && !!type) { - const customComponentDecl = arkts.getDecl(type); + const customComponentDecl = arkts.getPeerIdentifierDecl(type.peer); isReusable = !!customComponentDecl && arkts.isClassDefinition(customComponentDecl) && @@ -94,6 +104,9 @@ export function builderLambdaArgumentName(annotation: arkts.AnnotationUsage): st return property.value.str; } +/** + * @deprecated + */ export function isBuilderLambda(node: arkts.AstNode, nodeDecl?: arkts.AstNode | undefined): boolean { const builderLambdaCall: arkts.AstNode | undefined = getDeclForBuilderLambda(node, nodeDecl); if (!builderLambdaCall) { @@ -102,6 +115,14 @@ export function isBuilderLambda(node: arkts.AstNode, nodeDecl?: arkts.AstNode | return !!builderLambdaCall; } +export function isBuilderLambdaFromInfo(metadata: CallInfo): boolean { + const rootCallInfo: CallInfo | undefined = metadata.rootCallInfo ?? metadata; + if (!rootCallInfo) { + return false; + } + return !!rootCallInfo.annotationInfo?.hasComponentBuilder; +} + /** * Determine whether it is a function with receiver method definition. * @@ -120,7 +141,7 @@ export function isFunctionWithReceiver(node: arkts.MethodDefinition): boolean { * @param node identifier node */ export function isFunctionWithReceiverCall(node: arkts.Identifier): boolean { - const decl: arkts.AstNode | undefined = arkts.getDecl(node); + const decl: arkts.AstNode | undefined = arkts.getPeerIdentifierDecl(node.peer); if (decl && arkts.isMethodDefinition(decl)) { return isFunctionWithReceiver(decl); } @@ -129,29 +150,50 @@ export function isFunctionWithReceiverCall(node: arkts.Identifier): boolean { /** * Determine whether it is a style chained call. - * - * @param node call expression node */ -export function isStyleChainedCall(node: arkts.CallExpression): boolean { - return ( - arkts.isMemberExpression(node.expression) && - arkts.isIdentifier(node.expression.property) && - arkts.isCallExpression(node.expression.object) - ); +export function isStyleChainedCall(node: arkts.AstNode, metadata: CallInfo): boolean; + +/** + * @deprecated + */ +export function isStyleChainedCall(node: arkts.CallExpression): boolean; + +export function isStyleChainedCall(node: arkts.AstNode, metadata?: CallInfo): boolean { + if (!metadata && arkts.isCallExpression(node)) { + return ( + arkts.isMemberExpression(node.expression) && + arkts.isIdentifier(node.expression.property) && + arkts.isCallExpression(node.expression.object) + ); + } + return arkts.isMemberExpression(node) && arkts.isCallExpression(node.object); } /** * Determine whether it is a style function with receiver call. - * - * @param node call expression node */ -export function isStyleWithReceiverCall(node: arkts.CallExpression): boolean { - return ( - arkts.isIdentifier(node.expression) && - isFunctionWithReceiverCall(node.expression) && - !!node.arguments.length && - arkts.isCallExpression(node.arguments[0]) - ); +export function isStyleWithReceiverCall(node: arkts.CallExpression, callee: arkts.AstNode, metadata: CallInfo): boolean; + +/** + * @deprecated + */ +export function isStyleWithReceiverCall(node: arkts.CallExpression): boolean; + +export function isStyleWithReceiverCall( + node: arkts.CallExpression, + callee?: arkts.AstNode, + metadata?: CallInfo +): boolean { + if (!metadata && !callee) { + return ( + arkts.isIdentifier(node.expression) && + isFunctionWithReceiverCall(node.expression) && + !!node.arguments.length && + arkts.isCallExpression(node.arguments[0]) + ); + } + const isReceiver = !!metadata?.hasReceiver; + return isReceiver && arkts.isIdentifier(callee!) && arkts.isCallExpression(node.arguments.at(0)!); } /** @@ -166,11 +208,26 @@ export function replaceBuilderLambdaDeclMethodName(name: string | undefined): st return undefined; } +/** + * @deprecated + */ export function isBuilderLambdaMethodDecl(node: arkts.AstNode): boolean { const builderLambdaMethodDecl: arkts.AstNode | undefined = getDeclForBuilderLambdaMethodDecl(node); return !!builderLambdaMethodDecl; } +export function isBuilderLambdaMethodDeclFromInfo(metadata: StructMethodInfo | FunctionInfo): boolean { + const isStructMethod = checkIsStructMethodFromInfo(metadata); + let isBuilderLambda: boolean = !!metadata.annotationInfo?.hasComponentBuilder; + if (isStructMethod) { + isBuilderLambda &&= + checkIsCustomComponentDeclaredClassFromInfo(metadata.structInfo) && + metadata.name === BuilderLambdaNames.ORIGIN_METHOD_NAME; + } + const isMethodDecl: boolean = !!metadata.isDecl; + return isBuilderLambda && isMethodDecl; +} + export function getDeclForBuilderLambdaMethodDecl(node: arkts.AstNode): arkts.AstNode | undefined { if (!node || !arkts.isMethodDefinition(node)) { return undefined; @@ -226,8 +283,11 @@ export function isBuilderLambdaCall( ): boolean { let decl = nodeDecl; if (decl === undefined) { - const expr = arkts.isIdentifier(node) ? node : node.expression; - decl = arkts.getDecl(expr); + if (arkts.isIdentifier(node)) { + decl = arkts.getPeerIdentifierDecl(node.peer); + } else { + decl = arkts.getDecl(node.expression); + } } if (!decl) { @@ -313,13 +373,20 @@ export function findBuilderLambdaInCall( return undefined; } +/** + * @deprecated + */ export function findBuilderLambdaDecl(node: arkts.CallExpression | arkts.Identifier): arkts.AstNode | undefined { - const expr = arkts.isIdentifier(node) ? node : node.expression; - const decl = arkts.getDecl(expr); + let decl: arkts.AstNode | undefined; + if (arkts.isIdentifier(node)) { + decl = arkts.getPeerIdentifierDecl(node.peer); + } else { + decl = arkts.getDecl(node.expression); + } if (!decl) { return undefined; } - const moduleName: string = arkts.getProgramFromAstNode(decl).moduleName; + const moduleName = arkts.getProgramFromAstNode(decl)?.moduleName; if (!moduleName) { return undefined; } @@ -327,6 +394,16 @@ export function findBuilderLambdaDecl(node: arkts.CallExpression | arkts.Identif return decl; } +export function findRootCalleeDecl(rootCall: arkts.CallExpression | arkts.Identifier): arkts.AstNode | undefined { + let decl: arkts.AstNode | undefined; + if (arkts.isIdentifier(rootCall)) { + decl = arkts.getPeerIdentifierDecl(rootCall.peer); + } else { + decl = arkts.getDecl(rootCall.expression); + } + return decl; +} + /** * check whether `` is the passing parameter. * @@ -343,35 +420,74 @@ export function isParameterPassing(prop: arkts.Property): boolean | undefined { ); } -export function findBuilderLambdaDeclInfo(decl: arkts.AstNode | undefined): BuilderLambdaDeclInfo | undefined { - if (!decl) { +export function findBuilderLambdaDeclInfo(node: arkts.AstNode, metadata: CallInfo): BuilderLambdaDeclInfo | undefined; + +/** + * @deprecated + */ +export function findBuilderLambdaDeclInfo(decl: arkts.AstNode | undefined): BuilderLambdaDeclInfo | undefined; + +export function findBuilderLambdaDeclInfo( + node: arkts.AstNode | undefined, + metadata?: CallInfo +): BuilderLambdaDeclInfo | undefined { + if (!node) { return undefined; } - const moduleName: string = arkts.getProgramFromAstNode(decl).moduleName; - if (!moduleName) { + if (!metadata) { + const moduleName = arkts.getProgramFromAstNode(node)?.moduleName; + if (!moduleName) { + return undefined; + } + if (arkts.isMethodDefinition(node)) { + const params = node.scriptFunction.params.map((p) => p.clone()); + const returnType = node.scriptFunction.returnTypeAnnotation?.clone(); + const isFunctionCall = isBuilderLambdaFunctionCall(node); + return { isFunctionCall, params, returnType, moduleName }; + } return undefined; } - if (arkts.isMethodDefinition(decl)) { - const params = decl.scriptFunction.params.map((p) => p.clone()); - const returnType = decl.scriptFunction.returnTypeAnnotation?.clone(); - const isFunctionCall = isBuilderLambdaFunctionCall(decl); - return { isFunctionCall, params, returnType, moduleName }; + if (!metadata?.isDeclFromMethod && !metadata?.isDeclFromFunction) { + return undefined; } - - return undefined; + const rootCallee: arkts.CallExpression = coerceToAstNode(node); + const decl: arkts.MethodDefinition = coerceToAstNode(findRootCalleeDecl(rootCallee)!); + const func: arkts.ScriptFunction = decl.scriptFunction; + const params: arkts.Expression[] = func.params.map((p) => p.clone()); + const returnType: arkts.TypeNode | undefined = func.returnTypeAnnotation?.clone(); + const isFunctionCall: boolean = + !!metadata.fromStructInfo && isBuilderLambdaFunctionCall(node, metadata.fromStructInfo); + const moduleName: string = metadata.moduleName!; + const isTrailingCall: boolean | undefined = metadata.isTrailingCall; + return { isFunctionCall, params, returnType, moduleName, isTrailingCall }; } -export function isBuilderLambdaFunctionCall(decl: arkts.AstNode | undefined): boolean { - if (!decl) { +export function isBuilderLambdaFunctionCall(node: arkts.AstNode | undefined, info: StructMethodInfo): boolean; + +/** + * @deprecated + */ +export function isBuilderLambdaFunctionCall(decl: arkts.AstNode | undefined): boolean; + +export function isBuilderLambdaFunctionCall(node: arkts.AstNode | undefined, info?: StructMethodInfo): boolean { + if (!info) { + if (!node) { + return false; + } + if (arkts.isMethodDefinition(node)) { + return ( + node.name.name !== BuilderLambdaNames.ORIGIN_METHOD_NAME && + node.name.name !== BuilderLambdaNames.TRANSFORM_METHOD_NAME + ); + } return false; } - if (arkts.isMethodDefinition(decl)) { - return ( - decl.name.name !== BuilderLambdaNames.ORIGIN_METHOD_NAME && - decl.name.name !== BuilderLambdaNames.TRANSFORM_METHOD_NAME - ); + if (!info.name) { + return false; } - return false; + return ( + info.name !== BuilderLambdaNames.ORIGIN_METHOD_NAME && info.name !== BuilderLambdaNames.TRANSFORM_METHOD_NAME + ); } export function callIsGoodForBuilderLambda(leaf: arkts.CallExpression): boolean { @@ -448,11 +564,11 @@ export function isDoubleDollarCall( return false; } if (!ignoreDecl) { - const decl = arkts.getDecl(value.expression); + const decl = arkts.getPeerIdentifierDecl(value.expression.peer); if (!decl) { return false; } - const moduleName: string = arkts.getProgramFromAstNode(decl).moduleName; + const moduleName = arkts.getProgramFromAstNode(decl)?.moduleName; if (!moduleName || !matchPrefix(ARKUI_IMPORT_PREFIX_NAMES, moduleName)) { return false; } diff --git a/arkui-plugins/ui-plugins/checked-cache-factory.ts b/arkui-plugins/ui-plugins/checked-cache-factory.ts new file mode 100644 index 0000000000000000000000000000000000000000..c47502e31d90156caac3643f9528074e5e12abdd --- /dev/null +++ b/arkui-plugins/ui-plugins/checked-cache-factory.ts @@ -0,0 +1,292 @@ +/* + * 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 { + CallInfo, + CustomComponentInfo, + CustomComponentInterfaceInfo, + CustomComponentInterfacePropertyInfo, + FunctionInfo, + NormalClassInfo, + NormalClassMethodInfo, + NormalClassPropertyInfo, + NormalInterfaceInfo, + NormalInterfacePropertyInfo, + StructMethodInfo, + StructPropertyInfo, +} from '../collectors/ui-collectors/records'; +import { + checkIsCustomComponentDeclaredClassFromInfo, + checkIsCustomComponentFromInfo, + checkIsETSGlobalClassFromInfo, +} from '../collectors/ui-collectors/utils'; +import { coerceToAstNode } from '../collectors/ui-collectors/validators/utils'; +import { addMemoAnnotation } from '../collectors/memo-collectors/utils'; +import { collect } from '../common/arkts-utils'; +import { ARKUI_BUILDER_SOURCE_NAME, EntryWrapperNames, NodeCacheNames } from '../common/predefines'; +import { factory as UIFactory } from './ui-factory'; +import { factory as StructFactory } from './struct-translators/factory'; +import { factory as PropertyFactory } from './property-translators/factory'; +import { factory as BuilderLambdaFactory } from './builder-lambda-translators/factory'; +import { factory as EntryFactory } from './entry-translators/factory'; +import { StructType } from './struct-translators/utils'; +import { InterfacePropertyTranslator, PropertyTranslator } from './property-translators/base'; +import { classifyPropertyFromInfo, classifyPropertyInInterfaceFromInfo } from './property-translators'; +import { isBuilderLambdaFromInfo, isBuilderLambdaMethodDeclFromInfo } from './builder-lambda-translators/utils'; +import { PropertyRewriteCache } from './property-translators/utils'; +import { + checkIsCustomComponentClassFromInfo, + checkIsGlobalFunctionFromInfo, + checkIsNormalClassMethodFromInfo, + checkIsNormalClassPropertyFromInfo, + checkIsNormalInterfacePropertyFromInfo, + checkIsStructInterfacePropertyFromInfo, + checkIsStructMethodFromInfo, + checkIsStructPropertyFromInfo, +} from './utils'; +import { + CachedMetadata, + ClassDeclarationRecordInfo, + ClassPropertyRecordInfo, + MethodDefinitionRecordInfo, +} from './shared-types'; + +export class RewriteFactory { + /** + * @internal + */ + static rewriteCustomComponentDecl( + node: arkts.ClassDeclaration, + metadata: CachedMetadata + ): arkts.AstNode { + return StructFactory.tranformClassMembersFromInfo(node, metadata, StructType.CUSTOM_COMPONENT_DECL); + } + + /** + * @internal + */ + static rewriteStruct(node: arkts.ClassDeclaration, metadata: CachedMetadata): arkts.AstNode { + return StructFactory.tranformClassMembersFromInfo(node, metadata, StructType.STRUCT); + } + + /** + * @internal + */ + static rewriteCustomComponentClass( + node: arkts.ClassDeclaration, + metadata: CachedMetadata + ): arkts.AstNode { + if (checkIsCustomComponentFromInfo(metadata)) { + // Struct + return RewriteFactory.rewriteStruct(node, metadata); + } + if (checkIsCustomComponentDeclaredClassFromInfo(metadata)) { + // CustomComponent/CustomComponentV2/CustomDialog + return RewriteFactory.rewriteCustomComponentDecl(node, metadata); + } + return node; + } + + /** + * @internal + */ + static rewriteETSGlobalClass( + node: arkts.ClassDeclaration, + metadata: CachedMetadata + ): arkts.AstNode { + return StructFactory.transformETSGlobalClassFromInfo(node, metadata); + } + + /** + * @internal + */ + static rewriteNormalClass( + node: arkts.ClassDeclaration, + metadata: CachedMetadata + ): arkts.AstNode { + if (checkIsETSGlobalClassFromInfo(metadata)) { + return RewriteFactory.rewriteETSGlobalClass(node, metadata); + } + // TODO: add transform logic here + return node; + } + + /** + * @internal + */ + static rewriteStructProperty( + node: arkts.ClassProperty, + metadata: CachedMetadata + ): arkts.AstNode { + const propertyTranslator: PropertyTranslator | undefined = classifyPropertyFromInfo(node, metadata); + if (!propertyTranslator) { + return node; + } + const newNodes: arkts.AstNode[] = propertyTranslator.rewriteMember(); + PropertyRewriteCache.getInstance().collectRewriteNodes(node.peer, newNodes); + return node; + } + + /** + * @internal + */ + static rewriteNormalClassProperty( + node: arkts.ClassProperty, + metadata: CachedMetadata + ): arkts.AstNode { + // TODO: add transform logic here + return node; + } + + /** + * @internal + */ + static rewriteStructMethod( + node: arkts.MethodDefinition, + metadata: CachedMetadata + ): arkts.AstNode { + // rewrite `$_instantiate` in CustomComponent/CustomComponentV2/CustomDialog decl class + if (isBuilderLambdaMethodDeclFromInfo(metadata)) { + return BuilderLambdaFactory.transformBuilderLambdaMethodDeclFromInfo(node, metadata); + } + return StructFactory.transformNonPropertyMembersInClassFromInfo(node, metadata); + } + + /** + * @internal + */ + static rewriteStructInterfaceProperty( + node: arkts.MethodDefinition, + metadata: CachedMetadata + ): arkts.AstNode { + const interfacePropertyTranslator: InterfacePropertyTranslator | undefined = + classifyPropertyInInterfaceFromInfo(node, metadata); + if (!interfacePropertyTranslator) { + return node; + } + return interfacePropertyTranslator.translateProperty(); + } + + /** + * @internal + */ + static rewriteNormalClassMethod( + node: arkts.MethodDefinition, + metadata: CachedMetadata + ): arkts.AstNode { + if (!metadata.classInfo) { + return node; + } + // Entry + if (metadata.classInfo?.name === EntryWrapperNames.WRAPPER_CLASS_NAME) { + EntryFactory.addMemoToEntryWrapperClassMethodFromInfo(node, metadata); + return node; + } + // TODO: add transform logic here + return node; + } + + /** + * @internal + */ + static rewriteNormalInterfaceProperty( + node: arkts.MethodDefinition, + metadata: CachedMetadata + ): arkts.AstNode { + // TODO: add transform logic here + return node; + } + + /** + * @internal + */ + static rewriteGlobalFunction(node: arkts.MethodDefinition, metadata: CachedMetadata): arkts.AstNode { + // rewrite `@ComponentBuilder` declared method. + if (isBuilderLambdaMethodDeclFromInfo(metadata)) { + return BuilderLambdaFactory.transformBuilderLambdaMethodDeclFromInfo(node, metadata); + } + // TODO: add transform logic here + return node; + } + + static rewriteClassDeclaration( + node: T, + metadata: CachedMetadata + ): arkts.AstNode { + const _node = coerceToAstNode(node); + if (checkIsCustomComponentClassFromInfo(metadata)) { + return RewriteFactory.rewriteCustomComponentClass(_node, metadata); + } + return RewriteFactory.rewriteNormalClass(_node, metadata); + } + + static rewriteMethodDefinition( + node: T, + metadata: CachedMetadata + ): arkts.AstNode { + const _node = coerceToAstNode(node); + if (checkIsStructMethodFromInfo(metadata)) { + return RewriteFactory.rewriteStructMethod(_node, metadata); + } + if (checkIsGlobalFunctionFromInfo(metadata)) { + return RewriteFactory.rewriteGlobalFunction(_node, metadata); + } + if (checkIsNormalClassMethodFromInfo(metadata)) { + return RewriteFactory.rewriteNormalClassMethod(_node, metadata); + } + if (checkIsStructInterfacePropertyFromInfo(metadata)) { + return RewriteFactory.rewriteStructInterfaceProperty(_node, metadata); + } + if (checkIsNormalInterfacePropertyFromInfo(metadata)) { + return RewriteFactory.rewriteNormalInterfaceProperty(_node, metadata); + } + return _node; + } + + static rewriteClassProperty( + node: T, + metadata: CachedMetadata + ): arkts.AstNode { + const _node = coerceToAstNode(node); + if (checkIsStructPropertyFromInfo(metadata)) { + return RewriteFactory.rewriteStructProperty(_node, metadata); + } + if (checkIsNormalClassPropertyFromInfo(metadata)) { + return RewriteFactory.rewriteNormalClassProperty(_node, metadata); + } + return _node; + } + + static rewriteCallExpression( + node: T, + metadata: CachedMetadata + ): arkts.AstNode { + const _node = coerceToAstNode(node); + if (isBuilderLambdaFromInfo(metadata)) { + return BuilderLambdaFactory.transformBuilderLambdaFromInfo(_node, metadata); + } + return _node; + } +} + +type RewriteFunction = (node: T, metadata: CachedMetadata) => arkts.AstNode; + +export const rewriteByType = new Map([ + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CLASS_DECLARATION, RewriteFactory.rewriteClassDeclaration], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CLASS_PROPERTY, RewriteFactory.rewriteClassProperty], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_METHOD_DEFINITION, RewriteFactory.rewriteMethodDefinition], + [arkts.Es2pandaAstNodeType.AST_NODE_TYPE_CALL_EXPRESSION, RewriteFactory.rewriteCallExpression], +]); diff --git a/arkui-plugins/ui-plugins/checked-transformer.ts b/arkui-plugins/ui-plugins/checked-transformer.ts index 8fe41f30c05dbeb4d2cc58ef523cc2f0673d8243..0416ef9f8d75adccc856cd92a6c723d054b878b6 100644 --- a/arkui-plugins/ui-plugins/checked-transformer.ts +++ b/arkui-plugins/ui-plugins/checked-transformer.ts @@ -18,7 +18,7 @@ import { ProjectConfig } from '../common/plugin-context'; import { factory as structFactory } from './struct-translators/factory'; import { factory as builderLambdaFactory } from './builder-lambda-translators/factory'; import { factory as entryFactory } from './entry-translators/factory'; -import { AbstractVisitor } from '../common/abstract-visitor'; +import { AbstractVisitor, VisitorOptions } from '../common/abstract-visitor'; import { isBuilderLambda, isBuilderLambdaMethodDecl } from './builder-lambda-translators/utils'; import { isEntryWrapperClass } from './entry-translators/utils'; import { ImportCollector } from '../common/import-collector'; @@ -29,21 +29,21 @@ import { CustomComponentScopeInfo, initResourceInfo, loadBuildJson, - LoaderJson, - ResourceInfo, ScopeInfoCollection, - isForEachDecl + isForEachDecl, } from './struct-translators/utils'; -import { - collectCustomComponentScopeInfo, - CustomComponentNames, - CustomDialogNames, - isCustomComponentClass, - isSpecificNewClass, -} from './utils'; +import { collectCustomComponentScopeInfo, isCustomComponentClass, isSpecificNewClass } from './utils'; import { findAndCollectMemoableNode } from '../collectors/memo-collectors/factory'; import { InteroperAbilityNames } from './interop/predefines'; import { generateBuilderCompatible } from './interop/builder-interop'; +import { CustomComponentNames, CustomDialogNames, NodeCacheNames } from '../common/predefines'; +import { rewriteByType } from './checked-cache-factory'; +import { CachedMetadata, CheckedTransformerMetadata, LoaderJson, ResourceInfo } from './shared-types'; + +export interface CheckedTransformerOptions extends VisitorOptions { + projectConfig?: ProjectConfig; + useCache?: boolean; +} export class CheckedTransformer extends AbstractVisitor { private scope: ScopeInfoCollection; @@ -52,9 +52,12 @@ export class CheckedTransformer extends AbstractVisitor { aceBuildJson: LoaderJson; resourceInfo: ResourceInfo; - constructor(projectConfig: ProjectConfig | undefined) { - super(); - this.projectConfig = projectConfig; + private readonly useCache: boolean = false; + + constructor(options: CheckedTransformerOptions) { + super(options); + this.projectConfig = options.projectConfig; + this.useCache = options.useCache ?? false; this.scope = { customComponents: [] }; this.aceBuildJson = loadBuildJson(this.projectConfig); this.resourceInfo = initResourceInfo(this.projectConfig, this.aceBuildJson); @@ -62,6 +65,16 @@ export class CheckedTransformer extends AbstractVisitor { this.initBuilderMap(); } + getMetadata(): CheckedTransformerMetadata { + return { + ...this.getOptions(), + legacyBuilderSet: this.legacyBuilderSet, + projectConfig: this.projectConfig, + aceBuildJson: this.aceBuildJson, + resourceInfo: this.resourceInfo, + }; + } + initBuilderMap(): void { const moduleList = this.projectConfig?.dependentModuleList; if (moduleList === undefined) { @@ -83,9 +96,10 @@ export class CheckedTransformer extends AbstractVisitor { super.reset(); this.scope = { customComponents: [] }; PropertyCache.getInstance().reset(); - ImportCollector.getInstance().reset(); - DeclarationCollector.getInstance().reset(); - LogCollector.getInstance().reset(); + ImportCollector.getInstance().clearImports(); + // ImportCollector.getInstance().reset(); // TODO: deprecated + // DeclarationCollector.getInstance().reset(); // TODO: deprecated + // LogCollector.getInstance().reset(); // TODO: deprecated } enter(node: arkts.AstNode): void { @@ -118,19 +132,18 @@ export class CheckedTransformer extends AbstractVisitor { if (!decl || this.legacyBuilderSet.size === 0) { return false; } - const moduleName = arkts.getProgramFromAstNode(decl).moduleName?.split('/')[0]; - - if (!this.legacyBuilderSet.has(moduleName)) { + const moduleName = arkts.getProgramFromAstNode(decl)?.moduleName?.split('/')[0]; + if (!moduleName || !this.legacyBuilderSet.has(moduleName)) { return false; } let isFrom1_1 = false; if (arkts.isMethodDefinition(decl)) { const annotations = decl.scriptFunction.annotations; - const decorators: string[] = annotations.map(annotation => { + const decorators: string[] = annotations.map((annotation) => { return (annotation.expr as arkts.Identifier).name; }); - decorators.forEach(element => { + decorators.forEach((element) => { if (element === 'Builder') { isFrom1_1 = true; return; @@ -145,10 +158,34 @@ export class CheckedTransformer extends AbstractVisitor { ImportCollector.getInstance().collectImport('compatibleComponent'); } + private visitorWithCache(beforeChildren: arkts.AstNode): arkts.AstNode { + if (!arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).shouldUpdate(beforeChildren)) { + return beforeChildren; + } + const node = this.visitEachChild(beforeChildren); + // findAndCollectMemoableNode(node); + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).has(node)) { + const value = arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).get(node)!; + if (rewriteByType.has(value.type)) { + const metadata: CachedMetadata = { ...value.metadata, ...this.getMetadata() }; + return rewriteByType.get(value.type)!(node, metadata); + } + } + if (arkts.isEtsScript(node)) { + ImportCollector.getInstance().insertCurrentImports(this.program); + LogCollector.getInstance().shouldIgnoreError(this.projectConfig?.ignoreError); + LogCollector.getInstance().emitLogInfo(); + } + return node; + } + visitor(beforeChildren: arkts.AstNode): arkts.AstNode { + if (this.useCache) { + return this.visitorWithCache(beforeChildren); + } this.enter(beforeChildren); if (arkts.isCallExpression(beforeChildren)) { - const decl = arkts.getDecl(beforeChildren.expression); + const decl = arkts.getPeerIdentifierDecl(beforeChildren.expression.peer); if (arkts.isIdentifier(beforeChildren.expression) && this.isFromBuilder1_1(decl)) { // Builder this.addcompatibleComponentImport(); @@ -158,10 +195,7 @@ export class CheckedTransformer extends AbstractVisitor { return this.visitEachChild(lambda); } } else if (arkts.isMethodDefinition(beforeChildren) && isBuilderLambdaMethodDecl(beforeChildren)) { - const lambda = builderLambdaFactory.transformBuilderLambdaMethodDecl( - beforeChildren, - this.externalSourceName - ); + const lambda = builderLambdaFactory.transformBuilderLambdaMethodDecl(beforeChildren); return this.visitEachChild(lambda); } const node = this.visitEachChild(beforeChildren); @@ -192,7 +226,10 @@ export class CheckedTransformer extends AbstractVisitor { return structFactory.AddArrowTypeForParameter(node); } else if (arkts.isTSInterfaceDeclaration(node)) { return structFactory.tranformInterfaceMembers(node, this.externalSourceName); - } else if (arkts.isETSNewClassInstanceExpression(node) && isSpecificNewClass(node, CustomDialogNames.CUSTOM_DIALOG_CONTROLLER)) { + } else if ( + arkts.isETSNewClassInstanceExpression(node) && + isSpecificNewClass(node, CustomDialogNames.CUSTOM_DIALOG_CONTROLLER) + ) { return structFactory.transformCustomDialogController(node); } diff --git a/arkui-plugins/ui-plugins/component-transformer.ts b/arkui-plugins/ui-plugins/component-transformer.ts index a4c436972cfdb33ca6422c8112069ea3f6e933a7..9bce936099c9eb4da0928f3be2ebf280898062a4 100644 --- a/arkui-plugins/ui-plugins/component-transformer.ts +++ b/arkui-plugins/ui-plugins/component-transformer.ts @@ -19,7 +19,6 @@ const interop = require(getInteropPath()); const nullptr = interop.nullptr; import { AbstractVisitor, VisitorOptions } from '../common/abstract-visitor'; import { - CustomComponentNames, getCustomComponentOptionsName, findLocalImport, CustomComponentInfo, @@ -29,30 +28,22 @@ import { getComponentExtendsName, ComponentType, } from './utils'; -import { - backingField, - expectName, - annotation, - filterDefined, - collect, - createAndInsertImportDeclaration, - isDecoratorAnnotation, -} from '../common/arkts-utils'; +import { filterDefined, collect, createAndInsertImportDeclaration } from '../common/arkts-utils'; import { ProjectConfig } from '../common/plugin-context'; import { getEntryParams } from './entry-translators/utils'; import { factory as entryFactory } from './entry-translators/factory'; -import { hasDecoratorName, findDecoratorInfos } from './property-translators/utils'; +import { hasDecoratorName, findDecoratorInfos, backingField, expectName } from './property-translators/utils'; import { factory } from './ui-factory'; import { factory as propertyFactory } from './property-translators/factory'; import { StructMap } from '../common/program-visitor'; import { CUSTOM_COMPONENT_IMPORT_SOURCE_NAME, - DecoratorIntrinsicNames, DecoratorNames, DECORATOR_TYPE_MAP, ENTRY_POINT_IMPORT_SOURCE_NAME, NavigationNames, EntryWrapperNames, + CustomComponentNames, } from '../common/predefines'; import { generateInstantiateInterop } from './interop/interop'; @@ -212,10 +203,6 @@ export class ComponentTransformer extends AbstractVisitor { return node; } const updateStatements: arkts.AstNode[] = []; - if (this.shouldAddLinkIntrinsic) { - const expr = arkts.factory.createIdentifier(DecoratorIntrinsicNames.LINK); - updateStatements.push(factory.createIntrinsicAnnotationDeclaration({ expr })); - } if (this.componentInterfaceCollection.length > 0) { this.insertComponentImport(); updateStatements.push(...this.componentInterfaceCollection); @@ -301,7 +288,7 @@ export class ComponentTransformer extends AbstractVisitor { const returnTypeAnnotation = arkts.factory.createPrimitiveType(arkts.Es2pandaPrimitiveType.PRIMITIVE_TYPE_VOID); const flags = arkts.Es2pandaScriptFunctionFlags.SCRIPT_FUNCTION_FLAGS_METHOD; const kind = arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_METHOD; - const key = arkts.factory.createIdentifier(CustomComponentNames.BUILDCOMPATIBLENODE); + const key = arkts.factory.createIdentifier(CustomComponentNames.BUILD_COMPATIBLE_NODE); return factory.createMethodDefinition({ key, @@ -447,39 +434,30 @@ export class ComponentTransformer extends AbstractVisitor { } createInterfaceInnerMember(member: arkts.ClassProperty): arkts.ClassProperty[] { - const originalName: string = expectName(member.key); - const originMember: arkts.ClassProperty = propertyFactory.createOptionalClassProperty( - originalName, - member, - undefined, - arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PUBLIC - ); const infos = findDecoratorInfos(member); - const buildParamInfo = infos.find((it) => - isDecoratorAnnotation(it.annotation, DecoratorNames.BUILDER_PARAM, true) - ); - if (!!buildParamInfo) { - originMember.setAnnotations([buildParamInfo.annotation.clone()]); - return [originMember]; - } - const OnceInfo = infos.find((it) => it.name === DecoratorNames.ONCE); - const targetInfo = infos.find((it) => DECORATOR_TYPE_MAP.has(it.name)); - if (!!targetInfo) { - const newName: string = backingField(originalName); - const newMember: arkts.ClassProperty = propertyFactory.createOptionalClassProperty( - newName, + const annotations = infos.map((it) => it.annotation.clone()); + const originalName: string = expectName(member.key); + const originMember: arkts.ClassProperty = propertyFactory + .createOptionalClassProperty( + originalName, member, undefined, arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PUBLIC - ); - const annos = !!OnceInfo - ? [OnceInfo.annotation.clone(), targetInfo.annotation.clone()] - : [targetInfo.annotation.clone()]; - newMember.setAnnotations(annos); - if (isDecoratorAnnotation(targetInfo.annotation, DecoratorNames.LINK, true)) { - this.shouldAddLinkIntrinsic = true; - originMember.setAnnotations([annotation(DecoratorIntrinsicNames.LINK)]); - } + ) + .setAnnotations(annotations); + const typedAnnotations = infos + .filter((it) => DECORATOR_TYPE_MAP.has(it.name)) + .map((it) => it.annotation.clone()); + if (typedAnnotations.length > 0) { + const newName: string = backingField(originalName); + const newMember: arkts.ClassProperty = propertyFactory + .createOptionalClassProperty( + newName, + member, + undefined, + arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PUBLIC + ) + .setAnnotations(typedAnnotations); return [originMember, newMember]; } return [originMember]; diff --git a/arkui-plugins/ui-plugins/entry-translators/factory.ts b/arkui-plugins/ui-plugins/entry-translators/factory.ts index e4dd29d224a73bb929913285ac9d5fb2cb602a91..42a28f70270418725d01c9bea7c3101ffec5c52a 100644 --- a/arkui-plugins/ui-plugins/entry-translators/factory.ts +++ b/arkui-plugins/ui-plugins/entry-translators/factory.ts @@ -16,11 +16,17 @@ import * as arkts from '@koalaui/libarkts'; import * as path from 'path'; import { annotation, createAndInsertImportDeclaration } from '../../common/arkts-utils'; -import { ENTRY_POINT_IMPORT_SOURCE_NAME, EntryWrapperNames, NavigationNames } from '../../common/predefines'; +import { + ENTRY_POINT_IMPORT_SOURCE_NAME, + EntryWrapperNames, + NavigationNames, + NodeCacheNames, +} from '../../common/predefines'; import { ProjectConfig } from '../../common/plugin-context'; import { factory as uiFactory } from '../ui-factory'; import { getRelativePagePath } from './utils'; import { addMemoAnnotation } from '../../collectors/memo-collectors/utils'; +import { NormalClassMethodInfo } from '../../collectors/ui-collectors/records'; export class factory { /** @@ -211,6 +217,7 @@ export class factory { * add `@memo` to all class methods that are named 'entry'. * * @param node class declaration node + * @deprecated */ static addMemoToEntryWrapperClassMethods(node: arkts.ClassDeclaration): void { node.definition?.body.forEach((member) => { @@ -220,11 +227,27 @@ export class factory { member.scriptFunction.id.name === EntryWrapperNames.ENTRY_FUNC ) { addMemoAnnotation(member.scriptFunction); - arkts.NodeCache.getInstance().collect(member); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(member); } }); } + /** + * add `@memo` to `__EntryWrapper` class's `entry` method. + * + * @param node method definition node + * @param metadata normal class method information + */ + static addMemoToEntryWrapperClassMethodFromInfo( + node: arkts.MethodDefinition, + metadata: NormalClassMethodInfo + ): void { + if (metadata.name === EntryWrapperNames.ENTRY_FUNC) { + addMemoAnnotation(node.scriptFunction); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(node); + } + } + /** * add `@memo` to the class property's value (expecting an arrow function), where the property is named 'entry'. * diff --git a/arkui-plugins/ui-plugins/index.ts b/arkui-plugins/ui-plugins/index.ts index 1785e4854352aa9d54977fe12a7ed1909928947e..07b2d91ee6fa6d9fb3f91363cd401b4f82207850 100644 --- a/arkui-plugins/ui-plugins/index.ts +++ b/arkui-plugins/ui-plugins/index.ts @@ -18,8 +18,11 @@ import { ComponentTransformer } from './component-transformer'; import { CheckedTransformer } from './checked-transformer'; import { Plugins, PluginContext, ProjectConfig } from '../common/plugin-context'; import { ProgramVisitor } from '../common/program-visitor'; -import { EXTERNAL_SOURCE_PREFIX_NAMES } from '../common/predefines'; +import { EXTERNAL_SOURCE_PREFIX_NAMES, NodeCacheNames } from '../common/predefines'; import { debugDump, debugLog, getDumpFileName } from '../common/debug'; +import { ImportCollector } from '../common/import-collector'; +import { DeclarationCollector } from '../common/declaration-collector'; +import { LogCollector } from '../common/log-collector'; export function uiTransform(): Plugins { return { @@ -115,7 +118,7 @@ function checkedTransform(this: PluginContext): arkts.EtsScript | undefined { debugLog('[BEFORE STRUCT SCRIPT] script: ', script.dumpSrc()); debugDump( script.dumpSrc(), - getDumpFileName(0, 'SRC', 3, 'UI_AfterCheck_Begin'), + getDumpFileName(0, 'SRC', 5, 'UI_AfterCheck_Begin'), true, cachePath, program.fileNameWithExtension @@ -127,7 +130,7 @@ function checkedTransform(this: PluginContext): arkts.EtsScript | undefined { debugLog('[AFTER STRUCT SCRIPT] script: ', script.dumpSrc()); debugDump( script.dumpSrc(), - getDumpFileName(0, 'SRC', 4, 'UI_AfterCheck_End'), + getDumpFileName(0, 'SRC', 6, 'UI_AfterCheck_End'), true, cachePath, program.fileNameWithExtension @@ -151,11 +154,15 @@ function checkedProgramVisit( debugLog('[SKIP PHASE] phase: ui-checked, moduleName: ', program.moduleName); } else { debugLog('[CANT SKIP PHASE] phase: ui-checked, moduleName: ', program.moduleName); + // arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).visualize(); const projectConfig: ProjectConfig | undefined = context.getProjectConfig(); if (projectConfig && !projectConfig.appResource) { projectConfig.ignoreError = true; } - const checkedTransformer = new CheckedTransformer(projectConfig); + const checkedTransformer = new CheckedTransformer({ + projectConfig, + useCache: arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).isCollected(), + }); const programVisitor = new ProgramVisitor({ pluginName: uiTransform.name, state: arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED, @@ -164,6 +171,10 @@ function checkedProgramVisit( pluginContext: context, }); program = programVisitor.programVisitor(program); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).clear(); + ImportCollector.getInstance().reset(); + DeclarationCollector.getInstance().reset(); + LogCollector.getInstance().reset(); } return program; } diff --git a/arkui-plugins/ui-plugins/interop/builder-interop.ts b/arkui-plugins/ui-plugins/interop/builder-interop.ts index f2073b52d206698b503f71095287983f1f87a4df..37ccba70746481d614570413908044a770517143 100644 --- a/arkui-plugins/ui-plugins/interop/builder-interop.ts +++ b/arkui-plugins/ui-plugins/interop/builder-interop.ts @@ -24,6 +24,7 @@ import { getWrapValue, setPropertyESValue } from './utils'; +import { NodeCacheNames } from '../../common/predefines'; interface builderParam { args: arkts.AstNode[], @@ -504,7 +505,7 @@ export function generateBuilderCompatible(node: arkts.CallExpression, moduleName updater, ] ); - arkts.NodeCache.getInstance().collect(result); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(result); return result; } diff --git a/arkui-plugins/ui-plugins/interop/initstatevar.ts b/arkui-plugins/ui-plugins/interop/initstatevar.ts index 77846dadb0ad6323ea3d0d8393be1e006f682739..e6bb34d969377515f3fbbc4be85805a2068aec72 100644 --- a/arkui-plugins/ui-plugins/interop/initstatevar.ts +++ b/arkui-plugins/ui-plugins/interop/initstatevar.ts @@ -17,9 +17,8 @@ import * as arkts from '@koalaui/libarkts'; import { BuilderMethodNames, InteroperAbilityNames } from './predefines'; -import { annotation, backingField, isAnnotation } from '../../common/arkts-utils'; import { stateProxy, getWrapValue, setPropertyESValue } from './utils'; -import { hasDecorator } from '../property-translators/utils'; +import { backingField, hasDecorator } from '../property-translators/utils'; import { DecoratorNames } from '../../common/predefines'; diff --git a/arkui-plugins/ui-plugins/interop/interop.ts b/arkui-plugins/ui-plugins/interop/interop.ts index 8da4bc6d59e6567f8d924e9ead065ab5a57c86dc..75825ef3ef7e5c1fd51241a0d325c49f32d45e25 100644 --- a/arkui-plugins/ui-plugins/interop/interop.ts +++ b/arkui-plugins/ui-plugins/interop/interop.ts @@ -30,9 +30,9 @@ import { createInitReturn } from './utils'; import { ImportCollector } from '../../common/import-collector'; -import { factory as uiFactory } from '../ui-factory'; import { DecoratorNames } from '../../common/predefines'; import { hasDecorator } from '../property-translators/utils'; +import { NodeCacheNames } from '../../common/predefines'; function paramsLambdaDeclaration(name: string, args?: arkts.ObjectExpression): arkts.Statement[] { @@ -445,6 +445,6 @@ export function generateArkUICompatible(node: arkts.CallExpression): arkts.CallE arkts.factory.createThisExpression(), ] ); - arkts.NodeCache.getInstance().collect(result); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(result); return result; } \ No newline at end of file diff --git a/arkui-plugins/ui-plugins/property-translators/base.ts b/arkui-plugins/ui-plugins/property-translators/base.ts index ba0c0bd4119624e87d781fed8c5a81e6eeca60f8..32a0ce45c1b6db06e80a439b41583400642e8e32 100644 --- a/arkui-plugins/ui-plugins/property-translators/base.ts +++ b/arkui-plugins/ui-plugins/property-translators/base.ts @@ -17,24 +17,42 @@ import * as arkts from '@koalaui/libarkts'; import { collectStateManagementTypeImport, createGetter, createSetter } from './utils'; import { CustomComponentInfo, ClassInfo } from '../utils'; import { StateManagementTypes } from '../../common/predefines'; +import { + CustomComponentInterfacePropertyInfo, + StructPropertyInfo +} from '../../collectors/ui-collectors/records'; import { ClassScopeInfo } from '../struct-translators/utils'; export interface PropertyTranslatorOptions { property: arkts.ClassProperty; - structInfo: CustomComponentInfo; + /** + * @deprecated + */ + structInfo?: CustomComponentInfo; + propertyInfo?: StructPropertyInfo; } export abstract class PropertyTranslator { protected property: arkts.ClassProperty; - protected structInfo: CustomComponentInfo; + /** + * @deprecated + */ + protected structInfo?: CustomComponentInfo; + protected propertyInfo?: StructPropertyInfo; constructor(options: PropertyTranslatorOptions) { this.property = options.property; this.structInfo = options.structInfo; + this.propertyInfo = options.propertyInfo; } + /** + * @deprecated + */ abstract translateMember(): arkts.AstNode[]; + abstract rewriteMember(): arkts.AstNode[]; + translateGetter( originalName: string, typeAnnotation: arkts.TypeNode | undefined, @@ -87,6 +105,7 @@ export type InterfacePropertyTypes = arkts.MethodDefinition | arkts.ClassPropert export interface InterfacePropertyTranslatorOptions { property: T; + propertyInfo?: CustomComponentInterfacePropertyInfo; } export abstract class InterfacePropertyTranslator @@ -94,16 +113,26 @@ export abstract class InterfacePropertyTranslator) { this.property = options.property; + this.propertyInfo = options.propertyInfo; this.modified = false; } abstract translateProperty(): T; + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { return false; } + + static canBeTranslatedFromInfo(node: arkts.AstNode, metadata: CustomComponentInterfacePropertyInfo): node is InterfacePropertyTypes { + return false; + } } diff --git a/arkui-plugins/ui-plugins/property-translators/builderParam.ts b/arkui-plugins/ui-plugins/property-translators/builderParam.ts index 41c616f607c7c69f403d5c3db8862a4f7a5e67b8..84d31bc7af46d7383ca9c00175cfd624e50993dd 100644 --- a/arkui-plugins/ui-plugins/property-translators/builderParam.ts +++ b/arkui-plugins/ui-plugins/property-translators/builderParam.ts @@ -15,15 +15,31 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; -import { DecoratorNames } from '../../common/predefines'; -import { createGetter, createSetter, generateThisBacking, hasDecorator, removeDecorator, PropertyCache } from './utils'; +import { DecoratorNames, NodeCacheNames } from '../../common/predefines'; +import { + createGetter, + createSetter, + generateThisBacking, + hasDecorator, + removeDecorator, + PropertyCache, + expectName, + backingField, +} from './utils'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; import { factory } from './factory'; import { addMemoAnnotation, findCanAddMemoFromTypeAnnotation } from '../../collectors/memo-collectors/utils'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class BuilderParamTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + throw new Error('Method not implemented.'); + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -32,6 +48,9 @@ export class BuilderParamTranslator extends PropertyTranslator implements Initia } cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const mutableThis: arkts.Expression = generateThisBacking(newName); const initializeStruct: arkts.AstNode = this.generateInitializeStruct(mutableThis, originalName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); @@ -49,7 +68,7 @@ export class BuilderParamTranslator extends PropertyTranslator implements Initia arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PRIVATE, true ); - arkts.NodeCache.getInstance().collect(field); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(field); const thisSetValue: arkts.Expression = generateThisBacking(newName, false, false); const getter: arkts.MethodDefinition = this.translateGetter( originalName, @@ -58,9 +77,9 @@ export class BuilderParamTranslator extends PropertyTranslator implements Initia ? generateThisBacking(newName, false, false) : generateThisBacking(newName, false, true) ); - arkts.NodeCache.getInstance().collect(getter); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(getter); const setter: arkts.MethodDefinition = this.translateSetter(originalName, propertyType?.clone(), thisSetValue); - arkts.NodeCache.getInstance().collect(setter); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(setter); return [field, getter, setter]; } @@ -114,11 +133,21 @@ export class BuilderParamInterfaceTranslator e return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return !!metadata.annotationInfo?.hasBuilderParam; + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.BUILDER_PARAM)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.BUILDER_PARAM)) { - return true; + if (arkts.isMethodDefinition(node)) { + return hasDecorator(node, DecoratorNames.BUILDER_PARAM); + } else if (arkts.isClassProperty(node)) { + return hasDecorator(node, DecoratorNames.BUILDER_PARAM); } return false; } @@ -142,7 +171,7 @@ export class BuilderParamInterfaceTranslator e }); method.setOverloads(newOverLoads); removeDecorator(method, DecoratorNames.BUILDER_PARAM); - arkts.NodeCache.getInstance().collect(method, { isGetter: true }); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(method, { isGetter: true }); } else if (method.kind === arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_SET) { const param = method.scriptFunction.params.at(0)! as arkts.ETSParameterExpression; const type = param.type; @@ -150,7 +179,7 @@ export class BuilderParamInterfaceTranslator e addMemoAnnotation(type); } removeDecorator(method, DecoratorNames.BUILDER_PARAM); - arkts.NodeCache.getInstance().collect(method, { isSetter: true }); + arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.MEMO).collect(method, { isSetter: true }); } return method; } diff --git a/arkui-plugins/ui-plugins/property-translators/computed.ts b/arkui-plugins/ui-plugins/property-translators/computed.ts index 82daf847d2b2442ed57053ed0641c67ded719a28..190cbbb0bec1e9f13e5a9f679ce316370d2e0df5 100644 --- a/arkui-plugins/ui-plugins/property-translators/computed.ts +++ b/arkui-plugins/ui-plugins/property-translators/computed.ts @@ -15,10 +15,9 @@ import * as arkts from '@koalaui/libarkts'; -import { expectName } from '../../common/arkts-utils'; import { GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { computedField } from '../utils'; -import { generateThisBacking, PropertyCache, generateGetOrSetCall, collectStateManagementTypeImport } from './utils'; +import { generateThisBacking, generateGetOrSetCall, expectName } from './utils'; import { MethodTranslator } from './base'; import { InitializerConstructor } from './types'; import { factory as UIFactory } from '../ui-factory'; diff --git a/arkui-plugins/ui-plugins/property-translators/consume.ts b/arkui-plugins/ui-plugins/property-translators/consume.ts index 8bd40ec2e46c89602fc559259a56fe61a7ea69ef..f1e3046539e5719bb308f4ad0d4e1c4e05980f7b 100644 --- a/arkui-plugins/ui-plugins/property-translators/consume.ts +++ b/arkui-plugins/ui-plugins/property-translators/consume.ts @@ -15,7 +15,6 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { generateToRecord, @@ -26,12 +25,23 @@ import { getValueInAnnotation, hasDecorator, PropertyCache, + expectName, + backingField, + checkIsNameStartWithBackingField, } from './utils'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class ConsumeTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + throw new Error('Method not implemented.'); + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -40,6 +50,9 @@ export class ConsumeTranslator extends PropertyTranslator implements Initializer } cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const initializeStruct: arkts.AstNode = this.generateInitializeStruct(originalName, newName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); if (!!this.structInfo.annotations?.reusable) { @@ -124,11 +137,23 @@ export class ConsumeInterfaceTranslator extend return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return ( + !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasConsume + ); + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.CONSUME)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.CONSUME)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.CONSUME); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.CONSUME); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/consumer.ts b/arkui-plugins/ui-plugins/property-translators/consumer.ts index 368e45ccd7ef4ea9a342828d3e5a78fafc57c541..4b6e91a698e6916cd6a48b999a06043daeb44589 100644 --- a/arkui-plugins/ui-plugins/property-translators/consumer.ts +++ b/arkui-plugins/ui-plugins/property-translators/consumer.ts @@ -15,7 +15,6 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { createGetter, @@ -25,12 +24,23 @@ import { getValueInAnnotation, hasDecorator, PropertyCache, + expectName, + backingField, + checkIsNameStartWithBackingField, } from './utils'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class ConsumerTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + throw new Error('Method not implemented.'); + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -39,6 +49,9 @@ export class ConsumerTranslator extends PropertyTranslator implements Initialize } cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const initializeStruct: arkts.AstNode = this.generateInitializeStruct(originalName, newName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); } @@ -119,11 +132,23 @@ export class ConsumerInterfaceTranslator exten return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return ( + !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasConsumer + ); + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.CONSUMER)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.CONSUMER)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.CONSUMER); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.CONSUMER); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/factory.ts b/arkui-plugins/ui-plugins/property-translators/factory.ts index 0cc0f24ef46b1d12804784a225739ba06b7005ad..9e86ef4f0d5c9271b93d244b4edcaacb7392fb89 100644 --- a/arkui-plugins/ui-plugins/property-translators/factory.ts +++ b/arkui-plugins/ui-plugins/property-translators/factory.ts @@ -16,11 +16,12 @@ import * as arkts from '@koalaui/libarkts'; import { GenSymGenerator } from '../../common/gensym-generator'; import { + CustomComponentNames, DecoratorNames, DECORATOR_TYPE_MAP, - StateManagementTypes, - ObservedNames, MonitorNames, + ObservedNames, + StateManagementTypes, TypeNames, } from '../../common/predefines'; import { factory as UIFactory } from '../ui-factory'; @@ -30,11 +31,12 @@ import { getValueInAnnotation, hasDecorator, OptionalMemberInfo, + removAllDecorators, removeDecorator, } from './utils'; -import { CustomComponentNames } from '../utils'; import { addMemoAnnotation, findCanAddMemoFromTypeAnnotation } from '../../collectors/memo-collectors/utils'; import { annotation, isNumeric } from '../../common/arkts-utils'; +import { StructMethodInfo } from '../../collectors/ui-collectors/records'; export class factory { /** @@ -599,6 +601,7 @@ export class factory { /** * add `@memo` to the `@Builder` methods in class. + * @deprecated */ static addMemoToBuilderClassMethod(method: arkts.MethodDefinition): arkts.MethodDefinition { if (hasDecorator(method, DecoratorNames.BUILDER)) { @@ -608,6 +611,17 @@ export class factory { return method; } + /** + * add `@memo` to the `@Builder` methods in class. + */ + static addMemoToBuilderClassMethodFromInfo(method: arkts.MethodDefinition, metadata: StructMethodInfo): arkts.MethodDefinition { + if (metadata.annotationInfo?.hasBuilder) { + removeDecorator(method, DecoratorNames.BUILDER); + addMemoAnnotation(method.scriptFunction); + } + return method; + } + static createStorageLinkStateValue( property: arkts.ClassProperty, localStorageporpValueStr: string @@ -724,7 +738,7 @@ export class factory { return overload; }); method.setOverloads(newOverLoads); - removeDecorator(method, decorator); + removAllDecorators(method); if (!!newType) { method.scriptFunction.setReturnTypeAnnotation(newType); } @@ -733,7 +747,7 @@ export class factory { method.scriptFunction.params.at(0), decorator ); - removeDecorator(method, decorator); + removAllDecorators(method); if (!!newParam) { return UIFactory.updateMethodDefinition(method, { function: { params: [newParam] } }); } diff --git a/arkui-plugins/ui-plugins/property-translators/index.ts b/arkui-plugins/ui-plugins/property-translators/index.ts index 4aaf834360bdb4f165ef34f559842d698c002242..06d7ff16058c1656ebcb27fce50d1a91bb39c4fa 100644 --- a/arkui-plugins/ui-plugins/property-translators/index.ts +++ b/arkui-plugins/ui-plugins/property-translators/index.ts @@ -16,6 +16,7 @@ import * as arkts from '@koalaui/libarkts'; import { DecoratorNames } from '../../common/predefines'; +import { StructPropertyAnnotationInfo, StructPropertyInfo } from '../../collectors/ui-collectors/records'; import { InterfacePropertyTranslator, MethodTranslator, PropertyTranslator } from './base'; import { hasDecorator } from './utils'; import { StateInterfaceTranslator, StateTranslator } from './state'; @@ -61,6 +62,84 @@ export function classifyStructMembers( return undefined; } +export function classifyPropertyFromInfo( + node: arkts.ClassProperty, + metadata: StructPropertyInfo +): PropertyTranslator | undefined { + if (!metadata.structInfo) { + return undefined; + } + if (isStatic(node)) { + return new staticPropertyTranslator({ property: node, propertyInfo: metadata }); + } + const annotationInfo = metadata.annotationInfo; + if (!annotationInfo) { + return new RegularPropertyTranslator({ property: node, propertyInfo: metadata }); + } + let propertyTranslator: PropertyTranslator | undefined; + propertyTranslator = classifyV1PropertyFromInfo(node, metadata); + if (!!propertyTranslator) { + return propertyTranslator; + } + // TODO: add V2 property translator here + return propertyTranslator; +} + +export function classifyV1PropertyFromInfo( + node: arkts.ClassProperty, + metadata: StructPropertyInfo +): PropertyTranslator | undefined { + const property: arkts.ClassProperty = node; + const propertyInfo: StructPropertyInfo = metadata; + const annotationInfo: StructPropertyAnnotationInfo = metadata.annotationInfo!; + if (annotationInfo.hasState) { + return new StateTranslator({ property, propertyInfo }); + } + if (annotationInfo.hasProp) { + return new PropTranslator({ property, propertyInfo }); + } + if (annotationInfo.hasLink) { + return new LinkTranslator({ property, propertyInfo }); + } + return undefined; +} + +export function classifyPropertyInInterfaceFromInfo( + property: arkts.AstNode, + metadata: StructPropertyInfo +): InterfacePropertyTranslator | undefined { + let interfacePropertyTranslater: InterfacePropertyTranslator | undefined; + interfacePropertyTranslater = classifyV1PropertyInInterfaceFromInfo(property, metadata); + if (!!interfacePropertyTranslater) { + return interfacePropertyTranslater; + } + // TODO: add V2 interface property translator here + if (RegularInterfaceTranslator.canBeTranslatedFromInfo(property, metadata)) { + return new RegularInterfaceTranslator({ property, propertyInfo: metadata }); + } + return undefined; +} + +export function classifyV1PropertyInInterfaceFromInfo( + property: arkts.AstNode, + metadata: StructPropertyInfo +): InterfacePropertyTranslator | undefined { + const propertyInfo: StructPropertyInfo = metadata; + if (StateInterfaceTranslator.canBeTranslatedFromInfo(property, propertyInfo)) { + return new StateInterfaceTranslator({ property, propertyInfo }); + } + if (LinkInterfaceTranslator.canBeTranslatedFromInfo(property, propertyInfo)) { + return new LinkInterfaceTranslator({ property, propertyInfo }); + } + if (PropInterfaceTranslator.canBeTranslatedFromInfo(property, propertyInfo)) { + return new PropInterfaceTranslator({ property, propertyInfo }); + } + return undefined; +} + +/** + * @deprecated + */ export function classifyProperty( property: arkts.AstNode, structInfo: CustomComponentInfo @@ -83,6 +162,9 @@ export function classifyProperty( return new RegularPropertyTranslator({ property, structInfo }); } +/** + * @deprecated + */ export function classifyV1Property( property: arkts.ClassProperty, structInfo: CustomComponentInfo @@ -133,6 +215,9 @@ export function classifyV1Property( return undefined; } +/** + * @deprecated + */ export function classifyV2Property( property: arkts.ClassProperty, structInfo: CustomComponentInfo @@ -156,6 +241,9 @@ export function classifyV2Property( return undefined; } +/** + * @deprecated + */ export function classifyPropertyInInterface(property: arkts.AstNode): InterfacePropertyTranslator | undefined { let interfacePropertyTranslater: InterfacePropertyTranslator | undefined = undefined; @@ -175,6 +263,9 @@ export function classifyPropertyInInterface(property: arkts.AstNode): InterfaceP return undefined; } +/** + * @deprecated + */ export function classifyV1PropertyInInterface(property: arkts.AstNode): InterfacePropertyTranslator | undefined { if (StateInterfaceTranslator.canBeTranslated(property)) { return new StateInterfaceTranslator({ property }); @@ -221,6 +312,9 @@ export function classifyV1PropertyInInterface(property: arkts.AstNode): Interfac return undefined; } +/** + * @deprecated + */ export function classifyV2PropertyInInterface(property: arkts.AstNode): InterfacePropertyTranslator | undefined { if (LocalInterfaceTranslator.canBeTranslated(property)) { return new LocalInterfaceTranslator({ property }); diff --git a/arkui-plugins/ui-plugins/property-translators/link.ts b/arkui-plugins/ui-plugins/property-translators/link.ts index 65217d539ea207a9cd60a0503eeea15a59d8a442..a0c748a16068cbfa3f667eeaea8d2e58be76a2ee 100644 --- a/arkui-plugins/ui-plugins/property-translators/link.ts +++ b/arkui-plugins/ui-plugins/property-translators/link.ts @@ -15,9 +15,7 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; -import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; -import { CustomComponentNames } from '../utils'; +import { CustomComponentNames, DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { generateToRecord, createGetter, @@ -27,12 +25,45 @@ import { collectStateManagementTypeImport, hasDecorator, PropertyCache, + expectName, + backingField, + checkIsNameStartWithBackingField, } from './utils'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class LinkTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + if (!this.propertyInfo || !this.propertyInfo.structInfo) { + return []; + } + if (!this.propertyInfo.name) { + return []; + } + const originalName = this.propertyInfo.name; + const newName: string = backingField(originalName); + this.cacheTranslatedInitializerFromInfo(newName, originalName); + return this.translateWithoutInitializer(newName, originalName); + } + + cacheTranslatedInitializerFromInfo(newName: string, originalName: string): void { + if (!this.propertyInfo?.structInfo?.name) { + return; + } + const structName: string = this.propertyInfo.structInfo.name; + const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); + PropertyCache.getInstance().collectInitializeStruct(structName, [initializeStruct]); + if (!!this.propertyInfo.structInfo.annotationInfo?.hasReusable) { + const toRecord = generateToRecord(newName, originalName); + PropertyCache.getInstance().collectToRecord(structName, [toRecord]); + } + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -41,7 +72,13 @@ export class LinkTranslator extends PropertyTranslator implements InitializerCon return this.translateWithoutInitializer(newName, originalName); } + /** + * @deprecated + */ cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); if (!!this.structInfo.annotations?.reusable) { @@ -131,7 +168,7 @@ export class LinkTranslator extends PropertyTranslator implements InitializerCon } } -export class LinkInterfaceTranslator extends InterfacePropertyTranslator { +export class LinkInterfaceTranslator extends InterfacePropertyTranslator { translateProperty(): T { if (arkts.isMethodDefinition(this.property)) { this.modified = true; @@ -143,11 +180,21 @@ export class LinkInterfaceTranslator extends I return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasLink; + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.LINK)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.LINK)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.LINK); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.LINK); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/local.ts b/arkui-plugins/ui-plugins/property-translators/local.ts index c1b7bdb58411d4c60f87faec0c61e5b7ae41276b..650d1a431902d5fecd67775bde471c96d3916b2e 100644 --- a/arkui-plugins/ui-plugins/property-translators/local.ts +++ b/arkui-plugins/ui-plugins/property-translators/local.ts @@ -15,7 +15,6 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { createGetter, @@ -25,12 +24,23 @@ import { hasDecorator, collectStateManagementTypeImport, PropertyCache, + expectName, + backingField, + checkIsNameStartWithBackingField, } from './utils'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class LocalTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + throw new Error('Method not implemented.'); + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -39,6 +49,9 @@ export class LocalTranslator extends PropertyTranslator implements InitializerCo } cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); } @@ -117,11 +130,23 @@ export class LocalInterfaceTranslator extends return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return ( + !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasLocal + ); + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.LOCAL)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.LOCAL)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.LOCAL); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.LOCAL); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/localStoragePropRef.ts b/arkui-plugins/ui-plugins/property-translators/localStoragePropRef.ts index 26053062dc7a07b9e4bb62da10a0aae2a205baf6..9a743521a2b030093c6a424695ff6d10b8aba1f0 100644 --- a/arkui-plugins/ui-plugins/property-translators/localStoragePropRef.ts +++ b/arkui-plugins/ui-plugins/property-translators/localStoragePropRef.ts @@ -15,7 +15,6 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; @@ -29,10 +28,21 @@ import { hasDecorator, PropertyCache, getValueInAnnotation, + expectName, + backingField, + checkIsNameStartWithBackingField, } from './utils'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class LocalStoragePropRefTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + throw new Error('Method not implemented.'); + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -42,6 +52,9 @@ export class LocalStoragePropRefTranslator extends PropertyTranslator implements } cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); if (!!this.structInfo.annotations?.reusable) { @@ -135,11 +148,23 @@ export class LocalStoragePropRefInterfaceTranslator< return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return ( + !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasLocalStoragePropRef + ); + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.LOCAL_STORAGE_PROP_REF)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.LOCAL_STORAGE_PROP_REF)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.LOCAL_STORAGE_PROP_REF); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.LOCAL_STORAGE_PROP_REF); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/localstoragelink.ts b/arkui-plugins/ui-plugins/property-translators/localstoragelink.ts index eae40f683e9b97e154bf85d2108187f274fa50b4..69b5b927d1cd8f27a202e028c30f54a49d0fce95 100755 --- a/arkui-plugins/ui-plugins/property-translators/localstoragelink.ts +++ b/arkui-plugins/ui-plugins/property-translators/localstoragelink.ts @@ -15,7 +15,6 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; @@ -29,10 +28,21 @@ import { hasDecorator, PropertyCache, getValueInAnnotation, + expectName, + backingField, + checkIsNameStartWithBackingField, } from './utils'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class LocalStorageLinkTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + throw new Error('Method not implemented.'); + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -42,6 +52,9 @@ export class LocalStorageLinkTranslator extends PropertyTranslator implements In } cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); if (!!this.structInfo.annotations?.reusable) { @@ -135,11 +148,23 @@ export class LocalStorageLinkInterfaceTranslator< return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return ( + !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasLocalStorageLink + ); + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.LOCAL_STORAGE_LINK)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.LOCAL_STORAGE_LINK)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.LOCAL_STORAGE_LINK); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.LOCAL_STORAGE_LINK); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/localstorageprop.ts b/arkui-plugins/ui-plugins/property-translators/localstorageprop.ts index 58eec31cc257158fb2b40e78e5832c5829e55e88..aa04e4944b5f26897e5c0c45fe7157d536a9c1e8 100644 --- a/arkui-plugins/ui-plugins/property-translators/localstorageprop.ts +++ b/arkui-plugins/ui-plugins/property-translators/localstorageprop.ts @@ -15,10 +15,12 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; import { DecoratorNames, StateManagementTypes } from '../../common/predefines'; import { + backingField, + checkIsNameStartWithBackingField, collectStateManagementTypeImport, + expectName, generateToRecord, hasDecorator, PropertyCache, @@ -26,6 +28,7 @@ import { import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; function getLocalStorageporpValueStr(node: arkts.AstNode): string | undefined { if (!arkts.isClassProperty(node) || !node.value) return undefined; @@ -57,6 +60,13 @@ function getLocalStorageporpValueInAnnotation(node: arkts.ClassProperty): string } export class LocalStoragePropTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + throw new Error('Method not implemented.'); + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -66,6 +76,9 @@ export class LocalStoragePropTranslator extends PropertyTranslator implements In } cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); const updateStruct: arkts.AstNode = this.generateUpdateStruct(newName, originalName); @@ -210,11 +223,23 @@ export class LocalStoragePropInterfaceTranslator< return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return ( + !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasLocalStorageProp + ); + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.LOCAL_STORAGE_PROP)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.LOCAL_STORAGE_PROP)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.LOCAL_STORAGE_PROP); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.LOCAL_STORAGE_PROP); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/monitor.ts b/arkui-plugins/ui-plugins/property-translators/monitor.ts index 9dffc1ad8586177e7ec7805a3b8304387af5f11f..c08a04a410105a5275f7889afc362e63855b6bdc 100644 --- a/arkui-plugins/ui-plugins/property-translators/monitor.ts +++ b/arkui-plugins/ui-plugins/property-translators/monitor.ts @@ -15,10 +15,9 @@ import * as arkts from '@koalaui/libarkts'; -import { expectName } from '../../common/arkts-utils'; import { DecoratorNames, MonitorNames, StateManagementTypes } from '../../common/predefines'; import { monitorField } from '../utils'; -import { generateThisBacking, PropertyCache, collectStateManagementTypeImport } from './utils'; +import { generateThisBacking, PropertyCache, collectStateManagementTypeImport, expectName } from './utils'; import { MethodTranslator } from './base'; import { InitializerConstructor } from './types'; import { factory as UIFactory } from '../ui-factory'; diff --git a/arkui-plugins/ui-plugins/property-translators/objectlink.ts b/arkui-plugins/ui-plugins/property-translators/objectlink.ts index 2f4793dadced5e3eb5b472d4d4a7653fb96cc947..899167280f6010d837ab0f0edc383d455de1fc28 100644 --- a/arkui-plugins/ui-plugins/property-translators/objectlink.ts +++ b/arkui-plugins/ui-plugins/property-translators/objectlink.ts @@ -15,11 +15,12 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; -import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; -import { CustomComponentNames } from '../utils'; +import { CustomComponentNames, DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { + backingField, + checkIsNameStartWithBackingField, createGetter, + expectName, generateGetOrSetCall, generateThisBacking, generateToRecord, @@ -29,8 +30,16 @@ import { import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class ObjectLinkTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + throw new Error('Method not implemented.'); + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -39,6 +48,9 @@ export class ObjectLinkTranslator extends PropertyTranslator implements Initiali } cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); const updateStruct: arkts.AstNode = this.generateUpdateStruct(newName, originalName); @@ -130,11 +142,23 @@ export class ObjectLinkInterfaceTranslator ext return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return ( + !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasObjectLink + ); + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.OBJECT_LINK)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.OBJECT_LINK)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.OBJECT_LINK); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.OBJECT_LINK); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/observedTrack.ts b/arkui-plugins/ui-plugins/property-translators/observedTrack.ts index 3694e1692ce12a4cb7d6085512fde11942df9b2e..51edf7a697bd62cc39bb54675d7d97a446f49b73 100644 --- a/arkui-plugins/ui-plugins/property-translators/observedTrack.ts +++ b/arkui-plugins/ui-plugins/property-translators/observedTrack.ts @@ -14,11 +14,12 @@ */ import * as arkts from '@koalaui/libarkts'; -import { annotation, backingField, expectName } from '../../common/arkts-utils'; +import { annotation } from '../../common/arkts-utils'; import { DecoratorNames, StateManagementTypes, ObservedNames } from '../../common/predefines'; -import { ObservedPropertyTranslator } from './base'; import { + backingField, collectStateManagementTypeImport, + expectName, generateThisBacking, hasDecorator, hasDecoratorName, @@ -28,6 +29,7 @@ import { import { ClassScopeInfo } from '../struct-translators/utils'; import { factory } from './factory'; import { factory as uiFactory } from '../ui-factory'; +import { ObservedPropertyTranslator } from './base'; export class ObservedTrackTranslator extends ObservedPropertyTranslator { private hasImplement: boolean; diff --git a/arkui-plugins/ui-plugins/property-translators/observedV2Trace.ts b/arkui-plugins/ui-plugins/property-translators/observedV2Trace.ts index 547b9ab17932ff2cdc2d086f4715115aed48589d..20f210c4382967b87b08ca42f9616faf8280d63c 100644 --- a/arkui-plugins/ui-plugins/property-translators/observedV2Trace.ts +++ b/arkui-plugins/ui-plugins/property-translators/observedV2Trace.ts @@ -14,11 +14,13 @@ */ import * as arkts from '@koalaui/libarkts'; -import { annotation, backingField, expectName } from '../../common/arkts-utils'; +import { annotation } from '../../common/arkts-utils'; import { DecoratorNames, ObservedNames, StateManagementTypes } from '../../common/predefines'; import { ObservedPropertyTranslator } from './base'; import { + backingField, collectStateManagementTypeImport, + expectName, generateThisBacking, hasDecorator, hasDecoratorName, diff --git a/arkui-plugins/ui-plugins/property-translators/once.ts b/arkui-plugins/ui-plugins/property-translators/once.ts index 13f9868ad4003d266f7dc2f6b5967edc9d3fc69e..0261ff19804854fca9ac6cb0d9641971158add17 100644 --- a/arkui-plugins/ui-plugins/property-translators/once.ts +++ b/arkui-plugins/ui-plugins/property-translators/once.ts @@ -15,9 +15,7 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; -import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; -import { CustomComponentNames } from '../utils'; +import { CustomComponentNames, DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { createGetter, createSetter2, @@ -26,12 +24,23 @@ import { hasDecorator, collectStateManagementTypeImport, PropertyCache, + expectName, + backingField, + checkIsNameStartWithBackingField, } from './utils'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class OnceTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + throw new Error('Method not implemented.'); + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -40,6 +49,9 @@ export class OnceTranslator extends PropertyTranslator implements InitializerCon } cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); } @@ -137,11 +149,23 @@ export class OnceInterfaceTranslator extends I return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return ( + !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasOnce + ); + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.ONCE)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.ONCE)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.ONCE); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.ONCE); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/param.ts b/arkui-plugins/ui-plugins/property-translators/param.ts index 8f307b7535d37a8fbf27e829499d3b6922e8ad77..50741afb9483b38fe6411ee12eb63ed60176cca4 100644 --- a/arkui-plugins/ui-plugins/property-translators/param.ts +++ b/arkui-plugins/ui-plugins/property-translators/param.ts @@ -15,9 +15,7 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; -import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; -import { CustomComponentNames } from '../utils'; +import { CustomComponentNames, DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { createGetter, generateThisBacking, @@ -25,12 +23,23 @@ import { hasDecorator, collectStateManagementTypeImport, PropertyCache, + expectName, + backingField, + checkIsNameStartWithBackingField, } from './utils'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class ParamTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + throw new Error('Method not implemented.'); + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -39,6 +48,9 @@ export class ParamTranslator extends PropertyTranslator implements InitializerCo } cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); const updateStruct: arkts.AstNode = this.generateUpdateStruct(generateThisBacking(newName), originalName); @@ -135,11 +147,23 @@ export class ParamInterfaceTranslator extends return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return ( + !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasParam + ); + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.PARAM)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.PARAM)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.PARAM); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.PARAM); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/prop.ts b/arkui-plugins/ui-plugins/property-translators/prop.ts index 47722196db452e716a43b5c89decfcd99d79c50b..d93ef2d2121e7092192d0799d268399fca7fe493 100644 --- a/arkui-plugins/ui-plugins/property-translators/prop.ts +++ b/arkui-plugins/ui-plugins/property-translators/prop.ts @@ -15,9 +15,7 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; -import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; -import { CustomComponentNames } from '../utils'; +import { CustomComponentNames, DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { collectStateManagementTypeImport, createGetter, @@ -27,12 +25,48 @@ import { generateToRecord, hasDecorator, PropertyCache, + expectName, + backingField, + checkIsNameStartWithBackingField, } from './utils'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class PropTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + if (!this.propertyInfo || !this.propertyInfo.structInfo) { + return []; + } + if (!this.propertyInfo.name) { + return []; + } + const originalName = this.propertyInfo.name; + const newName: string = backingField(originalName); + this.cacheTranslatedInitializerFromInfo(newName, originalName); + return this.translateWithoutInitializer(newName, originalName); + } + + cacheTranslatedInitializerFromInfo(newName: string, originalName: string): void { + if (!this.propertyInfo?.structInfo?.name) { + return; + } + const structName: string = this.propertyInfo.structInfo.name; + const mutableThis: arkts.Expression = generateThisBacking(newName); + const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); + PropertyCache.getInstance().collectInitializeStruct(structName, [initializeStruct]); + const updateStruct: arkts.AstNode = this.generateUpdateStruct(mutableThis, originalName); + PropertyCache.getInstance().collectUpdateStruct(structName, [updateStruct]); + if (!!this.propertyInfo.structInfo.annotationInfo?.hasReusable) { + const toRecord = generateToRecord(newName, originalName); + PropertyCache.getInstance().collectToRecord(structName, [toRecord]); + } + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -41,7 +75,13 @@ export class PropTranslator extends PropertyTranslator implements InitializerCon return this.translateWithoutInitializer(newName, originalName); } + /** + * @deprecated + */ cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const mutableThis: arkts.Expression = generateThisBacking(newName); const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); @@ -160,11 +200,23 @@ export class PropInterfaceTranslator extends I return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return ( + !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasProp + ); + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.PROP)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.PROP)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.PROP); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.PROP); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/propRef.ts b/arkui-plugins/ui-plugins/property-translators/propRef.ts index 48328550604b1199e2ce085ae9a4d07a91371b4c..fc3ac5aa906d8b97688e326bed0f0f7ae6baef23 100644 --- a/arkui-plugins/ui-plugins/property-translators/propRef.ts +++ b/arkui-plugins/ui-plugins/property-translators/propRef.ts @@ -15,9 +15,7 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; -import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; -import { CustomComponentNames } from '../utils'; +import { CustomComponentNames, DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { generateToRecord, createGetter, @@ -27,12 +25,23 @@ import { collectStateManagementTypeImport, hasDecorator, PropertyCache, + expectName, + backingField, + checkIsNameStartWithBackingField, } from './utils'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class PropRefTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + throw new Error('Method not implemented.'); + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -42,6 +51,9 @@ export class PropRefTranslator extends PropertyTranslator implements Initializer } cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const mutableThis: arkts.Expression = generateThisBacking(newName); const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); @@ -169,11 +181,23 @@ export class PropRefInterfaceTranslator extend return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return ( + !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasPropRef + ); + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.PROP_REF)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.PROP_REF)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.PROP_REF); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.PROP_REF); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/provide.ts b/arkui-plugins/ui-plugins/property-translators/provide.ts index fcdc93b168b8bc34044e3b7777bfa5f05f7f1ef6..c76ff6c710c4bec7c53574d292ba4da04193bf60 100644 --- a/arkui-plugins/ui-plugins/property-translators/provide.ts +++ b/arkui-plugins/ui-plugins/property-translators/provide.ts @@ -15,9 +15,7 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; -import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; -import { CustomComponentNames } from '../utils'; +import { CustomComponentNames, DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { createGetter, generateToRecord, @@ -28,12 +26,23 @@ import { ProvideOptions, hasDecorator, PropertyCache, + expectName, + backingField, + checkIsNameStartWithBackingField, } from './utils'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class ProvideTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + throw new Error('Method not implemented.'); + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -42,6 +51,9 @@ export class ProvideTranslator extends PropertyTranslator implements Initializer } cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const initializeStruct: arkts.AstNode = this.generateInitializeStruct(originalName, newName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); if (!!this.structInfo.annotations?.reusable) { @@ -138,11 +150,23 @@ export class ProvideInterfaceTranslator extend return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return ( + !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasProvide + ); + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.PROVIDE)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.PROVIDE)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.PROVIDE); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.PROVIDE); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/provider.ts b/arkui-plugins/ui-plugins/property-translators/provider.ts index 474b78b160db9ef1669edde91885b44ad43e9712..05f6f8b2249186bd2ff551e48946607afb4d76de 100644 --- a/arkui-plugins/ui-plugins/property-translators/provider.ts +++ b/arkui-plugins/ui-plugins/property-translators/provider.ts @@ -15,7 +15,6 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { createGetter, @@ -25,12 +24,23 @@ import { hasDecorator, PropertyCache, getValueInAnnotation, + expectName, + backingField, + checkIsNameStartWithBackingField, } from './utils'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class ProviderTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + throw new Error('Method not implemented.'); + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -39,6 +49,9 @@ export class ProviderTranslator extends PropertyTranslator implements Initialize } cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const initializeStruct: arkts.AstNode = this.generateInitializeStruct(originalName, newName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); } @@ -119,11 +132,23 @@ export class ProviderInterfaceTranslator exten return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return ( + !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasState + ); + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.PROVIDER)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.PROVIDER)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.PROVIDER); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.PROVIDER); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/regularProperty.ts b/arkui-plugins/ui-plugins/property-translators/regularProperty.ts index 03ff22e98ffdbfb2f44e42a8e8ee13c3ce0b03b2..7ee69dfee0911a855c415ecd20c0c1beca5f60a3 100644 --- a/arkui-plugins/ui-plugins/property-translators/regularProperty.ts +++ b/arkui-plugins/ui-plugins/property-translators/regularProperty.ts @@ -22,14 +22,53 @@ import { createSetter2, PropertyCache, isCustomDialogController, + expectName, + backingField, } from './utils'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; -import { backingField, expectName } from '../../common/arkts-utils'; import { factory } from './factory'; -import { CustomComponentNames } from '../utils'; +import { CustomComponentNames } from '../../common/predefines'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class RegularPropertyTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + if (!this.propertyInfo || !this.propertyInfo.structInfo) { + return []; + } + if (!this.propertyInfo.name) { + return []; + } + const originalName = this.propertyInfo.name; + const newName: string = backingField(originalName); + return this.translateWithoutInitializer(newName, originalName); + } + + cacheTranslatedInitializerFromInfo(newName: string, originalName: string): void { + if (!this.propertyInfo?.structInfo?.name) { + return; + } + const structName: string = this.propertyInfo.structInfo.name; + const value = this.property.value ?? arkts.factory.createUndefinedLiteral(); + let initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName, value); + if ( + !!this.propertyInfo.structInfo.annotationInfo?.hasCustomDialog && + !!this.property.typeAnnotation && + isCustomDialogController(this.property.typeAnnotation) + ) { + initializeStruct = this.generateControllerInit(originalName, initializeStruct); + } + PropertyCache.getInstance().collectInitializeStruct(structName, [initializeStruct]); + if (!!this.propertyInfo.structInfo.annotationInfo?.hasReusable) { + const toRecord = generateToRecord(newName, originalName); + PropertyCache.getInstance().collectToRecord(structName, [toRecord]); + } + } + + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -37,7 +76,13 @@ export class RegularPropertyTranslator extends PropertyTranslator implements Ini return this.translateWithoutInitializer(newName, originalName); } + /** + * @deprecated + */ cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const value = this.property.value ?? arkts.factory.createUndefinedLiteral(); let initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName, value); if ( @@ -99,7 +144,7 @@ export class RegularPropertyTranslator extends PropertyTranslator implements Ini return createSetter2(originalName, typeAnnotation, statement); } - generateInitializeStruct(newName: string, originalName: string, value: arkts.Expression): arkts.AstNode { + generateInitializeStruct(newName: string, originalName: string, value: arkts.Expression | undefined): arkts.AstNode { const binaryItem = arkts.factory.createBinaryExpression( factory.createBlockStatementForOptionalExpression( arkts.factory.createIdentifier(CustomComponentNames.COMPONENT_INITIALIZERS_NAME), @@ -132,6 +177,16 @@ export class RegularInterfaceTranslator extend return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return true; + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { return true; } diff --git a/arkui-plugins/ui-plugins/property-translators/state.ts b/arkui-plugins/ui-plugins/property-translators/state.ts index 13f5095a847c38a1eafce791ea0e95dffb61b339..6ed0c7619f99228efe0f823f2c7834d26f1f33c6 100644 --- a/arkui-plugins/ui-plugins/property-translators/state.ts +++ b/arkui-plugins/ui-plugins/property-translators/state.ts @@ -15,9 +15,7 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; -import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; -import { CustomComponentNames } from '../utils'; +import { CustomComponentNames, DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { generateToRecord, createGetter, @@ -27,12 +25,45 @@ import { hasDecorator, collectStateManagementTypeImport, PropertyCache, + expectName, + backingField, + checkIsNameStartWithBackingField, } from './utils'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class StateTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + if (!this.propertyInfo || !this.propertyInfo.structInfo) { + return []; + } + if (!this.propertyInfo.name) { + return []; + } + const originalName = this.propertyInfo.name; + const newName: string = backingField(originalName); + this.cacheTranslatedInitializerFromInfo(newName, originalName); + return this.translateWithoutInitializer(newName, originalName); + } + + cacheTranslatedInitializerFromInfo(newName: string, originalName: string): void { + if (!this.propertyInfo?.structInfo?.name) { + return; + } + const structName: string = this.propertyInfo.structInfo.name; + const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); + PropertyCache.getInstance().collectInitializeStruct(structName, [initializeStruct]); + if (!!this.propertyInfo.structInfo.annotationInfo?.hasReusable) { + const toRecord = generateToRecord(newName, originalName); + PropertyCache.getInstance().collectToRecord(structName, [toRecord]); + } + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -40,7 +71,13 @@ export class StateTranslator extends PropertyTranslator implements InitializerCo return this.translateWithoutInitializer(newName, originalName); } + /** + * @deprecated + */ cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); if (!!this.structInfo.annotations?.reusable) { @@ -134,11 +171,23 @@ export class StateInterfaceTranslator extends return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return ( + !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasState + ); + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.STATE)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.STATE)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.STATE); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.STATE); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/staticProperty.ts b/arkui-plugins/ui-plugins/property-translators/staticProperty.ts index 12e9535c5eebcbfcafca53beb45df1dcc221a1b0..73d72a6be4b565ffc17788f5b9fbaa07bbe51b26 100644 --- a/arkui-plugins/ui-plugins/property-translators/staticProperty.ts +++ b/arkui-plugins/ui-plugins/property-translators/staticProperty.ts @@ -15,12 +15,26 @@ import * as arkts from '@koalaui/libarkts'; -import { createGetter, createSetter } from './utils'; +import { backingField, createGetter, createSetter, expectName } from './utils'; import { PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; -import { backingField, expectName } from '../../common/arkts-utils'; export class staticPropertyTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + if (!this.propertyInfo || !this.propertyInfo.structInfo) { + return []; + } + if (!this.propertyInfo.name) { + return []; + } + const originalName = this.propertyInfo.name; + const newName: string = backingField(originalName); + return this.translateWithoutInitializer(newName, originalName); + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); diff --git a/arkui-plugins/ui-plugins/property-translators/storageProp.ts b/arkui-plugins/ui-plugins/property-translators/storageProp.ts index f1952c88da16e4964d5769321094407ac3629852..115f962e4ae18d837a8abcc41dbaeae625c2d422 100644 --- a/arkui-plugins/ui-plugins/property-translators/storageProp.ts +++ b/arkui-plugins/ui-plugins/property-translators/storageProp.ts @@ -15,7 +15,6 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; @@ -29,10 +28,21 @@ import { hasDecorator, PropertyCache, getValueInAnnotation, + expectName, + backingField, + checkIsNameStartWithBackingField, } from './utils'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class StoragePropTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + throw new Error('Method not implemented.'); + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -42,6 +52,9 @@ export class StoragePropTranslator extends PropertyTranslator implements Initial } cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); if (!!this.structInfo.annotations?.reusable) { @@ -134,11 +147,23 @@ export class StoragePropInterfaceTranslator ex return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return ( + !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasStorageProp + ); + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.STORAGE_PROP)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.STORAGE_PROP)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.STORAGE_PROP); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.STORAGE_PROP); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/storagePropRef.ts b/arkui-plugins/ui-plugins/property-translators/storagePropRef.ts index d14668cc72670d87d2d9a91cfd3fb6fe6987eeb4..09970368b465390d5d309fdaa8f4a87543279167 100644 --- a/arkui-plugins/ui-plugins/property-translators/storagePropRef.ts +++ b/arkui-plugins/ui-plugins/property-translators/storagePropRef.ts @@ -15,7 +15,6 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; @@ -29,10 +28,21 @@ import { hasDecorator, PropertyCache, getValueInAnnotation, + expectName, + backingField, + checkIsNameStartWithBackingField, } from './utils'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class StoragePropRefTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + throw new Error('Method not implemented.'); + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -42,6 +52,9 @@ export class StoragePropRefTranslator extends PropertyTranslator implements Init } cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); if (!!this.structInfo.annotations?.reusable) { @@ -136,11 +149,23 @@ export class StoragePropRefInterfaceTranslator< return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return ( + !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasStoragePropRef + ); + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.STORAGE_PROP_REF)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.STORAGE_PROP_REF)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.STORAGE_PROP_REF); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.STORAGE_PROP_REF); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/storagelink.ts b/arkui-plugins/ui-plugins/property-translators/storagelink.ts index 579fe88329d9b5bef5605a452e260f76820d7129..8a72453319575c5cddb9d1922f1acdaae7372b2e 100644 --- a/arkui-plugins/ui-plugins/property-translators/storagelink.ts +++ b/arkui-plugins/ui-plugins/property-translators/storagelink.ts @@ -15,7 +15,6 @@ import * as arkts from '@koalaui/libarkts'; -import { backingField, expectName } from '../../common/arkts-utils'; import { DecoratorNames, GetSetTypes, StateManagementTypes } from '../../common/predefines'; import { InterfacePropertyTranslator, InterfacePropertyTypes, PropertyTranslator } from './base'; import { GetterSetter, InitializerConstructor } from './types'; @@ -29,10 +28,21 @@ import { hasDecorator, PropertyCache, getValueInAnnotation, + expectName, + backingField, + checkIsNameStartWithBackingField, } from './utils'; import { factory } from './factory'; +import { CustomComponentInterfacePropertyInfo } from '../../collectors/ui-collectors/records'; export class StorageLinkTranslator extends PropertyTranslator implements InitializerConstructor, GetterSetter { + rewriteMember(): arkts.AstNode[] { + throw new Error('Method not implemented.'); + } + + /** + * @deprecated + */ translateMember(): arkts.AstNode[] { const originalName: string = expectName(this.property.key); const newName: string = backingField(originalName); @@ -42,6 +52,9 @@ export class StorageLinkTranslator extends PropertyTranslator implements Initial } cacheTranslatedInitializer(newName: string, originalName: string): void { + if (!this.structInfo) { + return; + } const initializeStruct: arkts.AstNode = this.generateInitializeStruct(newName, originalName); PropertyCache.getInstance().collectInitializeStruct(this.structInfo.name, [initializeStruct]); if (!!this.structInfo.annotations?.reusable) { @@ -133,11 +146,23 @@ export class StorageLinkInterfaceTranslator ex return this.property; } + static canBeTranslatedFromInfo( + node: arkts.AstNode, + metadata: CustomComponentInterfacePropertyInfo + ): node is InterfacePropertyTypes { + return ( + !!metadata.name?.startsWith(StateManagementTypes.BACKING) && !!metadata.annotationInfo?.hasStorageLink + ); + } + + /** + * @deprecated + */ static canBeTranslated(node: arkts.AstNode): node is InterfacePropertyTypes { - if (arkts.isMethodDefinition(node) && hasDecorator(node, DecoratorNames.STORAGE_LINK)) { - return true; - } else if (arkts.isClassProperty(node) && hasDecorator(node, DecoratorNames.STORAGE_LINK)) { - return true; + if (arkts.isMethodDefinition(node)) { + return checkIsNameStartWithBackingField(node.name) && hasDecorator(node, DecoratorNames.STORAGE_LINK); + } else if (arkts.isClassProperty(node)) { + return checkIsNameStartWithBackingField(node.key) && hasDecorator(node, DecoratorNames.STORAGE_LINK); } return false; } diff --git a/arkui-plugins/ui-plugins/property-translators/utils.ts b/arkui-plugins/ui-plugins/property-translators/utils.ts index 868e43aa1f8f43db12aadd71b33d5b7a119644a0..711289fbe6e03cc2eb6433e99011c8c5887c40f2 100644 --- a/arkui-plugins/ui-plugins/property-translators/utils.ts +++ b/arkui-plugins/ui-plugins/property-translators/utils.ts @@ -17,19 +17,18 @@ import * as arkts from '@koalaui/libarkts'; import { ImportCollector } from '../../common/import-collector'; import { isDecoratorAnnotation } from '../../common/arkts-utils'; import { - DecoratorIntrinsicNames, DecoratorNames, - DECORATOR_TYPE_MAP, StateManagementTypes, GetSetTypes, ObservedNames, + CustomDialogNames, } from '../../common/predefines'; import { addMemoAnnotation, findCanAddMemoFromParameter, findCanAddMemoFromTypeAnnotation, } from '../../collectors/memo-collectors/utils'; -import { CustomDialogNames } from '../utils'; +import { AstNodePointer } from '../../common/safe-types'; export interface DecoratorInfo { annotation: arkts.AnnotationUsage; @@ -41,13 +40,6 @@ export interface OptionalMemberInfo { isNumeric?: boolean; } -export function isDecoratorIntrinsicAnnotation( - anno: arkts.AnnotationUsage, - decoratorName: DecoratorIntrinsicNames -): boolean { - return !!anno.expr && arkts.isIdentifier(anno.expr) && anno.expr.name === decoratorName; -} - export function removeDecorator( property: arkts.ClassProperty | arkts.ClassDefinition | arkts.MethodDefinition, decoratorName: DecoratorNames, @@ -66,6 +58,16 @@ export function removeDecorator( } } +export function removAllDecorators( + property: arkts.ClassProperty | arkts.ClassDefinition | arkts.MethodDefinition +): void { + if (arkts.isMethodDefinition(property)) { + property.scriptFunction.setAnnotations([]); + } else { + property.setAnnotations([]); + } +} + /** * checking whether astNode's annotations contain given corresponding decorator name, * regardless where the annotation's declaration is from arkui declaration files. @@ -408,6 +410,27 @@ export function removeImplementProperty(originalName: string): string { return originalName.substring(prefix.length); } +export function expectName(node: arkts.AstNode | undefined): string { + if (!node) { + throw new Error('Expected an identifier, got empty node'); + } + if (!arkts.isIdentifier(node)) { + throw new Error('Expected an identifier, got: ' + arkts.nodeType(node).toString()); + } + return node.name; +} + +export function backingField(originalName: string): string { + return `${StateManagementTypes.BACKING}_${originalName}`; +} + +export function checkIsNameStartWithBackingField(node: arkts.AstNode | undefined): boolean { + if (!node || !arkts.isIdentifier(node)) { + return false; + } + return node.name.startsWith(StateManagementTypes.BACKING); +} + // CACHE export interface PropertyCachedBody { initializeBody?: arkts.AstNode[]; @@ -475,3 +498,33 @@ export class PropertyCache { this._cache.set(name, { ...this._cache.get(name), constructorBody: newConstructorBody }); } } + +export class PropertyRewriteCache { + private _cache: Map; + private static instance: PropertyRewriteCache; + + private constructor() { + this._cache = new Map(); + } + + static getInstance(): PropertyRewriteCache { + if (!this.instance) { + this.instance = new PropertyRewriteCache(); + } + return this.instance; + } + + reset(): void { + this._cache.clear(); + } + + getRewriteNodes(ptr: AstNodePointer): arkts.AstNode[] { + return this._cache.get(ptr) ?? []; + } + + collectRewriteNodes(ptr: AstNodePointer, nodes: arkts.AstNode[]): void { + const originProperties = this._cache.get(ptr) ?? []; + const newProperties = [...originProperties, ...nodes]; + this._cache.set(ptr, newProperties); + } +} diff --git a/arkui-plugins/ui-plugins/shared-types.ts b/arkui-plugins/ui-plugins/shared-types.ts new file mode 100644 index 0000000000000000000000000000000000000000..88152616465ddc68da161da70e6a96d3a8088e6a --- /dev/null +++ b/arkui-plugins/ui-plugins/shared-types.ts @@ -0,0 +1,77 @@ +/* + * 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 { VisitorOptions } from '../common/abstract-visitor'; +import { ProjectConfig } from '../common/plugin-context'; +import { + CallInfo, + CustomComponentInfo, + CustomComponentInterfaceInfo, + CustomComponentInterfacePropertyInfo, + FunctionInfo, + NormalClassInfo, + NormalClassMethodInfo, + NormalClassPropertyInfo, + NormalInterfaceInfo, + NormalInterfacePropertyInfo, + StructMethodInfo, + StructPropertyInfo, +} from '../collectors/ui-collectors/records'; + +export type ClassDeclarationRecordInfo = NormalClassInfo | CustomComponentInfo; + +export type MethodDefinitionRecordInfo = + | FunctionInfo + | NormalClassMethodInfo + | StructMethodInfo + | NormalInterfacePropertyInfo + | CustomComponentInterfacePropertyInfo; + +export type ClassPropertyRecordInfo = NormalClassPropertyInfo | StructPropertyInfo; + +export type TSInterfaceDeclarationRecordInfo = NormalInterfaceInfo | CustomComponentInterfaceInfo; + +export type CallExpressionRecordInfo = CallInfo; + +export type RecordInfo = + | MethodDefinitionRecordInfo + | ClassPropertyRecordInfo + | ClassDeclarationRecordInfo + | TSInterfaceDeclarationRecordInfo + | CallExpressionRecordInfo; + +export interface CheckedTransformerMetadata extends VisitorOptions { + legacyBuilderSet?: Set; + projectConfig?: ProjectConfig | undefined; + aceBuildJson?: LoaderJson; + resourceInfo?: ResourceInfo; +} + +export type CachedMetadata = T & CheckedTransformerMetadata; + +export type ResourceMap = Map>; + +export interface ResourceList { + [key: string]: ResourceMap; +} + +export interface ResourceInfo { + resourcesList: ResourceList; + rawfile: Set; +} + +export interface LoaderJson { + hspResourcesMap: Record; +} \ No newline at end of file diff --git a/arkui-plugins/ui-plugins/struct-translators/factory.ts b/arkui-plugins/ui-plugins/struct-translators/factory.ts index d4fd4e5d1d88d7b00caed14fdf65a0e4da916e03..69e2dbd17821c70be4d1b98a1fb89aadc25348c4 100644 --- a/arkui-plugins/ui-plugins/struct-translators/factory.ts +++ b/arkui-plugins/ui-plugins/struct-translators/factory.ts @@ -15,9 +15,6 @@ import * as arkts from '@koalaui/libarkts'; import { - BuilderLambdaNames, - CustomComponentNames, - CustomDialogNames, getCustomComponentOptionsName, getGettersFromClassDecl, getTypeNameFromTypeParameter, @@ -29,7 +26,7 @@ import { import { factory as UIFactory } from '../ui-factory'; import { factory as PropertyFactory } from '../property-translators/factory'; import { factory as BuilderLambdaFactory } from '../builder-lambda-translators/factory'; -import { backingField, collect, filterDefined } from '../../common/arkts-utils'; +import { collect, filterDefined } from '../../common/arkts-utils'; import { classifyInObservedClass, classifyPropertyInInterface, @@ -41,7 +38,6 @@ import { import { CustomComponentScopeInfo, isEtsGlobalClass, - ResourceInfo, checkRawfileResource, generateResourceModuleName, generateResourceBundleName, @@ -56,12 +52,17 @@ import { findBuilderIndexInControllerOptions, ObservedAnnoInfo, getNoTransformationMembersInClass, + RewritedStructMethodInfo, + StructType, + collectRewritedStructMethodInfo, } from './utils'; import { + backingField, collectStateManagementTypeImport, generateThisBacking, hasDecorator, PropertyCache, + PropertyRewriteCache, } from '../property-translators/utils'; import { ProjectConfig } from '../../common/plugin-context'; import { ImportCollector } from '../../common/import-collector'; @@ -75,6 +76,9 @@ import { RESOURCE_TYPE, ARKUI_BUILDER_SOURCE_NAME, TypeNames, + BuilderLambdaNames, + CustomComponentNames, + CustomDialogNames, } from '../../common/predefines'; import { ObservedTranslator } from '../property-translators/index'; import { @@ -84,7 +88,13 @@ import { } from '../../collectors/memo-collectors/utils'; import { generateArkUICompatible, isArkUICompatible } from '../interop/interop'; import { GenSymGenerator } from '../../common/gensym-generator'; -import { MethodTranslator } from 'ui-plugins/property-translators/base'; +import { MethodTranslator } from '../property-translators/base'; +import { + CustomComponentInfo as CustomComponentRecordInfo, + NormalClassInfo, + StructMethodInfo, +} from '../../collectors/ui-collectors/records'; +import { CachedMetadata, ResourceInfo } from '../shared-types'; export class factory { /** @@ -98,9 +108,19 @@ export class factory { } /** - * create __initializeStruct method. + * create `__initializeStruct` method. + */ + static createInitializeStruct(optionsTypeName: string, metadata: CustomComponentRecordInfo): arkts.MethodDefinition; + + /** + * @deprecated */ - static createInitializeStruct(optionsTypeName: string, scope: CustomComponentScopeInfo): arkts.MethodDefinition { + static createInitializeStruct(optionsTypeName: string, scope: CustomComponentScopeInfo): arkts.MethodDefinition; + + static createInitializeStruct( + optionsTypeName: string, + metadata: CustomComponentRecordInfo | CustomComponentScopeInfo + ): arkts.MethodDefinition { const updateKey: arkts.Identifier = arkts.factory.createIdentifier( CustomComponentNames.COMPONENT_INITIALIZE_STRUCT ); @@ -108,8 +128,8 @@ export class factory { let body: arkts.BlockStatement | undefined; let modifiers: arkts.Es2pandaModifierFlags = arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PUBLIC | arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_DECLARE; - if (!scope.isDecl) { - body = arkts.factory.createBlock(PropertyCache.getInstance().getInitializeBody(scope.name)); + if (!metadata.isDecl) { + body = arkts.factory.createBlock(PropertyCache.getInstance().getInitializeBody(metadata.name!)); modifiers = arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PUBLIC; } const scriptFunction: arkts.ScriptFunction = arkts.factory @@ -184,9 +204,19 @@ export class factory { } /** - * create __updateStruct method. + * create `__updateStruct` method. + */ + static createUpdateStruct(optionsTypeName: string, metadata: CustomComponentRecordInfo): arkts.MethodDefinition; + + /** + * @deprecated */ - static createUpdateStruct(optionsTypeName: string, scope: CustomComponentScopeInfo): arkts.MethodDefinition { + static createUpdateStruct(optionsTypeName: string, scope: CustomComponentScopeInfo): arkts.MethodDefinition; + + static createUpdateStruct( + optionsTypeName: string, + metadata: CustomComponentScopeInfo | CustomComponentRecordInfo + ): arkts.MethodDefinition { const updateKey: arkts.Identifier = arkts.factory.createIdentifier( CustomComponentNames.COMPONENT_UPDATE_STRUCT ); @@ -194,11 +224,10 @@ export class factory { let body: arkts.BlockStatement | undefined; let modifiers: arkts.Es2pandaModifierFlags = arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PUBLIC | arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_DECLARE; - if (!scope.isDecl) { - body = arkts.factory.createBlock(PropertyCache.getInstance().getUpdateBody(scope.name)); + if (!metadata.isDecl) { + body = arkts.factory.createBlock(PropertyCache.getInstance().getUpdateBody(metadata.name!)); modifiers = arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_PUBLIC; } - const scriptFunction: arkts.ScriptFunction = arkts.factory .createScriptFunction( body, @@ -223,14 +252,24 @@ export class factory { } /** - * create __toRecord method when the component is decorated with @Reusable. + * create `__toRecord` method when the component is decorated with `@Reusable`. + */ + static createToRecord(optionsTypeName: string, metadata: CustomComponentRecordInfo): arkts.MethodDefinition; + + /** + * @deprecated */ - static createToRecord(optionsTypeName: string, scope: CustomComponentScopeInfo): arkts.MethodDefinition { + static createToRecord(optionsTypeName: string, scope: CustomComponentScopeInfo): arkts.MethodDefinition; + + static createToRecord( + optionsTypeName: string, + metadata: CustomComponentScopeInfo | CustomComponentRecordInfo + ): arkts.MethodDefinition { const paramsCasted = factory.generateParamsCasted(optionsTypeName); const returnRecord = arkts.factory.createReturnStatement( arkts.ObjectExpression.createObjectExpression( arkts.Es2pandaAstNodeType.AST_NODE_TYPE_OBJECT_EXPRESSION, - PropertyCache.getInstance().getToRecordBody(scope.name), + PropertyCache.getInstance().getToRecordBody(metadata.name!), false ) ); @@ -250,7 +289,7 @@ export class factory { return arkts.factory.createMethodDefinition( arkts.Es2pandaMethodDefinitionKind.METHOD_DEFINITION_KIND_CONSTRUCTOR, - arkts.factory.createIdentifier('__toRecord'), + arkts.factory.createIdentifier(CustomComponentNames.COMPONENT_TO_RECORD), toRecordScriptFunction, arkts.Es2pandaModifierFlags.MODIFIER_FLAGS_OVERRIDE, false @@ -448,6 +487,7 @@ export class factory { /** * transform property members in custom-component class. + * @deprecated */ static tranformPropertyMembers( propertyTranslators: (PropertyTranslator | MethodTranslator)[], @@ -468,8 +508,27 @@ export class factory { return collect(...collections, ...propertyMembers); } + static collectStructPropertyRewriteStatements( + optionsTypeName: string, + metadata: CustomComponentRecordInfo, + scope: RewritedStructMethodInfo + ): arkts.AstNode[] { + const collections = []; + if (!scope.hasInitializeStruct) { + collections.push(this.createInitializeStruct(optionsTypeName, metadata)); + } + if (!scope.hasUpdateStruct) { + collections.push(this.createUpdateStruct(optionsTypeName, metadata)); + } + if (!scope.hasToRecord && !!metadata.annotationInfo?.hasReusable) { + collections.push(this.createToRecord(optionsTypeName, metadata)); + } + return collections; + } + /** * transform non-property members in custom-component class. + * @deprecated */ static transformNonPropertyMembersInClass(member: arkts.AstNode, isDecl?: boolean): arkts.AstNode { if (arkts.isMethodDefinition(member)) { @@ -485,8 +544,26 @@ export class factory { return member; } + /** + * transform non-property members in custom-component class. + */ + static transformNonPropertyMembersInClassFromInfo( + member: arkts.MethodDefinition, + metadata: StructMethodInfo + ): arkts.AstNode { + PropertyFactory.addMemoToBuilderClassMethodFromInfo(member, metadata); + if (!!metadata.isCtor && !metadata.isDecl) { + return this.setStructConstructorToPrivate(member); + } + if (metadata.name === CustomComponentNames.COMPONENT_BUILD_ORI) { + addMemoAnnotation(member.scriptFunction); + } + return member; + } + /** * transform members in custom-component class. + * @deprecated */ static tranformClassMembers(node: arkts.ClassDeclaration, scope: CustomComponentScopeInfo): arkts.ClassDeclaration { if (!node.definition) { @@ -536,6 +613,48 @@ export class factory { return arkts.factory.updateClassDeclaration(node, updateClassDef); } + /** + * transform members in custom-component class. + */ + static tranformClassMembersFromInfo( + node: arkts.ClassDeclaration, + metadata: CustomComponentRecordInfo, + structType: StructType + ): arkts.ClassDeclaration { + const definition = node.definition; + if (!definition || !metadata.name) { + return node; + } + let scopeInfo: RewritedStructMethodInfo = {}; + const transformedBody = definition.body.map((child: arkts.AstNode) => { + scopeInfo = collectRewritedStructMethodInfo(child, scopeInfo); + if (structType === StructType.CUSTOM_COMPONENT_DECL) { + return [child]; + } + const nodes = PropertyRewriteCache.getInstance().getRewriteNodes(child.peer); + if (nodes.length > 0) { + return nodes; + } + return [child]; + }); + let optionsTypeName: string | undefined; + if (structType === StructType.CUSTOM_COMPONENT_DECL) { + const [_, classOptions] = getTypeParamsFromClassDecl(node); + optionsTypeName = getTypeNameFromTypeParameter(classOptions); + } + const newStatements = this.collectStructPropertyRewriteStatements( + optionsTypeName ?? getCustomComponentOptionsName(metadata.name), + metadata, + scopeInfo + ); + // TODO: add CustomDialog property here. + const newDefinition = this.updateCustomComponentClass(definition, collect(newStatements, ...transformedBody)); + if (structType === StructType.STRUCT) { + PropertyRewriteCache.getInstance().reset(); + } + return arkts.factory.updateClassDeclaration(node, newDefinition); + } + /** * transform `$r` and `$rawfile` function calls. */ @@ -795,6 +914,9 @@ export class factory { return node; } + /** + * @deprecated + */ static transformETSGlobalClass(node: arkts.ClassDeclaration, externalSourceName?: string): arkts.ClassDeclaration { if (!node.definition) { return node; @@ -834,6 +956,35 @@ export class factory { ); } + static transformETSGlobalClassFromInfo( + node: arkts.ClassDeclaration, + metadata: CachedMetadata + ): arkts.ClassDeclaration { + if (!node.definition) { + return node; + } + const updatedBody = node.definition.body; // TODO: add animateExtend transform here. + let newStatements: arkts.AstNode[] = []; + if (metadata.externalSourceName === ARKUI_BUILDER_SOURCE_NAME) { + newStatements.push(...BuilderLambdaFactory.addConditionBuilderDecls()); + } + return arkts.factory.updateClassDeclaration( + node, + arkts.factory.updateClassDefinition( + node.definition, + node.definition.ident, + node.definition.typeParams, + node.definition.superTypeParams, + node.definition.implements, + undefined, + node.definition.super, + [...updatedBody, ...newStatements], + node.definition.modifiers, + arkts.classDefinitionFlags(node.definition) + ) + ); + } + static transformNormalClass(node: arkts.ClassDeclaration, externalSourceName?: string): arkts.ClassDeclaration { if (!node.definition) { return node; diff --git a/arkui-plugins/ui-plugins/struct-translators/struct-transformer.ts b/arkui-plugins/ui-plugins/struct-translators/struct-transformer.ts index 3101184cdba3342b645ef30ed3c71c73166d4cfb..2a021046f87f70ea8267ae8d5bd9c42deb0256bc 100644 --- a/arkui-plugins/ui-plugins/struct-translators/struct-transformer.ts +++ b/arkui-plugins/ui-plugins/struct-translators/struct-transformer.ts @@ -14,15 +14,13 @@ */ import * as arkts from '@koalaui/libarkts'; -import { AbstractVisitor } from '../../common/abstract-visitor'; +import { AbstractVisitor, VisitorOptions } from '../../common/abstract-visitor'; import { ProjectConfig } from '../../common/plugin-context'; -import { collectCustomComponentScopeInfo, CustomComponentNames, isCustomComponentClass } from '../utils'; +import { collectCustomComponentScopeInfo, isCustomComponentClass } from '../utils'; import { CustomComponentScopeInfo, isResourceNode, ScopeInfoCollection, - LoaderJson, - ResourceInfo, loadBuildJson, initResourceInfo, } from './utils'; @@ -33,6 +31,14 @@ import { ImportCollector } from '../../common/import-collector'; import { DeclarationCollector } from '../../common/declaration-collector'; import { PropertyCache } from '../property-translators/utils'; import { generateArkUICompatible, isArkUICompatible } from '../interop/interop'; +import { CustomComponentNames, NodeCacheNames } from '../../common/predefines'; +import { CachedMetadata, CheckedTransformerMetadata, LoaderJson, ResourceInfo } from '../shared-types'; +import { rewriteByType } from '../checked-cache-factory'; + +export interface StructTransformerOptions extends VisitorOptions { + projectConfig?: ProjectConfig; + useCache?: boolean; +} export class StructTransformer extends AbstractVisitor { private scope: ScopeInfoCollection; @@ -40,20 +46,33 @@ export class StructTransformer extends AbstractVisitor { aceBuildJson: LoaderJson; resourceInfo: ResourceInfo; - constructor(projectConfig: ProjectConfig | undefined) { + private readonly useCache: boolean = false; + + constructor(options: StructTransformerOptions) { super(); - this.projectConfig = projectConfig; + this.projectConfig = options.projectConfig; + this.useCache = options.useCache ?? false; this.scope = { customComponents: [] }; this.aceBuildJson = loadBuildJson(this.projectConfig); this.resourceInfo = initResourceInfo(this.projectConfig, this.aceBuildJson); } + getMetadata(): CheckedTransformerMetadata { + return { + ...this.getOptions(), + projectConfig: this.projectConfig, + aceBuildJson: this.aceBuildJson, + resourceInfo: this.resourceInfo, + }; + } + reset(): void { super.reset(); this.scope = { customComponents: [] }; PropertyCache.getInstance().reset(); - ImportCollector.getInstance().reset(); - DeclarationCollector.getInstance().reset(); + ImportCollector.getInstance().clearImports(); + // ImportCollector.getInstance().reset(); // TODO: deprecated + // DeclarationCollector.getInstance().reset(); // TODO: deprecated } enter(node: arkts.AstNode): void { @@ -81,7 +100,25 @@ export class StructTransformer extends AbstractVisitor { } } + private visitorWithCache(beforeChildren: arkts.AstNode): arkts.AstNode { + const node = this.visitEachChild(beforeChildren); + if (arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).has(node)) { + const value = arkts.NodeCacheFactory.getInstance().getCache(NodeCacheNames.UI).get(node)!; + if (rewriteByType.has(value.type)) { + const metadata: CachedMetadata = { ...value.metadata, ...this.getMetadata() }; + return rewriteByType.get(value.type)!(node, metadata); + } + } + if (arkts.isEtsScript(node)) { + ImportCollector.getInstance().insertCurrentImports(this.program); + } + return node; + } + visitor(beforeChildren: arkts.AstNode): arkts.AstNode { + if (this.useCache) { + return this.visitorWithCache(beforeChildren); + } this.enter(beforeChildren); const node = this.visitEachChild(beforeChildren); if ( diff --git a/arkui-plugins/ui-plugins/struct-translators/utils.ts b/arkui-plugins/ui-plugins/struct-translators/utils.ts index ecba338d0f2218eb219efc9b0dbd8431ded149ac..b4cc8a3ee0c3734a283636595ca0a60ad973fcd5 100644 --- a/arkui-plugins/ui-plugins/struct-translators/utils.ts +++ b/arkui-plugins/ui-plugins/struct-translators/utils.ts @@ -16,7 +16,7 @@ import * as fs from 'fs'; import * as path from 'path'; import * as arkts from '@koalaui/libarkts'; -import { CustomComponentInfo, CustomComponentNames, CustomDialogNames, isKnownMethodDefinition } from '../utils'; +import { CustomComponentInfo, isKnownMethodDefinition } from '../utils'; import { matchPrefix } from '../../common/arkts-utils'; import { ARKUI_IMPORT_PREFIX_NAMES, @@ -28,11 +28,19 @@ import { InnerComponentNames, ARKUI_FOREACH_SOURCE_NAME, DecoratorNames, + CustomDialogNames, + CustomComponentNames, } from '../../common/predefines'; import { DeclarationCollector } from '../../common/declaration-collector'; import { ProjectConfig } from '../../common/plugin-context'; import { LogCollector } from '../../common/log-collector'; -import { hasDecorator } from '../../ui-plugins/property-translators/utils'; +import { hasDecorator } from '../property-translators/utils'; +import { LoaderJson, ResourceInfo, ResourceList, ResourceMap } from '../shared-types'; + +export enum StructType { + STRUCT, + CUSTOM_COMPONENT_DECL +} export type ScopeInfoCollection = { customComponents: CustomComponentScopeInfo[]; @@ -44,21 +52,6 @@ export type CustomComponentScopeInfo = CustomComponentInfo & { hasReusableRebind?: boolean; }; -type ResourceMap = Map>; - -export interface ResourceList { - [key: string]: ResourceMap; -} - -export interface ResourceInfo { - resourcesList: ResourceList; - rawfile: Set; -} - -export interface LoaderJson { - hspResourcesMap: Record; -} - export interface ResourceParameter { id: number; type: number; @@ -108,11 +101,11 @@ export function isResourceNode(node: arkts.CallExpression, ignoreDecl: boolean = return false; } if (!ignoreDecl) { - const decl = arkts.getDecl(node.expression); + const decl = arkts.getPeerIdentifierDecl(node.expression.peer); if (!decl) { return false; } - const moduleName: string = arkts.getProgramFromAstNode(decl).moduleName; + const moduleName = arkts.getProgramFromAstNode(decl)?.moduleName; if (!moduleName || !matchPrefix(ARKUI_IMPORT_PREFIX_NAMES, moduleName)) { return false; } @@ -345,7 +338,7 @@ export function checkRawfileResource( ): void { if (!fromOtherModule && !rawfileSet.has(rawfileStr.str)) { LogCollector.getInstance().collectLogInfo({ - type: LogType.ERROR, + level: LogType.ERROR, node: resourceNode, message: `No such '${rawfileStr.str}' resource in current module.`, code: '10904333', @@ -381,7 +374,7 @@ export function preCheckResourceData( } if (!!code && !!message) { LogCollector.getInstance().collectLogInfo({ - type: LogType.ERROR, + level: LogType.ERROR, node: resourceNode, message: message, code: code, @@ -456,7 +449,7 @@ function resourceCheck( } if (!!code && !!message) { LogCollector.getInstance().collectLogInfo({ - type: logType, + level: logType, node: resourceNode, message: message, code: code, @@ -604,3 +597,28 @@ export function getNoTransformationMembersInClass( ) ); } + +export interface RewritedStructMethodInfo { + hasInitializeStruct?: boolean; + hasUpdateStruct?: boolean; + hasToRecord?: boolean; +} + +export function collectRewritedStructMethodInfo( + node: arkts.AstNode, + info?: RewritedStructMethodInfo +): RewritedStructMethodInfo { + const currInfo = info ?? {}; + if (!arkts.isMethodDefinition(node)) { + return currInfo; + } + const methodName = node.name.name; + const hasInitializeStruct = methodName === CustomComponentNames.COMPONENT_INITIALIZE_STRUCT; + const hasUpdateStruct = methodName === CustomComponentNames.COMPONENT_UPDATE_STRUCT; + const hasToRecord = methodName === CustomComponentNames.COMPONENT_TO_RECORD; + return { + ...(!currInfo.hasInitializeStruct && { hasInitializeStruct }), + ...(!currInfo.hasUpdateStruct && { hasUpdateStruct }), + ...(!currInfo.hasToRecord && { hasToRecord }), + }; +} diff --git a/arkui-plugins/ui-plugins/ui-factory.ts b/arkui-plugins/ui-plugins/ui-factory.ts index c8c7cfc6f1689a4adbd58177a3305f8f8ba06907..79100623b0d5dd9e9c756bb472068cd207a9a2b4 100644 --- a/arkui-plugins/ui-plugins/ui-factory.ts +++ b/arkui-plugins/ui-plugins/ui-factory.ts @@ -15,15 +15,12 @@ import * as arkts from '@koalaui/libarkts'; import { - BuilderLambdaNames, CustomComponentAnontations, - CustomComponentNames, - CustomDialogNames, hasNullOrUndefinedType, hasPropertyInAnnotation, } from './utils'; import { PartialExcept, PartialNested, PartialNestedExcept } from '../common/safe-types'; -import { DecoratorNames } from '../common/predefines'; +import { BuilderLambdaNames, CustomComponentNames, CustomDialogNames, DecoratorNames } from '../common/predefines'; import { needDefiniteOrOptionalModifier } from './property-translators/utils'; import { addMemoAnnotation } from '../collectors/memo-collectors/utils'; diff --git a/arkui-plugins/ui-plugins/utils.ts b/arkui-plugins/ui-plugins/utils.ts index 5bcfa691802aa287fc5fb41092f0ed976b0323d3..bb6cb3b971beb90d223574e8560d0e861f3de56f 100644 --- a/arkui-plugins/ui-plugins/utils.ts +++ b/arkui-plugins/ui-plugins/utils.ts @@ -19,46 +19,76 @@ import { ARKUI_IMPORT_PREFIX_NAMES, CUSTOM_DIALOG_CONTROLLER_SOURCE_NAME, DecoratorNames, + CustomComponentNames, + CustomDialogNames, StructDecoratorNames, } from '../common/predefines'; import { DeclarationCollector } from '../common/declaration-collector'; +import { + CustomComponentInterfacePropertyInfo, + FunctionInfo, + NormalClassMethodInfo, + NormalClassPropertyInfo, + NormalInterfacePropertyInfo, + StructMethodInfo, + StructPropertyInfo, +} from '../collectors/ui-collectors/records'; +import { + checkIsCustomComponentDeclaredClassFromInfo, + checkIsCustomComponentFromInfo, + checkIsETSGlobalClassFromInfo, +} from '../collectors/ui-collectors/utils'; import { hasDecorator } from './property-translators/utils'; +import { + CachedMetadata, + ClassDeclarationRecordInfo, + ClassPropertyRecordInfo, + MethodDefinitionRecordInfo, +} from './shared-types'; + +// COLLECTOR UTILS +export function checkIsCustomComponentClassFromInfo(info: CachedMetadata): info is CachedMetadata { + return checkIsCustomComponentFromInfo(info) || checkIsCustomComponentDeclaredClassFromInfo(info); +} -export enum CustomComponentNames { - COMPONENT_BUILD_ORI = 'build', - COMPONENT_CONSTRUCTOR_ORI = 'constructor', - COMPONENT_CLASS_NAME = 'CustomComponent', - COMPONENT_V2_CLASS_NAME = 'CustomComponentV2', - BASE_CUSTOM_DIALOG_NAME = 'BaseCustomDialog', - COMPONENT_INTERFACE_PREFIX = '__Options_', - COMPONENT_INITIALIZE_STRUCT = '__initializeStruct', - COMPONENT_UPDATE_STRUCT = '__updateStruct', - COMPONENT_INITIALIZERS_NAME = 'initializers', - BUILDCOMPATIBLENODE = '_buildCompatibleNode', - OPTIONS = 'options', - PAGE_LIFE_CYCLE = 'PageLifeCycle', - LAYOUT_CALLBACK = 'LayoutCallback', +export function checkIsStructPropertyFromInfo(info: CachedMetadata): info is CachedMetadata { + return Object.hasOwn(info, 'structInfo'); } -export enum CustomDialogNames { - CUSTOM_DIALOG_ANNOTATION_NAME = 'CustomDialog', - CUSTOM_DIALOG_CONTROLLER = 'CustomDialogController', - CUSTOM_DIALOG_CONTROLLER_OPTIONS = 'CustomDialogControllerOptions', - SET_DIALOG_CONTROLLER_METHOD = '__setDialogController__', - CONTROLLER = 'controller', - OPTIONS_BUILDER = 'builder', - BASE_COMPONENT = 'baseComponent', - EXTENDABLE_COMPONENT = 'ExtendableComponent', - CUSTOM_BUILDER = 'CustomBuilder', +export function checkIsNormalClassPropertyFromInfo( + info: CachedMetadata +): info is CachedMetadata { + return Object.hasOwn(info, 'classInfo'); } -export enum BuilderLambdaNames { - ANNOTATION_NAME = 'ComponentBuilder', - ORIGIN_METHOD_NAME = '$_instantiate', - TRANSFORM_METHOD_NAME = '_instantiateImpl', - STYLE_PARAM_NAME = 'style', - STYLE_ARROW_PARAM_NAME = 'instance', - CONTENT_PARAM_NAME = 'content', +export function checkIsStructMethodFromInfo(info: CachedMetadata): info is CachedMetadata { + return Object.hasOwn(info, 'structInfo'); +} + +export function checkIsGlobalFunctionFromInfo(info: CachedMetadata): info is CachedMetadata { + return ( + !Object.hasOwn(info, 'classInfo') && !Object.hasOwn(info, 'structInfo') && !Object.hasOwn(info, 'interfaceInfo') + ); +} + +export function checkIsNormalClassMethodFromInfo(info: CachedMetadata): info is CachedMetadata { + return Object.hasOwn(info, 'classInfo'); +} + +export function checkIsStructInterfacePropertyFromInfo( + info: CachedMetadata +): info is CachedMetadata { + if (!Object.hasOwn(info, 'interfaceInfo')) { + return false; + } + const interfaceInfo = (info as CustomComponentInterfacePropertyInfo).interfaceInfo; + return checkIsCustomComponentFromInfo(interfaceInfo); +} + +export function checkIsNormalInterfacePropertyFromInfo( + info: CachedMetadata +): info is CachedMetadata { + return Object.hasOwn(info, 'interfaceInfo'); } // IMPORT @@ -193,11 +223,11 @@ export function isCustomComponentAnnotation( return false; } if (!ignoreDecl) { - const decl = arkts.getDecl(anno.expr); + const decl = arkts.getPeerIdentifierDecl(anno.expr.peer); if (!decl) { return false; } - const moduleName: string = arkts.getProgramFromAstNode(decl).moduleName; + const moduleName = arkts.getProgramFromAstNode(decl)?.moduleName; if (!moduleName || !matchPrefix(ARKUI_IMPORT_PREFIX_NAMES, moduleName)) { return false; } @@ -250,7 +280,7 @@ export function collectCustomComponentScopeInfo( return { name: definition.ident.name, isDecl, - annotations: annotations as CustomComponentAnontations, + annotations, }; } @@ -371,4 +401,4 @@ export function computedField(name: string): string { export function monitorField(name: string): string { return `__monitor_${name}`; -} \ No newline at end of file +} diff --git a/arkui-plugins/ui-syntax-plugins/index.ts b/arkui-plugins/ui-syntax-plugins/index.ts index 250f6db37bbb7aba5a04a047c90f2b5ed78b2843..fa4a5aff6ffb7fd4256a49576cdd30df7b2488c4 100644 --- a/arkui-plugins/ui-syntax-plugins/index.ts +++ b/arkui-plugins/ui-syntax-plugins/index.ts @@ -24,18 +24,92 @@ import { UISyntaxLinterVisitor } from './transformers/ui-syntax-linter-visitor'; import rules from './rules'; import { matchPrefix } from '../common/arkts-utils'; import { EXCLUDE_EXTERNAL_SOURCE_PREFIXES, tracePerformance } from './utils'; +import { debugDump, debugLog, getDumpFileName } from '../common/debug'; +import { UIVisitor } from '../collectors/ui-collectors/ui-visitor'; +import { MemoVisitor } from '../collectors/memo-collectors/memo-visitor'; +import { Collector } from '../collectors/collector'; +import { ProgramVisitor } from '../common/program-visitor'; +import { EXTERNAL_SOURCE_PREFIX_NAMES } from '../common/predefines'; export function uiSyntaxLinterTransform(): Plugins { - const processor = createUISyntaxRuleProcessor(rules); - const parsedTransformer = new ParsedUISyntaxLinterTransformer(processor); - const checkedTransformer = new CheckedUISyntaxLinterTransformer(processor); + // const processor = createUISyntaxRuleProcessor(rules); + // const parsedTransformer = new ParsedUISyntaxLinterTransformer(processor); + // const checkedTransformer = new CheckedUISyntaxLinterTransformer(processor); return { name: 'ui-syntax-plugin', - parsed: createTransformer('parsed', processor, parsedTransformer), - checked: createTransformer('checked', processor, checkedTransformer), + checked: collectAndLint, + // parsed: createTransformer('parsed', processor, parsedTransformer), + // checked: createTransformer('checked', processor, checkedTransformer), }; } +function collectAndLint(this: PluginContext): arkts.EtsScript | undefined { + let script: arkts.EtsScript | undefined; + console.log('[UI LINTER PLUGIN] AFTER CHECKED ENTER'); + // arkts.Performance.getInstance().memoryTrackerPrintCurrent('ArkTS:Parse'); + // arkts.Performance.getInstance().memoryTrackerReset(); + // arkts.Performance.getInstance().startMemRecord('Node:UIPlugin:AfterParse'); + const contextPtr = this.getContextPtr() ?? arkts.arktsGlobal.compilerContext?.peer; + if (!!contextPtr) { + let program = arkts.getOrUpdateGlobalContext(contextPtr).program; + script = program.astNode; + const cachePath: string | undefined = this.getProjectConfig()?.cachePath; + // const canSkipPhases = program.canSkipPhases(); + debugLog('[BEFORE LINTER SCRIPT] script: ', script.dumpSrc()); + debugDump( + script.dumpSrc(), + getDumpFileName(0, 'SRC', 3, 'UI_LINTER_AfterCheck_Begin'), + true, + cachePath, + program.fileNameWithExtension + ); + arkts.Performance.getInstance().createEvent('ui-linter'); + program = parsedProgramVisit(program, this, false); + script = program.astNode; + arkts.Performance.getInstance().stopEvent('ui-linter', true); + debugLog('[AFTER LINTER SCRIPT] script: ', script.dumpSrc()); + debugDump( + script.dumpSrc(), + getDumpFileName(0, 'SRC', 4, 'UI_LINTER_AfterCheck_End'), + true, + cachePath, + program.fileNameWithExtension + ); + this.setArkTSAst(script); + // arkts.Performance.getInstance().memoryTrackerGetDelta('UIPlugin:AfterParse'); + // arkts.Performance.getInstance().memoryTrackerReset(); + // arkts.Performance.getInstance().stopMemRecord('Node:UIPlugin:AfterParse'); + console.log('[UI LINTER PLUGIN] AFTER CHECKED EXIT'); + return script; + } + console.log('[UI LINTER PLUGIN] AFTER CHECKED EXIT WITH NO TRANSFORM'); + return script; +} + +function parsedProgramVisit( + program: arkts.Program, + context: PluginContext, + canSkipPhases: boolean = false +): arkts.Program { + if (canSkipPhases) { + debugLog('[SKIP PHASE] phase: ui-checker, moduleName: ', program.moduleName); + } else { + debugLog('[CANT SKIP PHASE] phase: ui-checker, moduleName: ', program.moduleName); + // const uiCollector = new UIVisitor(); + const collector = new Collector(); + const programVisitor = new ProgramVisitor({ + pluginName: uiSyntaxLinterTransform.name, + state: arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED, + visitors: [collector], + skipPrefixNames: EXTERNAL_SOURCE_PREFIX_NAMES, + pluginContext: context, + }); + program = programVisitor.programVisitor(program); + } + return program; +} + + function createTransformer( phase: string, processor: UISyntaxRuleProcessor, diff --git a/arkui-plugins/ui-syntax-plugins/utils/index.ts b/arkui-plugins/ui-syntax-plugins/utils/index.ts index 0e3f34341be809724e5b4355f51a60b3c9707c88..5b7b97a9d96520630b6315b77dc031267c07e589 100644 --- a/arkui-plugins/ui-syntax-plugins/utils/index.ts +++ b/arkui-plugins/ui-syntax-plugins/utils/index.ts @@ -486,7 +486,7 @@ export function getAnnotationUsageByName( return false; } const program = arkts.getProgramFromAstNode(annotationDeclaration); - if (!isFromPresetModules(program.moduleName)) { + if (!program || !isFromPresetModules(program.moduleName)) { return false; } return true; diff --git a/koala-wrapper/native/src/bridges.cc b/koala-wrapper/native/src/bridges.cc index 4e0a1f331c8eb096400afc4d49c26904164e95ea..59313d879ec20389dac6ece4c6d7308a22926e89 100644 --- a/koala-wrapper/native/src/bridges.cc +++ b/koala-wrapper/native/src/bridges.cc @@ -269,6 +269,141 @@ KNativePointer impl_DeclarationFromIdentifier(KNativePointer context, KNativePoi } KOALA_INTEROP_2(DeclarationFromIdentifier, KNativePointer, KNativePointer, KNativePointer) +KNativePointer impl_ClassVariableDeclaration(KNativePointer context, KNativePointer classInstance) +{ + const auto _context = reinterpret_cast(context); + const auto _classInstance = reinterpret_cast(classInstance); + auto _typedTsType = GetImpl()->TypedTsType(_context, _classInstance); + if (_typedTsType == nullptr) { + return nullptr; + } + const auto _instanceType = reinterpret_cast(_typedTsType); + auto _typeVar = GetImpl()->TypeVariable(_context, _instanceType); + if (_typeVar == nullptr) { + return nullptr; + } + const auto result = reinterpret_cast(GetImpl()->VariableDeclaration(_context, _typeVar)); + const auto declNode = GetImpl()->DeclNode(_context, result); + return declNode; +} +KOALA_INTEROP_2(ClassVariableDeclaration, KNativePointer, KNativePointer, KNativePointer); + +static KNativePointer findPropertyInClassDefinition(KNativePointer context, KNativePointer classInstance, char *keyName) +{ + const auto _context = reinterpret_cast(context); + const auto _instance = reinterpret_cast(classInstance); + std::size_t bodySize = 0; + const auto _body = GetImpl()->ClassDefinitionBody(_context, _instance, &bodySize); + if (_body == nullptr) { + return nullptr; + } + const auto _bodyInstance = reinterpret_cast(_body); + for (std::size_t i = 0; i < bodySize; i++) { + const auto _member = reinterpret_cast(_bodyInstance[i]); + const auto _key = reinterpret_cast(GetImpl()->ClassElementKey(_context, _member)); + if (strcmp(GetImpl()->IdentifierName(_context, _key), keyName) == 0) { + return _member; + } + } + return nullptr; +} + +static KNativePointer findPropertyInTSInterfaceDeclaration(KNativePointer context, KNativePointer classInstance, char *keyName) +{ + const auto _context = reinterpret_cast(context); + const auto _instance = reinterpret_cast(classInstance); + const auto _body = GetImpl()->TSInterfaceDeclarationBody(_context, _instance); + if (_body == nullptr) { + return nullptr; + } + const auto _bodyInstance = reinterpret_cast(_body); + std::size_t bodySize = 0; + const auto _bodyBody = GetImpl()->TSInterfaceBodyBodyConst(_context, _bodyInstance, &bodySize); + if (_bodyBody == nullptr) { + return nullptr; + } + const auto _bodyBodyInstance = reinterpret_cast(_bodyBody); + for (std::size_t i = 0; i < bodySize; i++) { + const auto _member = reinterpret_cast(_bodyBodyInstance[i]); + const auto _key = reinterpret_cast(GetImpl()->ClassElementKey(_context, _member)); + if (strcmp(GetImpl()->IdentifierName(_context, _key), keyName) == 0) { + return _member; + } + } + return nullptr; +} + +KNativePointer impl_DeclarationFromProperty(KNativePointer context, KNativePointer property) +{ + const auto _context = reinterpret_cast(context); + const auto _property = reinterpret_cast(property); + auto _key = GetImpl()->PropertyKey(_context, _property); + if (_key == nullptr) { + return nullptr; + } + auto _parent = GetImpl()->AstNodeParent(_context, _property); + if (_parent == nullptr) { + return nullptr; + } + const auto _parentInstance = reinterpret_cast(_parent); + auto _decl = impl_ClassVariableDeclaration(_context, _parentInstance); + if (_decl == nullptr) { + return nullptr; + } + const auto _declInstance = reinterpret_cast(_decl); + const auto _keyInstance = reinterpret_cast(_key); + auto _keyName = GetImpl()->IdentifierName(_context, _keyInstance); + if (GetImpl()->IsClassDefinition(_declInstance)) { + return findPropertyInClassDefinition(_context, _declInstance, _keyName); + } + if (GetImpl()->IsTSInterfaceDeclaration(_declInstance)) { + return findPropertyInTSInterfaceDeclaration(_context, _declInstance, _keyName); + } + return nullptr; +} +KOALA_INTEROP_2(DeclarationFromProperty, KNativePointer, KNativePointer, KNativePointer); + +KNativePointer impl_DeclarationFromMemberExpression(KNativePointer context, KNativePointer nodePtr) +{ + const auto _context = reinterpret_cast(context); + const auto _node = reinterpret_cast(nodePtr); + auto _object = GetImpl()->MemberExpressionObject(_context, _node); + auto _property = GetImpl()->MemberExpressionProperty(_context, _node); + if (_property == nullptr) { + return nullptr; + } + const auto _propertyInstance = reinterpret_cast(_property); + if (GetImpl()->IsNumberLiteral(_propertyInstance) && _object != nullptr) { + const auto _objectInstance = reinterpret_cast(_object); + if (GetImpl()->IsMemberExpression(_objectInstance)) { + return impl_DeclarationFromMemberExpression(_context, _objectInstance); + } + return GetImpl()->DeclarationFromIdentifier(_context, _objectInstance); + } + if (GetImpl()->IsMemberExpression(_propertyInstance)) { + return impl_DeclarationFromMemberExpression(_context, _propertyInstance); + } + return GetImpl()->DeclarationFromIdentifier(_context, _propertyInstance); +} +KOALA_INTEROP_2(DeclarationFromMemberExpression, KNativePointer, KNativePointer, KNativePointer); + +KNativePointer impl_DeclarationFromAstNode(KNativePointer context, KNativePointer nodePtr) +{ + const auto _context = reinterpret_cast(context); + const auto _node = reinterpret_cast(nodePtr); + if (GetImpl()->IsMemberExpression(_node)) { + return impl_DeclarationFromMemberExpression(_context, _node); + } + if (GetImpl()->IsObjectExpression(_node)) { + return impl_ClassVariableDeclaration(_context, _node); + } + if (GetImpl()->IsProperty(_node)) { + return impl_DeclarationFromProperty(_context, _node); + } + return GetImpl()->DeclarationFromIdentifier(_context, _node); +} +KOALA_INTEROP_2(DeclarationFromAstNode, KNativePointer, KNativePointer, KNativePointer); + static KNativePointer impl_ProgramExternalSources(KNativePointer contextPtr, KNativePointer instancePtr) { auto context = reinterpret_cast(contextPtr); @@ -485,25 +620,6 @@ KNativePointer impl_ProgramAbsoluteNameConst(KNativePointer contextPtr, KNativeP } KOALA_INTEROP_2(ProgramAbsoluteNameConst, KNativePointer, KNativePointer, KNativePointer); -KNativePointer impl_ClassVariableDeclaration(KNativePointer context, KNativePointer classInstance) -{ - const auto _context = reinterpret_cast(context); - const auto _classInstance = reinterpret_cast(classInstance); - auto _typedTsType = GetImpl()->TypedTsType(_context, _classInstance); - if (_typedTsType == nullptr) { - return nullptr; - } - const auto _instanceType = reinterpret_cast(_typedTsType); - auto _typeVar = GetImpl()->TypeVariable(_context, _instanceType); - if (_typeVar == nullptr) { - return nullptr; - } - const auto result = reinterpret_cast(GetImpl()->VariableDeclaration(_context, _typeVar)); - const auto declNode = GetImpl()->DeclNode(_context, result); - return declNode; -} -KOALA_INTEROP_2(ClassVariableDeclaration, KNativePointer, KNativePointer, KNativePointer) - KBoolean impl_IsMethodDefinition(KNativePointer nodePtr) { auto node = reinterpret_cast(nodePtr); diff --git a/koala-wrapper/native/src/common.cc b/koala-wrapper/native/src/common.cc index 29baa82db80f92c41980e9f36373686a97da7f75..9d867f6a9516045ae190ed23b8befbf82aca5752 100644 --- a/koala-wrapper/native/src/common.cc +++ b/koala-wrapper/native/src/common.cc @@ -266,10 +266,77 @@ KNativePointer impl_AstNodeProgram(KNativePointer contextPtr, KNativePointer ins if (GetImpl()->AstNodeIsProgramConst(_context, _receiver)) { return GetImpl()->ETSModuleProgram(_context, _receiver); } - return impl_AstNodeProgram(_context, GetImpl()->AstNodeParent(_context, _receiver)); + auto parent = GetImpl()->AstNodeParent(_context, _receiver); + if (parent == nullptr) { + return nullptr; + } + return impl_AstNodeProgram(_context, parent); } KOALA_INTEROP_2(AstNodeProgram, KNativePointer, KNativePointer, KNativePointer) +thread_local KBoolean targetChildFound = false; +thread_local es2panda_AstNode *targetInnerChild = nullptr; +thread_local KInt targetAstNodeType = -1; + +static void findNodeInnerChild(es2panda_AstNode *node) +{ + if (targetInnerChild == node) { + targetChildFound = true; + } +} + +KBoolean impl_AstNodeFindNodeInInnerChild(KNativePointer contextPtr, KNativePointer instancePtr, KNativePointer tartgetPtr) +{ + if (tartgetPtr == nullptr) { + return false; + } + auto _context = reinterpret_cast(contextPtr); + auto _receiver = reinterpret_cast(instancePtr); + auto _target = reinterpret_cast(tartgetPtr); + targetChildFound = false; + targetInnerChild = _target; + GetImpl()->AstNodeIterateConst(_context, _receiver, findNodeInnerChild); + return targetChildFound; +} +KOALA_INTEROP_3(AstNodeFindNodeInInnerChild, KBoolean, KNativePointer, KNativePointer, KNativePointer); + +static void findInnerChild(es2panda_AstNode *node, void *arg) +{ + auto *context = static_cast(arg); + if (targetAstNodeType == GetImpl()->AstNodeTypeConst(context, node)) { + targetInnerChild = node; + } +} + +KNativePointer impl_AstNodeFindInnerChild(KNativePointer contextPtr, KNativePointer instancePtr, KInt AstNodeType) +{ + auto _context = reinterpret_cast(contextPtr); + auto _receiver = reinterpret_cast(instancePtr); + targetAstNodeType = AstNodeType; + + GetImpl()->AstNodeForEach(_receiver, findInnerChild, _context); + return targetInnerChild; +} +KOALA_INTEROP_3(AstNodeFindInnerChild, KNativePointer, KNativePointer, KNativePointer, KInt); + +KNativePointer impl_AstNodeFindOuterParent(KNativePointer contextPtr, KNativePointer instancePtr, KInt AstNodeType) +{ + auto _context = reinterpret_cast(contextPtr); + auto _receiver = reinterpret_cast(instancePtr); + if (GetImpl()->AstNodeIsProgramConst(_context, _receiver)) { + return nullptr; + } + if (AstNodeType == GetImpl()->AstNodeTypeConst(_context, _receiver)) { + return _receiver; + } + auto parent = GetImpl()->AstNodeParent(_context, _receiver); + if (parent == nullptr) { + return nullptr; + } + return impl_AstNodeFindOuterParent(_context, parent, AstNodeType); +} +KOALA_INTEROP_3(AstNodeFindOuterParent, KNativePointer, KNativePointer, KNativePointer, KInt); + thread_local es2panda_AstNode *cachedParentNode; thread_local es2panda_Context *cachedContext; diff --git a/koala-wrapper/src/Es2pandaNativeModule.ts b/koala-wrapper/src/Es2pandaNativeModule.ts index ebdb8ed3d6e9528c8974258600691cb166ec4f89..9fcd3159fcd660fe7630845791c4f5a66ca2719a 100644 --- a/koala-wrapper/src/Es2pandaNativeModule.ts +++ b/koala-wrapper/src/Es2pandaNativeModule.ts @@ -717,6 +717,15 @@ export class Es2pandaNativeModule { _DeclarationFromIdentifier(context: KPtr, identifier: KPtr): KPtr { throw new Error('Not implemented'); } + _DeclarationFromProperty(context: KPtr, property: KPtr): KPtr { + throw new Error('Not implemented'); + } + _DeclarationFromMemberExpression(context: KPtr, expression: KPtr): KPtr { + throw new Error('Not implemented'); + } + _DeclarationFromAstNode(context: KPtr, node: KPtr): KPtr { + throw new Error('Not implemented'); + } _IsTSInterfaceDeclaration(ast: KNativePointer): KBoolean { throw new Error('Not implemented'); } @@ -971,6 +980,18 @@ export class Es2pandaNativeModule { _ProgramSourceFilePathConst(context: KPtr, decl: KPtr): KNativePointer { throw new Error('Not implemented'); } + + _AstNodeFindNodeInInnerChild(context: KNativePointer, node: KNativePointer, target: KNativePointer): boolean { + throw new Error('AstNodeFindNodeInInnerChild was not overloaded by native module initialization'); + } + + _AstNodeFindInnerChild(context: KNativePointer, node: KNativePointer, nodeType: KInt): KNativePointer { + throw new Error('AstNodeFindInnerChild was not overloaded by native module initialization'); + } + + _AstNodeFindOuterParent(context: KNativePointer, node: KNativePointer, nodeType: KInt): KNativePointer { + throw new Error('AstNodeFindOuterParent was not overloaded by native module initialization'); + } } export function initEs2panda(): Es2pandaNativeModule { diff --git a/koala-wrapper/src/arkts-api/class-by-peer.ts b/koala-wrapper/src/arkts-api/class-by-peer.ts index 4306cff12a48d89144fcc6bff6ca23b33a8c5e09..515502e68070e3929910a5dc292ef0d4b7321319 100644 --- a/koala-wrapper/src/arkts-api/class-by-peer.ts +++ b/koala-wrapper/src/arkts-api/class-by-peer.ts @@ -13,29 +13,11 @@ * limitations under the License. */ -import { Es2pandaAstNodeType } from '../Es2pandaEnums'; +import { KNativePointer, nullptr } from '@koalaui/interop'; import { throwError } from '../utils'; import { global } from './static/global'; -import { KNativePointer, nullptr } from '@koalaui/interop'; import { AstNode, UnsupportedNode } from './peers/AstNode'; - -type AstNodeConstructor = new (peer: KNativePointer) => AstNode; -export const nodeByType = new Map([]); - -const cache = new Map(); -export function clearNodeCache(): void { - cache.clear(); -} - -export function getOrPut(peer: KNativePointer, create: (peer: KNativePointer) => AstNode): AstNode { - if (cache.has(peer)) { - return cache.get(peer)!; - } - - const newNode = create(peer); - cache.set(peer, newNode); - return newNode; -} +import { getOrPut, nodeByType } from './node-by-type'; export function classByPeer(peer: KNativePointer): T { if (peer === nullptr) { diff --git a/koala-wrapper/src/arkts-api/factory/nodeFactory.ts b/koala-wrapper/src/arkts-api/factory/nodeFactory.ts index 6b0de31f4db00f66fd268224495c590fedabb2e9..11bee27d7f08faae9f0d53d4f462acb5022c46d3 100644 --- a/koala-wrapper/src/arkts-api/factory/nodeFactory.ts +++ b/koala-wrapper/src/arkts-api/factory/nodeFactory.ts @@ -83,89 +83,109 @@ import { SwitchCaseStatement, SpreadElement, } from '../../generated'; -import { updateIdentifier } from '../node-utilities/Identifier'; -import { updateCallExpression } from '../node-utilities/CallExpression'; -import { updateExpressionStatement } from '../node-utilities/ExpressionStatement'; -import { updateMemberExpression } from '../node-utilities/MemberExpression'; -import { updateFunctionDeclaration } from '../node-utilities/FunctionDeclaration'; -import { updateBlockStatement } from '../node-utilities/BlockStatement'; -import { updateArrowFunctionExpression } from '../node-utilities/ArrowFunctionExpression'; -import { updateScriptFunction } from '../node-utilities/ScriptFunction'; -import { updateStringLiteral } from '../node-utilities/StringLiteral'; -import { updateNumberLiteral } from '../node-utilities/NumberLiteral'; -import { updateETSParameterExpression } from '../node-utilities/ETSParameterExpression'; -import { updateTSTypeParameter } from '../node-utilities/TSTypeParameter'; -import { updateTSTypeParameterDeclaration } from '../node-utilities/TSTypeParameterDeclaration'; -import { updateETSPrimitiveType } from '../node-utilities/ETSPrimitiveType'; -import { updateETSTypeReference } from '../node-utilities/ETSTypeReference'; -import { updateETSTypeReferencePart } from '../node-utilities/ETSTypeReferencePart'; -import { updateETSImportDeclaration } from '../node-utilities/ETSImportDeclaration'; -import { updateImportSpecifier } from '../node-utilities/ImportSpecifier'; -import { updateVariableDeclaration } from '../node-utilities/VariableDeclaration'; -import { updateVariableDeclarator } from '../node-utilities/VariableDeclarator'; -import { updateETSUnionType } from '../node-utilities/ETSUnionType'; -import { updateReturnStatement } from '../node-utilities/ReturnStatement'; -import { updateIfStatement } from '../node-utilities/IfStatement'; -import { updateBinaryExpression } from '../node-utilities/BinaryExpression'; -import { updateClassDeclaration } from '../node-utilities/ClassDeclaration'; -import { updateStructDeclaration } from '../node-utilities/StructDeclaration'; -import { updateClassDefinition } from '../node-utilities/ClassDefinition'; -import { updateClassProperty } from '../node-utilities/ClassProperty'; -import { updateETSFunctionType } from '../node-utilities/ETSFunctionType'; -import { updateFunctionExpression } from '../node-utilities/FunctionExpression'; -import { updateMethodDefinition } from '../node-utilities/MethodDefinition'; -import { updateSuperExpression } from '../node-utilities/SuperExpression'; -import { updateTSTypeParameterInstantiation } from '../node-utilities/TSTypeParameterInstantiation'; -import { updateTSInterfaceDeclaration } from '../node-utilities/TSInterfaceDeclaration'; -import { updateTSInterfaceBody } from '../node-utilities/TSInterfaceBody'; -import { updateUndefinedLiteral } from '../node-utilities/UndefinedLiteral'; -import { updateAnnotationUsage, update1AnnotationUsage } from '../node-utilities/AnnotationUsage'; -import { updateAssignmentExpression } from '../node-utilities/AssignmentExpression'; -import { updateETSUndefinedType } from '../node-utilities/ETSUndefinedType'; -import { updateConditionalExpression } from '../node-utilities/ConditionalExpression'; -import { updateTSAsExpression } from '../node-utilities/TSAsExpression'; -import { updateThisExpression } from '../node-utilities/ThisExpression'; -import { updateTSTypeAliasDeclaration } from '../node-utilities/TSTypeAliasDeclaration'; -import { updateTSNonNullExpression } from '../node-utilities/TSNonNullExpression'; -import { updateChainExpression } from '../node-utilities/ChainExpression'; -import { updateBlockExpression } from '../node-utilities/BlockExpression'; -import { updateNullLiteral } from '../node-utilities/NullLiteral'; -import { updateETSNewClassInstanceExpression } from '../node-utilities/ETSNewClassInstanceExpression'; -import { updateObjectExpression } from '../node-utilities/ObjectExpression'; -import { updateProperty } from '../node-utilities/Property'; -import { updateTemplateLiteral } from '../node-utilities/TemplateLiteral'; -import { updateArrayExpression } from '../node-utilities/ArrayExpression'; -import { updateAnnotationDeclaration } from '../node-utilities/AnnotationDeclaration'; -import { updateTryStatement } from '../node-utilities/TryStatement'; -import { updateTSClassImplements } from '../node-utilities/TSClassImplements'; -import { updateForUpdateStatement } from '../node-utilities/ForUpdateStatement'; -import { updateForInStatement } from '../node-utilities/ForInStatement'; -import { updateForOfStatement } from '../node-utilities/ForOfStatement'; -import { updateSwitchStatement } from '../node-utilities/SwitchStatement'; -import { updateSwitchCaseStatement } from '../node-utilities/SwitchCaseStatement'; -import { updateSpreadElement } from '../node-utilities/SpreadElement'; +import { createIdentifier, updateIdentifier } from '../node-utilities/Identifier'; +import { createCallExpression, updateCallExpression } from '../node-utilities/CallExpression'; +import { createExpressionStatement, updateExpressionStatement } from '../node-utilities/ExpressionStatement'; +import { createMemberExpression, updateMemberExpression } from '../node-utilities/MemberExpression'; +import { createFunctionDeclaration, updateFunctionDeclaration } from '../node-utilities/FunctionDeclaration'; +import { createBlockStatement, updateBlockStatement } from '../node-utilities/BlockStatement'; +import { + createArrowFunctionExpression, + updateArrowFunctionExpression, +} from '../node-utilities/ArrowFunctionExpression'; +import { createScriptFunction, updateScriptFunction } from '../node-utilities/ScriptFunction'; +import { createStringLiteral, updateStringLiteral } from '../node-utilities/StringLiteral'; +import { createNumberLiteral, updateNumberLiteral } from '../node-utilities/NumberLiteral'; +import { createETSParameterExpression, updateETSParameterExpression } from '../node-utilities/ETSParameterExpression'; +import { createTSTypeParameter, updateTSTypeParameter } from '../node-utilities/TSTypeParameter'; +import { + createTSTypeParameterDeclaration, + updateTSTypeParameterDeclaration, +} from '../node-utilities/TSTypeParameterDeclaration'; +import { createETSPrimitiveType, updateETSPrimitiveType } from '../node-utilities/ETSPrimitiveType'; +import { createETSTypeReference, updateETSTypeReference } from '../node-utilities/ETSTypeReference'; +import { createETSTypeReferencePart, updateETSTypeReferencePart } from '../node-utilities/ETSTypeReferencePart'; +import { createETSImportDeclaration, updateETSImportDeclaration } from '../node-utilities/ETSImportDeclaration'; +import { createImportSpecifier, updateImportSpecifier } from '../node-utilities/ImportSpecifier'; +import { createVariableDeclaration, updateVariableDeclaration } from '../node-utilities/VariableDeclaration'; +import { createVariableDeclarator, updateVariableDeclarator } from '../node-utilities/VariableDeclarator'; +import { createETSUnionType, updateETSUnionType } from '../node-utilities/ETSUnionType'; +import { createReturnStatement, updateReturnStatement } from '../node-utilities/ReturnStatement'; +import { createIfStatement, updateIfStatement } from '../node-utilities/IfStatement'; +import { createBinaryExpression, updateBinaryExpression } from '../node-utilities/BinaryExpression'; +import { createClassDeclaration, updateClassDeclaration } from '../node-utilities/ClassDeclaration'; +import { createStructDeclaration, updateStructDeclaration } from '../node-utilities/StructDeclaration'; +import { createClassDefinition, updateClassDefinition } from '../node-utilities/ClassDefinition'; +import { createClassProperty, updateClassProperty } from '../node-utilities/ClassProperty'; +import { createETSFunctionType, updateETSFunctionType } from '../node-utilities/ETSFunctionType'; +import { createFunctionExpression, updateFunctionExpression } from '../node-utilities/FunctionExpression'; +import { createMethodDefinition, updateMethodDefinition } from '../node-utilities/MethodDefinition'; +import { createSuperExpression, updateSuperExpression } from '../node-utilities/SuperExpression'; +import { + createTSTypeParameterInstantiation, + updateTSTypeParameterInstantiation, +} from '../node-utilities/TSTypeParameterInstantiation'; +import { createTSInterfaceDeclaration, updateTSInterfaceDeclaration } from '../node-utilities/TSInterfaceDeclaration'; +import { createTSInterfaceBody, updateTSInterfaceBody } from '../node-utilities/TSInterfaceBody'; +import { createUndefinedLiteral, updateUndefinedLiteral } from '../node-utilities/UndefinedLiteral'; +import { + updateAnnotationUsage, + update1AnnotationUsage, + createAnnotationUsage, + create1AnnotationUsage, +} from '../node-utilities/AnnotationUsage'; +import { createAssignmentExpression, updateAssignmentExpression } from '../node-utilities/AssignmentExpression'; +import { createETSUndefinedType, updateETSUndefinedType } from '../node-utilities/ETSUndefinedType'; +import { createConditionalExpression, updateConditionalExpression } from '../node-utilities/ConditionalExpression'; +import { createTSAsExpression, updateTSAsExpression } from '../node-utilities/TSAsExpression'; +import { createThisExpression, updateThisExpression } from '../node-utilities/ThisExpression'; +import { createTSTypeAliasDeclaration, updateTSTypeAliasDeclaration } from '../node-utilities/TSTypeAliasDeclaration'; +import { createTSNonNullExpression, updateTSNonNullExpression } from '../node-utilities/TSNonNullExpression'; +import { createChainExpression, updateChainExpression } from '../node-utilities/ChainExpression'; +import { createBlockExpression, updateBlockExpression } from '../node-utilities/BlockExpression'; +import { createNullLiteral, updateNullLiteral } from '../node-utilities/NullLiteral'; +import { + createETSNewClassInstanceExpression, + updateETSNewClassInstanceExpression, +} from '../node-utilities/ETSNewClassInstanceExpression'; +import { createObjectExpression, updateObjectExpression } from '../node-utilities/ObjectExpression'; +import { createProperty, updateProperty } from '../node-utilities/Property'; +import { createTemplateLiteral, updateTemplateLiteral } from '../node-utilities/TemplateLiteral'; +import { createArrayExpression, updateArrayExpression } from '../node-utilities/ArrayExpression'; +import { createAnnotationDeclaration, updateAnnotationDeclaration } from '../node-utilities/AnnotationDeclaration'; +import { createTryStatement, updateTryStatement } from '../node-utilities/TryStatement'; +import { createTSClassImplements, updateTSClassImplements } from '../node-utilities/TSClassImplements'; +import { createForUpdateStatement, updateForUpdateStatement } from '../node-utilities/ForUpdateStatement'; +import { createForInStatement, updateForInStatement } from '../node-utilities/ForInStatement'; +import { createForOfStatement, updateForOfStatement } from '../node-utilities/ForOfStatement'; +import { createSwitchStatement, updateSwitchStatement } from '../node-utilities/SwitchStatement'; +import { createSwitchCaseStatement, updateSwitchCaseStatement } from '../node-utilities/SwitchCaseStatement'; +import { createSpreadElement, updateSpreadElement } from '../node-utilities/SpreadElement'; +import { updateETSModule } from '../node-utilities/ETSModule'; +import { createETSStringLiteralType } from '../node-utilities/ETSStringLiteralType'; +import { createBooleanLiteral } from '../node-utilities/BooleanLiteral'; export const factory = { - get createIdentifier(): (...args: Parameters) => Identifier { - return Identifier.create2Identifier; + get createIdentifier(): (...args: Parameters) => Identifier { + return createIdentifier; }, get updateIdentifier(): (...args: Parameters) => Identifier { return updateIdentifier; }, - get createCallExpression(): (...args: Parameters) => CallExpression { - return CallExpression.create; + get createCallExpression(): (...args: Parameters) => CallExpression { + return createCallExpression; }, get updateCallExpression(): (...args: Parameters) => CallExpression { return updateCallExpression; }, - get createExpressionStatement(): (...args: Parameters) => ExpressionStatement { - return ExpressionStatement.create; + get createExpressionStatement(): (...args: Parameters) => ExpressionStatement { + return createExpressionStatement; }, get updateExpressionStatement(): (...args: Parameters) => ExpressionStatement { return updateExpressionStatement; }, - get createMemberExpression(): (...args: Parameters) => MemberExpression { - return MemberExpression.create; + get createMemberExpression(): (...args: Parameters) => MemberExpression { + return createMemberExpression; }, get updateMemberExpression(): (...args: Parameters) => MemberExpression { return updateMemberExpression; @@ -173,215 +193,195 @@ export const factory = { get createEtsScript(): (...args: Parameters) => EtsScript { return EtsScript.createFromSource; }, - get updateEtsScript(): (...args: Parameters) => EtsScript { - return EtsScript.updateByStatements; + get updateEtsScript(): (...args: Parameters) => EtsScript { + return updateETSModule; }, - get createFunctionDeclaration(): (...args: Parameters) => FunctionDeclaration { - return FunctionDeclaration.create; + get createFunctionDeclaration(): (...args: Parameters) => FunctionDeclaration { + return createFunctionDeclaration; }, get updateFunctionDeclaration(): (...args: Parameters) => FunctionDeclaration { return updateFunctionDeclaration; }, - get createBlock(): (...args: Parameters) => BlockStatement { - return BlockStatement.createBlockStatement; + get createBlock(): (...args: Parameters) => BlockStatement { + return createBlockStatement; }, get updateBlock(): (...args: Parameters) => BlockStatement { return updateBlockStatement; }, - get createArrowFunction(): (...args: Parameters) => ArrowFunctionExpression { - return ArrowFunctionExpression.create; + get createArrowFunction(): (...args: Parameters) => ArrowFunctionExpression { + return createArrowFunctionExpression; }, get updateArrowFunction(): (...args: Parameters) => ArrowFunctionExpression { return updateArrowFunctionExpression; }, - get createScriptFunction(): (...args: Parameters) => ScriptFunction { - return ScriptFunction.createScriptFunction; + get createScriptFunction(): (...args: Parameters) => ScriptFunction { + return createScriptFunction; }, get updateScriptFunction(): (...args: Parameters) => ScriptFunction { return updateScriptFunction; }, - get createStringLiteral(): (...args: Parameters) => StringLiteral { - return StringLiteral.create1StringLiteral; + get createStringLiteral(): (...args: Parameters) => StringLiteral { + return createStringLiteral; }, get updateStringLiteral(): (...args: Parameters) => StringLiteral { return updateStringLiteral; }, - get create1StringLiteral(): (...args: Parameters) => StringLiteral { - return StringLiteral.create1StringLiteral; + get create1StringLiteral(): (...args: Parameters) => StringLiteral { + return createStringLiteral; }, get update1StringLiteral(): (...args: Parameters) => StringLiteral { return updateStringLiteral; }, - get createNumericLiteral(): (...args: Parameters) => NumberLiteral { - return NumberLiteral.create; + get createNumericLiteral(): (...args: Parameters) => NumberLiteral { + return createNumberLiteral; }, get updateNumericLiteral(): (...args: Parameters) => NumberLiteral { return updateNumberLiteral; }, get createParameterDeclaration(): ( - ...args: Parameters + ...args: Parameters ) => ETSParameterExpression { - return ETSParameterExpression.create; + return createETSParameterExpression; }, get updateParameterDeclaration(): ( ...args: Parameters ) => ETSParameterExpression { return updateETSParameterExpression; }, - get createTypeParameter(): (...args: Parameters) => TSTypeParameter { - return TSTypeParameter.createTSTypeParameter; + get createTypeParameter(): (...args: Parameters) => TSTypeParameter { + return createTSTypeParameter; }, get updateTypeParameter(): (...args: Parameters) => TSTypeParameter { return updateTSTypeParameter; }, get createTypeParameterDeclaration(): ( - ...args: Parameters + ...args: Parameters ) => TSTypeParameterDeclaration { - return TSTypeParameterDeclaration.createTSTypeParameterDeclaration; + return createTSTypeParameterDeclaration; }, get updateTypeParameterDeclaration(): ( ...args: Parameters ) => TSTypeParameterDeclaration { return updateTSTypeParameterDeclaration; }, - get createPrimitiveType(): ( - ...args: Parameters - ) => ETSPrimitiveType { - return ETSPrimitiveType.createETSPrimitiveType; + get createPrimitiveType(): (...args: Parameters) => ETSPrimitiveType { + return createETSPrimitiveType; }, get updatePrimitiveType(): (...args: Parameters) => ETSPrimitiveType { return updateETSPrimitiveType; }, - get createTypeReference(): ( - ...args: Parameters - ) => ETSTypeReference { - return ETSTypeReference.createETSTypeReference; + get createTypeReference(): (...args: Parameters) => ETSTypeReference { + return createETSTypeReference; }, get updateTypeReference(): (...args: Parameters) => ETSTypeReference { return updateETSTypeReference; }, - get createTypeReferencePart(): ( - ...args: Parameters - ) => ETSTypeReferencePart { - return ETSTypeReferencePart.createETSTypeReferencePart; + get createTypeReferencePart(): (...args: Parameters) => ETSTypeReferencePart { + return createETSTypeReferencePart; }, get updateTypeReferencePart(): (...args: Parameters) => ETSTypeReferencePart { return updateETSTypeReferencePart; }, - get createImportDeclaration(): ( - ...args: Parameters - ) => ETSImportDeclaration { - return ETSImportDeclaration.createETSImportDeclaration; + get createImportDeclaration(): (...args: Parameters) => ETSImportDeclaration { + return createETSImportDeclaration; }, get updateImportDeclaration(): (...args: Parameters) => ETSImportDeclaration { return updateETSImportDeclaration; }, - get createImportSpecifier(): ( - ...args: Parameters - ) => ImportSpecifier { - return ImportSpecifier.createImportSpecifier; + get createImportSpecifier(): (...args: Parameters) => ImportSpecifier { + return createImportSpecifier; }, get updateImportSpecifier(): (...args: Parameters) => ImportSpecifier { return updateImportSpecifier; }, - get createVariableDeclaration(): (...args: Parameters) => VariableDeclaration { - return VariableDeclaration.create; + get createVariableDeclaration(): (...args: Parameters) => VariableDeclaration { + return createVariableDeclaration; }, get updateVariableDeclaration(): (...args: Parameters) => VariableDeclaration { return updateVariableDeclaration; }, - get createVariableDeclarator(): (...args: Parameters) => VariableDeclarator { - return VariableDeclarator.create; + get createVariableDeclarator(): (...args: Parameters) => VariableDeclarator { + return createVariableDeclarator; }, get updateVariableDeclarator(): (...args: Parameters) => VariableDeclarator { return updateVariableDeclarator; }, - get createUnionType(): (...args: Parameters) => ETSUnionType { - return ETSUnionType.createETSUnionType; + get createUnionType(): (...args: Parameters) => ETSUnionType { + return createETSUnionType; }, get updateUnionType(): (...args: Parameters) => ETSUnionType { return updateETSUnionType; }, - get createReturnStatement(): ( - ...args: Parameters - ) => ReturnStatement { - return ReturnStatement.create1ReturnStatement; + get createReturnStatement(): (...args: Parameters) => ReturnStatement { + return createReturnStatement; }, get updateReturnStatement(): (...args: Parameters) => ReturnStatement { return updateReturnStatement; }, - get createIfStatement(): (...args: Parameters) => IfStatement { - return IfStatement.create; + get createIfStatement(): (...args: Parameters) => IfStatement { + return createIfStatement; }, get updateIfStatement(): (...args: Parameters) => IfStatement { return updateIfStatement; }, - get createBinaryExpression(): ( - ...args: Parameters - ) => BinaryExpression { - return BinaryExpression.createBinaryExpression; + get createBinaryExpression(): (...args: Parameters) => BinaryExpression { + return createBinaryExpression; }, get updateBinaryExpression(): (...args: Parameters) => BinaryExpression { return updateBinaryExpression; }, - get createClassDeclaration(): ( - ...args: Parameters - ) => ClassDeclaration { - return ClassDeclaration.createClassDeclaration; + get createClassDeclaration(): (...args: Parameters) => ClassDeclaration { + return createClassDeclaration; }, get updateClassDeclaration(): (...args: Parameters) => ClassDeclaration { return updateClassDeclaration; }, - get createStructDeclaration(): (...args: Parameters) => StructDeclaration { - return StructDeclaration.create; + get createStructDeclaration(): (...args: Parameters) => StructDeclaration { + return createStructDeclaration; }, get updateStructDeclaration(): (...args: Parameters) => StructDeclaration { return updateStructDeclaration; }, - get createClassDefinition(): ( - ...args: Parameters - ) => ClassDefinition { - return ClassDefinition.createClassDefinition; + get createClassDefinition(): (...args: Parameters) => ClassDefinition { + return createClassDefinition; }, get updateClassDefinition(): (...args: Parameters) => ClassDefinition { return updateClassDefinition; }, - get createClassProperty(): (...args: Parameters) => ClassProperty { - return ClassProperty.createClassProperty; + get createClassProperty(): (...args: Parameters) => ClassProperty { + return createClassProperty; }, get updateClassProperty(): (...args: Parameters) => ClassProperty { return updateClassProperty; }, - get createFunctionType(): (...args: Parameters) => ETSFunctionType { - return ETSFunctionType.createETSFunctionType; + get createFunctionType(): (...args: Parameters) => ETSFunctionType { + return createETSFunctionType; }, get updateFunctionType(): (...args: Parameters) => ETSFunctionType { return updateETSFunctionType; }, - get createFunctionExpression(): (...args: Parameters) => FunctionExpression { - return FunctionExpression.create; + get createFunctionExpression(): (...args: Parameters) => FunctionExpression { + return createFunctionExpression; }, get updateFunctionExpression(): (...args: Parameters) => FunctionExpression { return updateFunctionExpression; }, - get createMethodDefinition(): (...args: Parameters) => MethodDefinition { - return MethodDefinition.create; + get createMethodDefinition(): (...args: Parameters) => MethodDefinition { + return createMethodDefinition; }, get updateMethodDefinition(): (...args: Parameters) => MethodDefinition { return updateMethodDefinition; }, - get createSuperExpression(): ( - ...args: Parameters - ) => SuperExpression { - return SuperExpression.createSuperExpression; + get createSuperExpression(): (...args: Parameters) => SuperExpression { + return createSuperExpression; }, get updateSuperExpression(): (...args: Parameters) => SuperExpression { return updateSuperExpression; }, get createTSTypeParameterInstantiation(): ( - ...args: Parameters + ...args: Parameters ) => TSTypeParameterInstantiation { - return TSTypeParameterInstantiation.createTSTypeParameterInstantiation; + return createTSTypeParameterInstantiation; }, get updateTSTypeParameterInstantiation(): ( ...args: Parameters @@ -389,67 +389,57 @@ export const factory = { return updateTSTypeParameterInstantiation; }, get createInterfaceDeclaration(): ( - ...args: Parameters + ...args: Parameters ) => TSInterfaceDeclaration { - return TSInterfaceDeclaration.createTSInterfaceDeclaration; + return createTSInterfaceDeclaration; }, get updateInterfaceDeclaration(): ( ...args: Parameters ) => TSInterfaceDeclaration { return updateTSInterfaceDeclaration; }, - get createInterfaceBody(): (...args: Parameters) => TSInterfaceBody { - return TSInterfaceBody.createTSInterfaceBody; + get createInterfaceBody(): (...args: Parameters) => TSInterfaceBody { + return createTSInterfaceBody; }, get updateInterfaceBody(): (...args: Parameters) => TSInterfaceBody { return updateTSInterfaceBody; }, - get createUndefinedLiteral(): ( - ...args: Parameters - ) => UndefinedLiteral { - return UndefinedLiteral.createUndefinedLiteral; + get createUndefinedLiteral(): (...args: Parameters) => UndefinedLiteral { + return createUndefinedLiteral; }, get updateUndefinedLiteral(): (...args: Parameters) => UndefinedLiteral { return updateUndefinedLiteral; }, get createAnnotationDeclaration(): ( - ...args: Parameters + ...args: Parameters ) => AnnotationDeclaration { - return AnnotationDeclaration.create1AnnotationDeclaration; + return createAnnotationDeclaration; }, get updateAnnotationDeclaration(): ( ...args: Parameters ) => AnnotationDeclaration { return updateAnnotationDeclaration; }, - get createAnnotationUsage(): ( - ...args: Parameters - ) => AnnotationUsage { - return AnnotationUsage.createAnnotationUsage; + get createAnnotationUsage(): (...args: Parameters) => AnnotationUsage { + return createAnnotationUsage; }, get updateAnnotationUsage(): (...args: Parameters) => AnnotationUsage { return updateAnnotationUsage; }, - get create1AnnotationUsage(): ( - ...args: Parameters - ) => AnnotationUsage { - return AnnotationUsage.create1AnnotationUsage; + get create1AnnotationUsage(): (...args: Parameters) => AnnotationUsage { + return create1AnnotationUsage; }, get update1AnnotationUsage(): (...args: Parameters) => AnnotationUsage { return update1AnnotationUsage; }, - get createAssignmentExpression(): ( - ...args: Parameters - ) => AssignmentExpression { - return AssignmentExpression.create; + get createAssignmentExpression(): (...args: Parameters) => AssignmentExpression { + return createAssignmentExpression; }, get updateAssignmentExpression(): (...args: Parameters) => AssignmentExpression { return updateAssignmentExpression; }, - get createETSUndefinedType(): ( - ...args: Parameters - ) => ETSUndefinedType { - return ETSUndefinedType.createETSUndefinedType; + get createETSUndefinedType(): (...args: Parameters) => ETSUndefinedType { + return createETSUndefinedType; }, get updateETSUndefinedType(): (...args: Parameters) => ETSUndefinedType { return updateETSUndefinedType; @@ -460,167 +450,145 @@ export const factory = { return FunctionSignature.createFunctionSignature; }, get createConditionalExpression(): ( - ...args: Parameters + ...args: Parameters ) => ConditionalExpression { - return ConditionalExpression.createConditionalExpression; + return createConditionalExpression; }, get updateConditionalExpression(): ( ...args: Parameters ) => ConditionalExpression { return updateConditionalExpression; }, - get createTSAsExpression(): (...args: Parameters) => TSAsExpression { - return TSAsExpression.createTSAsExpression; + get createTSAsExpression(): (...args: Parameters) => TSAsExpression { + return createTSAsExpression; }, get updateTSAsExpression(): (...args: Parameters) => TSAsExpression { return updateTSAsExpression; }, - get createThisExpression(): (...args: Parameters) => ThisExpression { - return ThisExpression.createThisExpression; + get createThisExpression(): (...args: Parameters) => ThisExpression { + return createThisExpression; }, get updateThisExpression(): (...args: Parameters) => ThisExpression { return updateThisExpression; }, get createTSTypeAliasDeclaration(): ( - ...args: Parameters + ...args: Parameters ) => TSTypeAliasDeclaration { - return TSTypeAliasDeclaration.createTSTypeAliasDeclaration; + return createTSTypeAliasDeclaration; }, get updateTSTypeAliasDeclaration(): ( ...args: Parameters ) => TSTypeAliasDeclaration { return updateTSTypeAliasDeclaration; }, - get createTSNonNullExpression(): ( - ...args: Parameters - ) => TSNonNullExpression { - return TSNonNullExpression.createTSNonNullExpression; + get createTSNonNullExpression(): (...args: Parameters) => TSNonNullExpression { + return createTSNonNullExpression; }, get updateTSNonNullExpression(): (...args: Parameters) => TSNonNullExpression { return updateTSNonNullExpression; }, - get createChainExpression(): ( - ...args: Parameters - ) => ChainExpression { - return ChainExpression.createChainExpression; + get createChainExpression(): (...args: Parameters) => ChainExpression { + return createChainExpression; }, get updateChainExpression(): (...args: Parameters) => ChainExpression { return updateChainExpression; }, - get createBlockExpression(): ( - ...args: Parameters - ) => BlockExpression { - return BlockExpression.createBlockExpression; + get createBlockExpression(): (...args: Parameters) => BlockExpression { + return createBlockExpression; }, get updateBlockExpression(): (...args: Parameters) => BlockExpression { return updateBlockExpression; }, - get createNullLiteral(): (...args: Parameters) => NullLiteral { - return NullLiteral.createNullLiteral; + get createNullLiteral(): (...args: Parameters) => NullLiteral { + return createNullLiteral; }, get updateNullLiteral(): (...args: Parameters) => NullLiteral { return updateNullLiteral; }, get createETSNewClassInstanceExpression(): ( - ...args: Parameters + ...args: Parameters ) => ETSNewClassInstanceExpression { - return ETSNewClassInstanceExpression.createETSNewClassInstanceExpression; + return createETSNewClassInstanceExpression; }, get updateETSNewClassInstanceExpression(): ( ...args: Parameters ) => ETSNewClassInstanceExpression { return updateETSNewClassInstanceExpression; }, - get createETSStringLiteralType(): ( - ...args: Parameters - ) => ETSStringLiteralType { - return ETSStringLiteralType.create; + get createETSStringLiteralType(): (...args: Parameters) => ETSStringLiteralType { + return createETSStringLiteralType; }, - get createBooleanLiteral(): (...args: Parameters) => BooleanLiteral { - return BooleanLiteral.createBooleanLiteral; + get createBooleanLiteral(): (...args: Parameters) => BooleanLiteral { + return createBooleanLiteral; }, - get createObjectExpression(): ( - ...args: Parameters - ) => ObjectExpression { - return ObjectExpression.createObjectExpression; + get createObjectExpression(): (...args: Parameters) => ObjectExpression { + return createObjectExpression; }, get updateObjectExpression(): (...args: Parameters) => ObjectExpression { return updateObjectExpression; }, - get createProperty(): (...args: Parameters) => Property { - return Property.createProperty; + get createProperty(): (...args: Parameters) => Property { + return createProperty; }, get updateProperty(): (...args: Parameters) => Property { return updateProperty; }, - get createTemplateLiteral(): ( - ...args: Parameters - ) => TemplateLiteral { - return TemplateLiteral.createTemplateLiteral; + get createTemplateLiteral(): (...args: Parameters) => TemplateLiteral { + return createTemplateLiteral; }, get updateTemplateLiteral(): (...args: Parameters) => TemplateLiteral { return updateTemplateLiteral; }, - get createArrayExpression(): ( - ...args: Parameters - ) => ArrayExpression { - return ArrayExpression.createArrayExpression; + get createArrayExpression(): (...args: Parameters) => ArrayExpression { + return createArrayExpression; }, get updateArrayExpression(): (...args: Parameters) => ArrayExpression { return updateArrayExpression; }, - get createTryStatement(): (...args: Parameters) => TryStatement { - return TryStatement.createTryStatement; + get createTryStatement(): (...args: Parameters) => TryStatement { + return createTryStatement; }, get updateTryStatement(): (...args: Parameters) => TryStatement { return updateTryStatement; }, - get createTSClassImplements(): ( - ...args: Parameters - ) => TSClassImplements { - return TSClassImplements.createTSClassImplements; + get createTSClassImplements(): (...args: Parameters) => TSClassImplements { + return createTSClassImplements; }, get UpdateTSClassImplements(): (...args: Parameters) => TSClassImplements { return updateTSClassImplements; }, - get createForUpdateStatement(): ( - ...args: Parameters - ) => ForUpdateStatement { - return ForUpdateStatement.createForUpdateStatement; + get createForUpdateStatement(): (...args: Parameters) => ForUpdateStatement { + return createForUpdateStatement; }, get updateForUpdateStatement(): (...args: Parameters) => ForUpdateStatement { return updateForUpdateStatement; }, - get createForInStatement(): (...args: Parameters) => ForInStatement { - return ForInStatement.createForInStatement; + get createForInStatement(): (...args: Parameters) => ForInStatement { + return createForInStatement; }, get updateForInStatement(): (...args: Parameters) => ForInStatement { return updateForInStatement; }, - get createForOfStatement(): (...args: Parameters) => ForOfStatement { - return ForOfStatement.createForOfStatement; + get createForOfStatement(): (...args: Parameters) => ForOfStatement { + return createForOfStatement; }, get updateForOfStatement(): (...args: Parameters) => ForOfStatement { return updateForOfStatement; }, - get createSwitchStatement(): ( - ...args: Parameters - ) => SwitchStatement { - return SwitchStatement.createSwitchStatement; + get createSwitchStatement(): (...args: Parameters) => SwitchStatement { + return createSwitchStatement; }, get updateSwitchStatement(): (...args: Parameters) => SwitchStatement { return updateSwitchStatement; }, - get createSwitchCaseStatement(): ( - ...args: Parameters - ) => SwitchCaseStatement { - return SwitchCaseStatement.createSwitchCaseStatement; + get createSwitchCaseStatement(): (...args: Parameters) => SwitchCaseStatement { + return createSwitchCaseStatement; }, get updateSwitchCaseStatement(): (...args: Parameters) => SwitchCaseStatement { return updateSwitchCaseStatement; }, - get createSpreadElement(): (...args: Parameters) => SpreadElement { - return SpreadElement.createSpreadElement; + get createSpreadElement(): (...args: Parameters) => SpreadElement { + return createSpreadElement; }, get updateSpreadElement(): (...args: Parameters) => SpreadElement { return updateSpreadElement; diff --git a/koala-wrapper/src/arkts-api/index.ts b/koala-wrapper/src/arkts-api/index.ts index f62d57430c29cfa15f498f5e6c48661f4f51a4a6..618fddb36f718381a63b2ad51f5cf2bbf9f199b1 100644 --- a/koala-wrapper/src/arkts-api/index.ts +++ b/koala-wrapper/src/arkts-api/index.ts @@ -71,6 +71,7 @@ export * from '../generated/peers/ContinueStatement'; export * from '../generated/peers/SwitchCaseStatement'; export * from '../generated/peers/SwitchStatement'; +export * from './class-by-peer'; export * from './types'; export * from './utilities/private'; export * from './utilities/public'; diff --git a/koala-wrapper/src/arkts-api/node-by-type.ts b/koala-wrapper/src/arkts-api/node-by-type.ts new file mode 100644 index 0000000000000000000000000000000000000000..b12dc0cf1474f3b5ec52c41ad2268de4515d93a1 --- /dev/null +++ b/koala-wrapper/src/arkts-api/node-by-type.ts @@ -0,0 +1,35 @@ +/* + * 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 { KNativePointer } from '@koalaui/interop'; +import { Es2pandaAstNodeType } from '../Es2pandaEnums'; +import type { AstNode } from './peers/AstNode'; + +export const nodeByType = new Map([]); + +const cache = new Map(); +export function clearNodeCache(): void { + cache.clear(); +} + +export function getOrPut(peer: KNativePointer, create: (peer: KNativePointer) => AstNode): AstNode { + if (cache.has(peer)) { + return cache.get(peer)!; + } + + const newNode = create(peer); + cache.set(peer, newNode); + return newNode; +} \ No newline at end of file diff --git a/koala-wrapper/src/arkts-api/node-utilities/AnnotationDeclaration.ts b/koala-wrapper/src/arkts-api/node-utilities/AnnotationDeclaration.ts index 345d95f213023ba56c28a1b1db72b9f222ec014e..8cbccdc1477994990692939614c186c362d5feed 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/AnnotationDeclaration.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/AnnotationDeclaration.ts @@ -15,9 +15,24 @@ import { AnnotationDeclaration, Expression } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; import { AstNode } from '../peers/AstNode'; +export function createAnnotationDeclaration( + expr: Expression | undefined, + properties: readonly AstNode[] +): AnnotationDeclaration { + const create = createThenAttach(AnnotationDeclaration.create1AnnotationDeclaration, attachUpdateToCreatedNode); + return create(expr, properties); +} + export function updateAnnotationDeclaration( original: AnnotationDeclaration, expr: Expression | undefined, @@ -27,6 +42,11 @@ export function updateAnnotationDeclaration( return original; } - const update = updateThenAttach(AnnotationDeclaration.update1AnnotationDeclaration, attachModifiers); + const update = updateThenAttach( + AnnotationDeclaration.update1AnnotationDeclaration, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, expr, properties); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/AnnotationUsage.ts b/koala-wrapper/src/arkts-api/node-utilities/AnnotationUsage.ts index 82b28fec3036a8fb56826c7bcc29fb462ef82405..a568b4ccdc96231ff7eeb52b912338f2bf1ca300 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/AnnotationUsage.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/AnnotationUsage.ts @@ -15,9 +15,26 @@ import { AnnotationUsage, Expression } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; import { AstNode } from '../peers/AstNode'; +export function createAnnotationUsage(expr?: Expression): AnnotationUsage { + const create = createThenAttach(AnnotationUsage.createAnnotationUsage, attachUpdateToCreatedNode); + return create(expr); +} + +export function create1AnnotationUsage(expr: Expression | undefined, properties: readonly AstNode[]): AnnotationUsage { + const create = createThenAttach(AnnotationUsage.create1AnnotationUsage, attachUpdateToCreatedNode); + return create(expr, properties); +} + export function updateAnnotationUsage(original: AnnotationUsage, expr?: Expression): AnnotationUsage { if (isSameNativeObject(expr, original.expr)) { return original; @@ -27,11 +44,20 @@ export function updateAnnotationUsage(original: AnnotationUsage, expr?: Expressi return update(original, expr); } -export function update1AnnotationUsage(original: AnnotationUsage, expr: Expression | undefined, properties: readonly AstNode[]): AnnotationUsage { +export function update1AnnotationUsage( + original: AnnotationUsage, + expr: Expression | undefined, + properties: readonly AstNode[] +): AnnotationUsage { if (isSameNativeObject(expr, original.expr) && isSameNativeObject(properties, original.properties)) { return original; } - const update = updateThenAttach(AnnotationUsage.update1AnnotationUsage, attachModifiers); + const update = updateThenAttach( + AnnotationUsage.update1AnnotationUsage, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, expr, properties); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ArrayExpression.ts b/koala-wrapper/src/arkts-api/node-utilities/ArrayExpression.ts index 320b0d678bd9f868eddc5eeeaffb2aa1ef1c195d..2a706c0d6fe6f630107c0f521723e72c847e3216 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ArrayExpression.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ArrayExpression.ts @@ -15,7 +15,19 @@ import { ArrayExpression, Expression } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createArrayExpression(elements: readonly Expression[]): ArrayExpression { + const create = createThenAttach(ArrayExpression.createArrayExpression, attachUpdateToCreatedNode); + return create(elements); +} export function updateArrayExpression(original: ArrayExpression, elements: readonly Expression[]): ArrayExpression { if (isSameNativeObject(elements, original.elements)) { @@ -24,7 +36,9 @@ export function updateArrayExpression(original: ArrayExpression, elements: reado const update = updateThenAttach( ArrayExpression.updateArrayExpression, attachModifiers, - attachOptionalAndDeclaration + attachOptionalAndDeclaration, + attachParent, + refreshNodeCache ); return update(original, elements); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ArrowFunctionExpression.ts b/koala-wrapper/src/arkts-api/node-utilities/ArrowFunctionExpression.ts index a787698d718980e62d0294e41933ca4ac8e94e6d..ffb654a7b8ed8eda6a2c15c04245080b31d6f4e5 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ArrowFunctionExpression.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ArrowFunctionExpression.ts @@ -16,8 +16,19 @@ import { ScriptFunction } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; import { ArrowFunctionExpression } from '../types'; -import { NodeCache } from '../utilities/nodeCache'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createArrowFunctionExpression(func: ScriptFunction): ArrowFunctionExpression { + const create = createThenAttach(ArrowFunctionExpression.create, attachUpdateToCreatedNode); + return create(func); +} export function updateArrowFunctionExpression( original: ArrowFunctionExpression, @@ -30,11 +41,9 @@ export function updateArrowFunctionExpression( const update = updateThenAttach( ArrowFunctionExpression.update, attachModifiers, - (node: ArrowFunctionExpression, original: ArrowFunctionExpression) => node.setAnnotations(original.annotations) + (node: ArrowFunctionExpression, original: ArrowFunctionExpression) => node.setAnnotations(original.annotations), + attachParent, + refreshNodeCache ); - const newNode = update(original, func); - if (NodeCache.getInstance().has(original)) { - NodeCache.getInstance().refresh(original, newNode); - } - return newNode; + return update(original, func); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/AssignmentExpression.ts b/koala-wrapper/src/arkts-api/node-utilities/AssignmentExpression.ts index de701b0ad9173acd411f65d35015cf31a8cf1b12..8ddf29fd74bd1873cbc2eb2d0aa256e8fa72103b 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/AssignmentExpression.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/AssignmentExpression.ts @@ -16,9 +16,25 @@ import { isSameNativeObject } from '../peers/ArktsObject'; import { AstNode } from '../peers/AstNode'; import { AssignmentExpression } from '../types'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; import { Es2pandaTokenType } from '../../generated/Es2pandaEnums'; +export function createAssignmentExpression( + left: AstNode, + assignmentOperator: Es2pandaTokenType, + right: AstNode +): AssignmentExpression { + const create = createThenAttach(AssignmentExpression.create, attachUpdateToCreatedNode); + return create(left, assignmentOperator, right); +} + export function updateAssignmentExpression( original: AssignmentExpression, left: AstNode, @@ -33,6 +49,6 @@ export function updateAssignmentExpression( return original; } - const update = updateThenAttach(AssignmentExpression.update, attachModifiers); + const update = updateThenAttach(AssignmentExpression.update, attachModifiers, attachParent, refreshNodeCache); return update(original, left, assignmentOperator, right); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/BinaryExpression.ts b/koala-wrapper/src/arkts-api/node-utilities/BinaryExpression.ts index 25a182b160449a25f6823707ea4951fd07dd44c2..0e75fd30f7782fd15ec30a4f28d53811e7c62bba 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/BinaryExpression.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/BinaryExpression.ts @@ -15,9 +15,25 @@ import { BinaryExpression, Expression } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; import { Es2pandaTokenType } from '../../generated/Es2pandaEnums'; +export function createBinaryExpression( + left: Expression | undefined, + right: Expression | undefined, + operatorType: Es2pandaTokenType +): BinaryExpression { + const create = createThenAttach(BinaryExpression.createBinaryExpression, attachUpdateToCreatedNode); + return create(left, right, operatorType); +} + export function updateBinaryExpression( original: BinaryExpression, left: Expression | undefined, @@ -32,6 +48,11 @@ export function updateBinaryExpression( return original; } - const update = updateThenAttach(BinaryExpression.updateBinaryExpression, attachModifiers); + const update = updateThenAttach( + BinaryExpression.updateBinaryExpression, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, left, right, operatorType); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/BlockExpression.ts b/koala-wrapper/src/arkts-api/node-utilities/BlockExpression.ts index e1489fb2e3b0542f2b2a324f54480447fba4417f..72887ab876eaf6fdb66179433856ee8e689ec909 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/BlockExpression.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/BlockExpression.ts @@ -15,13 +15,30 @@ import { BlockExpression, Statement } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createBlockExpression(statements: readonly Statement[]): BlockExpression { + const create = createThenAttach(BlockExpression.createBlockExpression, attachUpdateToCreatedNode); + return create(statements); +} export function updateBlockExpression(original: BlockExpression, statements: readonly Statement[]): BlockExpression { if (isSameNativeObject(statements, original.statements)) { return original; } - const update = updateThenAttach(BlockExpression.updateBlockExpression, attachModifiers); + const update = updateThenAttach( + BlockExpression.updateBlockExpression, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, statements); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/BlockStatement.ts b/koala-wrapper/src/arkts-api/node-utilities/BlockStatement.ts index d9571384f43b00c9136bda88ca794a2f0b159b18..df5b09658e8eb9b306a072247da3eab14b914044 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/BlockStatement.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/BlockStatement.ts @@ -15,13 +15,30 @@ import { BlockStatement, Statement } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createBlockStatement(statementList: readonly Statement[]): BlockStatement { + const create = createThenAttach(BlockStatement.createBlockStatement, attachUpdateToCreatedNode); + return create(statementList); +} export function updateBlockStatement(original: BlockStatement, statementList: readonly Statement[]): BlockStatement { if (isSameNativeObject(statementList, original.statements)) { return original; } - const update = updateThenAttach(BlockStatement.updateBlockStatement, attachModifiers); + const update = updateThenAttach( + BlockStatement.updateBlockStatement, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, statementList); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/BooleanLiteral.ts b/koala-wrapper/src/arkts-api/node-utilities/BooleanLiteral.ts new file mode 100644 index 0000000000000000000000000000000000000000..5e4e96ab8696276dad94c393723f8820b554e019 --- /dev/null +++ b/koala-wrapper/src/arkts-api/node-utilities/BooleanLiteral.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 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 { createThenAttach } from '../utilities/private'; +import { BooleanLiteral } from '../../generated'; + +export function createBooleanLiteral(value: boolean): BooleanLiteral { + const create = createThenAttach(BooleanLiteral.createBooleanLiteral); + return create(value); +} diff --git a/koala-wrapper/src/arkts-api/node-utilities/CallExpression.ts b/koala-wrapper/src/arkts-api/node-utilities/CallExpression.ts index 843798827d52fdba2515bca58485b23df99560b6..f01350149703eeb1c03c20120ba1ff0ddef9327b 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/CallExpression.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/CallExpression.ts @@ -17,8 +17,25 @@ import { TypeNode } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; import { AstNode } from '../peers/AstNode'; import { CallExpression } from '../types'; -import { NodeCache } from '../utilities/nodeCache'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createCallExpression( + expression: AstNode, + typeArguments: readonly TypeNode[] | undefined, + args: readonly AstNode[] | undefined, + isOptional?: boolean, + trailingComma?: boolean +): CallExpression { + const create = createThenAttach(CallExpression.create, attachUpdateToCreatedNode); + return create(expression, typeArguments, args, isOptional, trailingComma); +} export function updateCallExpression( original: CallExpression, @@ -40,11 +57,9 @@ export function updateCallExpression( CallExpression.update, attachModifiers, (node: CallExpression, original: CallExpression) => - !!original.trailingBlock ? node.setTralingBlock(original.trailingBlock) : node + !!original.trailingBlock ? node.setTralingBlock(original.trailingBlock) : node, + attachParent, + refreshNodeCache ); - const newNode = update(original, expression, typeArguments, args, isOptional, trailingComma); - if (NodeCache.getInstance().has(original)) { - NodeCache.getInstance().refresh(original, newNode); - } - return newNode; + return update(original, expression, typeArguments, args, isOptional, trailingComma); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ChainExpression.ts b/koala-wrapper/src/arkts-api/node-utilities/ChainExpression.ts index fdadb8843bd5e9098305e6200af159c7bc2b8630..d64740adecdff49ed4f282ec1ef9e09c73115ffd 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ChainExpression.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ChainExpression.ts @@ -15,13 +15,30 @@ import { ChainExpression, Expression } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createChainExpression(expression?: Expression): ChainExpression { + const create = createThenAttach(ChainExpression.createChainExpression, attachUpdateToCreatedNode); + return create(expression); +} export function updateChainExpression(original: ChainExpression, expression?: Expression): ChainExpression { if (isSameNativeObject(expression, original.getExpression)) { return original; } - const update = updateThenAttach(ChainExpression.updateChainExpression, attachModifiers); + const update = updateThenAttach( + ChainExpression.updateChainExpression, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, expression); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ClassDeclaration.ts b/koala-wrapper/src/arkts-api/node-utilities/ClassDeclaration.ts index 1474e8d847203ff4d62783fdbeb02a1d26ceb3eb..a3ba74afd1bc9e0872e11cdbb08bfe3c2669f7fa 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ClassDeclaration.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ClassDeclaration.ts @@ -15,13 +15,30 @@ import { ClassDeclaration, ClassDefinition } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createClassDeclaration(def?: ClassDefinition): ClassDeclaration { + const create = createThenAttach(ClassDeclaration.createClassDeclaration, attachUpdateToCreatedNode); + return create(def); +} export function updateClassDeclaration(original: ClassDeclaration, def?: ClassDefinition): ClassDeclaration { if (isSameNativeObject(def, original.definition)) { return original; } - const update = updateThenAttach(ClassDeclaration.updateClassDeclaration, attachModifiers); + const update = updateThenAttach( + ClassDeclaration.updateClassDeclaration, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, def); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ClassDefinition.ts b/koala-wrapper/src/arkts-api/node-utilities/ClassDefinition.ts index feeac630221456f06585187ee9cef3b4e87e0e9c..4908ace1fc2d814feac9841041184d3ae60d39ad 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ClassDefinition.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ClassDefinition.ts @@ -24,10 +24,31 @@ import { import { isSameNativeObject } from '../peers/ArktsObject'; import { AstNode } from '../peers/AstNode'; import { MethodDefinition } from '../types'; -import { updateThenAttach } from '../utilities/private'; +import { + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; import { Es2pandaClassDefinitionModifiers, Es2pandaModifierFlags } from '../../generated/Es2pandaEnums'; import { classDefinitionFlags } from '../utilities/public'; +export function createClassDefinition( + ident: Identifier | undefined, + typeParams: TSTypeParameterDeclaration | undefined, + superTypeParams: TSTypeParameterInstantiation | undefined, + _implements: readonly TSClassImplements[], + ctor: MethodDefinition | undefined, + superClass: Expression | undefined, + body: readonly AstNode[], + modifiers: Es2pandaClassDefinitionModifiers, + flags: Es2pandaModifierFlags +): ClassDefinition { + const create = createThenAttach(ClassDefinition.createClassDefinition, attachUpdateToCreatedNode); + return create(ident, typeParams, superTypeParams, _implements, ctor as any, superClass, body, modifiers, flags); +} + export function updateClassDefinition( original: ClassDefinition, ident: Identifier | undefined, @@ -56,7 +77,9 @@ export function updateClassDefinition( const update = updateThenAttach( ClassDefinition.updateClassDefinition, - (node: ClassDefinition, original: ClassDefinition) => node.setAnnotations(original.annotations) + (node: ClassDefinition, original: ClassDefinition) => node.setAnnotations(original.annotations), + attachParent, + refreshNodeCache ); return update( original, diff --git a/koala-wrapper/src/arkts-api/node-utilities/ClassProperty.ts b/koala-wrapper/src/arkts-api/node-utilities/ClassProperty.ts index 1d31c28588a253d92fc5735de160b8694336b1ee..f6e6be04b04dbf61c0502099dab070607e1c90ef 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ClassProperty.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ClassProperty.ts @@ -15,10 +15,26 @@ import { ClassProperty, Expression, TypeNode } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { updateThenAttach } from '../utilities/private'; +import { + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; import { classPropertySetOptional, hasModifierFlag } from '../utilities/public'; import { Es2pandaModifierFlags } from '../../generated/Es2pandaEnums'; -import { NodeCache } from '../utilities/nodeCache'; + +export function createClassProperty( + key: Expression | undefined, + value: Expression | undefined, + typeAnnotation: TypeNode | undefined, + modifiers: Es2pandaModifierFlags, + isComputed: boolean +): ClassProperty { + const create = createThenAttach(ClassProperty.createClassProperty, attachUpdateToCreatedNode); + return create(key, value, typeAnnotation, modifiers, isComputed); +} export function updateClassProperty( original: ClassProperty, @@ -46,11 +62,9 @@ export function updateClassProperty( return classPropertySetOptional(node, true); } return node; - } + }, + attachParent, + refreshNodeCache ); - const newNode = update(original, key, value, typeAnnotation, modifiers, isComputed); - if (NodeCache.getInstance().has(original)) { - NodeCache.getInstance().refresh(original, newNode); - } - return newNode; + return update(original, key, value, typeAnnotation, modifiers, isComputed); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ConditionalExpression.ts b/koala-wrapper/src/arkts-api/node-utilities/ConditionalExpression.ts index e1d2d5b2f27a69bc6462bb2a953298312a7c99ae..9c24d65fccf3e48ea37c104bf990d0c546893bad 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ConditionalExpression.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ConditionalExpression.ts @@ -15,7 +15,23 @@ import { ConditionalExpression, Expression } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createConditionalExpression( + test?: Expression, + consequent?: Expression, + alternate?: Expression +): ConditionalExpression { + const create = createThenAttach(ConditionalExpression.createConditionalExpression, attachUpdateToCreatedNode); + return create(test, consequent, alternate); +} export function updateConditionalExpression( original: ConditionalExpression, @@ -31,6 +47,11 @@ export function updateConditionalExpression( return original; } - const update = updateThenAttach(ConditionalExpression.updateConditionalExpression, attachModifiers); + const update = updateThenAttach( + ConditionalExpression.updateConditionalExpression, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, test, consequent, alternate); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ETSFunctionType.ts b/koala-wrapper/src/arkts-api/node-utilities/ETSFunctionType.ts index c4e44197444b5f24678212b0566cafab7561cd3c..1a697740ff58322ea5441c682e5e0bf86182a22d 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ETSFunctionType.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ETSFunctionType.ts @@ -15,9 +15,23 @@ import { ETSFunctionType, FunctionSignature } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; import { Es2pandaScriptFunctionFlags } from '../../generated/Es2pandaEnums'; -import { NodeCache } from '../utilities/nodeCache'; + +export function createETSFunctionType( + signature: FunctionSignature | undefined, + funcFlags: Es2pandaScriptFunctionFlags +): ETSFunctionType { + const create = createThenAttach(ETSFunctionType.createETSFunctionType, attachUpdateToCreatedNode); + return create(signature, funcFlags); +} export function updateETSFunctionType( original: ETSFunctionType, @@ -37,11 +51,9 @@ export function updateETSFunctionType( const update = updateThenAttach( ETSFunctionType.updateETSFunctionType, attachModifiers, - (node: ETSFunctionType, original: ETSFunctionType) => node.setAnnotations(original.annotations) + (node: ETSFunctionType, original: ETSFunctionType) => node.setAnnotations(original.annotations), + attachParent, + refreshNodeCache ); - const newNode = update(original, signature, funcFlags); - if (NodeCache.getInstance().has(original)) { - NodeCache.getInstance().refresh(original, newNode); - } - return newNode; + return update(original, signature, funcFlags); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ETSImportDeclaration.ts b/koala-wrapper/src/arkts-api/node-utilities/ETSImportDeclaration.ts index 1186fe3d4ac7406f656d7cd4bd2da521c90556c4..04255d5448bd3a3df833e2660165347741b32340 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ETSImportDeclaration.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ETSImportDeclaration.ts @@ -14,10 +14,29 @@ */ import { ETSImportDeclaration, StringLiteral } from '../../generated'; -import { isSameNativeObject } from '../peers/ArktsObject'; +import { ArktsObject, isSameNativeObject } from '../peers/ArktsObject'; import { AstNode } from '../peers/AstNode'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; import { Es2pandaImportKinds } from '../../generated/Es2pandaEnums'; +import { Es2pandaImportFlags } from '../../Es2pandaEnums'; + +export function createETSImportDeclaration( + source: StringLiteral | undefined, + specifiers: readonly AstNode[], + importKind: Es2pandaImportKinds, + program: ArktsObject, + flags: Es2pandaImportFlags +): ETSImportDeclaration { + const create = createThenAttach(ETSImportDeclaration.createETSImportDeclaration); + return create(source, specifiers, importKind, program, flags); +} export function updateETSImportDeclaration( original: ETSImportDeclaration, @@ -34,6 +53,11 @@ export function updateETSImportDeclaration( return original; } - const update = updateThenAttach(ETSImportDeclaration.updateETSImportDeclaration, attachModifiers); + const update = updateThenAttach( + ETSImportDeclaration.updateETSImportDeclaration, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, source, specifiers, importKind); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ETSModule.ts b/koala-wrapper/src/arkts-api/node-utilities/ETSModule.ts new file mode 100644 index 0000000000000000000000000000000000000000..93a82e00f8565963c549ce893a8174cb871c7527 --- /dev/null +++ b/koala-wrapper/src/arkts-api/node-utilities/ETSModule.ts @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024 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 { isSameNativeObject } from '../peers/ArktsObject'; +import { attachParent, refreshNodeCache, updateThenAttach } from '../utilities/private'; +import { AstNode } from '../peers/AstNode'; +import { EtsScript } from '../types'; + +export function updateETSModule(original: EtsScript, statements: readonly AstNode[]): EtsScript { + if (isSameNativeObject(statements, original.statements)) { + return original; + } + + const update = updateThenAttach(EtsScript.updateByStatements, attachParent, refreshNodeCache); + + return update(original, statements); +} diff --git a/koala-wrapper/src/arkts-api/node-utilities/ETSNewClassInstanceExpression.ts b/koala-wrapper/src/arkts-api/node-utilities/ETSNewClassInstanceExpression.ts index 512085cb09e0554f74b2532893eb6adfc9dcc23f..7427725f3e636d3dd45501046bdc88c202281198 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ETSNewClassInstanceExpression.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ETSNewClassInstanceExpression.ts @@ -15,7 +15,25 @@ import { ETSNewClassInstanceExpression, Expression } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createETSNewClassInstanceExpression( + typeReference: Expression | undefined, + _arguments: readonly Expression[] +): ETSNewClassInstanceExpression { + const create = createThenAttach( + ETSNewClassInstanceExpression.createETSNewClassInstanceExpression, + attachUpdateToCreatedNode + ); + return create(typeReference, _arguments); +} export function updateETSNewClassInstanceExpression( original: ETSNewClassInstanceExpression, @@ -29,6 +47,11 @@ export function updateETSNewClassInstanceExpression( return original; } - const update = updateThenAttach(ETSNewClassInstanceExpression.updateETSNewClassInstanceExpression, attachModifiers); + const update = updateThenAttach( + ETSNewClassInstanceExpression.updateETSNewClassInstanceExpression, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, typeReference, _arguments); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ETSParameterExpression.ts b/koala-wrapper/src/arkts-api/node-utilities/ETSParameterExpression.ts index 23923cd754012a58b9f5a01fc4074da05cbc0aa3..7fb8fb2396d61551324add995a2cd383ff4fbae2 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ETSParameterExpression.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ETSParameterExpression.ts @@ -17,8 +17,22 @@ import { Identifier } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; import { AstNode } from '../peers/AstNode'; import { ETSParameterExpression } from '../types'; -import { NodeCache } from '../utilities/nodeCache'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createETSParameterExpression( + identifier: Identifier, + initializer: AstNode | undefined +): ETSParameterExpression { + const create = createThenAttach(ETSParameterExpression.create, attachUpdateToCreatedNode); + return create(identifier, initializer); +} export function updateETSParameterExpression( original: ETSParameterExpression, @@ -39,10 +53,8 @@ export function updateETSParameterExpression( node.annotations = original.annotations; return node; }, + attachParent, + refreshNodeCache ); - const newNode = update(original, identifier, initializer); - if (NodeCache.getInstance().has(original)) { - NodeCache.getInstance().refresh(original, newNode); - } - return newNode; + return update(original, identifier, initializer); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ETSPrimitiveType.ts b/koala-wrapper/src/arkts-api/node-utilities/ETSPrimitiveType.ts index 0cba48bd87532edc4f24c64403a08315e5b6873a..fe73512250532b1a9ca8a0abd0c18cac7089af08 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ETSPrimitiveType.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ETSPrimitiveType.ts @@ -15,14 +15,31 @@ import { ETSPrimitiveType } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; import { Es2pandaPrimitiveType } from '../../generated/Es2pandaEnums'; +export function createETSPrimitiveType(type: Es2pandaPrimitiveType): ETSPrimitiveType { + const create = createThenAttach(ETSPrimitiveType.createETSPrimitiveType, attachUpdateToCreatedNode); + return create(type); +} + export function updateETSPrimitiveType(original: ETSPrimitiveType, type: Es2pandaPrimitiveType): ETSPrimitiveType { if (isSameNativeObject(type, original.getPrimitiveType)) { return original; } - const update = updateThenAttach(ETSPrimitiveType.updateETSPrimitiveType, attachModifiers); + const update = updateThenAttach( + ETSPrimitiveType.updateETSPrimitiveType, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, type); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ETSStringLiteralType.ts b/koala-wrapper/src/arkts-api/node-utilities/ETSStringLiteralType.ts new file mode 100644 index 0000000000000000000000000000000000000000..7fa074e2bb6bf811ca9db078e01c1b46979f7bfd --- /dev/null +++ b/koala-wrapper/src/arkts-api/node-utilities/ETSStringLiteralType.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 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 { createThenAttach } from '../utilities/private'; +import { ETSStringLiteralType } from '../types'; + +export function createETSStringLiteralType(str: string): ETSStringLiteralType { + const create = createThenAttach(ETSStringLiteralType.create); + return create(str); +} diff --git a/koala-wrapper/src/arkts-api/node-utilities/ETSTypeReference.ts b/koala-wrapper/src/arkts-api/node-utilities/ETSTypeReference.ts index 005d510bf40fdaf6ec98dc9340db1e0d2c11ada5..b61188d4bb5e80f5bba054da8235433e1a9e5ea9 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ETSTypeReference.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ETSTypeReference.ts @@ -15,13 +15,30 @@ import { ETSTypeReference, ETSTypeReferencePart } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createETSTypeReference(part?: ETSTypeReferencePart): ETSTypeReference { + const create = createThenAttach(ETSTypeReference.createETSTypeReference, attachUpdateToCreatedNode); + return create(part); +} export function updateETSTypeReference(original: ETSTypeReference, part?: ETSTypeReferencePart): ETSTypeReference { if (isSameNativeObject(part, original.part)) { return original; } - const update = updateThenAttach(ETSTypeReference.updateETSTypeReference, attachModifiers); + const update = updateThenAttach( + ETSTypeReference.updateETSTypeReference, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, part); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ETSTypeReferencePart.ts b/koala-wrapper/src/arkts-api/node-utilities/ETSTypeReferencePart.ts index fcc8212035801aa56744c56266511c90fffb81af..b307fa2ab792be750fd30a4a322b1579d66f87e4 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ETSTypeReferencePart.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ETSTypeReferencePart.ts @@ -15,7 +15,23 @@ import { ETSTypeReferencePart, Expression, TSTypeParameterInstantiation } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createETSTypeReferencePart( + name?: Expression, + typeParams?: TSTypeParameterInstantiation, + prev?: ETSTypeReferencePart +): ETSTypeReferencePart { + const create = createThenAttach(ETSTypeReferencePart.createETSTypeReferencePart, attachUpdateToCreatedNode); + return create(name, typeParams, prev); +} export function updateETSTypeReferencePart( original: ETSTypeReferencePart, @@ -31,6 +47,11 @@ export function updateETSTypeReferencePart( return original; } - const update = updateThenAttach(ETSTypeReferencePart.updateETSTypeReferencePart, attachModifiers); + const update = updateThenAttach( + ETSTypeReferencePart.updateETSTypeReferencePart, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, name, typeParams, prev); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ETSUndefinedType.ts b/koala-wrapper/src/arkts-api/node-utilities/ETSUndefinedType.ts index f88a53794295206b111e60bc7b036bf346e1c99e..85d2d37f478a44afdb31172f6c5a944e7e63eab6 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ETSUndefinedType.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ETSUndefinedType.ts @@ -14,11 +14,28 @@ */ import { ETSUndefinedType } from '../../generated'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createETSUndefinedType(): ETSUndefinedType { + const create = createThenAttach(ETSUndefinedType.createETSUndefinedType); + return create(); +} export function updateETSUndefinedType(original: ETSUndefinedType): ETSUndefinedType { /* TODO: no getter provided yet */ - const update = updateThenAttach(ETSUndefinedType.updateETSUndefinedType, attachModifiers); + const update = updateThenAttach( + ETSUndefinedType.updateETSUndefinedType, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ETSUnionType.ts b/koala-wrapper/src/arkts-api/node-utilities/ETSUnionType.ts index 07ab40282d2de1e6d7f114ec389d334a0e3bd3b4..cc4ed0f168e715155078f98ed7073a60fface850 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ETSUnionType.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ETSUnionType.ts @@ -15,18 +15,25 @@ import { ETSUnionType, TypeNode } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { NodeCache } from '../utilities/nodeCache'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createETSUnionType(types: readonly TypeNode[]): ETSUnionType { + const create = createThenAttach(ETSUnionType.createETSUnionType, attachUpdateToCreatedNode); + return create(types); +} export function updateETSUnionType(original: ETSUnionType, types: readonly TypeNode[]): ETSUnionType { if (isSameNativeObject(types, original.types)) { return original; } - const update = updateThenAttach(ETSUnionType.updateETSUnionType, attachModifiers); - const newNode = update(original, types); - if (NodeCache.getInstance().has(original)) { - NodeCache.getInstance().refresh(original, newNode); - } - return newNode; + const update = updateThenAttach(ETSUnionType.updateETSUnionType, attachModifiers, attachParent, refreshNodeCache); + return update(original, types); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ExpressionStatement.ts b/koala-wrapper/src/arkts-api/node-utilities/ExpressionStatement.ts index 4950ba1ffb34f4e2c6c21f0eab84cbd8fef592a2..430ae1249815d81beb8420fd0714cf296b78ca84 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ExpressionStatement.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ExpressionStatement.ts @@ -16,13 +16,25 @@ import { isSameNativeObject } from '../peers/ArktsObject'; import { AstNode } from '../peers/AstNode'; import { ExpressionStatement } from '../types'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createExpressionStatement(expression: AstNode): ExpressionStatement { + const create = createThenAttach(ExpressionStatement.create, attachUpdateToCreatedNode); + return create(expression); +} export function updateExpressionStatement(original: ExpressionStatement, expression: AstNode): ExpressionStatement { if (isSameNativeObject(expression, original.expression)) { return original; } - const update = updateThenAttach(ExpressionStatement.update, attachModifiers); + const update = updateThenAttach(ExpressionStatement.update, attachModifiers, attachParent, refreshNodeCache); return update(original, expression); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ForInStatement.ts b/koala-wrapper/src/arkts-api/node-utilities/ForInStatement.ts index 40f78ab063b300786aaddf46ff46f6d4abb8d7fc..17cd1bc7df14b735d8a01d7028344cc0cded0311 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ForInStatement.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ForInStatement.ts @@ -16,7 +16,19 @@ import { ForInStatement, Statement, Expression } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; import { AstNode } from '../peers/AstNode'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createForInStatement(left?: AstNode, right?: Expression, body?: Statement): ForInStatement { + const create = createThenAttach(ForInStatement.createForInStatement, attachUpdateToCreatedNode); + return create(left, right, body); +} export function updateForInStatement( original: ForInStatement, @@ -32,6 +44,11 @@ export function updateForInStatement( return original; } - const updateNode = updateThenAttach(ForInStatement.updateForInStatement, attachModifiers); + const updateNode = updateThenAttach( + ForInStatement.updateForInStatement, + attachModifiers, + attachParent, + refreshNodeCache + ); return updateNode(original, left, right, body); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ForOfStatement.ts b/koala-wrapper/src/arkts-api/node-utilities/ForOfStatement.ts index 9c8d99a1d9f350572c5752a21b4e6dbdc5650908..23462c5c98223a723cc09524fbc04024e44cfe96 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ForOfStatement.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ForOfStatement.ts @@ -16,7 +16,24 @@ import { ForOfStatement, Statement, Expression } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; import { AstNode } from '../peers/AstNode'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createForOfStatement( + left: AstNode | undefined, + right: Expression | undefined, + body: Statement | undefined, + isAwait: boolean +): ForOfStatement { + const create = createThenAttach(ForOfStatement.createForOfStatement, attachUpdateToCreatedNode); + return create(left, right, body, isAwait); +} export function updateForOfStatement( original: ForOfStatement, @@ -33,6 +50,11 @@ export function updateForOfStatement( return original; } - const updateNode = updateThenAttach(ForOfStatement.updateForOfStatement, attachModifiers); + const updateNode = updateThenAttach( + ForOfStatement.updateForOfStatement, + attachModifiers, + attachParent, + refreshNodeCache + ); return updateNode(original, left, right, body, isAwait); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ForUpdateStatement.ts b/koala-wrapper/src/arkts-api/node-utilities/ForUpdateStatement.ts index 0fa41007b56654e89af71ec85e5973361f2e4057..dc4538afee676d8732c5d1bf40df6b86ee399c92 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ForUpdateStatement.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ForUpdateStatement.ts @@ -16,7 +16,24 @@ import { ForUpdateStatement, Statement, Expression } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; import { AstNode } from '../peers/AstNode'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createForUpdateStatement( + init?: AstNode, + test?: Expression, + update?: Expression, + body?: Statement +): ForUpdateStatement { + const create = createThenAttach(ForUpdateStatement.createForUpdateStatement, attachUpdateToCreatedNode); + return create(init, test, update, body); +} export function updateForUpdateStatement( original: ForUpdateStatement, @@ -34,6 +51,11 @@ export function updateForUpdateStatement( return original; } - const updateNode = updateThenAttach(ForUpdateStatement.updateForUpdateStatement, attachModifiers); + const updateNode = updateThenAttach( + ForUpdateStatement.updateForUpdateStatement, + attachModifiers, + attachParent, + refreshNodeCache + ); return updateNode(original, init, test, update, body); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/FunctionDeclaration.ts b/koala-wrapper/src/arkts-api/node-utilities/FunctionDeclaration.ts index 7a579c288cb33763d1c6f47689f57fd6f4093df3..12871598adef9804d4645f31cde415adbbf9f430 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/FunctionDeclaration.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/FunctionDeclaration.ts @@ -16,7 +16,23 @@ import { AnnotationUsage, ScriptFunction } from '../../generated'; import { FunctionDeclaration } from '../types'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createFunctionDeclaration( + scriptFunction: ScriptFunction, + isAnon: boolean, + annotations?: AnnotationUsage[] +): FunctionDeclaration { + const create = createThenAttach(FunctionDeclaration.create, attachUpdateToCreatedNode); + return create(scriptFunction, isAnon, annotations); +} export function updateFunctionDeclaration( original: FunctionDeclaration, @@ -32,6 +48,6 @@ export function updateFunctionDeclaration( return original; } - const update = updateThenAttach(FunctionDeclaration.update, attachModifiers); + const update = updateThenAttach(FunctionDeclaration.update, attachModifiers, attachParent, refreshNodeCache); return update(original, scriptFunction, isAnon, annotations); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/FunctionExpression.ts b/koala-wrapper/src/arkts-api/node-utilities/FunctionExpression.ts index ba213580140feac8c5b73169a164599e5714c915..e35bb08c65acf60b870fa46a7b65ff6f129f654d 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/FunctionExpression.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/FunctionExpression.ts @@ -16,13 +16,25 @@ import { ScriptFunction } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; import { FunctionExpression } from '../types'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createFunctionExpression(expression: ScriptFunction): FunctionExpression { + const create = createThenAttach(FunctionExpression.create, attachUpdateToCreatedNode); + return create(expression); +} export function updateFunctionExpression(original: FunctionExpression, expression: ScriptFunction): FunctionExpression { if (isSameNativeObject(expression, original.scriptFunction)) { return original; } - const update = updateThenAttach(FunctionExpression.update, attachModifiers); + const update = updateThenAttach(FunctionExpression.update, attachModifiers, attachParent, refreshNodeCache); return update(original, expression); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/Identifier.ts b/koala-wrapper/src/arkts-api/node-utilities/Identifier.ts index 3a1fff7830dadc55cc20183e6d1f8eb83f1705d5..7485cc29ec5b037e9a10f77a2f31ed74f329fee5 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/Identifier.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/Identifier.ts @@ -15,18 +15,25 @@ import { Identifier, TypeNode } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { NodeCache } from '../utilities/nodeCache'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createIdentifier(name: string, typeAnnotation?: TypeNode): Identifier { + const create = createThenAttach(Identifier.create2Identifier, attachUpdateToCreatedNode); + return create(name, typeAnnotation); +} export function updateIdentifier(original: Identifier, name: string, typeAnnotation?: TypeNode): Identifier { if (isSameNativeObject(name, original.name) && isSameNativeObject(typeAnnotation, original.typeAnnotation)) { return original; } - const update = updateThenAttach(Identifier.update2Identifier, attachModifiers); - const newNode = update(original, name, typeAnnotation); - if (NodeCache.getInstance().has(original)) { - NodeCache.getInstance().refresh(original, newNode); - } - return newNode; + const update = updateThenAttach(Identifier.update2Identifier, attachModifiers, attachParent, refreshNodeCache); + return update(original, name, typeAnnotation); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/IfStatement.ts b/koala-wrapper/src/arkts-api/node-utilities/IfStatement.ts index 2e3e9275cf46b24ca9c1222562823fc704013b3b..f7634d01ef987597a25442ca9039868a58d2a661 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/IfStatement.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/IfStatement.ts @@ -16,7 +16,19 @@ import { isSameNativeObject } from '../peers/ArktsObject'; import { AstNode } from '../peers/AstNode'; import { IfStatement } from '../types'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createIfStatement(test: AstNode, consequent: AstNode, alternate?: AstNode): IfStatement { + const create = createThenAttach(IfStatement.create, attachUpdateToCreatedNode); + return create(test, consequent, alternate); +} export function updateIfStatement( original: IfStatement, @@ -32,6 +44,6 @@ export function updateIfStatement( return original; } - const update = updateThenAttach(IfStatement.update, attachModifiers); + const update = updateThenAttach(IfStatement.update, attachModifiers, attachParent, refreshNodeCache); return update(original, test, consequent, alternate); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ImportSpecifier.ts b/koala-wrapper/src/arkts-api/node-utilities/ImportSpecifier.ts index d09684550598bffed9b4440c2b98980ff3eff188..179651afd501269455c10165ebab408f9e99cd31 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ImportSpecifier.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ImportSpecifier.ts @@ -15,7 +15,12 @@ import { Identifier, ImportSpecifier } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { attachModifiers, attachParent, attachUpdateToCreatedNode, createThenAttach, refreshNodeCache, updateThenAttach } from '../utilities/private'; + +export function createImportSpecifier(imported?: Identifier, local?: Identifier): ImportSpecifier { + const create = createThenAttach(ImportSpecifier.createImportSpecifier, attachUpdateToCreatedNode); + return create(imported, local); +} export function updateImportSpecifier( original: ImportSpecifier, @@ -26,6 +31,11 @@ export function updateImportSpecifier( return original; } - const update = updateThenAttach(ImportSpecifier.updateImportSpecifier, attachModifiers); + const update = updateThenAttach( + ImportSpecifier.updateImportSpecifier, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, imported, local); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/MemberExpression.ts b/koala-wrapper/src/arkts-api/node-utilities/MemberExpression.ts index 960dacfafe52ba8ff500e0cbbc3741c392634cf1..fb41ea5279a591edf494ba57d9b8425ac294bef4 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/MemberExpression.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/MemberExpression.ts @@ -16,9 +16,27 @@ import { isSameNativeObject } from '../peers/ArktsObject'; import { AstNode } from '../peers/AstNode'; import { MemberExpression } from '../to-be-generated/MemberExpression'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; import { Es2pandaMemberExpressionKind } from '../../generated/Es2pandaEnums'; +export function createMemberExpression( + object: AstNode, + property: AstNode, + kind: Es2pandaMemberExpressionKind, + computed: boolean, + optional: boolean +): MemberExpression { + const create = createThenAttach(MemberExpression.create, attachUpdateToCreatedNode); + return create(object, property, kind, computed, optional); +} + export function updateMemberExpression( original: MemberExpression, object: AstNode, @@ -37,6 +55,6 @@ export function updateMemberExpression( return original; } - const update = updateThenAttach(MemberExpression.update, attachModifiers); + const update = updateThenAttach(MemberExpression.update, attachModifiers, attachParent, refreshNodeCache); return update(original, object, property, kind, computed, optional); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/MethodDefinition.ts b/koala-wrapper/src/arkts-api/node-utilities/MethodDefinition.ts index 6318a0c84fd2c28d360abd7169b37f8eaec4c74b..7133c76eec1fb970f4e7b92ae52ad3939de683b0 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/MethodDefinition.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/MethodDefinition.ts @@ -17,10 +17,26 @@ import { KInt } from '@koalaui/interop'; import { isSameNativeObject } from '../peers/ArktsObject'; import { AstNode } from '../peers/AstNode'; import { MethodDefinition } from '../types'; -import { updateThenAttach } from '../utilities/private'; +import { + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; import { Es2pandaMethodDefinitionKind } from '../../generated/Es2pandaEnums'; import { ScriptFunction } from '../../generated'; -import { NodeCache } from '../utilities/nodeCache'; + +export function createMethodDefinition( + kind: Es2pandaMethodDefinitionKind, + key: AstNode, + value: ScriptFunction, + modifiers: KInt, + isComputed: boolean +): MethodDefinition { + const create = createThenAttach(MethodDefinition.create, attachUpdateToCreatedNode); + return create(kind, key, value, modifiers, isComputed); +} export function updateMethodDefinition( original: MethodDefinition, @@ -40,12 +56,11 @@ export function updateMethodDefinition( return original; } - const update = updateThenAttach(MethodDefinition.update, (node: MethodDefinition, original: MethodDefinition) => - node.setOverloads(original.overloads) + const update = updateThenAttach( + MethodDefinition.update, + (node: MethodDefinition, original: MethodDefinition) => node.setOverloads(original.overloads), + attachParent, + refreshNodeCache ); - const newNode = update(original, kind, key, value, modifiers, isComputed); - if (NodeCache.getInstance().has(original)) { - NodeCache.getInstance().refresh(original, newNode); - } - return newNode; + return update(original, kind, key, value, modifiers, isComputed); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/NullLiteral.ts b/koala-wrapper/src/arkts-api/node-utilities/NullLiteral.ts index 9ab1bb363d79b7efc62b11a0d887ce93882e0ef9..8f3c09c43d95ebe6f8a1192ddbe63f8f91b69749 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/NullLiteral.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/NullLiteral.ts @@ -14,11 +14,16 @@ */ import { NullLiteral } from '../../generated'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { attachModifiers, attachParent, createThenAttach, refreshNodeCache, updateThenAttach } from '../utilities/private'; + +export function createNullLiteral(): NullLiteral { + const create = createThenAttach(NullLiteral.createNullLiteral); + return create(); +} export function updateNullLiteral(original: NullLiteral): NullLiteral { /* TODO: no getter provided yet */ - const update = updateThenAttach(NullLiteral.updateNullLiteral, attachModifiers); + const update = updateThenAttach(NullLiteral.updateNullLiteral, attachModifiers, attachParent, refreshNodeCache); return update(original); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/NumberLiteral.ts b/koala-wrapper/src/arkts-api/node-utilities/NumberLiteral.ts index 1dfab1450328ddc197de0dec52c1d0b3b5ab60f9..108522cbbf3fbd43c7b508ef74752172cd9687bd 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/NumberLiteral.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/NumberLiteral.ts @@ -15,7 +15,19 @@ import { NumberLiteral } from '../types'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, compose, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + compose, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createNumberLiteral(value: number): NumberLiteral { + const create = createThenAttach(NumberLiteral.create); + return create(value); +} export function updateNumberLiteral(original: NumberLiteral, value: number): NumberLiteral { if (isSameNativeObject(value, original.value)) { @@ -24,7 +36,9 @@ export function updateNumberLiteral(original: NumberLiteral, value: number): Num const update = updateThenAttach( compose(NumberLiteral.create), // TODO: No UpdateNumberLiteral, need to change this - attachModifiers + attachModifiers, + attachParent, + refreshNodeCache ); return update(original, value); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ObjectExpression.ts b/koala-wrapper/src/arkts-api/node-utilities/ObjectExpression.ts index ac7a9d6b6931757ebb551b30a9c01ff43062cec5..7eb967f6b36fa2edac8d7117977f423db04d413d 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ObjectExpression.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ObjectExpression.ts @@ -15,9 +15,25 @@ import { ObjectExpression, Property } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; import { Es2pandaAstNodeType } from '../../Es2pandaEnums'; +export function createObjectExpression( + nodeType: Es2pandaAstNodeType, + properties: Property[], + trailingComma: boolean +): ObjectExpression { + const create = createThenAttach(ObjectExpression.createObjectExpression, attachUpdateToCreatedNode); + return create(nodeType, properties, trailingComma); +} + export function updateObjectExpression( original: ObjectExpression, nodeType: Es2pandaAstNodeType, @@ -32,6 +48,11 @@ export function updateObjectExpression( return original; } - const update = updateThenAttach(ObjectExpression.updateObjectExpression, attachModifiers); + const update = updateThenAttach( + ObjectExpression.updateObjectExpression, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, nodeType, properties, trailingComma); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/Property.ts b/koala-wrapper/src/arkts-api/node-utilities/Property.ts index fdb1443c593831eb1158f28398b4ed6484af27e5..d24943fd30c6f646d81aa3e5bbda512277bcfe7d 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/Property.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/Property.ts @@ -15,19 +15,25 @@ import { Expression, Property } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { NodeCache } from '../utilities/nodeCache'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createProperty(key?: Expression, value?: Expression): Property { + const create = createThenAttach(Property.createProperty, attachUpdateToCreatedNode); + return create(key, value); +} export function updateProperty(original: Property, key?: Expression, value?: Expression): Property { if (isSameNativeObject(key, original.key) && isSameNativeObject(value, original.value)) { return original; } - const update = updateThenAttach(Property.updateProperty, attachModifiers); - const newNode = update(original, key, value); - if (NodeCache.getInstance().has(original)) { - NodeCache.getInstance().refresh(original, newNode); - } - return newNode; - + const update = updateThenAttach(Property.updateProperty, attachModifiers, attachParent, refreshNodeCache); + return update(original, key, value); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ReturnStatement.ts b/koala-wrapper/src/arkts-api/node-utilities/ReturnStatement.ts index 984e0aa5d9afb1218ef7d8c0d1377d290b9a33dd..5bcabbb73940841f68af36117525ddc7bb0840ba 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ReturnStatement.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ReturnStatement.ts @@ -15,18 +15,30 @@ import { Expression, ReturnStatement } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { NodeCache } from '../utilities/nodeCache'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createReturnStatement(argument?: Expression): ReturnStatement { + const create = createThenAttach(ReturnStatement.create1ReturnStatement, attachUpdateToCreatedNode); + return create(argument); +} export function updateReturnStatement(original: ReturnStatement, argument?: Expression): ReturnStatement { if (isSameNativeObject(argument, original.argument)) { return original; } - const update = updateThenAttach(ReturnStatement.update1ReturnStatement, attachModifiers); - const newNode = update(original, argument); - if (NodeCache.getInstance().has(original)) { - NodeCache.getInstance().refresh(original, newNode); - } - return newNode; + const update = updateThenAttach( + ReturnStatement.update1ReturnStatement, + attachModifiers, + attachParent, + refreshNodeCache + ); + return update(original, argument); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ScriptFunction.ts b/koala-wrapper/src/arkts-api/node-utilities/ScriptFunction.ts index 16e30342a1e529803fdfddd818e5fcd358eb05dc..142ed94dd27bee58e7366fe37eb9d7df9e3ea5df 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ScriptFunction.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ScriptFunction.ts @@ -16,8 +16,23 @@ import { FunctionSignature, ScriptFunction } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; import { AstNode } from '../peers/AstNode'; -import { NodeCache } from '../utilities/nodeCache'; -import { updateThenAttach } from '../utilities/private'; +import { + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createScriptFunction( + databody: AstNode | undefined, + datasignature: FunctionSignature | undefined, + datafuncFlags: number, + dataflags: number +): ScriptFunction { + const create = createThenAttach(ScriptFunction.createScriptFunction, attachUpdateToCreatedNode); + return create(databody, datasignature, datafuncFlags, dataflags); +} export function updateScriptFunction( original: ScriptFunction, @@ -41,11 +56,9 @@ export function updateScriptFunction( const update = updateThenAttach( ScriptFunction.updateScriptFunction, (node: ScriptFunction, original: ScriptFunction) => (!!original.id ? node.setIdent(original.id) : node), - (node: ScriptFunction, original: ScriptFunction) => node.setAnnotations(original.annotations) + (node: ScriptFunction, original: ScriptFunction) => node.setAnnotations(original.annotations), + attachParent, + refreshNodeCache ); - const newNode = update(original, databody, datasignature, datafuncFlags, dataflags); - if (NodeCache.getInstance().has(original)) { - NodeCache.getInstance().refresh(original, newNode); - } - return newNode; + return update(original, databody, datasignature, datafuncFlags, dataflags); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/SpreadElement.ts b/koala-wrapper/src/arkts-api/node-utilities/SpreadElement.ts index f8e24176deed5b2fda83d523f7a434a7bebe2b0d..226c643b95d1147ecd4acb4acdc54bbb05a63107 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/SpreadElement.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/SpreadElement.ts @@ -15,10 +15,22 @@ import { Expression, SpreadElement } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; import { Es2pandaAstNodeType } from '../../Es2pandaEnums'; import { global } from '../static/global'; +export function createSpreadElement(nodeType: Es2pandaAstNodeType, argument?: Expression): SpreadElement { + const create = createThenAttach(SpreadElement.createSpreadElement, attachUpdateToCreatedNode); + return create(nodeType, argument); +} + export function updateSpreadElement( original: SpreadElement, nodeType: Es2pandaAstNodeType, @@ -29,6 +41,6 @@ export function updateSpreadElement( return original; } - const update = updateThenAttach(SpreadElement.updateSpreadElement, attachModifiers); + const update = updateThenAttach(SpreadElement.updateSpreadElement, attachModifiers, attachParent, refreshNodeCache); return update(original, nodeType, argument); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/StringLiteral.ts b/koala-wrapper/src/arkts-api/node-utilities/StringLiteral.ts index 53f330d429dcd102d3bd982721263f47e2cf324c..f2822e32085e0e116be35deab61d41ecbbc11d00 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/StringLiteral.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/StringLiteral.ts @@ -15,13 +15,23 @@ import { StringLiteral } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { attachModifiers, attachParent, createThenAttach, refreshNodeCache, updateThenAttach } from '../utilities/private'; + +export function createStringLiteral(str: string): StringLiteral { + const create = createThenAttach(StringLiteral.create1StringLiteral); + return create(str); +} export function updateStringLiteral(original: StringLiteral, str: string): StringLiteral { if (isSameNativeObject(str, original.str)) { return original; } - const update = updateThenAttach(StringLiteral.update1StringLiteral, attachModifiers); + const update = updateThenAttach( + StringLiteral.update1StringLiteral, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, str); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/StructDeclaration.ts b/koala-wrapper/src/arkts-api/node-utilities/StructDeclaration.ts index ee57547d244102466d0b257b38b1064bcb226772..c601af84b1899c05f946416c8591b2359378d37c 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/StructDeclaration.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/StructDeclaration.ts @@ -16,13 +16,24 @@ import { ClassDefinition } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; import { StructDeclaration } from '../types'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createStructDeclaration(definition: ClassDefinition): StructDeclaration { + const create = createThenAttach(StructDeclaration.create); + return create(definition); +} export function updateStructDeclaration(original: StructDeclaration, definition: ClassDefinition): StructDeclaration { if (isSameNativeObject(definition, original.definition)) { return original; } - const update = updateThenAttach(StructDeclaration.update, attachModifiers); + const update = updateThenAttach(StructDeclaration.update, attachModifiers, attachParent, refreshNodeCache); return update(original, definition); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/SuperExpression.ts b/koala-wrapper/src/arkts-api/node-utilities/SuperExpression.ts index d1bee071b81d28a585f306821c9b27551693b464..0e9e9883c3bb9d0a14a158e79310f5d04c3d0ea6 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/SuperExpression.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/SuperExpression.ts @@ -14,11 +14,27 @@ */ import { SuperExpression } from '../../generated'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createSuperExpression(): SuperExpression { + const create = createThenAttach(SuperExpression.createSuperExpression); + return create(); +} export function updateSuperExpression(original: SuperExpression): SuperExpression { /* TODO: no getter provided yet */ - const update = updateThenAttach(SuperExpression.updateSuperExpression, attachModifiers); + const update = updateThenAttach( + SuperExpression.updateSuperExpression, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/SwitchCaseStatement.ts b/koala-wrapper/src/arkts-api/node-utilities/SwitchCaseStatement.ts index 4e3e528ef59f0824c4794dd26d1953a69d148eb8..09324ffa963f6b7ec38f7299b407dbd1b972b6c8 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/SwitchCaseStatement.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/SwitchCaseStatement.ts @@ -15,7 +15,22 @@ import { Expression, Statement, SwitchCaseStatement } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createSwitchCaseStatement( + test: Expression | undefined, + consequent: readonly Statement[] +): SwitchCaseStatement { + const create = createThenAttach(SwitchCaseStatement.createSwitchCaseStatement, attachUpdateToCreatedNode); + return create(test, consequent); +} export function updateSwitchCaseStatement( original: SwitchCaseStatement, @@ -26,6 +41,11 @@ export function updateSwitchCaseStatement( return original; } - const update = updateThenAttach(SwitchCaseStatement.updateSwitchCaseStatement, attachModifiers); + const update = updateThenAttach( + SwitchCaseStatement.updateSwitchCaseStatement, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, test, consequent); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/SwitchStatement.ts b/koala-wrapper/src/arkts-api/node-utilities/SwitchStatement.ts index cf601ee8a50322f616f78d99072fa2a76ef9ffe7..2e75979d329473fc78d76c13f2ac1b4c65bb7e8e 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/SwitchStatement.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/SwitchStatement.ts @@ -15,7 +15,22 @@ import { Expression, SwitchCaseStatement, SwitchStatement } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createSwitchStatement( + discriminant: Expression | undefined, + cases: readonly SwitchCaseStatement[] +): SwitchStatement { + const create = createThenAttach(SwitchStatement.createSwitchStatement, attachUpdateToCreatedNode); + return create(discriminant, cases); +} export function updateSwitchStatement( original: SwitchStatement, @@ -26,6 +41,11 @@ export function updateSwitchStatement( return original; } - const update = updateThenAttach(SwitchStatement.updateSwitchStatement, attachModifiers); + const update = updateThenAttach( + SwitchStatement.updateSwitchStatement, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, discriminant, cases); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/TSAsExpression.ts b/koala-wrapper/src/arkts-api/node-utilities/TSAsExpression.ts index f82b8afc1224972eb39a3115c4a5f27020f58fba..cddbe99cc07fc5b070b9e31efc3e1312e8ff73c2 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/TSAsExpression.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/TSAsExpression.ts @@ -15,7 +15,23 @@ import { Expression, TSAsExpression, TypeNode } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createTSAsExpression( + expression: Expression | undefined, + typeAnnotation: TypeNode | undefined, + isConst: boolean +): TSAsExpression { + const create = createThenAttach(TSAsExpression.createTSAsExpression, attachUpdateToCreatedNode); + return create(expression, typeAnnotation, isConst); +} export function updateTSAsExpression( original: TSAsExpression, @@ -31,6 +47,11 @@ export function updateTSAsExpression( return original; } - const update = updateThenAttach(TSAsExpression.updateTSAsExpression, attachModifiers); + const update = updateThenAttach( + TSAsExpression.updateTSAsExpression, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, expression, typeAnnotation, isConst); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/TSClassImplements.ts b/koala-wrapper/src/arkts-api/node-utilities/TSClassImplements.ts index 1e51e9c444240d1f69dc6a327219d4d9e454f800..cccccb9804c219522e20e3e569efceddd5564ae6 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/TSClassImplements.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/TSClassImplements.ts @@ -15,7 +15,22 @@ import { Expression, TSClassImplements, TSTypeParameterInstantiation } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createTSClassImplements( + expression?: Expression, + typeParameters?: TSTypeParameterInstantiation +): TSClassImplements { + const create = createThenAttach(TSClassImplements.createTSClassImplements, attachUpdateToCreatedNode); + return create(expression, typeParameters); +} export function updateTSClassImplements( original: TSClassImplements, @@ -26,6 +41,11 @@ export function updateTSClassImplements( return original; } - const update = updateThenAttach(TSClassImplements.updateTSClassImplements, attachModifiers); + const update = updateThenAttach( + TSClassImplements.updateTSClassImplements, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, expression, typeParameters); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/TSInterfaceBody.ts b/koala-wrapper/src/arkts-api/node-utilities/TSInterfaceBody.ts index a1a6350f70b985b7bf40c2155f950959b1223130..f30c465141f343d8c12c80ac1f8fd6a4fd9acae0 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/TSInterfaceBody.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/TSInterfaceBody.ts @@ -16,13 +16,30 @@ import { TSInterfaceBody } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; import { AstNode } from '../peers/AstNode'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createTSInterfaceBody(body: readonly AstNode[]): TSInterfaceBody { + const create = createThenAttach(TSInterfaceBody.createTSInterfaceBody, attachUpdateToCreatedNode); + return create(body); +} export function updateTSInterfaceBody(original: TSInterfaceBody, body: readonly AstNode[]): TSInterfaceBody { if (isSameNativeObject(body, original.body)) { return original; } - const update = updateThenAttach(TSInterfaceBody.updateTSInterfaceBody, attachModifiers); + const update = updateThenAttach( + TSInterfaceBody.updateTSInterfaceBody, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, body); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/TSInterfaceDeclaration.ts b/koala-wrapper/src/arkts-api/node-utilities/TSInterfaceDeclaration.ts index 1d607b245d1ccb579317895894b35dafe5562bcd..8feee833c7ceca1fba9f56615bc34c124e21e8c9 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/TSInterfaceDeclaration.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/TSInterfaceDeclaration.ts @@ -16,7 +16,26 @@ import { TSInterfaceDeclaration, TSInterfaceHeritage } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; import { AstNode } from '../peers/AstNode'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createTSInterfaceDeclaration( + _extends: readonly TSInterfaceHeritage[], + id: AstNode | undefined, + typeParams: AstNode | undefined, + body: AstNode | undefined, + isStatic: boolean, + isExternal: boolean +): TSInterfaceDeclaration { + const create = createThenAttach(TSInterfaceDeclaration.createTSInterfaceDeclaration, attachUpdateToCreatedNode); + return create(_extends, id, typeParams, body, isStatic, isExternal); +} export function updateTSInterfaceDeclaration( original: TSInterfaceDeclaration, @@ -41,7 +60,9 @@ export function updateTSInterfaceDeclaration( const update = updateThenAttach( TSInterfaceDeclaration.updateTSInterfaceDeclaration, attachModifiers, - (node: TSInterfaceDeclaration, original: TSInterfaceDeclaration) => node.setAnnotations(original.annotations) + (node: TSInterfaceDeclaration, original: TSInterfaceDeclaration) => node.setAnnotations(original.annotations), + attachParent, + refreshNodeCache ); return update(original, _extends, id, typeParams, body, isStatic, isExternal); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/TSNonNullExpression.ts b/koala-wrapper/src/arkts-api/node-utilities/TSNonNullExpression.ts index d387e39f98c60b113453111e809d89bb7b1fffba..507c01ae54a32d854d54d57afa4406010737e523 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/TSNonNullExpression.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/TSNonNullExpression.ts @@ -15,13 +15,30 @@ import { Expression, TSNonNullExpression } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createTSNonNullExpression(expr?: Expression): TSNonNullExpression { + const create = createThenAttach(TSNonNullExpression.createTSNonNullExpression, attachUpdateToCreatedNode); + return create(expr); +} export function updateTSNonNullExpression(original: TSNonNullExpression, expr?: Expression): TSNonNullExpression { if (isSameNativeObject(expr, original.expr)) { return original; } - const update = updateThenAttach(TSNonNullExpression.updateTSNonNullExpression, attachModifiers); + const update = updateThenAttach( + TSNonNullExpression.updateTSNonNullExpression, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, expr); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/TSTypeAliasDeclaration.ts b/koala-wrapper/src/arkts-api/node-utilities/TSTypeAliasDeclaration.ts index a1d47e0e145ef76deb0721db001f0ebc96965870..86d46d36d70a38d826ba1b2b18e5ff3e470cf1c5 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/TSTypeAliasDeclaration.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/TSTypeAliasDeclaration.ts @@ -15,8 +15,23 @@ import { Identifier, TSTypeAliasDeclaration, TSTypeParameterDeclaration, TypeNode } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { NodeCache } from '../utilities/nodeCache'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createTSTypeAliasDeclaration( + id?: Identifier, + typeParams?: TSTypeParameterDeclaration, + typeAnnotation?: TypeNode +): TSTypeAliasDeclaration { + const create = createThenAttach(TSTypeAliasDeclaration.createTSTypeAliasDeclaration, attachUpdateToCreatedNode); + return create(id, typeParams, typeAnnotation); +} export function updateTSTypeAliasDeclaration( original: TSTypeAliasDeclaration, @@ -35,11 +50,9 @@ export function updateTSTypeAliasDeclaration( const update = updateThenAttach( TSTypeAliasDeclaration.updateTSTypeAliasDeclaration, attachModifiers, - (node: TSTypeAliasDeclaration, original: TSTypeAliasDeclaration) => node.setAnnotations(original.annotations) + (node: TSTypeAliasDeclaration, original: TSTypeAliasDeclaration) => node.setAnnotations(original.annotations), + attachParent, + refreshNodeCache ); - const newNode = update(original, id, typeParams, typeAnnotation); - if (NodeCache.getInstance().has(original)) { - NodeCache.getInstance().refresh(original, newNode); - } - return newNode; + return update(original, id, typeParams, typeAnnotation); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/TSTypeParameter.ts b/koala-wrapper/src/arkts-api/node-utilities/TSTypeParameter.ts index 9a5ac75d53b5163c779505bf1f5ac088c52289cb..fad4e8c7076db58cf123ff1f3ece5b872a4be187 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/TSTypeParameter.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/TSTypeParameter.ts @@ -15,7 +15,23 @@ import { Identifier, TSTypeParameter, TypeNode } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createTSTypeParameter( + name?: Identifier, + constraint?: TypeNode, + defaultType?: TypeNode +): TSTypeParameter { + const create = createThenAttach(TSTypeParameter.createTSTypeParameter, attachUpdateToCreatedNode); + return create(name, constraint, defaultType); +} export function updateTSTypeParameter( original: TSTypeParameter, @@ -31,6 +47,11 @@ export function updateTSTypeParameter( return original; } - const update = updateThenAttach(TSTypeParameter.updateTSTypeParameter, attachModifiers); + const update = updateThenAttach( + TSTypeParameter.updateTSTypeParameter, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, name, constraint, defaultType); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/TSTypeParameterDeclaration.ts b/koala-wrapper/src/arkts-api/node-utilities/TSTypeParameterDeclaration.ts index 3f1395049de403a21b2c870a07ab47123c84df77..ea614202496448959bc5c55c758709125c10a34f 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/TSTypeParameterDeclaration.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/TSTypeParameterDeclaration.ts @@ -15,7 +15,25 @@ import { TSTypeParameter, TSTypeParameterDeclaration } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createTSTypeParameterDeclaration( + params: readonly TSTypeParameter[], + requiredParams: number +): TSTypeParameterDeclaration { + const create = createThenAttach( + TSTypeParameterDeclaration.createTSTypeParameterDeclaration, + attachUpdateToCreatedNode + ); + return create(params, requiredParams); +} export function updateTSTypeParameterDeclaration( original: TSTypeParameterDeclaration, @@ -26,6 +44,11 @@ export function updateTSTypeParameterDeclaration( return original; } - const update = updateThenAttach(TSTypeParameterDeclaration.updateTSTypeParameterDeclaration, attachModifiers); + const update = updateThenAttach( + TSTypeParameterDeclaration.updateTSTypeParameterDeclaration, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, params, requiredParams); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/TSTypeParameterInstantiation.ts b/koala-wrapper/src/arkts-api/node-utilities/TSTypeParameterInstantiation.ts index 49d8746e4838f341d55b0daf0e533e3ff0bdd4ca..41ea95b427dbed41853d32963a99017300d8b82a 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/TSTypeParameterInstantiation.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/TSTypeParameterInstantiation.ts @@ -15,7 +15,22 @@ import { TSTypeParameterInstantiation, TypeNode } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createTSTypeParameterInstantiation(params: readonly TypeNode[]): TSTypeParameterInstantiation { + const create = createThenAttach( + TSTypeParameterInstantiation.createTSTypeParameterInstantiation, + attachUpdateToCreatedNode + ); + return create(params); +} export function updateTSTypeParameterInstantiation( original: TSTypeParameterInstantiation, @@ -25,6 +40,11 @@ export function updateTSTypeParameterInstantiation( return original; } - const update = updateThenAttach(TSTypeParameterInstantiation.updateTSTypeParameterInstantiation, attachModifiers); + const update = updateThenAttach( + TSTypeParameterInstantiation.updateTSTypeParameterInstantiation, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, params); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/TemplateLiteral.ts b/koala-wrapper/src/arkts-api/node-utilities/TemplateLiteral.ts index 840c0d12040a13f3a2c4e3704f4e0ca3fb7d68aa..32bacec1d8d1eff444deaf9bb0259c07575cd924 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/TemplateLiteral.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/TemplateLiteral.ts @@ -15,7 +15,23 @@ import { TemplateLiteral, TemplateElement, Expression } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createTemplateLiteral( + quasis: readonly TemplateElement[], + expressions: readonly Expression[], + multilineString: string +): TemplateLiteral { + const create = createThenAttach(TemplateLiteral.createTemplateLiteral, attachUpdateToCreatedNode); + return create(quasis, expressions, multilineString); +} export function updateTemplateLiteral( original: TemplateLiteral, @@ -23,13 +39,15 @@ export function updateTemplateLiteral( expressions: readonly Expression[], multilineString: string ): TemplateLiteral { - if ( - isSameNativeObject(quasis, original.quasis) && - isSameNativeObject(expressions, original.expressions) - ) { + if (isSameNativeObject(quasis, original.quasis) && isSameNativeObject(expressions, original.expressions)) { return original; } - const update = updateThenAttach(TemplateLiteral.updateTemplateLiteral, attachModifiers); + const update = updateThenAttach( + TemplateLiteral.updateTemplateLiteral, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original, quasis, expressions, multilineString); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/ThisExpression.ts b/koala-wrapper/src/arkts-api/node-utilities/ThisExpression.ts index f2f04c716fccf5b5124f85cb4a9a54ec0d1d751a..301564ed3f5a8b4a2b0dd7a7ef688c5e359f4f60 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/ThisExpression.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/ThisExpression.ts @@ -14,11 +14,27 @@ */ import { ThisExpression } from '../../generated'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createThisExpression(): ThisExpression { + const create = createThenAttach(ThisExpression.createThisExpression); + return create(); +} export function updateThisExpression(original: ThisExpression): ThisExpression { /* TODO: no getter provided yet */ - const update = updateThenAttach(ThisExpression.updateThisExpression, attachModifiers); + const update = updateThenAttach( + ThisExpression.updateThisExpression, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/TryStatement.ts b/koala-wrapper/src/arkts-api/node-utilities/TryStatement.ts index 32512066cbba85065a851c78200a77277bd0cd75..b75b3a879910ba4ccf2e6f23fe987301f7725e31 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/TryStatement.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/TryStatement.ts @@ -16,7 +16,25 @@ import { LabelPair } from '../../generated/peers/LabelPair'; import { BlockStatement, CatchClause, Statement, TryStatement } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createTryStatement( + block: BlockStatement | undefined, + catchClauses: readonly CatchClause[], + finalizer: BlockStatement | undefined, + finalizerInsertionsLabelPair: readonly LabelPair[], + finalizerInsertionsStatement: readonly Statement[] +): TryStatement { + const create = createThenAttach(TryStatement.createTryStatement, attachUpdateToCreatedNode); + return create(block, catchClauses, finalizer, finalizerInsertionsLabelPair, finalizerInsertionsStatement); +} export function updateTryStatement( original: TryStatement, @@ -36,6 +54,6 @@ export function updateTryStatement( return original; } - const update = updateThenAttach(TryStatement.updateTryStatement, attachModifiers); + const update = updateThenAttach(TryStatement.updateTryStatement, attachModifiers, attachParent, refreshNodeCache); return update(original, block, catchClauses, finalizer, finalizerInsertionsLabelPair, finalizerInsertionsStatement); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/UndefinedLiteral.ts b/koala-wrapper/src/arkts-api/node-utilities/UndefinedLiteral.ts index aaedc726cc1d7a0992dae75cf83029da8887675f..4b56caa36f611f04d12553241932541e26f39220 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/UndefinedLiteral.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/UndefinedLiteral.ts @@ -14,11 +14,27 @@ */ import { UndefinedLiteral } from '../../generated'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; + +export function createUndefinedLiteral(): UndefinedLiteral { + const create = createThenAttach(UndefinedLiteral.createUndefinedLiteral); + return create(); +} export function updateUndefinedLiteral(original: UndefinedLiteral): UndefinedLiteral { /* TODO: no getter provided yet */ - const update = updateThenAttach(UndefinedLiteral.updateUndefinedLiteral, attachModifiers); + const update = updateThenAttach( + UndefinedLiteral.updateUndefinedLiteral, + attachModifiers, + attachParent, + refreshNodeCache + ); return update(original); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/VariableDeclaration.ts b/koala-wrapper/src/arkts-api/node-utilities/VariableDeclaration.ts index 0bd18e52d7ff919ae0ae03bf7f8a5dc27df7ce18..b9d982859da428ddc498432ecb99fb324a168070 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/VariableDeclaration.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/VariableDeclaration.ts @@ -16,9 +16,25 @@ import { KInt } from '@koalaui/interop'; import { isSameNativeObject } from '../peers/ArktsObject'; import { VariableDeclaration, VariableDeclarator } from '../types'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; import { Es2pandaVariableDeclarationKind } from '../../generated/Es2pandaEnums'; +export function createVariableDeclaration( + modifiers: KInt, + kind: Es2pandaVariableDeclarationKind, + declarators: readonly VariableDeclarator[] +): VariableDeclaration { + const create = createThenAttach(VariableDeclaration.create, attachUpdateToCreatedNode); + return create(modifiers, kind, declarators); +} + export function updateVariableDeclaration( original: VariableDeclaration, modifiers: KInt, @@ -36,7 +52,9 @@ export function updateVariableDeclaration( const update = updateThenAttach( VariableDeclaration.update, attachModifiers, - (node: VariableDeclaration, original: VariableDeclaration) => node.setAnnotations(original.annotations) + (node: VariableDeclaration, original: VariableDeclaration) => node.setAnnotations(original.annotations), + attachParent, + refreshNodeCache ); return update(original, modifiers, kind, declarators); } diff --git a/koala-wrapper/src/arkts-api/node-utilities/VariableDeclarator.ts b/koala-wrapper/src/arkts-api/node-utilities/VariableDeclarator.ts index 1f1739da249207a9650952e08f4d741ae977dafd..b975782e5356913ae75f84d36da4b1397cf77031 100644 --- a/koala-wrapper/src/arkts-api/node-utilities/VariableDeclarator.ts +++ b/koala-wrapper/src/arkts-api/node-utilities/VariableDeclarator.ts @@ -16,10 +16,25 @@ import { Identifier } from '../../generated'; import { isSameNativeObject } from '../peers/ArktsObject'; import { VariableDeclarator } from '../types'; -import { attachModifiers, updateThenAttach } from '../utilities/private'; +import { + attachModifiers, + attachParent, + attachUpdateToCreatedNode, + createThenAttach, + refreshNodeCache, + updateThenAttach, +} from '../utilities/private'; import { Es2pandaVariableDeclaratorFlag } from '../../generated/Es2pandaEnums'; import { AstNode } from '../peers/AstNode'; -import { NodeCache } from '../utilities/nodeCache'; + +export function createVariableDeclarator( + flag: Es2pandaVariableDeclaratorFlag, + name: Identifier, + initializer: AstNode | undefined +): VariableDeclarator { + const create = createThenAttach(VariableDeclarator.create, attachUpdateToCreatedNode); + return create(flag, name, initializer); +} export function updateVariableDeclarator( original: VariableDeclarator, @@ -35,10 +50,6 @@ export function updateVariableDeclarator( return original; } - const update = updateThenAttach(VariableDeclarator.update, attachModifiers); - const newNode = update(original, flag, name, initializer); - if (NodeCache.getInstance().has(original)) { - NodeCache.getInstance().refresh(original, newNode); - } - return newNode; + const update = updateThenAttach(VariableDeclarator.update, attachModifiers, attachParent, refreshNodeCache); + return update(original, flag, name, initializer); } diff --git a/koala-wrapper/src/arkts-api/peers/AstNode.ts b/koala-wrapper/src/arkts-api/peers/AstNode.ts index 6d49f5da998e17e29a875d811c038959fc96cb90..2b0294f387e6b6891fe5ed0d8977e585b86f78ae 100644 --- a/koala-wrapper/src/arkts-api/peers/AstNode.ts +++ b/koala-wrapper/src/arkts-api/peers/AstNode.ts @@ -20,6 +20,8 @@ import { throwError } from '../../utils'; import { Es2pandaModifierFlags } from '../../generated/Es2pandaEnums'; import { ArktsObject } from './ArktsObject'; import { SourcePosition } from './SourcePosition'; +import { nodeByType } from '../node-by-type'; +import { Es2pandaAstNodeType } from '../../Es2pandaEnums'; export abstract class AstNode extends ArktsObject { protected constructor(peer: KNativePointer) { @@ -103,6 +105,28 @@ export abstract class AstNode extends ArktsObject { return clonedNode as this; } + public findNodeInInnerChild(node: AstNode): boolean { + return global.es2panda._AstNodeFindNodeInInnerChild(global.context, this.peer, node.peer); + } + + public findInnerChild(nodeType: Es2pandaAstNodeType): T | undefined { + const childNodePeer = global.es2panda._AstNodeFindInnerChild(global.context, this.peer, nodeType); + if (childNodePeer === nullptr) { + return undefined; + } + const Node = nodeByType.get(nodeType) ?? UnsupportedNode; + return new Node(childNodePeer) as T; + } + + public findOuterParent(nodeType: Es2pandaAstNodeType): T | undefined { + const parentNodePeer = global.es2panda._AstNodeFindOuterParent(global.context, this.peer, nodeType); + if (parentNodePeer === nullptr) { + return undefined; + } + const Node = nodeByType.get(nodeType) ?? UnsupportedNode; + return new Node(parentNodePeer) as T; + } + public get parent(): AstNode | undefined { const parent = global.generatedEs2panda._AstNodeParent(global.context, this.peer); return unpackNode(parent); diff --git a/koala-wrapper/src/arkts-api/static/globalUtils.ts b/koala-wrapper/src/arkts-api/static/globalUtils.ts index 8e3a91074a38775262fbb0523b9afad98482083d..29a9123ab42a95c933691f5b6bf94186510bf7e0 100644 --- a/koala-wrapper/src/arkts-api/static/globalUtils.ts +++ b/koala-wrapper/src/arkts-api/static/globalUtils.ts @@ -16,7 +16,7 @@ import { KNativePointer } from "@koalaui/interop"; import { Context } from "../peers/Context"; import { global } from "./global"; -import { clearNodeCache } from "../class-by-peer"; +import { clearNodeCache } from "../node-by-type"; export function getOrUpdateGlobalContext(peer: KNativePointer): Context { if (!global.compilerContext || global.context !== peer) { diff --git a/koala-wrapper/src/arkts-api/types.ts b/koala-wrapper/src/arkts-api/types.ts index 640493db9230ac2589f35e80dd0dbdf4c1154d24..5d1474e339895a7939a0f3d65408b26b4b0d834b 100644 --- a/koala-wrapper/src/arkts-api/types.ts +++ b/koala-wrapper/src/arkts-api/types.ts @@ -36,14 +36,12 @@ import { unpackString, updatePeerByNode, } from './utilities/private'; -import { proceedToState } from './utilities/public'; +import { proceedToState, setAllParents } from './utilities/public'; import { Es2pandaAstNodeType } from '../Es2pandaEnums'; import { AstNode } from './peers/AstNode'; -import { ArktsObject } from './peers/ArktsObject'; import { Config } from './peers/Config'; import { Context } from './peers/Context'; -import * as path from 'node:path'; -import { nodeByType } from './class-by-peer'; +import { nodeByType } from './node-by-type'; import { MemberExpression } from './to-be-generated/MemberExpression'; import { AnnotationUsage, @@ -64,6 +62,7 @@ import { TSTypeParameterInstantiation, TypeNode, } from '../generated'; +import { createFunctionExpression, updateFunctionExpression } from './node-utilities/FunctionExpression'; export class EtsScript extends AstNode { constructor(peer: KPtr) { @@ -706,7 +705,7 @@ export class MethodDefinition extends AstNode { global.context, kind, passNode(key), - passNode(FunctionExpression.create(value)), + passNode(createFunctionExpression(value)), modifiers, isComputed ), @@ -728,7 +727,7 @@ export class MethodDefinition extends AstNode { node.peer, kind, passNode(key), - passNode(FunctionExpression.update(node.funcExpr, value)), + passNode(updateFunctionExpression(node.funcExpr, value)), modifiers, isComputed ), diff --git a/koala-wrapper/src/arkts-api/utilities/nodeCache.ts b/koala-wrapper/src/arkts-api/utilities/nodeCache.ts index 046b515367307e4585a72fb2355c588cdcd08b04..9919e0623d77e87a3726a8f4d390db6736a780d4 100644 --- a/koala-wrapper/src/arkts-api/utilities/nodeCache.ts +++ b/koala-wrapper/src/arkts-api/utilities/nodeCache.ts @@ -17,7 +17,7 @@ import { KNativePointer } from '@koalaui/interop'; import { Es2pandaAstNodeType } from '../../Es2pandaEnums'; import { AstNode, UnsupportedNode } from '../peers/AstNode'; import { global } from '../static/global'; -import { getOrPut, nodeByType } from '../class-by-peer'; +import { getOrPut, nodeByType } from '../node-by-type'; export interface AstNodeCacheValue { peer: KNativePointer; @@ -25,35 +25,42 @@ export interface AstNodeCacheValue { metadata?: AstNodeCacheValueMetadata; } -export interface AstNodeCacheValueMetadata { - callName?: string; - hasReceiver?: boolean; - isSetter?: boolean; - isGetter?: boolean; - forbidTypeRewrite?: boolean; - isWithinTypeParams?: boolean; - hasMemoSkip?: boolean; - hasMemoIntrinsic?: boolean; - hasMemoEntry?: boolean; +export type AstNodeCacheValueMetadata = { + [key in string]?: any; } export class NodeCache { private _isCollected: boolean = false; private cacheMap: Map; - private static instance: NodeCache; + private nodesToUpdate: Set; - private constructor() { + constructor() { this.cacheMap = new Map(); + this.nodesToUpdate = new Set(); } - static getInstance(): NodeCache { - if (!this.instance) { - this.instance = new NodeCache(); - } - return this.instance; + collect(node: AstNode, metadata?: AstNodeCacheValueMetadata): void { + this._collectNodesToUpdate(node, node.parent); + this._collect(node, metadata); } - collect(node: AstNode, metadata?: AstNodeCacheValueMetadata): void { + shouldUpdate(node: AstNode): boolean { + return this.nodesToUpdate.has(node.peer); + } + + shouldUpdateByPeer(peer: KNativePointer): boolean { + return this.nodesToUpdate.has(peer); + } + + addNodeToUpdate(node: AstNode): void { + this.nodesToUpdate.add(node.peer); + } + + addNodeToUpdateByPeer(peer: KNativePointer): void { + this.nodesToUpdate.add(peer); + } + + private _collect(node: AstNode, metadata?: AstNodeCacheValueMetadata): void { const peer = node.peer; const type = global.generatedEs2panda._AstNodeTypeConst(global.context, node.peer); let currMetadata: AstNodeCacheValueMetadata | undefined = metadata ?? {}; @@ -66,6 +73,15 @@ export class NodeCache { this._isCollected = true; } + private _collectNodesToUpdate(node: AstNode, parent?: AstNode): void { + this.nodesToUpdate.add(node.peer); + let currParent: AstNode | undefined = parent; + while (!!currParent && !this.nodesToUpdate.has(currParent.peer)) { + this.nodesToUpdate.add(currParent.peer); + currParent = currParent.parent; + } + } + refresh(original: AstNode, node: AstNode): void { let metadata: AstNodeCacheValueMetadata | undefined; if (this.has(original)) { @@ -75,6 +91,13 @@ export class NodeCache { this.collect(node, metadata); } + refreshUpdate(original: AstNode, node: AstNode): void { + if (this.shouldUpdate(original)) { + this.nodesToUpdate.delete(original.peer); + } + this._collectNodesToUpdate(node, original.parent); + } + isCollected(): boolean { return this._isCollected; } @@ -96,10 +119,69 @@ export class NodeCache { Array.from(this.cacheMap.values()).forEach(({ peer, type, metadata }) => { const node = nodeByType.get(type) ?? UnsupportedNode; const newNode = getOrPut(peer, (peer) => new node(peer)) as AstNode; + const shouldUpdate = this.nodesToUpdate.has(peer); console.log( - `[NODE CACHE] ptr ${peer}, type: ${type}, metadata: ${JSON.stringify(metadata)}, node: `, + `[NODE CACHE] ptr ${peer}, type: ${type}, shouldUpdate: ${shouldUpdate}, metadata: ${JSON.stringify(metadata)}, node: `, newNode.dumpSrc() ); }); } } + +export class NodeCacheFactory { + private cacheMap: Map; + private static instance: NodeCacheFactory; + + private constructor() { + this.cacheMap = new Map(); + } + + static getInstance(): NodeCacheFactory { + if (!this.instance) { + this.instance = new NodeCacheFactory(); + } + return this.instance; + } + + getCacheMap(): Map { + return this.cacheMap; + } + + getCache(key: string): NodeCache { + if (!this.cacheMap.has(key)) { + this.cacheMap.set(key, new NodeCache()); + } + return this.cacheMap.get(key)!; + } + + clear(): void { + this.cacheMap.forEach((cache) => { + cache.clear(); + }); + this.cacheMap = new Map(); + } + + has(node: AstNode): boolean { + return Array.from(this.cacheMap.values()).some((cache) => cache.has(node)); + } + + shouldUpdate(node: AstNode): boolean { + return Array.from(this.cacheMap.values()).some((cache) => cache.shouldUpdate(node)); + } + + refresh(original: AstNode, node: AstNode): void { + this.cacheMap.forEach((cache) => { + if (cache.has(original)) { + cache.refresh(original, node); + } + }); + } + + refreshUpdate(original: AstNode, node: AstNode): void { + this.cacheMap.forEach((cache) => { + if (cache.shouldUpdate(original)) { + cache.refreshUpdate(original, node); + } + }); + } +} \ No newline at end of file diff --git a/koala-wrapper/src/arkts-api/utilities/private.ts b/koala-wrapper/src/arkts-api/utilities/private.ts index c343fb8e26c9bdd17782f2cc01ab267d10948ee0..f074919169b67aa3798a54eed549a510d1780281 100644 --- a/koala-wrapper/src/arkts-api/utilities/private.ts +++ b/koala-wrapper/src/arkts-api/utilities/private.ts @@ -30,6 +30,7 @@ import { classByPeer } from '../class-by-peer'; import type { AstNode } from '../peers/AstNode'; import { ArktsObject } from '../peers/ArktsObject'; import { Es2pandaAstNodeType } from '../../Es2pandaEnums'; +import { NodeCacheFactory } from './nodeCache'; export const arrayOfNullptr = new BigUint64Array([nullptr]); @@ -191,7 +192,45 @@ export function updateThenAttach( }; } +export function createThenAttach( + create: (...args: ARGS) => T, + ...attachFuncs: ((node: T) => T)[] +): (...args: ARGS) => T { + return (...args: ARGS) => { + let _node: T = create(...args); + attachFuncs.forEach((attach) => { + _node = attach(_node); + }); + return _node; + }; +} + export function attachModifiers(node: T, original: T): T { node.modifiers = original.modifiers; return node; } + +export function attachParent(node: T, original: T): T { + node.parent = original.parent; + return node; +} + +export function refreshNodeCache(node: T, original: T): T { + NodeCacheFactory.getInstance().refresh(original, node); + NodeCacheFactory.getInstance().refreshUpdate(original, node); + return node; +} + +export function attachUpdateToCreatedNode(node: T): T { + const cacheMap = NodeCacheFactory.getInstance().getCacheMap(); + const childrenPeer = global.es2panda._AstNodeChildren(global.context, node.peer); + new NativePtrDecoder().decode(childrenPeer).forEach((peer: KNativePointer) => { + global.generatedEs2panda._AstNodeSetParent(global.context, peer, node?.peer ?? nullptr); + cacheMap.forEach((cache) => { + if (!cache.shouldUpdate(node) && cache.shouldUpdateByPeer(peer)) { + cache.addNodeToUpdate(node); + } + }); + }); + return node; +} \ No newline at end of file diff --git a/koala-wrapper/src/arkts-api/utilities/public.ts b/koala-wrapper/src/arkts-api/utilities/public.ts index b75860e156b99d2115db865c7f0e0243a98d12e3..54f4da568f55dd91d3561662d983bb80bbf0350a 100644 --- a/koala-wrapper/src/arkts-api/utilities/public.ts +++ b/koala-wrapper/src/arkts-api/utilities/public.ts @@ -39,7 +39,7 @@ import { type AnnotationUsage, } from '../../generated'; import { Program } from '../peers/Program'; -import { clearNodeCache } from '../class-by-peer'; +import { clearNodeCache } from '../node-by-type'; import { SourcePosition } from '../peers/SourcePosition'; import { MemberExpression } from '../to-be-generated/MemberExpression'; import { Es2pandaAstNodeType } from '../../Es2pandaEnums'; @@ -98,25 +98,33 @@ export function getDecl(node: AstNode): AstNode | undefined { if (isMemberExpression(node)) { return getDeclFromArrayOrObjectMember(node); } - if (isObjectExpression(node)) { - return getPeerObjectDecl(passNode(node)); - } - const decl = getPeerDecl(passNode(node)); + // if (isObjectExpression(node)) { + // return getPeerObjectDecl(passNode(node)); + // } + const decl = getPeerIdentifierDecl(passNode(node)); if (!!decl) { return decl; } - if (!!node.parent && isProperty(node.parent)) { - return getDeclFromProperty(node.parent); - } + // if (!!node.parent && isProperty(node.parent)) { + // return getDeclFromProperty(node.parent); + // } return undefined; } +// export function getDecl(node: AstNode): AstNode | undefined { +// const decl = global.es2panda._DeclarationFromAstNode(global.context, node.peer); +// if (decl === nullptr) { +// return undefined; +// } +// return unpackNonNullableNode(decl); +// } + function getDeclFromProperty(node: Property): AstNode | undefined { if (!node.key) { return undefined; } if (!!node.parent && !isObjectExpression(node.parent)) { - return getPeerDecl(passNode(node.key)); + return getPeerIdentifierDecl(passNode(node.key)); } return getDeclFromObjectExpressionProperty(node); } @@ -150,7 +158,7 @@ function getDeclFromArrayOrObjectMember(node: MemberExpression): AstNode | undef return getDecl(node.property); } -export function getPeerDecl(peer: KNativePointer): AstNode | undefined { +export function getPeerIdentifierDecl(peer: KNativePointer): AstNode | undefined { const decl = global.es2panda._DeclarationFromIdentifier(global.context, peer); if (decl === nullptr) { return undefined; @@ -166,6 +174,22 @@ export function getPeerObjectDecl(peer: KNativePointer): AstNode | undefined { return unpackNonNullableNode(decl); } +export function getPeerMemberDecl(peer: KNativePointer): AstNode | undefined { + const decl = global.es2panda._DeclarationFromMemberExpression(global.context, peer); + if (decl === nullptr) { + return undefined; + } + return unpackNonNullableNode(decl); +} + +export function getPeerPropertyDecl(peer: KNativePointer): AstNode | undefined { + const decl = global.es2panda._DeclarationFromProperty(global.context, peer); + if (decl === nullptr) { + return undefined; + } + return unpackNonNullableNode(decl); +} + export function getAnnotations(node: AstNode): readonly AnnotationUsage[] { if (!isFunctionDeclaration(node) && !isScriptFunction(node) && !isClassDefinition(node)) { throwError('for now annotations allowed only for: functionDeclaration, scriptFunction, classDefinition'); @@ -217,8 +241,12 @@ export function importDeclarationInsert(node: ETSImportDeclaration, program: Pro global.es2panda._InsertETSImportDeclarationAndParse(global.context, program.peer, node.peer); } -export function getProgramFromAstNode(node: AstNode): Program { - return new Program(global.es2panda._AstNodeProgram(global.context, node.peer)); +export function getProgramFromAstNode(node: AstNode): Program | undefined { + const programPeer = global.es2panda._AstNodeProgram(global.context, node.peer); + if (programPeer === nullptr) { + return undefined; + } + return new Program(programPeer); } export function hasModifierFlag(node: AstNode, flag: Es2pandaModifierFlags): boolean { diff --git a/koala-wrapper/src/generated/peers/SpreadElement.ts b/koala-wrapper/src/generated/peers/SpreadElement.ts index 99aa74efe9913a92585551165d6fafd603fd6265..582e24fd5f476ab665cde8c018a61205ef5585df 100644 --- a/koala-wrapper/src/generated/peers/SpreadElement.ts +++ b/koala-wrapper/src/generated/peers/SpreadElement.ts @@ -78,7 +78,7 @@ export class SpreadElement extends AnnotatedExpression { return this; } get validateExpression(): ValidationInfo | undefined { - return new ValidationInfo(global.generatedEs2panda._SpreadElementValidateExpression(global.context, this.peer)); + return new ValidationInfo(global.generatedEs2panda._SpreadElementValidateExpression(global.context, this.peer)) } get typeAnnotation(): TypeNode | undefined { return unpackNode(global.generatedEs2panda._SpreadElementTypeAnnotationConst(global.context, this.peer)); diff --git a/koala-wrapper/src/reexport-for-generated.ts b/koala-wrapper/src/reexport-for-generated.ts index 37e3c6f565f14d5955d4983e7975932a0f668b40..cefb8764c1ab409ab387e38564156daafd0914f9 100644 --- a/koala-wrapper/src/reexport-for-generated.ts +++ b/koala-wrapper/src/reexport-for-generated.ts @@ -27,6 +27,6 @@ export { unpackObject, assertValidPeer } from "./arkts-api/utilities/private" -export { nodeByType } from "./arkts-api/class-by-peer" +export { nodeByType } from "./arkts-api/node-by-type" export { global } from "./arkts-api/static/global" export { Es2pandaMemberExpressionKind } from "./generated/Es2pandaEnums"